Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

CutUtils.h

00001 //A collection of handy methods for doing cuts etc to make sure things are working
00002 
00003 #include <TEventList.h>
00004 #include <TH1.h>
00005 #include <TROOT.h>
00006 
00007 unsigned int errorCode = 0;
00008 double Chi2Test(TH1* h1, TH1 *h2, Option_t *option, Int_t constraint);
00009 
00010 //Save an eventlist based on cut and returns the number passing it
00011 int count(TTree& t, string name, string cut) {
00012     string cmd = ">>" + name;
00013     t.Draw(cmd.c_str(), cut.c_str());
00014     TEventList *list = (TEventList*)gDirectory->Get(name.c_str()); 
00015 
00016     return list->GetN();
00017 }
00018 
00026 double cut(TTree& t, string name, string quantity, double meanCut, double rmsCut, double numberCut, bool prependAbs=true, string cut="1>0") {
00027     string histname = "h" + name;
00028     string cmd = quantity + ">>" + histname + "(100)";    
00029     t.Draw(cmd.c_str(), cut.c_str());
00030     TH1* hist = (TH1*)gDirectory->Get(histname.c_str());
00031 
00032     if (hist->GetMean() > meanCut) {
00033     ++errorCode;
00034     cout << "Failed mean cut for: " << quantity << " cut: " << meanCut << endl;
00035     }
00036     if (hist->GetRMS() > rmsCut) {
00037     ++errorCode;
00038     cout << "Failed rms cut for: " << quantity << " cut: " << meanCut << endl;
00039     }
00040     
00041     ostringstream oss;
00042     if (prependAbs) oss << "abs";
00043     oss << quantity << ">" << numberCut << " && " << cut;
00044     return count(t, name, oss.str())/(double)t.GetEntriesFast();
00045 }
00046 
00050 double compareShape(TTree& t, const string& name, const string& quantity1, const string& quantity2, const string& cut="1>0") {
00051     string histName1 = "h" + name + "1";
00052     string cmd1 = quantity1 + ">>" + histName1 + "(100)";
00053     t.Draw(cmd1.c_str(), cut.c_str());
00054     TH1* hist1 = (TH1*)gDirectory->Get(histName1.c_str());
00055     
00056     string histName2 = "h" + name + "2";
00057     string cmd2 = quantity2 + ">>" + histName2 + "(100)";
00058     t.Draw(cmd2.c_str(), cut.c_str());
00059     TH1* hist2 = (TH1*)gDirectory->Get(histName2.c_str());
00060     
00061     //Must be integer things!
00062     
00063     if (hist1->GetNbinsX() != hist2->GetNbinsX() || hist1->GetBinCenter(1)!=hist2->GetBinCenter(1) 
00064     || hist1->GetBinCenter(hist1->GetNbinsX())!=hist2->GetBinCenter(hist2->GetNbinsX())) {
00065     double lowedge = hist1->GetBinCenter(1)<hist2->GetBinCenter(1) ? hist1->GetBinCenter(1) : hist2->GetBinCenter(1);
00066     double highedge = hist1->GetBinCenter(hist1->GetNbinsX())>hist2->GetBinCenter(hist2->GetNbinsX())
00067               ? hist1->GetBinCenter(hist1->GetNbinsX()) : hist2->GetBinCenter(hist2->GetNbinsX());
00068     strstream oss1;
00069     oss1 << quantity1 << ">>" << histName1 << "(100," << lowedge << "," << highedge << ")";
00070     cmd1 = oss1.str();
00071     delete hist1;
00072     t.Draw(cmd1.c_str(), cut.c_str());
00073     hist1 = (TH1*)gDirectory->Get(histName1.c_str());
00074     
00075     strstream oss2;
00076     oss2 << quantity2 << ">>" << histName2 << "(100," << lowedge << "," << highedge << ")";
00077     cmd2 = oss2.str();
00078     delete hist2;
00079     t.Draw(cmd2.c_str(), cut.c_str());
00080     hist2 = (TH1*)gDirectory->Get(histName2.c_str());
00081     }
00082  
00083     if (hist1->GetEntries() == 0 || hist2->GetEntries()==0) return -1;
00084     
00085     //double kol = hist1->KolmogorovTest(hist2, "D");
00086     //cout << "Kolmogorov probability: " << (kol*100) << "%" << endl;
00087     return Chi2Test(hist1, hist2, "", 1);
00088 }
00089 
00094 double Chi2Test(TH1* h1, TH1 *h2, Option_t *option, Int_t constraint) {
00095   //The Chi2 (Pearson's) test for differences between h and this histogram. 
00096   //a small value of prob indicates a significant difference between the distributions
00097   //
00098   //if the data was collected in such a way that the number of entries
00099   //in the first histogram is necessarily equal to the number of entries
00100   //in the second, the parameter _constraint_ must be made 1. Default is 0.
00101   //any additional constraints on the data lower the number of degrees of freedom
00102   //(i.e. increase constraint to more positive values) in accordance with
00103   //their number
00104   //
00106   //"O" -overflows included
00107   //"U" - underflows included
00108   //
00109   //"P" - print information about number of degrees of freedom and
00110   //the value of chi2
00111   //by default underflows and overflows are not included
00112 
00113   //algorithm taken from "Numerical Recipes in C++"
00114   // implementation by Anna Kreshuk
00115   
00116   Int_t df;
00117   Double_t chsq = 0;
00118   Double_t prob;
00119   Double_t temp;
00120   Double_t koef1,koef2;
00121   Double_t nen1, nen2;
00122   Double_t bin1, bin2;
00123   Int_t i_start, i_end;
00124 
00125   TString opt = option;
00126   opt.ToUpper();
00127 
00128   TAxis *axis1 = h1->GetXaxis();
00129   TAxis *axis2 = h2->GetXaxis();
00130 
00131   Int_t nbins1 = axis1->GetNbins();
00132   Int_t nbins2 = axis2->GetNbins();
00133 
00134   //check dimensions
00135   if (h1->GetDimension()!=1 || h2->GetDimension()!=1){
00136      cout << "Chi2Test for 1-d only" << endl;
00137      return 0;
00138   }
00139   //check that the histograms are not empty
00140   nen1 = h1->GetEntries();
00141   nen2 = h2->GetEntries();
00142   if((nen1==0)||(nen2==0)){
00143      cout << "Chi2Test one of the histograms is empty" << endl;
00144      return 0;
00145   }
00146   //check number of channels
00147   if (nbins1 != nbins2){
00148      cout << "Chi2Test different number of channels" << endl;
00149      return 0;
00150   }
00151 
00152   //check binning
00153   Double_t diffprec = 1e-5;
00154   Double_t diff1 = TMath::Abs(axis1->GetXmin() - axis2->GetXmin());
00155   Double_t diff2 = TMath::Abs(axis1->GetXmax() - axis2->GetXmax());
00156   if ((diff1 > diffprec)||(diff2>diffprec)){
00157      cout << "Chi2Test different binning" << endl;
00158      return 0;
00159   }
00160 
00161   //see options
00162 
00163   i_start = 1;
00164   i_end = nbins1;
00165   df=nbins1-constraint;
00166 
00167   if(opt.Contains("O")) {
00168      i_end = nbins1+1;
00169      df++;
00170   }
00171   if(opt.Contains("U")) {
00172      i_start = 0;
00173      df++;
00174   }
00175 
00176    //the test
00177   if (TMath::Abs(nen1-nen2) > diffprec){
00178     koef1 = TMath::Sqrt(nen2/nen1);
00179     koef2 = TMath::Sqrt(nen1/nen2);
00180   } else{
00181     koef1 = 1;
00182     koef2 = 1;
00183   }
00184 
00185   for (Int_t i=i_start; i<=i_end; i++){
00186      bin1 = h1->GetBinContent(i);
00187      bin2 = h2->GetBinContent(i);
00188      if (bin1 ==0 && bin2==0){
00189         --df; //no data means one less degree of freedom
00190      } else {
00191         temp  = koef1*bin1-koef2*bin2;
00192         chsq += temp*temp/(bin1+bin2);
00193      }
00194   }
00195   
00196   prob = TMath::Prob(0.5*chsq, Int_t(0.5*df));
00197   
00198   if (opt.Contains("P")){
00199      cout << "the value of chi2 = " << chsq  << endl;
00200      cout << "the number of degrees of freedom = " << df << endl;
00201   }
00202 
00203   return prob;
00204 }

Generated on Thu Jul 15 09:50:44 2004 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5