Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

rootEnergyHist.cxx

Go to the documentation of this file.
00001 //  class rootEnergyHist
00002 //  Author:  Theodore Hierath
00003 //  This class contains a histogram and graphing class for
00004 //  energies.
00005 //  The bins are numbered from 0 to number of bins - 1;
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 // This function must be called before the drawing function
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         // calculate uncertainty by addition under quadrature
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         // clear temporary array
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 // scale_factor = number to multiply each bin by
00202 // mode = "normal", "begin", or "end"
00203 // current_plot = current_plot number (numbering starts at 0)
00204 // total_plots = the total number of plots to go on the graph
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 // If the output is going to be used for another source, the histogram should have 
00421 // a large enough number of bins to minimize rounding errors caused by bin size.
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         // Use center of bin to determine the energies
00429         double energy = retrieveEnergy(i) * 1000; // GeV->MeV
00430         double flux = double(retrieveFlux(i)) * scale_factor / energy; // E*Flux -> Flux
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 }

Generated on Wed Oct 16 14:01:30 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001