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

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 at Wed Nov 21 12:20:34 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000