utilities.cc

00001 #include "utilities.hh"
00002 #include "EventData.hh"
00003 
00004 #include "TFile.h"
00005 #include "TString.h"
00006 #include "TTree.h"
00007 #include "TGraph.h"
00008 #include "TGraphErrors.h"
00009 #include "TROOT.h"
00010 #include "TSeqCollection.h"
00011 #include "TMath.h"
00012 #include "TPad.h"
00013 #include "TBox.h"
00014 #include "TPave.h"
00015 #include "TTimeStamp.h"
00016 #include "TH1.h"
00017 #include "TH2.h"
00018 #include "TF1.h"
00019 #include "TH1F.h"
00020 #include "TH1D.h"
00021 #include "TProfile.h"
00022 #include "TPaveText.h"
00023 #include "TSystem.h"
00024 #include "TClass.h"
00025 #include "TList.h"
00026 #include "TClassMenuItem.h"
00027 
00028   
00029 
00030 #include "TGFileDialog.h"
00031 
00032 #include "Reader.hh"
00033 #include "EventHandler.hh"
00034 #include "ConvertData.hh"
00035 
00036 #include <algorithm>
00037 #include <numeric>
00038 #include <iostream>
00039 #include <fstream>
00040 #include <sstream>
00041 #include <iomanip>
00042 using namespace std;
00043 
00044 TFile* OpenFile(const char* filename, const char* option)
00045 {
00046   //see if it's already open
00047   TSeqCollection* files = gROOT->GetListOfFiles();
00048   for(int i=0; i< files->GetSize(); i++){
00049     if( TString(files->At(i)->GetName()) == TString(filename))
00050       return (TFile*)(files->At(i));
00051   }
00052   
00053   //otherwise try to open it
00054   TFile* f = new TFile(filename,option);
00055   if(!f || !f->IsOpen() || f->IsZombie()){
00056     cerr<<"Unable to open file "<<filename<<endl;
00057     return 0;
00058   }
00059   return f;
00060 }
00061 
00062 TTree* GetEventsTree(const char* filename)
00063 {
00064   TFile* f = OpenFile(filename);
00065   if(!f)
00066     return 0;
00067   TTree* Events = (TTree*)(f->Get("Events"));
00068   if(!Events){
00069     cerr<<"Unable to open Events tree from file "<<filename<<endl;
00070     return 0;
00071   }
00072   return Events;
00073 }
00074   
00075 TGraph* GetAverageGraph(const char* filename, int channel)
00076 {
00077   TFile* f = OpenFile(filename);
00078   if(!f)
00079     return 0;
00080   TString name = "average_channel";
00081   name += channel;
00082   TGraph* g = (TGraph*)(f->Get(name));
00083   if(!g){
00084     cerr<<"Unable to open graph "<<name<<" from file "<<filename<<endl;
00085     return 0;
00086   }
00087   return g;
00088 }
00089 
00090 TGraphErrors* GetAverageGraph(int run_no, int channel) {
00091   std::string run;
00092   std::stringstream out;
00093   out << run_no;
00094   run = out.str();
00095   std::string filename(6-run.size(), '0');
00096   filename = "/data/s1waveform/Run" + filename + run + ".root";
00097   //std::cerr << filename << std::endl;
00098   return (TGraphErrors*) GetAverageGraph(filename.c_str(), channel);
00099 }
00100 
00101 int DividePad(TPad* p, int nplots)
00102 {
00103   int npadsx = 1, npadsy=1;
00104   if( nplots < 2)
00105     {}
00106   else if( nplots == 2)
00107     npadsx=2;
00108   else if (nplots < 5){
00109     npadsx=2; npadsy=2;
00110   }
00111   else if(nplots < 7){
00112     npadsx=3; npadsy=2;
00113   }
00114   else if(nplots < 10){
00115     npadsx=3; npadsy=3;
00116   }
00117   else if(nplots < 13){
00118     npadsx=4, npadsy=3;
00119   }
00120   else if(nplots < 17){
00121     npadsx=4; npadsy=4;
00122   }
00123   else{
00124     npadsx=(int)TMath::Ceil(sqrt(nplots)); 
00125     npadsy=(int)TMath::Ceil(sqrt(nplots));
00126   }
00127   p->Divide(npadsx,npadsy);
00128   return npadsx*npadsy;
00129 }
00130 
00131 int explode_string(const std::string& s, char delim, 
00132                    std::vector<std::string>& out)
00133 {
00134   //find all the occurrences of delim
00135   size_t start = 0;
00136   while(1){
00137     size_t end = s.find(delim,start);
00138     if(end == std::string::npos)
00139       break;
00140     out.push_back(s.substr(start, end-start));
00141     start = end+1;
00142   }
00143   out.push_back(s.substr(start,std::string::npos));
00144   return out.size();
00145 }
00146 
00147 std::vector<std::string> explode_cut(const TCut& cut)
00148 {
00149   std::vector<std::string> out;
00150   //when you && or add cuts together, each cut is placed into parentheses
00151   //but have to avoid things like (x-y)/2
00152   std::string s = cut.GetTitle();
00153   size_t pos = 0;
00154   int prev = 0;
00155   while(pos < s.size() && pos != std::string::npos){
00156     //look for the combination )&&, which marks an edge
00157     pos = s.find(")&&",pos);
00158     if(pos == std::string::npos) pos = s.size()-1;
00159     //now look backward until you find the matching '('
00160     int open = 0;
00161     int pos2 = pos;
00162     while(--pos2 > prev){
00163       if(s[pos2] == ')') ++open;
00164       else if(s[pos2] == '('){
00165         if(open == 0) break;
00166         else --open;
00167       }
00168     }
00169     out.push_back(s.substr(pos2+1,pos-pos2-1-open));
00170     ++pos;
00171     prev = pos+2;
00172   }
00173   return out;
00174 }
00175 
00176 void DrawOperationsBoxes(bool drawbubble, bool drawrecirc)
00177 {
00178   double dummy, y1, y2;
00179   gPad->Update();
00180   gPad->GetRangeAxis(dummy,y1,dummy,y2);
00181   
00182   if(drawbubble){
00183     double x1[] = { TTimeStamp(2010,04,15,11,06,55,0,0).GetSec(),
00184                     TTimeStamp(2010,05,03,15,51,33,0,0).GetSec(),
00185                     TTimeStamp(2010,05,05,10,54,19,0,0).GetSec(),
00186                     TTimeStamp(2010,05,05,15,57,33,0,0).GetSec()
00187     };
00188     double x2[] = { TTimeStamp(2010,04,15,16,38,48,0,0).GetSec(),
00189                     TTimeStamp(2010,05,03,20,40,28,0,0).GetSec(),
00190                     TTimeStamp(2010,05,05,13,29,44,0,0).GetSec(),
00191                     TTimeStamp(2010,05,05,18,45,53,0,0).GetSec()
00192     };
00193     
00194     for(size_t i = 0; i < sizeof(x1)/sizeof(double); i++){
00195       TBox b(x1[i], y1, x2[i], y2);
00196       b.SetFillStyle(3002);
00197       b.SetFillColor(kRed);
00198       b.DrawClone();
00199     }
00200   }
00201   if(drawrecirc){
00202     double x1[] = { TTimeStamp(2010,05,07,15,40,32,0,0).GetSec(),
00203                     TTimeStamp(2010,07,14,17,23,00,0,0).GetSec()
00204     };
00205     double x2[] = { TTimeStamp(2010,05,07,23,59,59,0,0).GetSec(),
00206                     TTimeStamp(2010,07,15,16,27,21,0,0).GetSec()
00207     };
00208     for(size_t i = 0; i < sizeof(x1)/sizeof(double); i++){
00209       TBox b(x1[i], y1, x2[i], y2);
00210       b.SetFillStyle(3002);
00211       b.SetFillColor(kBlue);
00212       b.DrawClone();
00213     }
00214   }
00215 }
00216 
00217 double GetBaseline(TGraph* g, int npts, bool subtract)
00218 {
00219   double* gy = g->GetY();
00220   double baseline = accumulate(gy,gy+npts,0.)/(1.*npts);
00221   if(subtract){
00222     for(int i=0; i < g->GetN(); i++) gy[i] -= baseline;
00223   }
00224   return baseline;
00225 }
00226 
00227 TGraph* GetRealEvent(const char* filename, int eventnum, int channel)
00228 {
00229   Reader reader(filename);
00230   if(!reader.IsOk()){
00231     std::cerr<<"Unable to open file "<<filename<<std::endl;
00232     return 0;
00233   }
00234   
00235   EventHandler* handler = EventHandler::GetInstance();
00236   handler->AddModule<ConvertData>();
00237   handler->Initialize();
00238   RawEventPtr event = reader.GetEventWithID(eventnum);
00239   if(event == RawEventPtr()){
00240     std::cerr<<"Unable to load event with id "<<eventnum<<std::endl;
00241     return 0;
00242   }
00243   handler->Process(event);
00244   EventPtr evt = handler->GetCurrentEvent();
00245   handler->Finalize();
00246   
00247   ChannelData* chdata = evt->GetEventData()->GetChannelByID(channel);
00248   if(!chdata){
00249     std::cerr<<"Unable to load data for channel "<<channel<<std::endl;
00250     return 0;
00251   }
00252   return chdata->GetTGraph();
00253 }
00254 
00255 ChannelData* GetChannelData(const char* filename, int eventnum, int channel)
00256 {
00257   Reader reader(filename);
00258   if(!reader.IsOk()){
00259     std::cerr<<"Unable to open file "<<filename<<std::endl;
00260     return 0;
00261   }
00262 
00263   EventHandler* handler = EventHandler::GetInstance();
00264   handler->AddModule<ConvertData>();
00265   handler->Initialize();
00266 
00267   ChannelData* chdata = 0;
00268   
00269   while(reader.IsOk() && !reader.eof()){
00270     RawEventPtr event = reader.GetEventWithID(eventnum++);
00271     if(event == RawEventPtr()){
00272       std::cerr<<"Unable to load event with id "<<eventnum<<std::endl;
00273       return 0;
00274     }
00275     if(eventnum%5000 == 0)
00276       Message(INFO)<<"Processing event "<<eventnum<<std::endl;
00277     
00278     handler->Process(event);
00279   }
00280   EventPtr evt = handler->GetCurrentEvent();
00281   handler->Finalize();
00282   
00283   chdata = evt->GetEventData()->GetChannelByID(channel);
00284   if(!chdata){
00285     std::cerr<<"Unable to load data for channel "<<channel<<std::endl;
00286     return 0;
00287   }
00288   
00289   return chdata;
00290 }
00291 
00292 double CorrelationCoefficient(int npts, double* x, double* y)
00293 {
00294   double sumx=0, sumy=0, sumx2=0, sumy2=0, sumxy=0;
00295   for(int i=0; i< npts; i++){
00296     sumx += x[i];
00297     sumy += y[i];
00298     sumx2 += x[i]*x[i];
00299     sumy2 += y[i]*y[i];
00300     sumxy += x[i]*y[i];
00301   }
00302   //formula from wikipedia Correlation and Dependence
00303   return (npts * sumxy - sumx*sumy) / 
00304     ( sqrt(npts*sumx2 - sumx*sumx) * sqrt(npts*sumy2 - sumy*sumy) );
00305 }
00306 
00307 TCut GetStandardCuts()
00308 {
00309   TCut energy_min = "event.s1_full>50";
00310   TCut energy_max = "event.s1_full < 10000";
00311   TCut saturated = "!event.saturated";
00312   //TCut peak_time = "GetPulse(0)->peak_time-GetPulse(0)->start_time < 0.1";
00313   TCut s1length = "GetPulse(0)->end_time-GetPulse(0)->start_time<20";
00314   TCut baseline = "GetChannelByID(-2)->baseline.found_baseline";
00315   TCut p0start = "GetPulse(0)->start_time < 0.1 && GetPulse(0)->start_time > -0.1";  
00316   TCut status = "event.status==0";
00317   return energy_min + energy_max + saturated + s1length + baseline + p0start+status;
00318 }
00319 
00320 TCut GetTwoPulseCuts()
00321 {
00322   TCut drift="event.drift_time>20";
00323   TCut s2 = "event.s2_full>10";
00324   TCut t95="GetPulse(1).t95>10 && GetPulse(1).t95<30";
00325   TCut valid = "event.s1s2_fixed_valid";
00326   return GetStandardCuts()+drift+s2+t95+valid;
00327 }
00328 
00329 TCut GetOnePulseCuts(bool onlyone)
00330 {
00331   TCut base = GetStandardCuts()+"event.s1_fixed_valid";
00332   if(onlyone)
00333     base += "GetChannelByID(-2)->npulses == 1";
00334   return base;
00335 }
00336 
00337 TCanvas* TwoPulsePlots(TTree* Events, bool queryfit, TCut cuts,TCanvas* c)
00338 {
00339   TCut all_cuts=cuts+GetTwoPulseCuts();
00340   c->Clear();
00341   c->Divide(3,2);
00342   //set the canvas title
00343   EventData* evt=0;
00344   Events->SetBranchAddress("event",&evt);
00345   Events->GetEntry(0);
00346   if(evt){
00347     int first_run = evt->run_id;
00348     stringstream cantitle;
00349     cantitle<<"Run "<<first_run;
00350     Events->GetEntry(Events->GetEntries()-1);
00351     if(evt->run_id != first_run)
00352       cantitle<<" - Run "<<evt->run_id;
00353     c->SetTitle(cantitle.str().c_str());
00354   }
00355   bool plotlog = true;
00356   //uncorrected s2/s1 vs drift time
00357   c->cd(1);
00358   if(plotlog){
00359     Events->Draw("log(event.s2_full/event.s1_full) : drift_time",
00360                  all_cuts+"event.f90_full < 0.5","colz");
00361   }
00362   else{
00363     Events->Draw("(event.s2_full/event.s1_full) : drift_time",
00364                  all_cuts+"event.f90_full < 0.5","colz");
00365   }
00366   TH1* htemp = (TH1*)gROOT->FindObject("htemp");
00367   double tau = 1000000.;
00368   if(htemp){
00369     htemp->SetName("hraw");
00370     htemp->SetTitle("Ln(S2/S1) vs Drift Time");
00371     htemp->GetXaxis()->SetTitle("Drift time [#mus]");
00372     htemp->GetYaxis()->SetTitle("Ln(S2/S1)");
00373     
00374     TGraph* pf = (TGraph*)gROOT->FindObject("Graph");
00375     pf->SetName("gscatter");
00376     //TProfile* pf = ((TH2*)(htemp))->ProfileX("s2s1vtime");
00377     //pf->Draw("same");
00378     if(pf){
00379       const char* fitfunc = (plotlog ? "pol1" : "expo");
00380       double fitmin=50, fitmax = 120;
00381       if(queryfit){
00382         gPad->Update();
00383         std::cout<<"Enter '<min> <max>' range to fit lifetime:"<<std::endl;
00384         std::cin>>fitmin>>fitmax;
00385       }
00386       pf->Fit(fitfunc,"q","same",fitmin, fitmax);
00387       TF1* pol1 = pf->GetFunction(fitfunc);
00388       if(pol1){
00389         pol1->SetLineColor(kRed);
00390         pol1->Draw("same");
00391         tau = -1./pol1->GetParameter(1);
00392         TPaveText* pt = new TPaveText(0.1,0.1,0.9,0.3,"NDC");
00393         pt->SetBorderSize(0);
00394         stringstream text;
00395         text<<"Lifetime = "<<(int)tau<<"#pm"
00396             <<(int)(tau*tau*pol1->GetParError(1))
00397             <<" #mus";
00398         pt->AddText(text.str().c_str());
00399         text.str("");
00400         text<<std::setiosflags(std::ios::fixed)<<setprecision(2);
00401         text<<"Intercept = "<<pol1->GetParameter(0)<<"#pm"
00402             <<pol1->GetParError(0);
00403         pt->AddText(text.str().c_str());
00404         pt->Draw();
00405       }
00406     }
00407   }
00408   stringstream alias;
00409   alias<<"exp(event.drift_time/"<<tau<<")*event.s2_full / event.s1_full";
00410   Events->SetAlias("ratio_corrected",alias.str().c_str());
00411 
00412   c->cd(2);
00413   Events->Draw("log(ratio_corrected) : drift_time",
00414                all_cuts,"colz");
00415   htemp = (TH1*)gROOT->FindObject("htemp");
00416   if(htemp){
00417     htemp->SetName("hcorrected");
00418     htemp->SetTitle("Ln(S2/S1) Corrected vs Drift Time");
00419     htemp->GetXaxis()->SetTitle("Drift time [#mus]");
00420     htemp->GetYaxis()->SetTitle("Ln(S2/S1) Corrected");
00421     //gPad->SetLogz();
00422   }
00423   c->cd(3);
00424   Events->Draw("log10(ratio_corrected):event.f90_full>>hscatter(100,0,1,100,-3,3)",
00425                all_cuts,"colz");
00426   htemp = (TH1*)gROOT->FindObject("hscatter");
00427   if(htemp){
00428     htemp->SetName("hscatter1");
00429     htemp->SetTitle("Log(S2/S1) vs F90");
00430     htemp->GetXaxis()->SetTitle("F90");
00431     htemp->GetYaxis()->SetTitle("Log10(S2/S1) corrected for drift");
00432     gPad->SetLogz();
00433   }
00434   c->cd(4);
00435   Events->Draw("event.drift_time ",
00436                all_cuts);
00437   htemp = (TH1*)gROOT->FindObject("htemp");
00438   if(htemp){
00439     htemp->SetName("hdt");
00440     htemp->Rebin(2);
00441     htemp->SetTitle("Drift Time");
00442     htemp->GetXaxis()->SetTitle("drift time [#mus]");
00443   }
00444   c->cd(5);
00445   Events->Draw("log10(ratio_corrected)>>hratiolow(100,-3,3)",
00446                "event.f90_full>0 && event.f90_full<0.55"+all_cuts);
00447   htemp = (TH1*)gROOT->FindObject("hratiolow");
00448   if(htemp){
00449     htemp->SetName("hratiolow1");
00450     htemp->SetTitle("Log10(S2/S1) corrected");
00451     htemp->GetXaxis()->SetTitle("Log10(S2/S1) corrected");
00452   }
00453   Events->Draw("log10(ratio_corrected)>>hratiohigh(100,-3,3)",
00454                "event.f90_full>0.55 && event.f90_full<1"+all_cuts,"sames");
00455   htemp = (TH1*)gROOT->FindObject("hratiohigh");
00456   if(htemp){
00457     htemp->SetName("hratiohigh1");
00458     htemp->SetLineColor(kRed);
00459     htemp->SetTitle("F90>0.55");
00460     gPad->SetLogy();
00461   }
00462   
00463     
00464   c->cd(6);
00465   Events->Draw("event.y : event.x " , 
00466                "event.position_valid" + all_cuts);
00467   htemp = (TH1*)gROOT->FindObject("htemp");
00468   if(htemp){
00469     htemp->SetName("hxy");
00470     htemp->SetTitle("Event Position");
00471     htemp->GetXaxis()->SetTitle("X [cm]");
00472     htemp->GetYaxis()->SetTitle("Y [cm]");
00473   }
00474   
00475   
00476   
00477   c->cd(0);
00478   c->Modified();
00479   c->Update();
00480   return c;
00481   
00482 }
00483 
00484 TCanvas* OnePulsePlots(TTree* Events, TCut cuts,TCanvas* c)
00485 {
00486   TCut all_cuts = cuts+GetOnePulseCuts();
00487   EventData* evt=0;
00488   Events->SetBranchAddress("event",&evt);
00489   Events->GetEntry(0);
00490   if(evt){
00491     int first_run = evt->run_id;
00492     stringstream cantitle;
00493     cantitle<<"Run "<<first_run;
00494     Events->GetEntry(Events->GetEntries()-1);
00495     if(evt->run_id != first_run)
00496       cantitle<<" - Run "<<evt->run_id;
00497     c->SetTitle(cantitle.str().c_str());
00498   }
00499   
00500   c->Divide(2,2);
00501   c->cd(1);
00502   Events->Draw("event.s1_full>>hspec(200,0,4000)", all_cuts);
00503   TH1* htemp = (TH1*)gROOT->FindObject("hspec");
00504   if(htemp){
00505     htemp->SetTitle("Energy Spectrum");
00506     htemp->GetXaxis()->SetTitle("Energy [npe]");
00507   }
00508   c->cd(3);
00509   Events->Draw("event.f90_full:event.s1_full>>hfe(50,0,4000,50,0,1)",
00510                all_cuts, "colz");
00511   htemp = (TH1*)gROOT->FindObject("hfe");
00512   if(htemp){
00513     htemp->SetTitle("f90 vs Energy");
00514     htemp->GetXaxis()->SetTitle("Energy [npe]");
00515     htemp->GetYaxis()->SetTitle("f90");
00516   }
00517   c->cd(4);
00518   Events->Draw("event.f90_full>>hf90(100,0,1)",all_cuts);
00519   htemp = (TH1*)gROOT->FindObject("hf90");
00520   if(htemp){
00521     htemp->SetTitle("f90");
00522     htemp->GetXaxis()->SetTitle("f90");
00523   }
00524   return c;
00525 }
00526 
00527 TCanvas* PlotSpeDistributions(TTree* Events, bool normalize)
00528 {
00529   if(!Events) return 0;
00530   //get the runid from the first event
00531   EventData* evt = 0;
00532   Events->SetBranchAddress(EventData::GetBranchName(), &evt);
00533   Events->GetEntry(0);
00534   //try to load the calibration
00535 
00536   //info.LoadCalibrationInfo();
00537 
00538   //plot all the channel histograms
00539   int nchans = (int)Events->GetMaximum("nchans");
00540   TCanvas* can = new TCanvas;
00541   DividePad(can,nchans);
00542   for(int i=0; i<nchans; i++){
00543     can->cd(i+1);
00544     std::stringstream cmd;
00545     cmd<<"channels["<<i<<"].single_pe.integral";
00546     if(normalize)
00547       cmd<<"/channels["<<i<<"].spe_mean>>h"<<i<<"(100,0,3)";
00548     else
00549       cmd<<">>h"<<i<<"(100,0,"<<3*evt->channels[i].spe_mean<<")";
00550     Long64_t entries = Events->Draw(cmd.str().c_str(),"");
00551     //Draw a TLine at the single photoelectron
00552     gPad->Update();
00553     double x = (normalize ? 1 : evt->channels[i].spe_mean);
00554     double y = gPad->GetY2();
00555     TLine* line = new TLine(x, 0, x, y);
00556     line->SetLineColor(kBlue);
00557     line->Draw();
00558 
00559     //set logy
00560     if(entries)
00561       gPad->SetLogy();
00562     
00563                             
00564   }
00565   can->cd(0);
00566   return can;
00567 }
00568 
00569 
00570 double ElectronLifetime(TTree* Events, bool newcanvas, bool defaultlimits)
00571 {
00572   if(newcanvas) new TCanvas;
00573   Events->Draw("event.s2_full/event.s1_full : event.drift_time >>hprof",
00574                GetTwoPulseCuts()+"event.f90_full<0.5","prof");
00575   TProfile* hprof = (TProfile*)gROOT->FindObject("hprof");
00576   double min = 50, max = 120;
00577   gPad->Update();
00578 
00579   if(!defaultlimits){
00580     std::cout<<"Enter fit limits:"<<std::endl;
00581     std::cin>>min>>max;
00582   }
00583   hprof->Fit("expo","MIQ","",min,max);
00584   TF1* expo = hprof->GetFunction("expo");
00585   double tau = -1./expo->GetParameter(1);
00586   //std::cout<<"Lifetime = "<<tau<<"+/-"<<tau*tau*expo->GetParError(1)<<" ; "
00587   //   <<"Intercept = "<<expo->GetParameter(0)<<"+/-"<<expo->GetParError(0)
00588   //   <<std::endl;
00589   return tau;
00590 
00591   
00592 }
00593 
00594 void SaveHistoToFile(TObject* c)
00595 {
00596   if(!c->InheritsFrom("TH1"))
00597     return;
00598   TH1* h = (TH1*)c;
00599   static const char* filetypes[] = {
00600     "Text files","*.txt",
00601     0,0
00602   };
00603   TGFileInfo fi;
00604   fi.fFileTypes = filetypes;
00605   new TGFileDialog(gClient->GetRoot(),0,kFDSave,&fi);
00606   if(!fi.fFilename)
00607     return;
00608   std::string fname = fi.fFilename;
00609   if(fname.rfind(".txt")==std::string::npos)
00610     fname.append(".txt");
00611   std::cout<<"Saving histogram "<<h->GetName()<<" to file "<<fname<<std::endl;
00612   std::ofstream fout(fname.c_str());
00613   if(fout.is_open()){
00614     fout<<"#X\tY\tYerr\n";
00615     for(int i=1; i<=h->GetNbinsX(); ++i){
00616       fout<<h->GetBinLowEdge(i)<<"\t"
00617           <<h->GetBinContent(i)<<"\t"
00618           <<h->GetBinError(i)
00619           <<endl;
00620     }
00621   }
00622 }
00623 
00624 void CustomizeHistogramMenus()
00625 {
00626   //have to do each child class separately
00627   //TH1F
00628   TClass* cl = TH1F::Class();
00629   TList* l = cl->GetMenuList();
00630   l->AddFirst(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,cl,
00631                                  "Save as ASCII","SaveHistoToFile",0,
00632                                  "TObject*",0));
00633   //TH1D
00634   cl = TH1D::Class();
00635   l = cl->GetMenuList();
00636   l->AddFirst(new TClassMenuItem(TClassMenuItem::kPopupUserFunction,cl,
00637                                  "Save as ASCII","SaveHistoToFile",0,
00638                                  "TObject*",0));
00639   
00640 
00641 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1