00001
00002
00003
00004
00005
00006
00007 #include "rootEnergyHist.h"
00008 #include <iostream>
00009 #include <iomanip>
00010 #include <fstream>
00011
00012 rootEnergyHist::rootEnergyHist(int bins,
00013 double min_energy,
00014 double max_energy) :
00015 emin(min_energy),
00016 emax(max_energy),
00017 num_bins(bins)
00018 {
00019 range = log10(emax/emin);
00020 currentType = linear;
00021 flux_hist = new rootHist(bins);
00022 flux_sigma_hist = new rootHist(bins);
00023 raw_hist = new rootHist(bins);
00024 graphTitle = "No Title";
00025 xlabel = "";
00026 ylabel = "";
00027 fluxMode = false;
00028 use_flux_min = false;
00029 use_flux_max = false;
00030 }
00031
00032 rootEnergyHist::~rootEnergyHist(void)
00033 {
00034 delete flux_hist;
00035 delete flux_sigma_hist;
00036 delete raw_hist;
00037 }
00038
00039 rootEnergyHist::rootEnergyHist(const rootEnergyHist& oldHist) :
00040 emin(oldHist.emin),
00041 emax(oldHist.emax),
00042 num_bins(oldHist.num_bins)
00043 {
00044 range = oldHist.range;
00045 currentType = oldHist.currentType;
00046 flux_hist = new rootHist(num_bins);
00047 flux_sigma_hist = new rootHist(num_bins);
00048 raw_hist = new rootHist(num_bins);
00049
00050 for(int i = 0; i < num_bins; i++)
00051 {
00052 double oldCount = (oldHist.raw_hist)->retrieveBin(i);
00053 raw_hist->updateBin(i, oldCount );
00054
00055 oldCount = (oldHist.flux_hist)->retrieveBin(i);
00056 flux_hist->updateBin(i, oldCount );
00057
00058 oldCount = (oldHist.flux_sigma_hist)->retrieveBin(i);
00059 flux_sigma_hist->updateBin(i, oldCount );
00060 }
00061
00062 graphTitle = oldHist.graphTitle;
00063 xlabel = oldHist.xlabel;
00064 ylabel = oldHist.ylabel;
00065 fluxMode = oldHist.fluxMode;
00066 use_flux_min = oldHist.use_flux_min;
00067 use_flux_max = oldHist.use_flux_max;
00068 }
00069
00070
00071 void rootEnergyHist::setTitle(std::string title)
00072 {
00073 graphTitle = title;
00074 }
00075
00076 void rootEnergyHist::setXLabel(std::string label)
00077 {
00078 xlabel = label;
00079 }
00080
00081 void rootEnergyHist::setYLabel(std::string label)
00082 {
00083 ylabel = label;
00084 }
00085
00086 void rootEnergyHist::setGraphType(const char *graph_type)
00087 {
00088 if(0 == strcmp(graph_type,"linear"))
00089 currentType = linear;
00090 else if(0 == strcmp(graph_type,"semilogx"))
00091 currentType = semilogx;
00092 else if(0 == strcmp(graph_type,"semilogy"))
00093 currentType = semilogy;
00094 else if(0 == strcmp(graph_type,"log"))
00095 currentType = loglog;
00096 else
00097 std::cerr << "ERROR: Invalid Graph Type" << std::endl;
00098 }
00099
00100 void rootEnergyHist::store(double energy)
00101 {
00102 if(energy < emax && energy > emin)
00103 {
00104 if(currentType == loglog || currentType == semilogx)
00105 {
00106 int currentBin = int(num_bins * (log10(energy/emin) / range));
00107 double contents = raw_hist->retrieveBin(currentBin);
00108 raw_hist->updateBin(currentBin,++contents);
00109 }
00110 else
00111 {
00112 int currentBin = int(floor(num_bins * (energy - emin) / (emax - emin)));
00113 double contents = raw_hist->retrieveBin(currentBin);
00114 raw_hist->updateBin(currentBin,++contents);
00115 }
00116 }
00117 }
00118
00119 double rootEnergyHist::retrieveCount(int binNumber)
00120 {
00121 return raw_hist->retrieveBin(binNumber);
00122 }
00123
00124 double rootEnergyHist::retrieveFlux(int binNumber)
00125 {
00126 return flux_hist->retrieveBin(binNumber);
00127 }
00128
00129 double rootEnergyHist::retrieveFluxUncertainty(int binNumber)
00130 {
00131 return flux_sigma_hist->retrieveBin(binNumber);
00132 }
00133
00134 double rootEnergyHist::retrieveEnergy(int binNumber)
00135 {
00136 return emin*pow(10,((binNumber + 0.5)/num_bins) * range );
00137 }
00138
00139 double rootEnergyHist::retrieveRange(void)
00140 {
00141 return range;
00142 }
00143
00144
00145 void rootEnergyHist::setFluxMode(void)
00146 {
00147 fluxMode = true;
00148 }
00149
00150 void rootEnergyHist::setFluxMin(double f)
00151 {
00152 use_flux_min = true;
00153 flux_min = f;
00154 }
00155
00156 void rootEnergyHist::setFluxMax(double f)
00157 {
00158 use_flux_max = true;
00159 flux_max = f;
00160 }
00161
00162
00163 void rootEnergyHist::apply(double scale_factor)
00164 {
00165 for(int i = 0; i < num_bins; ++i)
00166 {
00167 double current_flux = flux_hist->retrieveBin(i);
00168 double current_count = raw_hist->retrieveBin(i);
00169 current_flux += (current_count * scale_factor);
00170 flux_hist->updateBin(i,current_flux);
00171
00172
00173 current_flux = sqrt(pow(flux_sigma_hist->retrieveBin(i),2)+current_count) * scale_factor;
00174 flux_sigma_hist->updateBin(i,current_flux);
00175
00176
00177 raw_hist->updateBin(i,0);
00178 }
00179 }
00180
00181 void rootEnergyHist::reset(void)
00182 {
00183 for(int i = 0; i < num_bins; ++i)
00184 {
00185 flux_hist->updateBin(i,0);
00186 flux_sigma_hist->updateBin(i,0);
00187 raw_hist->updateBin(i,0);
00188 }
00189
00190 graphTitle = "No Title";
00191 xlabel = "";
00192 ylabel = "";
00193 fluxMode = false;
00194 use_flux_min = false;
00195 use_flux_max = false;
00196 range = log10(emax/emin);
00197 currentType = linear;
00198 }
00199
00200
00201
00202
00203
00204
00205 void rootEnergyHist::draw(double scale_factor, std::string mode, int current_plot, int total_plots)
00206 {
00207 char *window_title = "Graph Window";
00208
00209 if(current_plot >= total_plots)
00210 {
00211 std::cerr << "Error: Invalid plot number" << std::endl;
00212 exit(0);
00213 }
00214
00215 if(current_plot == 0)
00216 {
00217 std::ofstream out_file;
00218
00219 if(mode != "end")
00220 {
00221 out_file.open("graph.cxx");
00222
00223 if(false == out_file.is_open())
00224 {
00225 std::cerr << "Unable to open temporary file for writing." << std::endl;
00226 exit(0);
00227 }
00228
00229 out_file <<
00230 "{\n"
00231 " gROOT->Reset();\n";
00232 }
00233 else
00234 {
00235 out_file.open("graph.cxx", std::ios::app);
00236 }
00237
00238 out_file <<
00239 " char *energy_window_title = \"" << window_title << "\";\n"
00240 " char *energy_graph_title = \"" << "Particle Flux vs. Kinetic Energy" << "\";\n"
00241 " char *energy_y_label = \"" << ylabel << "\";\n"
00242 " char *energy_x_label = \"" << xlabel << "\";\n"
00243
00244 " double energy_min= "<< emin << ", energy_max=" << emax << ";\n"
00245 " int num_bins = "<< num_bins << ";\n"
00246 " double log_energy_range = " << retrieveRange() << ";\n"
00247 " double energy[num_bins];\n"
00248 " double e_energy[num_bins];\n"
00249
00250 " for(int i = 0; i < num_bins; i++) {\n"
00251 " energy[i] = energy_min*pow(10,((i+0.5)/num_bins) * log_energy_range);\n"
00252 " e_energy[i] = 0;\n"
00253 " }\n"
00254 " // name, title, wtopx, wtopy, ww, wh\n"
00255 " c1 = new TCanvas(\"c1\",energy_window_title, 200, 200, 700, 500);\n"
00256 " c1->SetGrid();\n"
00257 " c1->GetFrame()->SetFillColor(21);\n"
00258 " c1->GetFrame()->SetBorderSize(12);\n";
00259
00260 if(currentType == loglog) out_file << " c1->SetLogx(1); c1->SetLogy(1);\n";
00261 else if(currentType == semilogx) out_file << " c1->SetLogx(1);\n";
00262 else if(currentType == semilogy) out_file << " c1->SetLogy(1);\n";
00263 else if(currentType == linear) ;
00264 else
00265 std::cerr << "Error: invalid graph type" << std::endl;
00266
00267 out_file <<
00268 " leg = new TLegend(0.73,0.83,0.99,0.99);\n"
00269 " double scale_factor" << current_plot << " = " << scale_factor << ";\n"
00270 " double count" << current_plot << "[] = {\n";
00271 {for(int i = 0; i < num_bins; ++i)
00272 out_file << std::setw(7) << retrieveFlux(i) << (i%5==4? ",\n" : ",");
00273 }
00274
00275 out_file <<
00276 " };\n"
00277 " double e_count" << current_plot << "[num_bins] = {\n";
00278 {for(int i = 0; i < num_bins; ++i)
00279 out_file << std::setw(7) << retrieveFluxUncertainty(i) << (i%5==4? ",\n" : ",");
00280 }
00281
00282 out_file <<
00283 " };\n"
00284 " for(i = 0; i < num_bins; i++) {\n"
00285 " e_count" << current_plot << "[i] *= scale_factor" << current_plot;
00286 if(fluxMode == true)
00287 out_file << "/(energy[i]*1000);\n";
00288 else
00289 out_file << ";\n";
00290
00291 out_file <<
00292 " count" << current_plot << "[i] *=scale_factor" << current_plot;
00293
00294 if(fluxMode == true)
00295 out_file << "/(energy[i]*1000);\n";
00296 else
00297 out_file << ";\n";
00298
00299 out_file <<
00300 " }\n"
00301 " gr" << current_plot << " = new TGraphErrors(num_bins,energy,count" << current_plot
00302 << ",e_energy,e_count" << current_plot << ");\n"
00303 " gr" << current_plot << "->SetTitle(energy_graph_title);\n"
00304 " gr" << current_plot << "->SetMarkerColor(2);\n"
00305 " gr" << current_plot << "->SetMarkerStyle(21);\n"
00306 " leg->AddEntry(gr" << current_plot << ",\"" << graphTitle << "\",\"P\");\n";
00307
00308 out_file.close();
00309 }
00310 else if(current_plot <= total_plots - 1)
00311 {
00312 std::ofstream out_file("graph.cxx", std::ios::app);
00313 out_file <<
00314 " c1->cd();\n"
00315 " double scale_factor" << current_plot << " = " << scale_factor << ";\n"
00316 " double count" << current_plot << "[] = {\n";
00317 {for(int i = 0; i < num_bins; i++)
00318 out_file << std::setw(5) << retrieveFlux(i) << (i%5==4? ",\n" : ",");
00319 }
00320
00321 out_file <<
00322 " };\n"
00323 " double e_count" << current_plot << "[num_bins] = {\n";
00324 {for(int i = 0; i < num_bins; ++i)
00325 out_file << std::setw(7) << retrieveFluxUncertainty(i) << (i%5==4? ",\n" : ",");
00326 }
00327
00328 out_file <<
00329 " };\n"
00330 " for(i = 0; i < num_bins; i++) {\n"
00331 " e_count" << current_plot << "[i] *= scale_factor" << current_plot;
00332 if(fluxMode == true)
00333 out_file << "/(energy[i]*1000);\n";
00334 else
00335 out_file << ";\n";
00336
00337 out_file <<
00338 " count" << current_plot << "[i] *=scale_factor" << current_plot;
00339
00340 if(fluxMode == true)
00341 out_file << "/(energy[i]*1000);\n";
00342 else
00343 out_file << ";\n";
00344
00345 out_file <<
00346 " }\n"
00347 " gr" << current_plot << " = new TGraphErrors(num_bins,energy,count" << current_plot
00348 << ",e_energy,e_count" << current_plot << ");\n"
00349 " gr" << current_plot << "->SetMarkerColor(" << 2+current_plot << ");\n"
00350 " gr" << current_plot << "->SetMarkerStyle(" << 21 << ");\n"
00351 " leg->AddEntry(gr" << current_plot << ",\"" << graphTitle << "\",\"P\");\n";
00352 out_file.close();
00353 }
00354
00355 if(current_plot >= total_plots - 1)
00356 {
00357 std::ofstream out_file("graph.cxx", std::ios::app);
00358
00359 out_file <<
00360 " double max_count = 0;\n"
00361 " double min_count = 1e12;\n"
00362 " for(int i = 0; i < num_bins; i++)\n"
00363 " {\n";
00364 {for(int plot = 0; plot < total_plots; plot++) {
00365 out_file <<
00366 " if(count" << plot << "[i] > max_count)\n"
00367 " max_count = count" << plot << "[i];\n"
00368 " if(count" << plot << "[i] < min_count && count" << plot << "[i] > 0)\n"
00369 " min_count = count" << plot << "[i];\n";
00370 }}
00371 out_file <<
00372 " }\n"
00373 " double energy_limits[] = {energy_min,energy_max};\n"
00374 " double count_limits[] = {";
00375
00376 if(use_flux_min)
00377 out_file << flux_min << ",";
00378 else
00379 out_file << "min_count,";
00380
00381 if(use_flux_max)
00382 out_file << flux_max;
00383 else
00384 out_file << "max_count";
00385
00386 out_file <<
00387 "};\n"
00388 " int bin_limits = 2;\n"
00389 " graph0 = new TGraph(bin_limits,energy_limits,count_limits);\n"
00390 " graph0->SetTitle(energy_graph_title);\n"
00391 " graph0->Draw(\"AP\");\n"
00392 " TAxis *ax = graph0->GetXaxis();\n"
00393 " TAxis *ay = graph0->GetYaxis();\n"
00394 " ay->SetTitle(energy_y_label); ay->CenterTitle(1);\n"
00395 " ax->SetLimits(energy_min, energy_max);\n"
00396 " ax->SetTitle(energy_x_label); ax->CenterTitle(1); \n"
00397 " ax->SetTitleOffset(1.2);\n";
00398
00399 {for(int plot = 0; plot < total_plots; plot++) {
00400 out_file <<
00401 " gr" << plot << "->Draw(\"P\");\n";
00402 }}
00403
00404 out_file <<
00405 " leg->Draw();\n"
00406 " c1->Modified();\n"
00407 " c1->Update();\n";
00408
00409 if(mode != "begin")
00410 out_file << "\n}\n";
00411
00412 out_file.close();
00413
00414 if(mode != "begin")
00415 system("root -l graph.cxx");
00416 }
00417 }
00418
00419
00420
00421
00422 void rootEnergyHist::writeFile(double scale_factor, std::ostream& out_file)
00423 {
00424 out_file << "%Energy (in MeV) vs. Flux (in particles/m2-s-sr-MeV)" << std::endl;
00425
00426 for(int i = 0; i < num_bins; i++)
00427 {
00428
00429 double energy = retrieveEnergy(i) * 1000;
00430 double flux = double(retrieveFlux(i)) * scale_factor / energy;
00431
00432 out_file << std::setiosflags(std::ios::right|std::ios::scientific)
00433 << std::setw(14) << std::setprecision(5) << energy
00434 << std::setiosflags(std::ios::right|std::ios::scientific)
00435 << std::setw(14) << std::setprecision(5) << flux
00436 << std::endl;
00437 }
00438
00439 }