Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MadDpID.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // MadDpID
00004 //
00005 // A class to calculate Dave Petyt's CC PID
00006 //
00007 // Created:  D. Petyt -- some time ago
00008 //
00009 // Transcribed: M. Kordosky, 11 August 2005
00010 //
00011 // $Author: rhatcher $ 
00012 //
00013 // $Revision: 1.17 $
00014 // 
00015 // $Name:  $
00016 //
00017 // $Id: MadDpID.cxx,v 1.17 2008/11/19 17:16:21 rhatcher Exp $
00018 //
00019 // $Log: MadDpID.cxx,v $
00020 // Revision 1.17  2008/11/19 17:16:21  rhatcher
00021 // replace non-standard "uint" with "unsigned int".
00022 //
00023 // Revision 1.16  2007/05/22 14:33:40  vahle
00024 // Update MadDpID to deal with non-standard names of far pdf files
00025 //
00026 // Revision 1.15  2007/02/06 16:44:42  vahle
00027 // Changed MadDpID::ChoosePDF to choose the le010z185i pdf file if the beam type is kLE
00028 //
00029 // Revision 1.14  2007/02/06 13:34:13  vahle
00030 // Changed MadDpID so that the pid for the horn off beam comes from the HE pdf file
00031 //
00032 // Revision 1.13  2007/02/06 13:25:15  vahle
00033 // Fixed reco_y, reco_x initialization bug, changed dpid PHCorrection to 1 if the recoversion is cedar
00034 //
00035 // Revision 1.12  2007/02/05 18:43:30  vahle
00036 // Changed ChoosePDFs in MadDpID to take reconstruction and MC versions as arguments.  This way it can figure out what pdf file to use based on the reco and mc versions.  Should be backwards compatible, if these two new parameters are not specified, the code will assume they are birch/carrot and load the pdf files that were used for the prl analysis
00037 //
00038 // Revision 1.11  2007/01/30 03:17:21  rhatcher
00039 // No longer user BeamType "class" found in MCReweight, but rather the
00040 // BeamType "namespace" found in Conventions package.
00041 // Also covert to using "Detector::" rather than "DetectorType::", though
00042 // for now they are synonyms.
00043 //
00044 // Revision 1.10  2007/01/29 23:05:13  boehm
00045 // Adjusting how the data files are loaded into the two PIDs.  Now the code looks first in the SRT_PRIVATE_CONTEXT and then checks the SRT_PUBLIC_CONTEXT.  This further detachs the CC-pids from the Mad Framework.
00046 //
00047 // Revision 1.9  2006/05/08 21:27:44  boehm
00048 // Primary change is the addition of functions to calculate the PID's from NtpSt objects.  Both PIDs may now be generated without relying on the rest of the Mad infrastructure.  Mad based code though should not be changed.
00049 //
00050 // Also removed the if(!ntpTrack.fit.pass) return;  from MadDpID.cxx as it does not reflect the current state of the CC analysis. This was removed in the branched version but remained in the development version.
00051 //
00052 // Revision 1.8  2006/05/04 21:32:41  boehm
00053 // Minor adjustment so that there now exists a CalcPid(var1, var2, var3) function
00054 // which generic non-Mad based programs can use to calculate a DP-PID value.
00055 //
00056 // Revision 1.7  2006/03/10 18:57:21  kordosky
00057 // correct MadDpID and MadMKAnalysis to account for 1.8% shift in pulseheight related PID quantities
00058 //
00059 // Revision 1.6  2006/02/15 19:59:51  kordosky
00060 // remove fiducial requirement to match jan-06 branch.
00061 //
00062 // Revision 1.5  2005/10/07 11:19:12  kordosky
00063 // deal with BeamMonSpill::StatusBits.beam_type==0 without asserting. Clearly, it can be zero!
00064 //
00065 // Revision 1.4  2005/10/06 18:40:52  kordosky
00066 // random additions
00067 //
00068 // Revision 1.3  2005/10/06 15:03:26  kordosky
00069 // various improvements, pids finally integrated into pan construction routine, still not fully debugged though
00070 //
00071 // Revision 1.2  2005/09/14 13:32:45  kordosky
00072 // DpID and NsID classes now fully working and validated with MadTestAnalysis by comparing nannpid vs. annpid and npid0 vs. pid0.  pdf files and weights stored in data subdirectory. FD pdfs needed for DpID.
00073 //
00074 //
00076 
00077 #include "Mad/MadDpID.h"
00078 #include "Mad/MadQuantities.h"
00079 
00080 #include <cassert>
00081 #include <sys/types.h>
00082 #include <sys/stat.h>
00083 #include <unistd.h>
00084 
00085 #include "TH1.h"
00086 #include "TFile.h"
00087 #include "TSystem.h"
00088 #include "string"
00089 
00090 #include "MadDpAnalysis.h"
00091 
00092 MadDpID::MadDpID() : 
00093   ph_correction(1.0),cache_det(Detector::kUnknown), cache_beam(BeamType::kUnknown), fLikeliHist(6){
00094   for (unsigned int i=0; i<6; i++) fLikeliHist[i]=0;
00095 }
00096 
00097 MadDpID::~MadDpID() {
00098   for (unsigned int i=0; i<fLikeliHist.size(); i++){
00099     if(fLikeliHist[i]) {
00100       // check that histogram really isn't in a directory
00101       // before deleting
00102       if(fLikeliHist[i]->GetDirectory()!=0){
00103         delete fLikeliHist[i];      
00104         fLikeliHist[i]=0;
00105       }
00106     }
00107   }
00108 }
00109 
00110 bool MadDpID::CalcVars(const NtpSRTrack* ntpTrack, const NtpSREvent* ntpEvent, 
00111          const NtpSREventSummary *eventSummary, Detector::Detector_t det,
00112          Int_t method, Float_t& var1, Float_t& var2, Float_t& var3)
00113 {
00114   if(method != 0) return false;
00115                                                                                 
00116   var1=var2=var3=0.0;
00117   if(ntpEvent==0 || ntpTrack==0) return false;
00118   if(eventSummary == 0) return false;                                                                              
00119   // basic checks on quality of event
00120 //  if(! ntpTrack->fit.pass) return false;
00121 
00122   //Calculate the Variables
00123 /*
00124   if(! MadDpAnalysis::InFidVol(ntpHeader->GetVldContext().GetDetector(),
00125                                ntpEvent->vtx.x, ntpEvent->vtx.y,
00126                                ntpEvent->vtx.z) ) return false;
00127   */
00128   // compute variables
00129 
00130   var1=eventSummary->plane.n;
00131   if(det == Detector::kNear){
00132     var1=ntpEvent->plane.end-ntpEvent->plane.beg+1;
00133   }
00134 
00135   Float_t phtrack=ntpTrack->ph.sigcor*ph_correction;
00136   Float_t phevent=ntpEvent->ph.sigcor*ph_correction;
00137                                                                                 
00138   if (phevent>0) {var2=phtrack/phevent;}
00139                                                                                 
00140   if (ntpTrack->plane.n!=0) var3 = float(ntpTrack->ph.sigcor*ph_correction)
00141                               /float(ntpTrack->plane.n);
00142   return true;
00143 }
00144 
00145 bool MadDpID::CalcVars(MadQuantities* mb, Int_t event, Int_t method,
00146                        Float_t& var1, Float_t& var2, Float_t& var3)
00147 {
00148   // calculate the variables used to construct the PID
00149   //
00150   // this routine should be used in PID calculation *and* to fill PDFs
00151   //
00152   // checks that the event passes certain criteria before doing the calc  
00153   // returns false in case of error, or if the event doesn't satisfy
00154   // 
00155 
00156   if(method!=0) return false;
00157   
00158   var1=var2=var3=0.0;
00159 
00160   const RecCandHeader* ntpHeader = mb->GetHeader();
00161   const NtpSREvent* ntpEvent=mb->GetEvent(event);
00162   Int_t track = -1;
00163   const NtpSRTrack* ntpTrack=mb->GetLargestTrackFromEvent(event,track);
00164   if(track==-1) return false;
00165 
00166   return CalcVars(ntpTrack, ntpEvent, mb->GetEventSummary(), 
00167                   ntpHeader->GetVldContext().GetDetector(), method, 
00168                   var1, var2, var3);
00169 }
00170 
00171 
00172 Float_t MadDpID::CalcPID(MadQuantities* mb, Int_t event, Int_t method)
00173 {
00174   // calculate a PID or return -10 in case the calculation of variables
00175   // encounters an error. The -10 maintains historical convention
00176   
00177   Float_t var1,var2,var3;
00178   if(!CalcVars(mb,event,method,var1,var2,var3) ) return -10;
00179 
00180   return CalcPID(var1, var2, var3);
00181 }
00182 
00183 Float_t MadDpID::CalcPID(const NtpSRTrack* ntpTrack, const NtpSREvent* ntpEvent,
00184          const NtpSREventSummary *eventSummary, Detector::Detector_t det,
00185          Int_t method)
00186 {
00187   Float_t var1, var2, var3;
00188   
00189   if(!CalcVars(ntpTrack,ntpEvent,eventSummary,det,method,var1,var2,var3) )
00190         return -10;
00191                                                                                 
00192   return CalcPID(var1, var2, var3);
00193 }
00194 
00195 Float_t MadDpID::CalcPID(Float_t var1, Float_t var2, Float_t var3)
00196 {
00197   assert(fLikeliHist[0]); // essentially make sure file was read
00198 
00199   Float_t ProbNC = 1.;
00200   Float_t ProbCC = 1.;
00201   Float_t PidCC = 0.;
00202 
00203   Float_t prob1=fLikeliHist[0]->GetBinContent(fLikeliHist[0]->FindBin(var1));
00204   Float_t prob2=fLikeliHist[2]->GetBinContent(fLikeliHist[2]->FindBin(var2));
00205   Float_t prob3=fLikeliHist[4]->GetBinContent(fLikeliHist[4]->FindBin(var3));
00206 
00207   if (prob1==0) {prob1=0.0001;}
00208   if (prob2==0) {prob2=0.0001;}
00209   if (prob3==0) {prob3=0.0001;}
00210  
00211   ProbCC=prob1*prob2*prob3;
00212 
00213   prob1=fLikeliHist[1]->GetBinContent(fLikeliHist[1]->FindBin(var1));
00214   prob2=fLikeliHist[3]->GetBinContent(fLikeliHist[3]->FindBin(var2));
00215   prob3=fLikeliHist[5]->GetBinContent(fLikeliHist[5]->FindBin(var3));
00216  
00217   if (prob1==0) {prob1=0.0001;}
00218   if (prob2==0) {prob2=0.0001;}
00219   if (prob3==0) {prob3=0.0001;}
00220  
00221   ProbNC=prob1*prob2*prob3;
00222 
00223   PidCC=-(sqrt(-TMath::Log(ProbCC))-sqrt(-TMath::Log(ProbNC)));
00224 
00225   return PidCC;
00226 }
00227 
00228 bool MadDpID::ReadPDFs(const char* name){
00229   
00230 
00231   // check if this file or directory exists
00232   Long_t id,size,flags,modtime;
00233   if(gSystem->GetPathInfo(name,&id,&size,&flags,&modtime) == 1) {
00234     return false;
00235   }
00236   // check that it is a file and not a directory
00237   if(flags>1) return false;
00238   
00239 
00240   TDirectory* sd = gDirectory;
00241   TFile fLikeliFile(name,"READ");
00242   bool found=true;
00243   if(fLikeliFile.IsOpen() && !fLikeliFile.IsZombie()) { //if file is found
00244     
00245     fLikeliFile.cd();
00246     
00247     fLikeliHist[0]=dynamic_cast<TH1*>( fLikeliFile.Get("Event length - cc"));
00248     fLikeliHist[1]=dynamic_cast<TH1*>( fLikeliFile.Get("Event length - nc"));
00249     fLikeliHist[2]=dynamic_cast<TH1*>( fLikeliFile.Get("Track ph frac - cc"));
00250     fLikeliHist[3]=dynamic_cast<TH1*>( fLikeliFile.Get("Track ph frac - nc"));
00251     fLikeliHist[4]=dynamic_cast<TH1*>( fLikeliFile.Get("ph per plane (cc)"));
00252     fLikeliHist[5]=dynamic_cast<TH1*>( fLikeliFile.Get("ph per plane (nc)"));
00253     
00254     for (unsigned int i=0;i<fLikeliHist.size();i++){
00255       assert(fLikeliHist[i]);
00256       fLikeliHist[i]->SetDirectory(0); // histogram owned by this object
00257       float integ = fLikeliHist[i]->Integral(); 
00258       fLikeliHist[i]->Scale(1./integ);
00259     }
00260     std::cout<<"Read MadDpID pdfs from : "<<name<<std::endl;
00261   }
00262   else found=false;
00263   if(sd) sd->cd();
00264   return found;
00265 }
00266 
00267 void MadDpID::WritePDFs(const char* name){
00268   // write histograms to a file but retain ownership with this object
00269   TDirectory* sd = gDirectory;
00270   TFile f(name,"recreate");
00271   for (unsigned int i=0; i<fLikeliHist.size(); i++){
00272     fLikeliHist[i]->Write();
00273   }
00274   if(sd) sd->cd();
00275 }
00276 
00277 
00278 void MadDpID::InitPDFs(const Detector::Detector_t& det){
00279   // create pdf histograms and assign to fLikeliHist array
00280 
00281   int nbins=60;
00282   float low=0; 
00283   float high=300;
00284   if(det==Detector::kFar){ nbins=50; low=0; high=500;}
00285   
00286   TH1F *evlength_nc = new TH1F("Event length - nc",
00287                                "Event length - nc",
00288                                nbins,low,high);
00289   evlength_nc->SetXTitle("Event length (planes)");
00290   TH1F *evlength_cc = new TH1F("Event length - cc",
00291                                "Event length - cc",
00292                                nbins,low,high);
00293   evlength_cc->SetXTitle("Event length (planes)");
00294 
00295 
00296   TH1F *phfrac_nc = new TH1F("Track ph frac - nc",
00297                                "Track ph frac - nc",
00298                                50,0,1);
00299   phfrac_nc->SetXTitle("pulse height fraction");
00300 
00301 
00302   TH1F *phfrac_cc = new TH1F("Track ph frac - cc",
00303                                "Track ph frac - cc",
00304                                50,0,1);
00305   phfrac_cc->SetXTitle("pulse height fraction");
00306 
00307 
00308   TH1F *phplane_nc = new TH1F("ph per plane (nc)",
00309                               "ph per plane (nc)",
00310                                50,0,5000);
00311   phplane_nc->SetXTitle("pulse height per plane");
00312   TH1F *phplane_cc = new TH1F("ph per plane (cc)",
00313                               "ph per plane (cc)",
00314                                50,0,5000);
00315   phplane_cc->SetXTitle("pulse height per plane");
00316 
00317 
00318   fLikeliHist[0] = evlength_cc;
00319   fLikeliHist[1] = evlength_nc;
00320   
00321   fLikeliHist[2] = phfrac_cc;
00322   fLikeliHist[3] = phfrac_nc;
00323   
00324   fLikeliHist[4] = phplane_cc;
00325   fLikeliHist[5] = phplane_nc;
00326 
00327   for (unsigned int i=0; i<fLikeliHist.size(); i++) fLikeliHist[i]->SetDirectory(0);
00328   
00329 }
00330 
00331 bool MadDpID::FillPDFs(MadQuantities* mb, Int_t event, Int_t method, 
00332                        Float_t weight){
00333   
00334   // fill PDFs for this event
00335   // the code checks truth information to determine
00336   // if the event is numu-CC or NC
00337   
00338 
00339   assert(fLikeliHist[0]);// assure histograms are there
00340 
00341   Float_t var1,var2,var3;
00342   if(!CalcVars(mb,event,method,var1,var2,var3) ) return false;
00343   
00344   Int_t mcevent=-1;
00345   const NtpMCTruth* ntpTruth = mb->GetTruthForReco(event,mcevent);
00346   if(mcevent == -1  || ntpTruth==0) return false;
00347 
00348   // check binning of histograms, possibly rebin 
00349   // not in love with this bit of the code!
00350   const RecCandHeader* header = mb->GetHeader();
00351   assert(header); // something deeply wrong
00352   CheckBinning(header->GetVldContext().GetDetector());
00353   
00354   //
00355   Int_t cc_nc = mb->IAction(mcevent);
00356   Int_t flavour = mb->Flavour(mcevent);
00357   
00358   if(flavour==2 && cc_nc==1){
00359     fLikeliHist[0]->Fill(var1,weight);
00360     fLikeliHist[2]->Fill(var2,weight);
00361     fLikeliHist[4]->Fill(var3,weight);
00362   }
00363   else if(cc_nc==0) {
00364     fLikeliHist[1]->Fill(var1,weight);
00365     fLikeliHist[3]->Fill(var2,weight);
00366     fLikeliHist[5]->Fill(var3,weight);
00367   }
00368   
00369   return true;
00370 }
00371 
00372 
00373 void MadDpID::CheckBinning(const Detector::Detector_t& det){
00374   // duplicate a funny little bit of code, which rebins
00375   // one of the pdfs in reaction to the detector type
00376   TH1* evlength_cc = fLikeliHist[0];
00377   TH1* evlength_nc = fLikeliHist[1];
00378   assert(evlength_cc);
00379   assert(evlength_nc);
00380 
00381   if(det==Detector::kFar){
00382     if (evlength_cc->GetNbinsX()==60) {
00383       evlength_cc->SetBins(50,0,500);
00384       evlength_nc->SetBins(50,0,500);
00385     }
00386   }
00387   else if(det==Detector::kNear){
00388     if (evlength_cc->GetBinLowEdge(50)>200) {
00389         evlength_cc->SetBins(60,0,300);
00390         evlength_nc->SetBins(60,0,300);
00391     }
00392   }
00393   
00394 }
00395 
00396 void MadDpID::ResetPDFs(){
00397   for (unsigned int i=0; i<fLikeliHist.size(); i++){
00398     TH1* h = fLikeliHist[i];
00399     delete h; fLikeliHist[i]=0;
00400   }
00401 }
00402 
00403 bool MadDpID::ChoosePDFs(const Detector::Detector_t& det, 
00404                          const BeamType::BeamType_t& beam,
00405                          std::string recover, std::string mcver)
00406 {
00407   // check to see if we already have this file
00408   if(det==cache_det && beam==cache_beam){
00409     // no action is needed 
00410     return true;
00411   }
00412   if(det==Detector::kUnknown || beam==BeamType::kUnknown){
00413     return false;
00414   }
00415   std::string priv="";
00416   std::string pub="";
00417 
00418   std::string base="";
00419 
00420   priv=getenv("SRT_PRIVATE_CONTEXT");
00421   pub = getenv("SRT_PUBLIC_CONTEXT");
00422  
00423   if(priv == "" && pub == ""){
00424     std::cerr<<"No SRT_PUBLIC_CONTEXT set"<<std::endl;
00425     assert(false);
00426   }
00427 
00428   
00429   priv += "/Mad/data/";
00430   pub += "/Mad/data/";
00431 
00432   struct stat ss;
00433   if(stat(priv.c_str(), &ss) == -1) {
00434    std::cout<<"Data not present in SRT_PRIVATE_CONTEXT trying SRT_PUBLIC"<<std::endl;
00435    if(stat(pub.c_str(), &ss) == -1) {
00436      std::cout<<"Data not present in SRT_PUBLIC - doesn't seem to exist"<<std::endl;
00437       assert(false);
00438    }else{ base = pub; }
00439   }else { base = priv; }
00440 
00441   base+="dp_pdf_";
00442 
00443   if((recover==""||recover.find("birch")<recover.size()||
00444      recover.find("Birch")<recover.size()||
00445      recover.find("BIRCH")<recover.size()||
00446      recover.find("R1.18")<recover.size())&&
00447      (mcver==""||mcver.find("carrot")<mcver.size()||
00448       mcver.find("Carrot")<mcver.size()||
00449       mcver.find("CARROT")<mcver.size())){
00450     if(det==Detector::kNear){
00451       base+="near";
00452     }
00453     else if(det==Detector::kFar){
00454       base+="far";
00455     }
00456     //  else return false;
00457     
00458     if(beam==BeamType::kLE || beam==BeamType::k010){
00459       base+="_le";
00460     }
00461     else if(beam==BeamType::kME){
00462       base+="_me";
00463     }
00464     else if(beam==BeamType::kHE){
00465       base+="_he";
00466     }
00467   }
00468   else if((mcver.find("daikon")<mcver.size()||
00469           mcver.find("Daikon")<mcver.size()||
00470           mcver.find("DAIKON")<mcver.size())&&
00471           (recover.find("cedar")<recover.size()||
00472            recover.find("Cedar")<recover.size()||
00473            recover.find("CEDAR")<recover.size()||
00474            recover.find("1.24")<recover.size())){
00475     BeamType::BeamType_t tmpbeam = beam;
00476     switch(beam){
00477     case BeamType::kL010z170i: tmpbeam = BeamType::kL010z185i; break;
00478     case BeamType::kL010z200i: tmpbeam = BeamType::kL010z185i; break;
00479       //forcing le to go to le010
00480     case BeamType::kL000z200i: tmpbeam = BeamType::kL010z185i; break;
00481     case BeamType::kL010z185i_lowintensity: 
00482       tmpbeam = BeamType::kL010z185i; break;
00483       //for birch, we used le010 pdfs for the horn off running,
00484       //but, I think we should use the he since the
00485       //mean neutrino energy in the horn off running is 
00486       //higher than le, more like he.
00487     case BeamType::kL010z000i: tmpbeam = BeamType::kL250z200i; break;
00488     default: tmpbeam = beam; break;
00489     }
00490     if(det==Detector::kNear){
00491       base+="near";
00492       base+=("_"+(string)BeamType::AsString(tmpbeam));
00493     }
00494     else if(det==Detector::kFar){
00495       base+="far";
00496       if(tmpbeam==BeamType::kL250z200i){
00497         base+="_phe";
00498       }
00499       else{
00500         base+="_le";
00501       }
00502     }
00503 
00504     base+="_cedar_daikon";
00505   }
00506 
00507   //  else return false;
00508   
00509   base+=".root";
00510   if(stat(base.c_str(),&ss) == -1) {
00511     std::cerr<<"The file '"<<base<<"' doesn't seem to exist"<<std::endl;
00512     //    assert(false);
00513     return false;
00514   }
00515   cout<<"Reading pdfs from "<<base<<endl;
00516   //  assert(ReadPDFs(base.c_str()));
00517   if(ReadPDFs(base.c_str())){
00518   // set these so we don't have to reread each event
00519     cache_det=det;
00520     cache_beam=beam;    
00521     return true;
00522   }
00523   else {
00524     return false;
00525   }
00526 }
00527 

Generated on Mon Feb 15 11:06:55 2010 for loon by  doxygen 1.3.9.1