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

NuCuts.cxx

Go to the documentation of this file.
00001 
00002 
00003 // Coded by Jeff Hartnell Dec/2005 onwards
00004 //
00005 // Contact: j.j.hartnell@rl.ac.uk
00007 
00008 #include <cmath>
00009 
00010 #include "TMath.h"
00011 #include "TH1F.h"
00012 #include "TROOT.h"
00013 
00014 #include "Conventions/BeamType.h"
00015 #include "DataUtil/infid.h"
00016 #include "DataUtil/infid_finder.h"
00017 #include "Conventions/Munits.h"
00018 #include "Conventions/ReleaseType.h"
00019 
00020 #include "NtupleUtils/NuCuts.h"
00021 #include "NtupleUtils/NuEvent.h"
00022 #include "NtupleUtils/NuMCEvent.h"
00023 #include "NtupleUtils/NuLibrary.h"
00024 #include "NtupleUtils/NuXMLConfig.h"
00025 
00026 using std::endl;
00027 using std::cout;
00028 
00029 CVSID("$Id: NuCuts.cxx,v 1.117 2010/02/07 16:00:33 bckhouse Exp $");
00030 
00031 //......................................................................
00032 // Functions to identify NuMuBar PQ and NQ selections
00033 Bool_t NuCuts::IsNMB(const NuEvent &nu) {
00034   return (nu.anaVersion == NuCuts::kNMB0325Alpha ||
00035           nu.anaVersion == NuCuts::kNMB0325Bravo ||
00036           nu.anaVersion == NuCuts::kNMB0325BravoTwo ||
00037           nu.anaVersion == NuCuts::kNMB0325Charlie ||
00038           nu.anaVersion == NuCuts::kNMB0325Delta ||
00039           nu.anaVersion == NuCuts::kNMB0325Echo ||
00040           nu.anaVersion == NuCuts::kNMB0325ChairSound ||
00041           nu.anaVersion == NuCuts::kRM1 ||
00042           nu.anaVersion == NuCuts::kRM2 ||
00043           nu.anaVersion == NuCuts::kJJE2 ||
00044           nu.anaVersion == NuCuts::kNMBFree ||
00045           nu.anaVersion == NuCuts::kRHC);
00046 }
00047 
00048 //......................................................................
00049 
00050 Bool_t NuCuts::IsNMBPQ(const NuEvent &nu) {
00051   return IsNMB(nu) && (nu.charge == 1);
00052 }
00053 
00054 //......................................................................
00055 
00056 Bool_t NuCuts::IsNMBNQ(const NuEvent &nu) {
00057   return IsNMB(nu) && (nu.charge == -1);
00058 }
00059 
00060 //......................................................................
00061 
00062 NuCuts::NuCuts()
00063 {
00064   MSG("NuCuts",Msg::kDebug)
00065     <<"Running NuCuts Constructor..."<<endl;
00066 
00067 
00068   MSG("NuCuts",Msg::kDebug)
00069     <<"Finished NuCuts Constructor"<<endl;
00070 }
00071 
00072 //......................................................................
00073 
00074 NuCuts::~NuCuts()
00075 {
00076   MSG("NuCuts",Msg::kDebug)
00077     <<"Running NuCuts Destructor..."<<endl;
00078 
00079 
00080   MSG("NuCuts",Msg::kDebug)
00081     <<"Finished NuCuts Destructor"<<endl;
00082 }
00083 
00084 //......................................................................
00085 
00086 Bool_t NuCuts::IsGoodNumberOfTracks(const NuEvent& nu) const
00087 {
00088   /*
00089     if (nu.anaVersion==NuCuts::kJJH1 ||
00090     nu.anaVersion==NuCuts::kJJE1) {
00091     MAXMSG("NuCuts",Msg::kInfo,1)
00092     <<"Making cut on number of tracks>=1"<<endl;
00093     return nu.ntrk>=1;
00094     }
00095     else if (nu.anaVersion==NuCuts::kCC0093Std ||
00096     nu.anaVersion==NuCuts::kCC0250Std ||
00097     nu.anaVersion==NuCuts::kCC0325Std) {
00098     MAXMSG("NuCuts",Msg::kInfo,1)
00099     <<"Making cut on number of tracks>=1"<<endl;
00100     return nu.ntrk>=1;
00101     }
00102     else {
00103     MAXMSG("NuCuts",Msg::kInfo,1)
00104     <<"Making cut on number of tracks>=1"<<endl;
00105     return nu.ntrk>=1;
00106     }
00107   */
00108 
00109   // For now, at least, all cuts make the same cut
00110   MAXMSG("NuCuts",Msg::kInfo,1)
00111     <<"Making cut on number of tracks>=1"<<endl;
00112   return nu.ntrk >= 1;
00113 }
00114 
00115 //......................................................................
00116 
00117 Bool_t NuCuts::IsGoodTrackFitPass(const NuEvent& nu) const
00118 {
00119   if (nu.anaVersion==NuCuts::kJJH1) {
00120     MAXMSG("NuCuts",Msg::kInfo,1)
00121       <<"Cutting on trk.fit.pass"<<endl;
00122     return nu.trkfitpass==1;
00123   }
00124   else if (IsNMBPQ(nu))
00125     {
00126       MAXMSG("NuCuts",Msg::kInfo,1)
00127         <<"Cutting on trk.fit.pass for +ve tracks"<<endl;
00128       return nu.trkfitpass==1;
00129     }
00130   else if (nu.anaVersion==NuCuts::kJJE1)
00131     {
00132       MAXMSG("NuCuts",Msg::kInfo,1)
00133         <<"Cutting on trk.fit.pass for +ve tracks, "
00134         << "trk.fit.pass w/ trk reclamation for -ve tracks." <<endl;
00135       if (nu.charge==1){
00136         // Not currently using track reclamation for RHC - but we could
00137         //if (nu.detector==Detector::kNear){
00138         //  return this->IsGoodTrackFitPassReclamation(nu);
00139         //}
00140         //else if (nu.detector==Detector::kFar){
00141         //  return nu.trkfitpass==1;
00142         //}
00143         //else {
00144         //  cout<<"Ahhhh det not known"<<endl;
00145         //  return nu.trkfitpass==1;
00146         //}
00147         return nu.trkfitpass==1;
00148       }
00149       else if (nu.charge==-1)
00150         {
00151           if (nu.detector==Detector::kNear){
00152             return this->IsGoodTrackFitPassReclamation(nu);
00153           }
00154           else if (nu.detector==Detector::kFar){
00155             return nu.trkfitpass==1;
00156           }
00157           else {
00158             cout<<"Ahhhh det not known"<<endl;
00159             return nu.trkfitpass==1;
00160           }
00161         }
00162       else
00163         {
00164           cout<<"Bad charge"<<endl;
00165           return false;
00166         }
00167     }
00168   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
00169     MAXMSG("NuCuts",Msg::kInfo,1)
00170       <<"Cutting on trk.fit.pass for +ve tracks, "
00171       << "letting IsNMBNQ deal with -ve tracks." <<endl;
00172     return nu.trkfitpass==1;
00173   }
00174   else if (nu.anaVersion==NuCuts::kCC0093Std ||
00175            nu.anaVersion==NuCuts::kCC0250Std ||
00176            nu.anaVersion==NuCuts::kCC0325Std ||
00177            nu.anaVersion==NuCuts::kCC0720Std ||
00178            nu.anaVersion==NuCuts::kCC0720Test || IsNMBNQ(nu))
00179     {
00180       if (nu.detector==Detector::kNear) {
00181         MAXMSG("NuCuts",Msg::kInfo,1)
00182           <<"Cutting on trk.fit.pass w/ trk reclamation"<<endl;
00183         return this->IsGoodTrackFitPassReclamation(nu);
00184       }
00185       else if (nu.detector==Detector::kFar) {
00186         MAXMSG("NuCuts",Msg::kInfo,1)
00187           <<"Cutting on trk.fit.pass"
00188           <<", NOT doing track reclamation for the FD"<<endl;
00189         return nu.trkfitpass==1;
00190       }
00191       else {
00192         cout<<"Ahhhh det not known"<<endl;
00193         return nu.trkfitpass==1;
00194       }
00195     }
00196   else {
00197     MAXMSG("NuCuts",Msg::kInfo,1)
00198       <<"Cutting on trk.fit.pass"<<endl;
00199     return nu.trkfitpass==1;
00200     }
00201 }
00202 
00203 //......................................................................
00204 
00205 Bool_t NuCuts::IsGoodTrackFitPassReclamation(const NuEvent& nu)
00206 {
00207   // If the track passes the fitter, it passes
00208   if (nu.trkfitpass==1) return true;
00209 
00210   // Reclaim only +ve's in RHC and only -ve's in FHC
00211   if (nu.hornIsReverse != (nu.charge == +1)) {
00212     return false;
00213   }
00214 
00215   //got these numbers from Masaki's spectrum validation talks
00216   Bool_t goodTrack= ( abs(nu.planeTrkBegu-nu.planeTrkBegv)<=5  &&
00217                       abs(nu.planeTrkEndu-nu.planeTrkEndv)<=40 &&
00218                       nu.planeTrkEndu<270 &&
00219                       nu.planeTrkEndv<270 );
00220   return goodTrack;
00221 }
00222 
00223 //......................................................................
00224 
00225 Bool_t NuCuts::IsGoodPID(const NuEvent& nu) const
00226 {
00227   if (nu.anaVersion==NuCuts::kJJH1) {
00228     return this->IsGoodAbID(nu);
00229   }
00230   else if (nu.anaVersion==NuCuts::kJJE1){
00231     if (nu.charge==1){
00232       return this->IsGoodDpID(nu);
00233     }
00234     else if (nu.charge==-1){
00235       return this->IsGoodAbID(nu);
00236     }
00237     else {
00238       cout<<"Bad charge"<<endl;
00239       return false;
00240     }
00241   }
00242   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
00243     return this->IsGoodDpID(nu);
00244   }
00245   else if (nu.anaVersion==NuCuts::kCC0093Std) {
00246     return this->IsGoodDpID(nu);
00247   }
00248   else if (nu.anaVersion==NuCuts::kCC0250Std) {
00249     return this->IsGoodAbID(nu);
00250   }
00251   else if (nu.anaVersion==NuCuts::kCC0325Std
00252            || nu.anaVersion == NuCuts::kCC0720Std
00253             || IsNMBNQ(nu)
00254             || nu.anaVersion == NuCuts::kNMB0325ChairSound
00255             || nu.anaVersion == NuCuts::kMSRock) {
00256     return this->IsGoodRoID(nu);
00257   }
00258   else if (nu.anaVersion==NuCuts::kCC0720Test){
00259     return (this->IsGoodRoID(nu) || this->IsGoodJmID(nu));
00260   }
00261   else if (((nu.anaVersion==NuCuts::kNMB0325Alpha) ||
00262             (nu.anaVersion==NuCuts::kNMB0325Charlie) ||
00263             (nu.anaVersion==NuCuts::kNMB0325Delta) ||
00264             (nu.anaVersion==NuCuts::kRM1) ||
00265             (nu.anaVersion==NuCuts::kRM2) ||
00266             (nu.anaVersion==NuCuts::kRHC) ) && IsNMBPQ(nu)) {
00267     // Both nmb and CC selectors are the same here
00268     return this->IsGoodRoID(nu);
00269   }
00270     else if ((nu.anaVersion == NuCuts::kNMB0325Bravo ||
00271             nu.anaVersion == NuCuts::kNMB0325BravoTwo) && IsNMBPQ(nu)) {
00272     return this->IsGoodDpID(nu);
00273     }
00274   else if ((nu.anaVersion == NuCuts::kNMB0325Echo) && IsNMBPQ(nu)) {
00275     return this->IsGoodPoKIN(nu);
00276   }
00277   else if ((nu.anaVersion == NuCuts::kNMBFree)&& IsNMBPQ(nu)){
00278     return true;
00279   }
00280   else {
00281     return this->IsGoodAbID(nu);
00282     }
00283   return true;
00284 }
00285 
00286 //......................................................................
00287 
00288 Bool_t NuCuts::IsGoodDpID(const NuEvent& nu) const
00289 {
00290   if (nu.anaVersion==NuCuts::kJJH1) {
00291     Float_t cutValue=0.4;//my numubar cut
00292     //Float_t cutValue=0.1;//get away from NC disagreement
00293     //Float_t cutValue=0.0;//my less harsh numubar cut
00294     //Float_t cutValue=-0.4;//MK's cut
00295 
00296     if (nu.charge==+1){
00297       MAXMSG("NuCuts",Msg::kInfo,1)
00298         <<"Making cut on +ve track: IsGoodDpID>"<<cutValue<<endl;
00299       if (nu.dpID>cutValue) return true;
00300       else return false;
00301     }
00302     else if (nu.charge==-1){
00303       if (nu.detector==Detector::kNear) cutValue=-0.1;
00304       else if (nu.detector==Detector::kFar) cutValue=-0.2;
00305       else {
00306         cout<<"Ahhh, detector="<<nu.detector<<endl;
00307         return false;
00308       }
00309 
00310       //override cutValue
00311       //cutValue=0.1;//get away from NC disagreement
00312 
00313       MAXMSG("NuCuts",Msg::kInfo,1)
00314         <<"Making cut on -ve track: IsGoodDpID>"<<cutValue<<endl;
00315       if (nu.dpID>cutValue) return true;
00316       else return false;
00317     }
00318     else {
00319       cout<<"Bad charge"<<endl;
00320       return false;
00321     }
00322   }
00323   else if (nu.anaVersion==NuCuts::kJJE1){
00324     if (nu.charge==1){
00325       MAXMSG("NuCuts",Msg::kInfo,1)
00326         <<"Making combined dpID and track jitter cut" <<endl;
00327       if (nu.dpID < 0.0){return false;}
00328       if (nu.jitter > 0.5){return false;}
00329       if (nu.jitter > (0.59*nu.dpID + 0.2)){return false;}
00330       return true;
00331     }
00332     else if(nu.charge==-1){
00333       Float_t cutValue=-0.1;
00334       if (nu.detector==Detector::kNear) cutValue=-0.1;
00335       else if (nu.detector==Detector::kFar) cutValue=-0.2;
00336       else {
00337         cout<<"Ahhh, detector="<<nu.detector<<endl;
00338         return false;
00339       }
00340       MAXMSG("NuCuts",Msg::kInfo,1)
00341         <<"Making cut: IsGoodDpID>"<<cutValue<<endl;
00342 
00343       if (nu.dpID>cutValue) return true;
00344       else return false;
00345     }
00346     else{
00347       cout<<"Bad charge"<<endl;
00348       return false;
00349     }
00350   }
00351   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
00352     MAXMSG("NuCuts",Msg::kInfo,1)
00353       <<"Making combined dpID and track jitter cut" <<endl;
00354     if (nu.dpID < 0.0){return false;}
00355     if (nu.jitter > 0.5){return false;}
00356     if (nu.jitter > (0.59*nu.dpID + 0.2)){return false;}
00357     return true;
00358   }
00359   else if (nu.anaVersion==NuCuts::kCC0093Std) {
00360     Float_t cutValue=-0.1;
00361     if (nu.detector==Detector::kNear) cutValue=-0.1;
00362     else if (nu.detector==Detector::kFar) cutValue=-0.2;
00363     else {
00364       cout<<"Ahhh, detector="<<nu.detector<<endl;
00365       return false;
00366     }
00367     MAXMSG("NuCuts",Msg::kInfo,1)
00368       <<"Making cut: IsGoodDpID>"<<cutValue<<endl;
00369 
00370     if (nu.dpID>cutValue) return true;
00371     else return false;
00372   }
00373   else if (nu.anaVersion==NuCuts::kCC0250Std ||
00374            nu.anaVersion==NuCuts::kCC0325Std || 
00375            nu.anaVersion==NuCuts::kCC0720Std ||
00376            nu.anaVersion==NuCuts::kCC0720Test || IsNMBNQ(nu)) {
00377     Float_t cutValue=-0.1;
00378     if (nu.detector==Detector::kNear) cutValue=-0.1;
00379     else if (nu.detector==Detector::kFar) cutValue=-0.2;
00380     else {
00381       cout<<"Ahhh, detector="<<nu.detector<<endl;
00382       return false;
00383     }
00384     MAXMSG("NuCuts",Msg::kInfo,1)
00385       <<"Making cut: IsGoodDpID>"<<cutValue<<endl;
00386 
00387     if (nu.dpID>cutValue) return true;
00388     else return false;
00389   }
00390    else if ((nu.anaVersion == NuCuts::kNMB0325Bravo ||
00391             nu.anaVersion == NuCuts::kNMB0325BravoTwo) && IsNMBPQ(nu)) {
00392     Float_t cutValue=0.25;
00393 
00394     if (nu.anaVersion == NuCuts::kNMB0325BravoTwo) {
00395       cutValue = 0.32;
00396       }
00397     MAXMSG("NuCuts",Msg::kInfo,1)
00398       << "Making +ve  cut: IsGoodDpID>"<<cutValue<<endl;
00399     if (nu.dpID>cutValue)
00400       return true;
00401     else
00402       return false;
00403       }
00404   else {
00405     //Float_t cutValue=0.4;//my numubar cut
00406     Float_t cutValue=0.0;//my less harsh numubar cut
00407     //Float_t cutValue=-0.4;//MK's cut
00408 
00409     if (nu.charge==+1){
00410       MAXMSG("NuCuts",Msg::kInfo,1)
00411         <<"Making cut on +ve track: IsGoodDpID>"<<cutValue<<endl;
00412       if (nu.dpID>cutValue) return true;
00413       else return false;
00414     }
00415     else if (nu.charge==-1){
00416       if (nu.detector==Detector::kNear) cutValue=-0.1;
00417       else if (nu.detector==Detector::kFar) cutValue=-0.2;
00418       else {
00419         cout<<"Ahhh, detector="<<nu.detector<<endl;
00420         return false;
00421       }
00422       MAXMSG("NuCuts",Msg::kInfo,1)
00423         <<"Making cut on -ve track: IsGoodDpID>"<<cutValue<<endl;
00424 
00425       if (nu.dpID>cutValue) return true;
00426       else return false;
00427     }
00428     else {
00429       cout<<"Bad charge"<<endl;
00430       return false;
00431     }
00432     }
00433   return true;
00434 }
00435 
00436 //......................................................................
00437 
00438 Bool_t NuCuts::IsGoodRoID(const NuEvent& nu) const
00439 {
00440   Float_t cutValue=0.3;
00441 
00442   // Check for the NuMuBar cuts first, then drop down to the default (original)
00443   // routine if none of them are to be used.
00444   if (IsNMBPQ(nu)) {
00445     if ((nu.anaVersion == NuCuts::kNMB0325Alpha) ||
00446         (nu.anaVersion == NuCuts::kNMB0325Charlie) ||
00447         (nu.anaVersion == NuCuts::kRM1)) {
00448       cutValue = 0.625;
00449     }
00450     else if (nu.anaVersion == NuCuts::kRM2) {
00451       cutValue = 0.80;
00452     }
00453     else if (nu.anaVersion == NuCuts::kNMB0325Delta) {
00454       cutValue = 0.55;
00455     }
00456     else if (nu.anaVersion == NuCuts::kRHC) {
00457         cutValue = 0.30; // Prelim. RHC cut the same as the CC cut
00458     }
00459     MAXMSG("NuCuts",Msg::kInfo,1)
00460       <<"Making +ve IsGoodRoID>"<<cutValue<<endl;
00461   }
00462 
00463   // Drop to original behaviour in two cases:
00464   // - Is NOT a numubar selector
00465   // - IS a nmb selector, but this event has negative charge (i.e. a neutrino event)
00466   if (!IsNMB(nu) || IsNMBNQ(nu)) {
00467     // Original Behaviour
00468     if (nu.detector==Detector::kNear) cutValue=0.3;
00469     else if (nu.detector==Detector::kFar) cutValue=0.3;
00470     else {
00471       cout<<"Ahhh, detector="<<nu.detector<<endl;
00472       return false;
00473     }
00474   }
00475 
00476   // Rock muons are different!
00477   if (nu.anaVersion == NuCuts::kMSRock) {
00478     cutValue = 0.20;
00479   }
00480 
00481   MAXMSG("NuCuts",Msg::kInfo,1)
00482     <<"Making cut: IsGoodRoID>"<<cutValue<<endl;
00483 
00484   return (nu.roID>cutValue);
00485   return true;
00486 }
00487 Bool_t NuCuts::IsGoodJmID(const NuEvent& nu) const
00488 {
00489   Float_t cutValue=0.5;
00490   MAXMSG("NuCuts",Msg::kInfo,1)
00491     <<"Making cut: IsGoodJmID>"<<cutValue<<endl;
00492   return (nu.jmID>cutValue);
00493   return true;
00494 } 
00495 Bool_t NuCuts::IsGoodNtID(const NuEvent& /*nu*/) const
00496 {
00497   Float_t cutValue=0.8;
00498   MAXMSG("NuCuts",Msg::kInfo,1)
00499     <<"Making cut: ISGoodNtID>"<<cutValue<<endl;
00500   //  return (nu.ntID>cutValue);
00501   return true;
00502 }
00503 
00504 //......................................................................
00505 
00506 Bool_t NuCuts::IsGoodPoKIN(const NuEvent& nu) const
00507 {
00508   Float_t cutValue=-0.1;
00509   MAXMSG("NuCuts",Msg::kInfo,1)
00510     <<"Making Cut: IsGoodPoKIN>" << cutValue << endl;
00511   // Check the value!
00512   if (nu.anaVersion == NuCuts::kNMB0325Echo) {
00513     if (nu.poIDKin <= cutValue) return false;
00514   }
00515 
00516   // return true for all other cases (not cutting, is correct)
00517   return true;
00518 }
00519 
00520 //......................................................................
00521 
00522 Bool_t NuCuts::IsGoodAbID(const NuEvent& nu) const
00523 {
00524   Float_t cutValue=0.85;
00525 
00526   if (nu.anaVersion==NuCuts::kJJH1) {
00527     cutValue=0.99;
00528 
00529     if (nu.charge==+1){
00530       MAXMSG("NuCuts",Msg::kInfo,1)
00531         <<"Making cut on +ve track: IsGoodAbID>"<<cutValue<<endl;
00532       if (nu.abID>cutValue) return true;
00533       else return false;
00534     }
00535     else if (nu.charge==-1){
00536       if (nu.detector==Detector::kNear) cutValue=0.85;
00537       else if (nu.detector==Detector::kFar) cutValue=0.85;
00538       else {
00539         cout<<"Ahhh, detector="<<nu.detector<<endl;
00540         return false;
00541       }
00542 
00543       MAXMSG("NuCuts",Msg::kInfo,1)
00544         <<"Making cut on -ve track: IsGoodAbID>"<<cutValue<<endl;
00545       if (nu.abID>cutValue) return true;
00546       else return false;
00547     }
00548     else {
00549       cout<<"Bad charge"<<endl;
00550       return false;
00551     }
00552   }
00553   else if (nu.anaVersion==NuCuts::kJJE1){
00554     MAXMSG("NuCuts",Msg::kInfo,1)
00555       <<"Making cut: IsGoodAbID>"<<cutValue<<endl;
00556     if (nu.abID>cutValue) return true;
00557     else return false;
00558   }
00559   else if (nu.anaVersion==NuCuts::kCC0093Std) {
00560     MAXMSG("NuCuts",Msg::kInfo,1)
00561       <<"Making cut: IsGoodAbID>"<<cutValue<<endl;
00562     if (nu.abID>cutValue) return true;
00563     else return false;
00564   }
00565   else if (nu.anaVersion==NuCuts::kCC0250Std ||
00566            nu.anaVersion==NuCuts::kCC0325Std ||
00567            nu.anaVersion==NuCuts::kCC0720Std ||
00568            nu.anaVersion==NuCuts::kCC0720Test ||  IsNMBNQ(nu)) {
00569     MAXMSG("NuCuts",Msg::kInfo,1)
00570       <<"Making cut: IsGoodAbID>"<<cutValue<<endl;
00571     if (nu.abID>cutValue) return true;
00572     else return false;
00573   }
00574   else {
00575     MAXMSG("NuCuts",Msg::kInfo,1)
00576       <<"Making cut: IsGoodAbID>"<<cutValue<<endl;
00577     if (nu.abID>cutValue) return true;
00578     else return false;
00579     }
00580   return true;
00581 }
00582 
00583 //......................................................................
00584 
00585 Bool_t NuCuts::IsGoodSigmaQP_QP(const NuEvent& nu) const
00586 {
00587   Float_t cutValue=0.3;
00588 
00589   if (nu.anaVersion==NuCuts::kJJH1) {
00590     //first cut on anti-neutrinos
00591     if (nu.charge>0){
00592       MAXMSG("NuCuts",Msg::kInfo,1)
00593         <<"Making cut on +ve track: SigmaQP/QP<"<<cutValue<<endl;
00594       if (fabs(nu.sigqp_qp)<cutValue) {
00595         return true;
00596       }
00597       else return false;
00598     }
00599     //now look at neutrinos
00600     else if (nu.charge<0) {
00601       Bool_t doCut=false;//switch
00602       if (doCut) {
00603         MAXMSG("NuCuts",Msg::kInfo,1)
00604           <<"If curv used, making cut on -ve track: SigmaQP/QP>"
00605           <<-1*cutValue<<"; if range used, no cut"<<endl;
00606         if (nu.usedRange) {
00607           return true;//don't cut on fit error if using range
00608           //neutrinos swamp anti-neutrinos so little background
00609         }
00610         else if (nu.usedCurv) {
00611           if (fabs(nu.sigqp_qp)<cutValue) return true;
00612           else return false;
00613         }
00614         else {
00615           MAXMSG("NuCuts",Msg::kWarning,10)
00616             <<"Ahh, usedRange="<<nu.usedRange
00617             <<"and usedCurv="<<nu.usedCurv<<endl;
00618           return false;
00619         }
00620       }
00621       else {
00622         //don't cut
00623         MAXMSG("NuCuts",Msg::kInfo,1)
00624           <<"Not cutting on SigmaQP/QP for -ve tracks"<<endl;
00625         return true;
00626       }
00627     }
00628     else {
00629       cout<<"Ahh, bad charge"<<endl;
00630       return false;
00631     }
00632   }
00633   else if (nu.anaVersion==NuCuts::kJJE1){
00634     if (1==nu.charge){
00635       cutValue = 0.065;
00636       MAXMSG("NuCuts",Msg::kInfo,1)
00637         <<"Making cut on sigmaQP>" << cutValue <<endl;
00638       if (nu.sigqp>cutValue){return false;}
00639       else{return true;}
00640     }
00641     else if (-1==nu.charge){
00642       //no cut
00643       MAXMSG("NuCuts",Msg::kInfo,1)
00644         <<"Not cutting on SigmaQP/QP"<<endl;
00645       return true;
00646     }
00647     else {
00648       cout<<"Bad charge"<<endl;
00649       return false;
00650     }
00651   }
00652   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
00653     cutValue = 0.065;
00654     MAXMSG("NuCuts",Msg::kInfo,1)
00655       <<"Making cut on sigmaQP>" << cutValue <<endl;
00656     if (nu.sigqp>cutValue){return false;}
00657     else{return true;}
00658   }
00659   else if (nu.anaVersion==NuCuts::kCC0093Std ||
00660            nu.anaVersion==NuCuts::kCC0250Std ||
00661            nu.anaVersion==NuCuts::kCC0325Std ||
00662            nu.anaVersion==NuCuts::kCC0720Std ||
00663            nu.anaVersion==NuCuts::kCC0720Test || IsNMBNQ(nu)) {
00664     //no cut
00665     MAXMSG("NuCuts",Msg::kInfo,1)
00666       <<"Not cutting on SigmaQP/QP"<<endl;
00667     return true;
00668   }
00669     else if (((nu.anaVersion == NuCuts::kNMB0325Bravo) ||
00670             (nu.anaVersion == NuCuts::kNMB0325Echo)) && IsNMBPQ(nu)){
00671     cutValue = 3.5;
00672     MAXMSG("NuCuts",Msg::kInfo,1)
00673       << "Making Cut on +ve, QP_sigmaQP>" << cutValue << endl;
00674     if (1./nu.sigqp_qp > cutValue)
00675       return true;
00676     else
00677       return false;
00678 
00679       }
00680   else if ((nu.anaVersion == NuCuts::kRM2) && IsNMBPQ(nu)){
00681     cutValue = 2.3;
00682     MAXMSG("NuCuts",Msg::kInfo,1)
00683       << "Making Cut on +ve, QP_sigmaQP>" << cutValue << endl;
00684     if (1./nu.sigqp_qp > cutValue)
00685       return true;
00686     else
00687       return false;
00688   }
00689   else if ((nu.anaVersion == NuCuts::kRM1) && IsNMBPQ(nu)) {
00690     cutValue = 2.0;
00691     MAXMSG("NuCuts",Msg::kInfo,1)
00692       << "Making Cut on +ve, QP_sigmaQP>" << cutValue << endl;
00693     if (1./nu.sigqp_qp > cutValue)
00694       return true;
00695     else
00696       return false;
00697   }
00698   else {
00699     //no cut
00700     MAXMSG("NuCuts",Msg::kInfo,1)
00701       <<"Not cutting on SigmaQP/QP"<<endl;
00702     return true;
00703     }
00704   return true;
00705 }
00706 
00707 //......................................................................
00708 
00709 Bool_t NuCuts::IsGoodRelAngle(const NuEvent &nu) const
00710 {
00711   // Calculate relative angle - pi
00712   Float_t cutValue = 0;
00713 
00714   // Only cut on NMB Selectors
00715   if (!IsNMB(nu))
00716     return true;
00717 
00718   // Don't cut on NMB negative charge events
00719   if (nu.charge == -1)
00720     return true;
00721   else if (nu.charge != 1)
00722     {
00723       cout << "Bad Charge: " << nu.charge << endl;
00724       return false;
00725     }
00726 
00727   // Do Rashid's relA selector for RM1
00728   if (nu.anaVersion == NuCuts::kRM1)
00729     {
00730       if (nu.relativeAngle < 1.0 || nu.relativeAngle > 5.0)
00731         return true;
00732       else
00733         return false;
00734     }
00735 
00736   switch (nu.anaVersion)
00737     {
00738     case NuCuts::kNMB0325Alpha:
00739       cutValue = 2.12;
00740       break;
00741        case NuCuts::kNMB0325Bravo:
00742       cutValue = 2.12;
00743       break;
00744     case NuCuts::kNMB0325BravoTwo:
00745       cutValue = 2.12;
00746       break;
00747     case NuCuts::kNMB0325Echo:
00748       cutValue = 2.02;
00749       break;
00750     case NuCuts::kRM2:
00751       cutValue = 2.0;
00752       break;
00753     default:
00754       // Do not cut if not one of the above
00755       MAXMSG("NuCuts",Msg::kInfo,1)
00756         << "Not Cutting on |relA-Pi|" << endl;
00757       return true;
00758     }
00759 
00760   MAXMSG("NuCuts",Msg::kInfo,1)
00761     << "Cutting on |relA-Pi|>" << cutValue << endl;
00762   if (abs(nu.relativeAngle - TMath::Pi()) <= cutValue)
00763     return false;
00764 
00765   return true;
00766 }
00767 
00768 //......................................................................
00769 
00770 Bool_t NuCuts::IsGoodTrackLength(const NuEvent &nu) const
00771 {
00772   Int_t cutValue = 0;
00773 
00774   // Only cut on NMB Selectors
00775   if (!IsNMB(nu))
00776     return true;
00777 
00778   // Don't cut on NMB negative charge events
00779   if (nu.charge == -1)
00780     return true;
00781   else if (nu.charge != 1)
00782     {
00783       cout << "Bad Charge: " << nu.charge << endl;
00784       return false;
00785     }
00786 
00787   switch (nu.anaVersion)
00788     {
00789     case NuCuts::kNMB0325Alpha:
00790     case NuCuts::kNMB0325Charlie:
00791       cutValue = 35;
00792       break;
00793     case NuCuts::kNMB0325Delta:
00794       cutValue = 37;
00795       break;
00796     case NuCuts::kRM1:
00797       cutValue = 36;
00798       break;
00799     case NuCuts::kJJE2:
00800       cutValue = 34;
00801       break;
00802     default:
00803       // Do not cut if not one of the above
00804       MAXMSG("NuCuts",Msg::kInfo,1) << "Not Cutting on trkL" << endl;
00805       return true;
00806     }
00807 
00808   // Since this function only cuts for NuMuBar selectors at the moment,
00809   // we can make a blanket acceptance for NQ events
00810   if (nu.charge == -1)
00811     return true;
00812   else if (nu.charge != 1) {
00813     cout << "Bad Charge: " << nu.charge << endl;
00814     return false;
00815   }
00816 
00817   MAXMSG("NuCuts",Msg::kInfo,1)
00818     << "Cutting on trkL>" << cutValue << endl;
00819   if (nu.trkLength <= cutValue)
00820     return false;
00821 
00822   return true;
00823 }
00824 
00825 //......................................................................
00826 
00827 
00828 Bool_t NuCuts::IsGoodTrackLengthInUV(const NuEvent &nu) const
00829 {
00830   Int_t cutValue = 19;
00831   Int_t DiffU=0;
00832   Int_t DiffV=0;
00833 
00834   // Only cut on NMB Selectors
00835   if (!IsNMB(nu))
00836     return true;
00837 
00838   // Don't cut on NMB negative charge events
00839   if (nu.charge == -1)
00840     return true;
00841   else if (nu.charge != 1)
00842     {
00843       cout << "Bad Charge for TrkLenghInUV cut: " << nu.charge << endl;
00844       return false;
00845     }
00846 
00847   if (nu.anaVersion == NuCuts::kRM2) {
00848     DiffV=nu.planeTrkEndv -nu.planeTrkBegv;
00849     DiffU=nu.planeTrkEndu -nu.planeTrkBegu;
00850     MAXMSG("NuCuts",Msg::kInfo,1)
00851       << "Making Cut on UV Track length >" << cutValue << endl;
00852     if (DiffU > cutValue && DiffV > cutValue)
00853       return true;
00854     else
00855       return false;
00856   }
00857   else {
00858     //no cut
00859     MAXMSG("NuCuts",Msg::kInfo,1)
00860       <<"Not cutting on UV Track length"<<endl;
00861     return true;
00862   }
00863 }
00864 
00865 //......................................................................
00866 
00867 Bool_t NuCuts::IsGoodQP(const NuEvent& nu) const
00868 {
00869   MAXMSG("NuCuts",Msg::kWarning,1) << "CUTTING ON QP. YOU PROBABLY DON'T WANT TO DO THIS" << endl;
00870 
00871   switch (nu.anaVersion)
00872     {
00873     case NuCuts::kNMB0325Alpha:
00874     case NuCuts::kNMB0325Bravo:
00875     case NuCuts::kNMB0325BravoTwo:
00876     case NuCuts::kNMB0325Charlie:
00877     case NuCuts::kNMB0325Delta:
00878     case NuCuts::kNMB0325Echo:
00879     case NuCuts::kRM2:
00880     case NuCuts::kNMBFree:
00881     case NuCuts::kRHC:
00882       { // brackets defeat "jump to case crosses intialization" errors
00883         MAXMSG("NuCuts",Msg::kInfo,1) << "Cutting on Q/P>0" << endl;
00884         if (nu.qp <= 0)
00885           return false;
00886         break;
00887       }
00888     default:
00889       {
00890         MAXMSG("NuCuts",Msg::kInfo,1) << "Not Cutting on Q/P" << endl;
00891       }
00892     }
00893 
00894   // Either not cutting or passed cut
00895   return true;
00896 }
00897 
00898 //......................................................................
00899 
00900 Bool_t NuCuts::IsGoodFitChi2PerNdof(const NuEvent& nu) const
00901 {
00902   Float_t cutValue=10;
00903 
00904   if (nu.anaVersion==NuCuts::kJJH1) {
00905     Bool_t doCut=false;
00906     if (doCut) {
00907       MAXMSG("NuCuts",Msg::kInfo,1)
00908         <<"Making cut on chi2PerNdof<"<<cutValue<<endl;
00909       //make cut
00910       if (nu.chi2PerNdof>cutValue) {
00911         return false;
00912       }
00913       else return true;
00914     }
00915     else {
00916       MAXMSG("NuCuts",Msg::kInfo,1)
00917         <<"Not cutting on Chi2PerNdof"<<endl;
00918       return true;
00919     }
00920   }
00921 
00922   else if (nu.anaVersion==NuCuts::kCC0093Std ||
00923            nu.anaVersion==NuCuts::kCC0250Std ||
00924            nu.anaVersion==NuCuts::kJJE1 ||
00925            nu.anaVersion==NuCuts::kCC0325Std ||
00926            nu.anaVersion==NuCuts::kCC0720Std ||
00927            nu.anaVersion==NuCuts::kCC0720Test || IsNMB(nu)) {
00928     //no cut
00929     MAXMSG("NuCuts",Msg::kInfo,1)
00930       <<"Not cutting on Chi2PerNdof"<<endl;
00931     return true;
00932   }
00933   else {
00934     //no cut
00935     MAXMSG("NuCuts",Msg::kInfo,1)
00936       <<"Not cutting on Chi2PerNdof"<<endl;
00937     return true;
00938   }
00939 }
00940 
00941 //......................................................................
00942 
00943 Bool_t NuCuts::IsGoodFitProb(const NuEvent& nu) const
00944 {
00945   Float_t cutValue=0.1;
00946 
00947   if (nu.anaVersion==NuCuts::kJJH1) {
00948     if (nu.charge==+1){
00949       cutValue=0.1;
00950       MAXMSG("NuCuts",Msg::kInfo,1)
00951         <<"Making cut on +ve track: Fit Prob>"<<cutValue<<endl;
00952       if (nu.prob>cutValue) return true;
00953       else return false;
00954     }
00955     else if (nu.charge==-1){
00956       Bool_t doCut=false;
00957 
00958       if (doCut) {
00959         //if (nu.detector==Detector::kNear) cutValue=-0.1;
00960         //else if (nu.detector==Detector::kFar) cutValue=-0.2;
00961         //else {
00962         //cout<<"Ahhh, detector="<<nu.detector<<endl;
00963         //return false;
00964         //}
00965         cutValue=0.0;
00966 
00967         MAXMSG("NuCuts",Msg::kInfo,1)
00968           <<"Making cut on -ve track: Fit Prob>="<<cutValue<<endl;
00969         if (nu.prob>=cutValue) return true;
00970         else return false;
00971       }
00972       else {
00973         //no cut
00974         MAXMSG("NuCuts",Msg::kInfo,1)
00975           <<"Not cutting on trk fit probability for -ve tracks"<<endl;
00976         return true;
00977       }
00978     }
00979     else {
00980       cout<<"Bad charge"<<endl;
00981       return false;
00982     }
00983   }
00984   else if (nu.anaVersion==NuCuts::kJJE1){
00985     if (1==nu.charge){
00986       MAXMSG("NuCuts",Msg::kInfo,1)
00987         <<"Making cut on tfProb>" << cutValue <<endl;
00988       cutValue = 0.1;
00989       if (nu.prob<0.1){return false;}
00990       else{return true;}
00991     }
00992     else if (-1==nu.charge){
00993       //no cut
00994       MAXMSG("NuCuts",Msg::kInfo,1)
00995         <<"Not cutting on Fit Prob"<<endl;
00996       return true;
00997     }
00998     else {
00999       cout<<"Bad charge"<<endl;
01000       return false;
01001     }
01002   }
01003   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
01004     MAXMSG("NuCuts",Msg::kInfo,1)
01005       <<"Making cut on tfProb>" << cutValue <<endl;
01006     cutValue = 0.1;
01007     if (nu.prob<0.1){return false;}
01008     else{return true;}
01009   }
01010   else if (nu.anaVersion==NuCuts::kCC0093Std ||
01011            nu.anaVersion==NuCuts::kCC0250Std ||
01012            nu.anaVersion==NuCuts::kCC0325Std ||
01013            nu.anaVersion==NuCuts::kCC0720Std ||
01014            nu.anaVersion==NuCuts::kCC0720Test ||
01015 
01016            IsNMBNQ(nu) ) {
01017     //no cut
01018     MAXMSG("NuCuts",Msg::kInfo,1)
01019       <<"Not cutting on Fit Prob"<<endl;
01020     return true;
01021   }
01022   else if ((nu.anaVersion == NuCuts::kNMB0325Delta) && IsNMBPQ(nu))
01023     {
01024       MAXMSG("NuCuts",Msg::kInfo,1) << "Cutting on prob>0.003" << endl;
01025       if (nu.prob <= 0.003)
01026         return false;
01027       else
01028         return true;
01029     } else {
01030     //no cut
01031     MAXMSG("NuCuts",Msg::kInfo,1)
01032       <<"Not cutting on Fit Prob"<<endl;
01033     return true;
01034     }
01035   return true;
01036 }
01037 
01038 //......................................................................
01039 
01040 Bool_t NuCuts::IsGoodMajorityCurvature(const NuEvent& nu) const
01041 {
01042   if (nu.anaVersion==NuCuts::kJJE1){
01043     if (1==nu.charge){
01044       MAXMSG("NuCuts",Msg::kInfo,1)
01045         <<"Making cut on Majority Curvature < 0" << endl;
01046       if (nu.smoothMajC<0.0){return false;}
01047       else{return true;}
01048     }
01049     else if (-1==nu.charge){
01050       //no cut
01051       MAXMSG("NuCuts",Msg::kInfo,1)
01052         <<"Not cutting on Majority Curvature for charge=-1"<<endl;
01053       return true;
01054     }
01055     else {
01056       cout<<"Bad charge"<<endl;
01057       return false;
01058     }
01059   }
01060   else if (nu.anaVersion==NuCuts::kJJE2 && nu.charge==1){
01061     MAXMSG("NuCuts",Msg::kInfo,1)
01062       <<"Making cut on Majority Curvature < 0" << endl;
01063     if (nu.smoothMajC<0.0){return false;}
01064     else{return true;}
01065   }
01066   else if (nu.anaVersion==NuCuts::kJJH1 ||
01067            nu.anaVersion==NuCuts::kCC0093Std ||
01068            nu.anaVersion==NuCuts::kCC0250Std ||
01069            nu.anaVersion==NuCuts::kCC0325Std ||
01070            nu.anaVersion==NuCuts::kCC0720Std ||
01071            nu.anaVersion==NuCuts::kCC0720Test ||
01072            IsNMBNQ(nu) ) {
01073     //no cut
01074     MAXMSG("NuCuts",Msg::kInfo,1)
01075       <<"Not cutting on Majority Curvature"<<endl;
01076     return true;
01077   }
01078   else if ((nu.anaVersion == NuCuts::kNMB0325Charlie) && IsNMBPQ(nu)) {
01079     MAXMSG("NuCuts",Msg::kInfo,1)<<"Making cut on Majority Curvature > -0.22" << endl;
01080 
01081     // Make the numubar cut
01082     if (nu.smoothMajC > -0.22)
01083       return true;
01084     else
01085       return false;
01086   }
01087   else {
01088     //no cut
01089     MAXMSG("NuCuts",Msg::kInfo,1)
01090       <<"Not cutting on Majority Curvature"<<endl;
01091     return true;
01092     }
01093   return true;
01094 }
01095 
01096 //......................................................................
01097 
01098 Bool_t NuCuts::IsLI(const NuEvent& nu) const
01099 {
01100   //for the ND just cut on litime
01101   if (nu.detector==Detector::kNear) {
01102     MAXMSG("NuCuts",Msg::kInfo,1)
01103       <<"Cutting on ND LI events using litime!=-1"<<endl;
01104     return (nu.litime!=-1);
01105   }
01106 
01107   //for the FD cut depending on the analysis version
01108   if (nu.anaVersion==NuCuts::kJJH1 ||
01109       nu.anaVersion==NuCuts::kJJE1 ||
01110       nu.anaVersion==NuCuts::kCC0325Std ||
01111       nu.anaVersion==NuCuts::kCC0720Std ||
01112       nu.anaVersion==NuCuts::kCC0720Test ||
01113       IsNMB(nu)) {
01114     //cut on LI
01115     MAXMSG("NuCuts",Msg::kInfo,1)
01116       <<"Cutting on LI events using LISieve and litime!=-1"<<endl;
01117     return (nu.isLI || nu.litime!=-1);
01118   }
01119   else if (nu.anaVersion==NuCuts::kCC0093Std ||
01120            nu.anaVersion==NuCuts::kCC0250Std) {
01121     MAXMSG("NuCuts",Msg::kInfo,1)
01122       <<"Cutting on LI events using FDRCBoundary and litime!=-1"<<endl;
01123     return (nu.litag>0 || nu.litime!=-1);
01124   }
01125   else {
01126     MAXMSG("NuCuts",Msg::kInfo,1)
01127       <<"Cutting on LI events using LISieve and litime!=-1"<<endl;
01128     return (nu.isLI || nu.litime!=-1);
01129   }
01130 }
01131 
01132 //......................................................................
01133 
01134 Bool_t NuCuts::IsCoilOk(const NuEvent& nu) const
01135 {
01136   //check if MC or data
01137   if (nu.simFlag!=SimFlag::kData) {
01138     MAXMSG("NuCuts",Msg::kInfo,1)
01139       <<"Not cutting on IsCoilOk for simFlag="<<nu.simFlag<<endl;
01140     return true;
01141   }
01142 
01143   //check if the flag is set to cut
01144   if (!nu.cutOnDataQuality) {//use data quality flag
01145     MAXMSG("NuCuts",Msg::kWarning,1)
01146       <<"Not cutting on IsCoilOk (flag set to not cut)"<<endl;
01147     return true;
01148   }
01149 
01150   MAXMSG("NuCuts",Msg::kInfo,1)
01151     <<"Cutting on coilIsOk"<<endl;
01152 
01153   //check if coil is ok (can be forward or reversed)
01154   if (nu.coilIsOk) {
01155     return true;
01156   }
01157   else {
01158     MAXMSG("NuCuts",Msg::kInfo,10)
01159       <<"Bad magnetic coil, coilIsOk="<<nu.coilIsOk<<endl;
01160     return false;
01161   }
01162 }
01163 
01164 //......................................................................
01165 
01166 Bool_t NuCuts::IsGoodCoilCurrent(const NuEvent& nu) const
01167 {
01168   //check if MC or data
01169   if (nu.simFlag!=SimFlag::kData) {
01170     MAXMSG("NuCuts",Msg::kInfo,1)
01171       <<"Not cutting on CoilCurrent for simFlag="<<nu.simFlag<<endl;
01172     return true;
01173   }
01174 
01175   //check if Near or not
01176   if (nu.detector!=Detector::kNear) {
01177     MAXMSG("NuCuts",Msg::kInfo,1)
01178       <<"Not cutting on ND CoilCurrent for detector="<<nu.detector
01179       <<endl;
01180     return true;
01181   }
01182 
01183   //check if the flag is set to cut
01184   if (!nu.cutOnDataQuality) {//use data quality flag
01185     MAXMSG("NuCuts",Msg::kWarning,1)
01186       <<"Not cutting on CoilCurrent (flag set to not cut)"<<endl;
01187     return true;
01188   }
01189 
01190   Float_t valueLow=-1000;
01191   Float_t valueHigh=1000;
01192 
01193   if (nu.anaVersion==NuCuts::kJJH1 ||
01194       nu.anaVersion==NuCuts::kJJE1 ||
01195       IsNMB(nu)) {
01196     //allow reversed field currents
01197     if (nu.coilCurrent<valueLow || nu.coilCurrent>valueHigh) {
01198       MAXMSG("NuCuts",Msg::kInfo,1)
01199         <<"Cutting on CoilCurrent < "<<valueLow
01200         <<" || CoilCurrent > "<<valueHigh<<endl;
01201       return true;
01202     }
01203     else {
01204       MAXMSG("NuCuts",Msg::kInfo,10)
01205         <<"Bad coil current="<<nu.coilCurrent<<endl;
01206       return false;
01207     }
01208   }
01209   else if (nu.anaVersion==NuCuts::kCC0093Std ||
01210            nu.anaVersion==NuCuts::kCC0250Std ||
01211            nu.anaVersion==NuCuts::kCC0325Std ||
01212            nu.anaVersion==NuCuts::kCC0720Std ||
01213            nu.anaVersion==NuCuts::kCC0720Test) {
01214     if (nu.coilCurrent<valueLow) {
01215       MAXMSG("NuCuts",Msg::kInfo,1)
01216         <<"Cutting on CoilCurrent < "<<valueLow<<endl;
01217       return true;
01218     }
01219     else {
01220       MAXMSG("NuCuts",Msg::kInfo,10)
01221         <<"Bad coil current="<<nu.coilCurrent<<endl;
01222       return false;
01223     }
01224   }
01225   else {
01226     if (nu.coilCurrent<valueLow) {
01227       MAXMSG("NuCuts",Msg::kInfo,1)
01228         <<"Cutting on CoilCurrent < "<<valueLow<<endl;
01229       return true;
01230     }
01231     else {
01232       MAXMSG("NuCuts",Msg::kInfo,10)
01233         <<"Bad coil current="<<nu.coilCurrent<<endl;
01234       return false;
01235     }
01236   }
01237 }
01238 
01239 //......................................................................
01240 
01241 Bool_t NuCuts::IsGoodBeamDetPOTCountingStage(const NuEvent& nu) const
01242 {
01244 
01245   //return if MC
01246   if (nu.simFlag!=SimFlag::kData) {
01247     MAXMSG("NuCuts",Msg::kInfo,1)
01248       <<"Not cutting on GoodBeam for simFlag="<<nu.simFlag<<endl;
01249     return true;
01250   }
01251 
01252   //don't do this here, since this is the sntp beam data
01253   //check if the flag is set to cut
01254   //if (!nu.cutOnBeamInfo) {
01255   //MAXMSG("NuCuts",Msg::kWarning,1)
01256   //    <<"Not cutting on BeamInfo (flag set to not cut)"<<endl;
01257   //return true;
01258   //}
01259 
01260   MAXMSG("NuCuts",Msg::kInfo,1)
01261     <<"Cutting on IsGoodBeamDetPOTCountingStage"<<endl;
01262 
01263   if (nu.goodBeamSntp && nu.coilIsOk) {
01264     return true;
01265   }
01266   return false;
01267 }
01268 
01269 //......................................................................
01270 
01271 Bool_t NuCuts::IsGoodBeam(const NuEvent& nu) const
01272 {
01274 
01275   //return if MC
01276   if (nu.simFlag!=SimFlag::kData) {
01277     MAXMSG("NuCuts",Msg::kInfo,1)
01278       <<"Not cutting on GoodBeam for simFlag="<<nu.simFlag<<endl;
01279     return true;
01280   }
01281 
01282   //check if the flag is set to cut
01283   if (!nu.cutOnBeamInfo) {
01284     MAXMSG("NuCuts",Msg::kWarning,1)
01285       <<"Not cutting on BeamInfo (flag set to not cut)"<<endl;
01286     return true;
01287   }
01288 
01289   //Trish's cuts:
01290   //goodbeam==1&&hornI<-10&&(beamcnf==3||beamcnf==10||beamcnf==11)
01291 
01292   //3=kL010z185i - LE-std
01293   //7=kL250z200i - phe (removed for CC0250 results)
01294   //10=kL010z170i - LE lower horn cur
01295   //11=kL010z200i - LE higher horn cur
01296   //15=kL150z200i - pmhe (removed for CC0250 results)
01297 
01298   if (nu.anaVersion==NuCuts::kCC0093Std ||
01299       nu.anaVersion==NuCuts::kCC0250Std) {
01300     MAXMSG("NuCuts",Msg::kInfo,1)
01301       <<"Cutting on GoodBeam with CC0250Std cuts"<<endl;
01302     if (nu.goodBeam &&
01303         nu.hornCur<-10 && nu.hornCur!=-999999 &&
01304         (nu.beamTypeDB==BeamType::kL010z185i ||
01305          nu.beamTypeDB==BeamType::kL010z170i ||
01306          nu.beamTypeDB==BeamType::kL010z200i)){
01307       return true;
01308     }
01309     else {
01310       MAXMSG("NuCuts",Msg::kInfo,100)
01311         <<"Bad beam: goodBeam="<<nu.goodBeam
01312         <<", goodBeamSntp="<<nu.goodBeamSntp
01313         <<", hornCur="<<nu.hornCur
01314         <<", nu.beamTypeDB="<<nu.beamTypeDB
01315         <<", hornIsReverse="<< (nu.hornIsReverse?"Yes":"No")
01316         << endl;
01317       if (nu.detector==Detector::kNear) {
01318         MAXMSG("NuCuts",Msg::kError,1000)
01319             <<"IsGoodBeam: cutting on Bad beam here messes"
01320           <<" up POT counting.  Event: " << nu.run << "/" << nu.subRun << ", " <<  nu.snarl <<endl;
01321       }
01322       return false;
01323     }
01324   }
01325   else if (nu.anaVersion == NuCuts::kCC0325Std ||
01326            nu.anaVersion == NuCuts::kCC0720Std ||
01327            nu.anaVersion == NuCuts::kCC0720Test || IsNMB(nu)){
01328     MAXMSG("NuCuts",Msg::kInfo,1)
01329       <<"Cutting on GoodBeam with CC0325Std cuts"<<endl;
01330 
01331 
01332     bool isGood = true;
01333 
01334     // Check current
01335     if (!nu.goodBeam)
01336       isGood = false;
01337     if (nu.hornCur==-999999)
01338       isGood = false;
01339 
01340     if (nu.hornCur < -10) {
01341       if (nu.beamTypeDB != BeamType::kL010z185i &&
01342           nu.beamTypeDB != BeamType::kL010z170i &&
01343           nu.beamTypeDB != BeamType::kL010z200i &&
01344           nu.beamTypeDB != BeamType::kL250z200i) {
01345         isGood = false;
01346       }
01347       if (nu.hornIsReverse) {
01348         MAXMSG("NuCuts",Msg::kError,1000)
01349         << "nu.hornIsReverse is true but it shouldn't be for beamTypeDB="
01350         << nu.beamTypeDB << endl;
01351       }
01352     }
01353     else if (nu.hornCur >  10) {
01354       if (nu.beamTypeDB != BeamType::kL010z185i_rev)
01355         isGood = false;
01356       if (!nu.hornIsReverse) {
01357         MAXMSG("NuCuts",Msg::kError,1000)
01358         << "nu.hornIsReverse is false but it shouldn't be for beamTypeDB="
01359         << nu.beamTypeDB << endl;
01360       }
01361     }
01362     else {
01363       if (nu.beamTypeDB != BeamType::kL010z000i)
01364         isGood = false;
01365     }
01366 
01367 
01368     if (!isGood) {
01369       MAXMSG("NuCuts",Msg::kInfo,100)
01370       <<"Bad beam: goodBeam="<<nu.goodBeam
01371       <<", goodBeamSntp="<<nu.goodBeamSntp
01372       <<", hornCur="<<nu.hornCur
01373       <<", nu.beamTypeDB="<<nu.beamTypeDB
01374       <<", hornIsReverse="<< (nu.hornIsReverse?"Yes":"No")
01375       << endl;
01376       if (nu.detector==Detector::kNear) {
01377         MAXMSG("NuCuts",Msg::kError,1000)
01378         <<"IsGoodBeam: cutting on Bad beam here messes"
01379         <<" up POT counting.  Event: " << nu.run << "/" << nu.subRun << ", " <<  nu.snarl <<endl;
01380       }
01381       return false;
01382     }
01383 
01384     //Make sure we're not getting mixed beam
01385     static Bool_t firstGoodEvent = true;
01386     static Int_t firstType = 0;
01387 
01388     if (firstGoodEvent){
01389       firstGoodEvent = false;
01390       firstType = nu.beamTypeDB;
01391       // Treat le10 170, 185, 200 as all the same
01392       if (firstType == BeamType::kL010z170i ||
01393           firstType == BeamType::kL010z200i) {
01394         firstType = BeamType::kL010z185i;
01395       }
01396     }
01397     else{
01398       Int_t thisType = nu.beamTypeDB;
01399       // Treat le10 170, 185, 200 as all the same
01400       if (nu.simFlag==SimFlag::kData && nu.detector==Detector::kFar){
01401         if (thisType == BeamType::kL010z170i ||
01402             thisType == BeamType::kL010z200i) {
01403           thisType = BeamType::kL010z185i;
01404         }
01405       }
01406 
01407       if (thisType != firstType) {
01408         MAXMSG("NuCuts",Msg::kWarning,100)
01409         << "Seeing mixed beam: firstType=" << firstType
01410         << ", thisType=" << thisType
01411         << ", beamTypeDB=" << nu.beamTypeDB << endl;
01412         if (nu.detector==Detector::kNear) {
01413           MAXMSG("NuCuts",Msg::kError,1000)
01414           <<"IsGoodBeam: cutting on Bad beam here messes"
01415           <<" up POT counting.  Event: " << nu.run << "/" << nu.subRun << ", " << nu.snarl <<endl;
01416         }
01417         return false;
01418       }
01419     }
01420     //Beam consistent with first event in DST, so we can let it pass
01421     return true;
01422   }
01423   else {
01424     MAXMSG("NuCuts",Msg::kInfo,1)
01425       <<"Not cutting on GoodBeam"<<endl;
01426     return true;
01427   }
01428 }
01429 
01430 //......................................................................
01431 
01432 Bool_t NuCuts::IsGoodDataQuality(const NuEvent& nu) const
01433 {
01434   //return if MC
01435   if (nu.simFlag!=SimFlag::kData) {
01436     MAXMSG("NuCuts",Msg::kInfo,1)
01437       <<"Not cutting on DataQuality for simFlag="<<nu.simFlag<<endl;
01438     return true;
01439   }
01440 
01441   //check if the flag is set to cut
01442   if (!nu.cutOnDataQuality) {
01443     MAXMSG("NuCuts",Msg::kWarning,1)
01444       <<"Not cutting on DataQuality (flag set to not cut)"
01445       <<", isGoodDataQuality="<<nu.isGoodDataQuality<<endl;
01446     return true;
01447   }
01448 
01449   //make the cut
01450   if (nu.detector==Detector::kFar) {
01451     MAXMSG("NuCuts",Msg::kInfo,1)
01452       <<"Cutting on IsGoodDataQuality"<<endl;
01453     return nu.isGoodDataQuality;
01454   }
01455   else if (nu.detector==Detector::kNear) {
01456     if (nu.anaVersion==NuCuts::kCC0093Std ||
01457         nu.anaVersion==NuCuts::kJJH1 ||
01458         nu.anaVersion==NuCuts::kCC0250Std ||
01459         nu.anaVersion==NuCuts::kJJE1 ||
01460         nu.anaVersion==NuCuts::kCC0325Std ||
01461         nu.anaVersion == NuCuts::kCC0720Std ||
01462         nu.anaVersion==NuCuts::kCC0720Test ||
01463         nu.anaVersion==NuCuts::kJJE2 ||
01464         nu.anaVersion == NuCuts::kNMB0325Alpha ||
01465         nu.anaVersion == NuCuts::kNMB0325Bravo ||
01466         nu.anaVersion == NuCuts::kNMB0325BravoTwo ||
01467         nu.anaVersion == NuCuts::kNMB0325Charlie ||
01468         nu.anaVersion == NuCuts::kNMB0325Delta ||
01469         nu.anaVersion == NuCuts::kNMB0325Echo  ||
01470         nu.anaVersion == NuCuts::kRM1  ||
01471         nu.anaVersion == NuCuts::kRM2  ||
01472         nu.anaVersion == NuCuts::kNMBFree) {
01473       MAXMSG("NuCuts",Msg::kInfo,1)
01474         <<"NOT cutting on IsGoodDataQuality for anaVersion="<<nu.anaVersion<<endl;
01475       //don't cut on coil current or data quality here due to
01476       //POT counting (now changed so that the "good" pot is
01477       //after data quality and coil current)
01478       //the data quality information was not available before the 7e20 analyses
01479       return true;
01480     }
01481     else {
01482       MAXMSG("NuCuts",Msg::kInfo,1)
01483         <<"Cutting on IsGoodDataQuality"<<endl;
01484       return nu.isGoodDataQuality;
01485     }
01486   }
01487   else {
01488     cout<<"Ahhh, det="<<nu.detector<<endl;
01489     return false;
01490   }
01491 }
01492 
01493 //......................................................................
01494 
01495 Bool_t NuCuts::IsGoodTimeToNearestSpill(const NuEvent& nu) const
01496 {
01499 
01500   //return if MC
01501   if (nu.simFlag!=SimFlag::kData) {
01502     MAXMSG("NuCuts",Msg::kInfo,1)
01503       <<"Not cutting on TimeToNearestSpill for simFlag="<<nu.simFlag
01504       <<endl;
01505     return true;
01506   }
01507 
01508   //return if ND
01509   if (nu.detector!=Detector::kFar) {
01510     MAXMSG("NuCuts",Msg::kInfo,1)
01511       <<"Not cutting on TimeToNearestSpill for detector="<<nu.detector
01512       <<endl;
01513     return true;
01514   }
01515 
01516   //check if the flag is set to cut
01517   if (!nu.cutOnSpillTiming) {
01518     MAXMSG("NuCuts",Msg::kWarning,1)
01519       <<"Not cutting on SpillTiming (flag set to not cut)"<<endl;
01520     return true;
01521   }
01522 
01523   //define the default time cuts
01524   Double_t lowerTimeBound=-20*(Munits::microsecond);
01525   Double_t upperTimeBound=+30*(Munits::microsecond);
01526 
01527   if (this->IsNMB(nu) || NuCuts::kJJE1==nu.anaVersion){
01528     //New and improved spill timing cut.
01529     lowerTimeBound=-2*(Munits::microsecond);
01530     upperTimeBound=+12*(Munits::microsecond);
01531   }
01532 
01533   MAXMSG("NuCuts",Msg::kInfo,1)
01534     <<"Cutting on TimeToNearestSpill: "
01535     <<lowerTimeBound/(Munits::microsecond)<<"<t<"
01536     <<upperTimeBound/(Munits::microsecond)<<" us"<<endl;
01537 
01538   if (nu.timeEvtMin-nu.timeToNearestSpill>lowerTimeBound &&
01539       nu.timeEvtMin-nu.timeToNearestSpill<upperTimeBound) {
01540     return true;
01541   }
01542   else return false;
01543 }
01544 
01545 //......................................................................
01546 
01547 Bool_t NuCuts::IsGoodDirCos(const NuEvent& nu) const
01548 {
01549   Float_t cutValue=0.6;
01550   //trkvtxdcosz //dirCosNu
01551   Float_t value=nu.dirCosNu;
01552 
01553   if (nu.detector==Detector::kNear) {
01554     MAXMSG("NuCuts",Msg::kInfo,1)
01555       <<"Not cutting on track direction cosine for ND"<<endl;
01556     return true;
01557   }
01558   else if (nu.detector==Detector::kFar) {
01559     MAXMSG("NuCuts",Msg::kInfo,1)
01560       <<"Making cut on track direction cosine>"<<cutValue<<endl;
01561     if (value>cutValue) return true;
01562     else return false;
01563   }
01564   else {
01565     cout<<"Ahhh, detector="<<nu.detector<<endl;
01566     return false;
01567   }
01568 }
01569 
01570 //......................................................................
01571 
01572 Bool_t NuCuts::IsInFidVol(Float_t x,Float_t y,Float_t z,
01573                           Float_t u,Float_t v,
01574                           Int_t planeTrkVtx,Float_t rTrkVtx,
01575                           Int_t detector,Int_t anaVersion,
01576                           Int_t releaseType,Int_t simFlag) const
01577 {
01578 
01579   static Bool_t infid_initialised=false;
01580 
01582   //NEAR detector
01584   if (detector==Detector::kNear){
01585     if (anaVersion==NuCuts::kCC0093Std) {
01586       MAXMSG("NuCuts",Msg::kInfo,1)
01587         <<"Cutting on ND xyz point being in kCC0093Std fid vol"<<endl;
01588       return this->IsInFidVolNDCC0093Std(x,y,z);
01589     }
01590     else if (anaVersion==NuCuts::kCC0250Std) {
01591       MAXMSG("NuCuts",Msg::kInfo,1)
01592         <<"Cutting on ND xyz point being in kCC0250Std fid vol"<<endl;
01593       return this->IsInFidVolNDCC0250Std(x,y,z);
01594     }
01595     else if ( anaVersion==NuCuts::kCC0325Std ||
01596               anaVersion == NuCuts::kCC0720Std ||
01597               anaVersion==NuCuts::kCC0720Test ||
01598               anaVersion==NuCuts::kJJH1 ||
01599               anaVersion==NuCuts::kJJE1 ||
01600               anaVersion==NuCuts::kJJE2 ||
01601               anaVersion == NuCuts::kNMB0325Alpha ||
01602               anaVersion == NuCuts::kNMB0325Bravo ||
01603               anaVersion == NuCuts::kNMB0325BravoTwo ||
01604               anaVersion == NuCuts::kNMB0325Charlie ||
01605               anaVersion == NuCuts::kNMB0325Delta ||
01606               anaVersion == NuCuts::kNMB0325Echo  ||
01607               anaVersion == NuCuts::kRM1  ||
01608               anaVersion == NuCuts::kRM2  ||
01609               anaVersion == NuCuts::kNMBFree ||
01610               anaVersion == NuCuts::kRHC ||
01611               anaVersion == NuCuts::kMSRock ) {
01612       static Int_t msgCounter = 0;
01613       if (msgCounter < 20){
01614         MAXMSG("NuCuts",Msg::kInfo,1)
01615           <<"Cutting on ND xyz point being in kCC0325Std fid vol"<<endl;
01616         ++msgCounter;
01617       }
01618       if (!infid_initialised) {
01619         infid_initialised=true;
01620         choose_infid_set("cc2008");
01621       }
01622       return infid(static_cast<Detector::Detector_t>(detector),
01623         static_cast<SimFlag::SimFlag_t>(simFlag),
01624         x,y,z);
01625     }
01626     else if (anaVersion==NuCuts::kFullDST) {
01627       MAXMSG("NuCuts",Msg::kInfo,1)
01628         <<"For kFullDST cutting on ND xyz point being in"
01629         <<" \"loose\" fid vol"<<endl;
01630       return this->IsInFidVolLoose(x,y,z,detector);
01631     }
01632     else {
01633       MAXMSG("NuCuts",Msg::kInfo,1)
01634         <<"Cutting on ND xyz point being in Pitt fid vol"<<endl;
01635       return this->IsInFidVolPitt(x,y,z,u,v);
01636     }
01637   }
01639   //FAR detector
01641   else if (detector==Detector::kFar){
01642     if (anaVersion==NuCuts::kCC0093Std) {
01643       MAXMSG("NuCuts",Msg::kInfo,1)
01644         <<"Cutting on FD xyz point being in kCC0093Std fid vol"<<endl;
01645       return this->IsInFidVolFDCC0093Std(x,y,z);
01646     }
01647     else if (anaVersion==NuCuts::kCC0250Std) {
01648       if (ReleaseType::IsBirch(releaseType)) {
01649         MSG("NuCuts",Msg::kError)
01650           <<"You can't run kCC0250Std cuts on Birch data since not all"
01651           <<" the variables are available!"<<endl;
01652         MSG("NuCuts",Msg::kFatal)<<"This doesn't print"<<endl;
01653       }
01654       MAXMSG("NuCuts",Msg::kInfo,1)
01655         <<"Cutting on FD xyz point being in kCC0250Std fid vol"<<endl;
01656       return this->IsInFidVolFDCC0250Std(planeTrkVtx,rTrkVtx);
01657     }
01658     else if (anaVersion==NuCuts::kCC0325Std ||
01659              anaVersion == NuCuts::kCC0720Std ||
01660              anaVersion==NuCuts::kCC0720Test ||
01661              anaVersion==NuCuts::kJJH1 ||
01662              anaVersion==NuCuts::kJJE1 ||
01663              anaVersion==NuCuts::kJJE2 ||
01664              anaVersion == NuCuts::kNMB0325Alpha ||
01665              anaVersion == NuCuts::kNMB0325Bravo ||
01666              anaVersion == NuCuts::kNMB0325BravoTwo ||
01667              anaVersion == NuCuts::kNMB0325Charlie ||
01668              anaVersion == NuCuts::kNMB0325Delta ||
01669              anaVersion == NuCuts::kNMB0325Echo ||
01670              anaVersion == NuCuts::kRM1 ||
01671              anaVersion == NuCuts::kRM2 ||
01672              anaVersion == NuCuts::kNMBFree ||
01673              anaVersion == NuCuts::kRHC ||
01674              anaVersion == NuCuts::kMSRock) {
01675       MAXMSG("NuCuts",Msg::kInfo,1)
01676         <<"Cutting on FD xyz point being in kCC0325Std fid vol"<<endl;
01677       if (!infid_initialised) {
01678         infid_initialised=true;
01679         choose_infid_set("cc2008");
01680       }
01681       Bool_t isin = infid(static_cast<Detector::Detector_t>(detector),
01682         static_cast<SimFlag::SimFlag_t>(simFlag),
01683         x,y,z);
01684       // Rock muons use an anti-fiducial cut
01685       if (anaVersion == NuCuts::kMSRock) {
01686         MAXMSG("NuCuts",Msg::kInfo,1)
01687           <<"Cutting on INVERSE fiducial volume"<<endl;
01688         return !isin;
01689       }
01690       return isin;
01691     }
01692     else if (anaVersion==NuCuts::kFullDST) {
01693       MAXMSG("NuCuts",Msg::kInfo,1)
01694         <<"For kFullDST cutting on FD xyz point being in"
01695         <<" \"loose\" fid vol"<<endl;
01696       return this->IsInFidVolLoose(x,y,z,detector);
01697     }
01698     else {
01699       //use kCC0093Std here since all the variables are safely defined
01700       MAXMSG("NuCuts",Msg::kInfo,1)
01701         <<"Cutting on FD xyz point being in kCC0093Std fid vol"<<endl;
01702       return this->IsInFidVolFDCC0093Std(x,y,z);
01703     }
01704   }
01705   else {
01706     cout<<"Ahhh, detector not recognised, det="<<detector<<endl;
01707     return false;
01708   }
01709 }
01710 
01711 //......................................................................
01712 
01713 Bool_t NuCuts::IsInFidVolTrueEvt(const NuMCEvent& mc) const
01714 {
01718   MAXMSG("NuCuts",Msg::kInfo,1)
01719     <<"Cutting on IsInFidVolTrueEvt()"<<endl;
01720   return this->IsInFidVol
01721     (mc.vtxxMC,mc.vtxyMC,mc.vtxzMC,mc.vtxuMC, mc.vtxvMC,
01722      mc.planeTrkVtxMC,mc.rTrkVtxMC,
01723      mc.detector,mc.anaVersion,mc.releaseType,mc.simFlag);
01724 }
01725 
01726 //......................................................................
01727 
01728 Bool_t NuCuts::IsInFidVolTrueEvt(const NuEvent& nu) const
01729 {
01733   //MAXMSG("NuCuts",Msg::kInfo,1) <<"Cutting on IsInFidVolTrueEvt()"<<endl;
01734   if (nu.simFlag != SimFlag::kMC) {
01735     MSG("NuCuts",Msg::kError) << "Cannot do true cut on data" << endl;
01736     MSG("NuCuts",Msg::kFatal) << "Cannot do true cut on data" << endl;
01737   }
01738   // Not sure if this needs to handle rock muons - but apply anyway
01739   return this->IsInFidVol
01740     (nu.vtxxMC,nu.vtxyMC,nu.vtxzMC,nu.vtxuMC, nu.vtxvMC,
01741      nu.planeTrkVtxMC,nu.rTrkVtxMC,
01742      nu.detector,nu.anaVersion,nu.releaseType,nu.simFlag);
01743 }
01744 
01745 //......................................................................
01746 
01747 Bool_t NuCuts::IsInFidVolTrk(const NuEvent& nu) const
01748 {
01751 
01752   //by default use the trk vtx as is
01753   Float_t z=nu.zTrkVtx;
01754 
01755   //move trk vtx upstream by 3.92cm from scintillator to steel
01756   //for these analysis versions
01757   if (nu.anaVersion==NuCuts::kCC0325Std ||
01758       nu.anaVersion==NuCuts::kCC0720Std ||
01759       nu.anaVersion==NuCuts::kCC0720Test ||
01760       nu.anaVersion==NuCuts::kJJH1 ||
01761       nu.anaVersion==NuCuts::kJJE1 ||
01762       IsNMB(nu) ) {
01763     z=nu.zTrkVtx-(0.0392*Munits::m);
01764   }
01765 
01766   MAXMSG("NuCuts",Msg::kInfo,1)
01767     <<"Cutting on IsInFidVolTrk()"<<endl;
01768   return this->IsInFidVol(nu.xTrkVtx,nu.yTrkVtx,
01769                           z,
01770                           nu.uTrkVtx,nu.vTrkVtx,
01771                           nu.planeTrkVtx,nu.rTrkVtx,
01772                           nu.detector,nu.anaVersion,
01773                           nu.releaseType,nu.simFlag);
01774 }
01775 
01776 //......................................................................
01777 
01778 Bool_t NuCuts::IsInFidVolEvt(const NuEvent& nu) const
01779 {
01782 
01783   //by default use the evt vtx as is
01784   Float_t z=nu.zEvtVtx;
01785 
01786   // TODO CJB I don't think we need to move the vertex, but I'm not sure
01787   /*
01788   //move trk vtx upstream by 3.92cm from scintillator to steel
01789   //for these analysis versions
01790   if (nu.anaVersion==NuCuts::kCC0325Std ||
01791       nu.anaVersion==NuCuts::kCC0720Std ||
01792       nu.anaVersion==NuCuts::kJJH1 ||
01793       nu.anaVersion==NuCuts::kJJE1 ||
01794       IsNMB(nu) ) {
01795     z=nu.zTrkVtx-(0.0392*Munits::m);
01796   }
01797   */
01798 
01799   MAXMSG("NuCuts",Msg::kInfo,1)
01800     <<"Cutting on IsInFidVolTrk()"<<endl;
01801   return this->IsInFidVol(nu.xEvtVtx,nu.yEvtVtx,
01802                           z,
01803                           nu.uEvtVtx,nu.vEvtVtx,
01804                           nu.planeEvtVtx,nu.rEvtVtx,
01805                           nu.detector,nu.anaVersion,
01806                           nu.releaseType,nu.simFlag);
01807 }
01808 
01809 //......................................................................
01810 
01811 Bool_t NuCuts::IsInFidVolOffset(Float_t x,Float_t y,Float_t z) const
01812 {
01813   const Float_t zerox=0.9*(Munits::m);
01814   const Float_t zeroy=0.0*(Munits::m);
01815   const Float_t minZ=1.0*(Munits::m);
01816   const Float_t maxZ=4.0*(Munits::m);
01817   const Float_t maxR=0.6*(Munits::m);
01818   Bool_t passFid=this->IsInCylindricalVolume(x,y,z,zerox,zeroy,
01819                                              minZ,maxZ,maxR);
01820   passFid=passFid && x>=0.7;
01821   return passFid;
01822 }
01823 
01824 //......................................................................
01825 
01826 Bool_t NuCuts::IsInFidVolOffset(const NuEvent& nu) const
01827 {
01828   return this->IsInFidVolOffset(nu.xTrkVtx,nu.yTrkVtx,nu.zTrkVtx);
01829 }
01830 
01831 //......................................................................
01832 
01833 Bool_t NuCuts::IsInFidVolNDNuMuBar(Float_t x,Float_t y,
01834                                    Float_t z) const
01835 {
01836   //fiducial criteria on vtx for near detector
01837   const Float_t beamzerox=1.4828*(Munits::m);//new for 2.5 analysis
01838   const Float_t beamzeroy=0.2384*(Munits::m);//new for 2.5 analysis
01839 
01840   //define this volume
01841   Float_t minZ=0.6*(Munits::m);
01842   Float_t maxZ=4.0*(Munits::m);
01843   Float_t maxR=0.8*(Munits::m);
01844 
01845   return this->IsInCylindricalVolume(x,y,z,beamzerox,beamzeroy,
01846                                      minZ,maxZ,maxR);
01847 }
01848 
01849 //......................................................................
01850 
01851 Bool_t NuCuts::IsInFidVolNDCC0093Std(Float_t x,Float_t y,
01852                                      Float_t z) const
01853 {
01854   //got these numbers from Masaki's spectrum validation talks
01855   //fiducial criteria on vtx for near detector
01856   const Float_t beamzerox=1.4885*(Munits::m);
01857   const Float_t beamzeroy=0.1397*(Munits::m);
01858   //Float_t beamzeroy = 0.1397-reco_vtxz*TMath::Tan(.058);
01859 
01860   //define this volume
01861   Float_t minZ=1.0*(Munits::m);
01862   Float_t maxZ=5.0*(Munits::m);
01863   Float_t maxR=1.0*(Munits::m);
01864 
01865   return this->IsInCylindricalVolume(x,y,z,beamzerox,beamzeroy,
01866                                      minZ,maxZ,maxR);
01867 }
01868 
01869 //......................................................................
01870 
01871 Bool_t NuCuts::IsInFidVolNDCC0250Std(Float_t x,Float_t y,
01872                                      Float_t z) const
01873 {
01874   //fiducial criteria on vtx for near detector
01875   const Float_t beamzerox=1.4828*(Munits::m);//new for 2.5 analysis
01876   const Float_t beamzeroy=0.2384*(Munits::m);//new for 2.5 analysis
01877 
01878   //define this volume
01879   Float_t minZ=1.0*(Munits::m);
01880   Float_t maxZ=5.0*(Munits::m);
01881   Float_t maxR=1.0*(Munits::m);
01882 
01883   return this->IsInCylindricalVolume(x,y,z,beamzerox,beamzeroy,
01884                                      minZ,maxZ,maxR);
01885 }
01886 
01887 //......................................................................
01888 
01889 Bool_t NuCuts::IsInFidVolFDNuMuBar(Int_t planeTrkVtx,
01890                                    Float_t rTrkVtx) const
01891 {
01892   //fiducial criteria on vtx for far detector
01893   //these are the CC-analysis 2.5e20 cuts
01894   //plus a coil hole cut based on John Marshall's talk DocDB 3644
01895 
01896   //minos-doc-3156
01897   if (rTrkVtx>(0.4*Munits::m) &&
01898       rTrkVtx<sqrt(14.)*Munits::m &&
01899       ((planeTrkVtx>4 && planeTrkVtx<241) ||
01900        (planeTrkVtx>253 && planeTrkVtx<466))) return true;
01901   else return false;
01902 }
01903 
01904 //......................................................................
01905 
01906 Bool_t NuCuts::IsInFidVolFDCC0093Std(Float_t x,Float_t y,
01907                                      Float_t z) const
01908 {
01909   //got these numbers from Masaki's spectrum validation talks
01910   //there is no coil cut!
01911   //fiducial criteria on vtx for far detector
01912   if(((z>0.50 && z<14.3) || (z>16.2 && z<28.0)) &&
01913      ((x*x)+(y*y))<14.0) return true;
01914   else return false;
01915 }
01916 
01917 //......................................................................
01918 
01919 Bool_t NuCuts::IsInFidVolFDCC0250Std(Int_t planeTrkVtx,
01920                                      Float_t rTrkVtx) const
01921 {
01922   //fiducial criteria on vtx for far detector
01923   //these are Andy Blake's cuts in DocDB 2728
01924   //but without the coil cut
01925 
01926   //if (drTrkFidvtx>(0.2*Munits::m) &&
01927   //    rTrkVtx>(0.4*Munits::m) &&
01928   //    ((planeTrkVtx>4 && planeTrkVtx<241) ||
01929   //     (planeTrkVtx>253 && planeTrkVtx<466))) return true;
01930 
01931   //minos-doc-3156
01932   if (rTrkVtx<sqrt(14.)*Munits::m &&
01933       ((planeTrkVtx>4 && planeTrkVtx<241) ||
01934        (planeTrkVtx>253 && planeTrkVtx<466))) return true;
01935   else return false;
01936 }
01937 
01938 //fiducial criteria on vtx for far detector
01939 //these are Andy Blake's cuts in DocDB 2728
01940 //coil cut added wrt 2.5e20 analysis
01941 //and coded using z position instead of plane
01942 
01943 //const Float_t minZSM1=0.215*Munits::m;
01944 //const Float_t maxZSM1=14.255*Munits::m;
01945 //const Float_t minZSM2=16.122*Munits::m;
01946 //const Float_t maxZSM2=28.722*Munits::m;
01947 //const Float_t minR=0.4*Munits::m;
01948 //const Float_t maxR=sqrt(14.)*Munits::m;
01949 
01950 //calc radius
01951 //Float_t r=sqrt((x*x)+(y*y));
01952 
01953 //make the cut
01954 //if ((z>minZSM1 && z<maxZSM1) ||
01955 //      (z>minZSM2 && z<maxZSM2) &&
01956 //      r>minR && r<maxR) return true;
01957 //else return false;
01958 
01959 //......................................................................
01960 
01961 Bool_t NuCuts::IsInFidVolPitt(Float_t x,Float_t y,Float_t z,
01962                               Float_t u,Float_t v) const
01963 {
01964   // Is the event vertex, (x,y,u,v,z) inside the fiducial volume
01965   // used by the pittsburgh group?
01966   // code from Mike
01967   if( !( z>0.6 && z<3.56) ) return kFALSE;
01968   if( !( u>0.3 && u<1.8) ) return kFALSE;
01969   if( !( v>-1.8 && v< -0.3) ) return kFALSE;
01970   if( x>=2.4) return kFALSE;
01971   const Float_t coil_cut=0.8*0.8;
01972   if( (x*x + y*y) <= coil_cut) return kFALSE;
01973   return kTRUE;
01974 }
01975 
01976 //......................................................................
01977 
01978 Bool_t NuCuts::IsInFidVolLoose(const NuEvent& nu) const
01979 {
01984 
01985   //get an instance of the code library
01986   const NuLibrary& lib=NuLibrary::Instance();
01987 
01989   Bool_t trkInFidLoose1=false;
01990   if (nu.trkExists1) trkInFidLoose1=lib.cuts.IsInFidVolLoose
01991                        (nu.xTrkVtx1,nu.yTrkVtx1,nu.zTrkVtx1,
01992                         nu.detector);
01993   Bool_t trkInFidLoose2=false;
01994   if (nu.trkExists2) trkInFidLoose2=lib.cuts.IsInFidVolLoose
01995                        (nu.xTrkVtx2,nu.yTrkVtx2,nu.zTrkVtx2,
01996                         nu.detector);
01997   Bool_t trkInFidLoose3=false;
01998   if (nu.trkExists3) trkInFidLoose3=lib.cuts.IsInFidVolLoose
01999                        (nu.xTrkVtx3,nu.yTrkVtx3,nu.zTrkVtx3,
02000                         nu.detector);
02002   Bool_t shwInFidLoose1=false;
02003   if (nu.shwExists1) shwInFidLoose1=lib.cuts.IsInFidVolLoose
02004                        (nu.xShwVtx1,nu.yShwVtx1,nu.zShwVtx1,
02005                         nu.detector);
02006   Bool_t shwInFidLoose2=false;
02007   if (nu.shwExists2) shwInFidLoose2=lib.cuts.IsInFidVolLoose
02008                        (nu.xShwVtx2,nu.yShwVtx2,nu.zShwVtx2,
02009                         nu.detector);
02010   Bool_t shwInFidLoose3=false;
02011   if (nu.shwExists3) shwInFidLoose3=lib.cuts.IsInFidVolLoose
02012                        (nu.xShwVtx3,nu.yShwVtx3,nu.zShwVtx3,
02013                         nu.detector);
02014   const Bool_t trkInFidLoose=trkInFidLoose1 || trkInFidLoose2 ||
02015     trkInFidLoose3;
02016   const Bool_t shwInFidLoose=shwInFidLoose1 || shwInFidLoose2 ||
02017     shwInFidLoose3;
02018   const Bool_t evtInFidLoose=lib.cuts.IsInFidVolLoose
02019     (nu.xEvtVtx,nu.yEvtVtx,nu.zEvtVtx,nu.detector);
02020 
02021   //cut out events that don't have either trk or shw or evt
02022   //in loose fid vol
02023   return (trkInFidLoose || shwInFidLoose || evtInFidLoose);
02024 }
02025 
02026 //......................................................................
02027 
02028 Bool_t NuCuts::IsInFidVolLoose(Float_t x,Float_t y,Float_t z,
02029                                Int_t detector) const
02030 {
02035 
02036   //return true for all FD events since almost all are in FV anyway
02037   if (detector==Detector::kFar) return true;
02038 
02039   //use the 0093CC analysis beam centre since it is more central
02040   //than the 0250CC analysis
02041   const Float_t beamzerox=1.4828*(Munits::m);
02042   const Float_t beamzeroy=0.1397*(Munits::m);
02043   const Float_t minZ=0.5*(Munits::m);
02044   const Float_t maxZ=5.1*(Munits::m);
02045   const Float_t maxR=1.15*(Munits::m);//allows 1m for zero-y & bc=0.23
02046 
02047   //check if in volume
02048   Bool_t passFid=this->IsInCylindricalVolume
02049     (x,y,z,beamzerox,beamzeroy,minZ,maxZ,maxR);
02050 
02051   //return selection
02052   return passFid;
02053 }
02054 
02055 //......................................................................
02056 
02057 Bool_t NuCuts::IsInCylindricalVolume(Float_t x,Float_t y,
02058                                      Float_t z,
02059                                      Float_t zerox,Float_t zeroy,
02060                                      Float_t minZ,Float_t maxZ,
02061                                      Float_t maxR) const
02062 {
02063   Float_t r=sqrt(pow((x-zerox),2)+pow((y-zeroy),2));
02064   if(z>minZ && z<maxZ && r<maxR) return true;
02065   else return false;
02066 }
02067 
02068 //......................................................................
02069 
02070 void NuCuts::FindZCuts() const
02071 {
02074 
02075   //NOTE: using trk.vtx.z-0.0392 for CC analysis to move vtx from scint
02076   //to steel where interaction happened
02077 
02078   //steel planes 14-68 inclusive for CC2008 analysis
02079   //ND LOWER CUT: actually want cut to be in the large air gap
02080   //upstream of plane 14, so use 13
02081   //ND UPPER CUT: want cut to be in large air gap downstream
02082   //of 68, so use 68
02083 
02084   //FD SM1 LOWER CUT: use plane 3 (based on trk.vtx.z-0.0392)
02085   //FD SM2 UPPER CUT: use plane 239
02086   //FD SM1 LOWER CUT: use plane 252
02087   //FD SM2 UPPER CUT: use plane 464
02088 
02089   //ND: trk.vtx.z-0.0392>0.809 && trk.vtx.z-0.0392<4.076
02090 
02091   //(trk.vtx.z-0.0392>0.215 && trk.vtx.z-0.0392<14.255) ||                      (trk.vtx.z-0.0392>16.122 && trk.vtx.z-0.0392<28.722)
02092   //These positions are based on MC (FD data is shifted by ~0.7-1.4cm wrt to MC)
02093   //Andy's cuts are currently in plane form:
02094   //(trk.vtx.plane>4 && trk.vtx.plane<241) || (trk.vtx.plane>253 && trk.vtx.plane<466)
02095 
02096   //enum EAirRegion {
02097   //kBetweenScintAndSteel =  0,
02098   //kDownstreamOfSteel          = +1
02099   //};
02100   //enum EPosition {
02101   //kUpstream           = -1,
02102   //kMiddle                     =  0,
02103   //kDownstream = +1
02104   //};
02105 
02106   FidVol::find_z_cuts(17,84,8,240,255,452,
02107                       FidVol::kBetweenScintAndSteel,
02108                       FidVol::kMiddle,Munits::micrometer);
02109 
02110   FidVol::find_z_cuts(17,84,8,240,255,452,
02111                       FidVol::kDownstreamOfSteel,
02112                       FidVol::kMiddle,Munits::micrometer);
02113 
02114   //use CC2008 cuts
02115   FidVol::find_z_cuts(13,68,3,239,252,464,
02116                       FidVol::kDownstreamOfSteel,
02117                       FidVol::kMiddle,Munits::micrometer);
02118 }
02119 
02120 //......................................................................
02121 
02122 Bool_t NuCuts::IsGoodUVVtx(const NuEvent& nu) const
02123 {
02124   Float_t cutValue=5;
02125   if (false) {
02126     MAXMSG("NuCuts",Msg::kInfo,1)
02127       <<"Cutting on UV trk vtx<="<<cutValue<<endl;
02128     if (abs(nu.trkVtxUVDiffPl)<=cutValue) return true;
02129     else return false;
02130   }
02131   else if (nu.anaVersion==NuCuts::kCC0093Std ||
02132            nu.anaVersion==NuCuts::kCC0250Std ||
02133            nu.anaVersion==NuCuts::kJJE1 ||
02134            nu.anaVersion==NuCuts::kCC0325Std ||
02135            nu.anaVersion==NuCuts::kCC0720Std ||
02136            nu.anaVersion==NuCuts::kCC0720Test ||
02137            nu.anaVersion==NuCuts::kJJH1 || IsNMB(nu) ) {
02138     MAXMSG("NuCuts",Msg::kInfo,1)
02139       <<"Not cutting on UV trk vtx"<<endl;
02140     return true;
02141   }
02142   else {
02143     MAXMSG("NuCuts",Msg::kInfo,1)
02144       <<"Cutting on UV trk vtx<="<<cutValue<<endl;
02145     if (abs(nu.trkVtxUVDiffPl)<=cutValue) return true;
02146     else return false;
02147   }
02148 }
02149 
02150 //......................................................................
02151 /*
02152   void NuCuts::FillTimeHistos(const NtpStRecord& ntp,
02153   const NtpSREvent& evt) const
02154   {
02155 
02156   static TH1F* hTimeLength=0;
02157   static TH1F* hTimeBefore=0;
02158   static TH1F* hTimeAfter=0;
02159 
02160   static TH1F* hSlcTimeLength=0;
02161   static TH1F* hSlcTimeBefore=0;
02162   static TH1F* hSlcTimeAfter=0;
02163 
02164   static TH1F* hTrkTimeLength=0;
02165   static TH1F* hTrkTimeBefore=0;
02166   static TH1F* hTrkTimeAfter=0;
02167 
02168   static TH1F* hMedianTrkSlcDiff=0;
02169 
02170   if (hTimeLength==0) {
02171   MSG("NuCuts",Msg::kInfo)
02172   <<"Creating time histos..."<<endl;
02173 
02174   hTimeLength=new TH1F("hTimeLength","hTimeLength",10000,-100,50000);
02175   hTimeLength->SetFillColor(0);
02176   hTimeLength->SetTitle("Snarl Length in Time");
02177   hTimeLength->GetXaxis()->SetTitle("Time (ns)");
02178   hTimeLength->GetXaxis()->CenterTitle();
02179 
02180   hTimeBefore=new TH1F("hTimeBefore","hTimeBefore",10000,-100,50000);
02181   hTimeBefore->SetFillColor(0);
02182   hTimeBefore->SetTitle("Time Between Event and First Hit");
02183   hTimeBefore->GetXaxis()->SetTitle("Time (ns)");
02184   hTimeBefore->GetXaxis()->CenterTitle();
02185 
02186   hTimeAfter=new TH1F("hTimeAfter","hTimeAfter",10000,-100,50000);
02187   hTimeAfter->SetFillColor(0);
02188   hTimeAfter->SetTitle("Time Between Event and Last Hit");
02189   hTimeAfter->GetXaxis()->SetTitle("Time (ns)");
02190   hTimeAfter->GetXaxis()->CenterTitle();
02191 
02192   hSlcTimeLength=new TH1F
02193   ("hSlcTimeLength","hSlcTimeLength",10000,-100,50000);
02194   hSlcTimeLength->SetFillColor(0);
02195   hSlcTimeLength->SetTitle("Slice Length in Time");
02196   hSlcTimeLength->GetXaxis()->SetTitle("Time (ns)");
02197   hSlcTimeLength->GetXaxis()->CenterTitle();
02198 
02199   hSlcTimeBefore=new TH1F
02200   ("hSlcTimeBefore","hSlcTimeBefore",10000,-100,50000);
02201   hSlcTimeBefore->SetFillColor(0);
02202   hSlcTimeBefore->SetTitle("Time Between Event and First Hit in Slice");
02203   hSlcTimeBefore->GetXaxis()->SetTitle("Time (ns)");
02204   hSlcTimeBefore->GetXaxis()->CenterTitle();
02205 
02206   hSlcTimeAfter=new TH1F
02207   ("hSlcTimeAfter","hSlcTimeAfter",10000,-100,50000);
02208   hSlcTimeAfter->SetFillColor(0);
02209   hSlcTimeAfter->SetTitle("Time Between Event and Last Hit in Slice");
02210   hSlcTimeAfter->GetXaxis()->SetTitle("Time (ns)");
02211   hSlcTimeAfter->GetXaxis()->CenterTitle();
02212 
02213   hTrkTimeLength=new TH1F
02214   ("hTrkTimeLength","hTrkTimeLength",10000,-100,50000);
02215   hTrkTimeLength->SetFillColor(0);
02216   hTrkTimeLength->SetTitle("Track Length in Time");
02217   hTrkTimeLength->GetXaxis()->SetTitle("Time (ns)");
02218   hTrkTimeLength->GetXaxis()->CenterTitle();
02219 
02220   hTrkTimeBefore=new TH1F
02221   ("hTrkTimeBefore","hTrkTimeBefore",10000,-100,50000);
02222   hTrkTimeBefore->SetFillColor(0);
02223   hTrkTimeBefore->SetTitle("Time Between Event and First Tracked Hit");
02224   hTrkTimeBefore->GetXaxis()->SetTitle("Time (ns)");
02225   hTrkTimeBefore->GetXaxis()->CenterTitle();
02226 
02227   hTrkTimeAfter=new TH1F
02228   ("hTrkTimeAfter","hTrkTimeAfter",10000,-100,50000);
02229   hTrkTimeAfter->SetFillColor(0);
02230   hTrkTimeAfter->SetTitle("Time Between Event and Last Tracked Hit");
02231   hTrkTimeAfter->GetXaxis()->SetTitle("Time (ns)");
02232   hTrkTimeAfter->GetXaxis()->CenterTitle();
02233 
02234   hMedianTrkSlcDiff=new TH1F
02235   ("hMedianTrkSlcDiff","hMedianTrkSlcDiff",10000,-3000,3000);
02236   hMedianTrkSlcDiff->SetFillColor(0);
02237   hMedianTrkSlcDiff->SetTitle("Diff. between Median Slc and Median Trk Time");
02238   hMedianTrkSlcDiff->GetXaxis()->SetTitle("Time (ns)");
02239   hMedianTrkSlcDiff->GetXaxis()->CenterTitle();
02240   }
02241 
02242   TClonesArray& stpTca=(*ntp.stp);
02243   Int_t numStps=stpTca.GetEntries();
02244 
02245   Double_t earliestTime=999;
02246   Double_t latestTime=-999;
02247   multiset<Double_t> times;
02248 
02249   //this loop is over ALL the strips
02250   for (Int_t i=0;i<numStps;i++){
02251 
02252   const NtpSRStrip* pstp=dynamic_cast<NtpSRStrip*>(stpTca[i]);
02253   const NtpSRStrip& stp=(*pstp);
02254 
02255   //Int_t pl=stp.plane;
02256 
02257   //get earliest and latest times in snarl
02258   if (stp.time1>=0 && stp.time1>latestTime) latestTime=stp.time1;
02259   if (stp.time0>=0 && stp.time0>latestTime) latestTime=stp.time0;
02260   if (stp.time1>=0 && stp.time1<earliestTime) earliestTime=stp.time1;
02261   if (stp.time0>=0 && stp.time0<earliestTime) earliestTime=stp.time0;
02262 
02263   Double_t time=stp.time0;
02264   if (time<0 || time>1) time=stp.time1;
02265 
02266   if (time>0 && time<=1) {
02267   times.insert(time);
02268   }
02269 
02270   MAXMSG("NuCuts",Msg::kDebug,500)
02271   <<"t0="<<stp.time0<<", t1="<<stp.time1
02272   <<", lT="<<latestTime<<", eT="<<earliestTime
02273   <<", dT="<<(latestTime-earliestTime)/Munits::ns<<endl;
02274   }
02275 
02276   //get the median time from the map
02277   multiset<Double_t>::const_iterator it=times.begin();
02278   advance(it,times.size()/2);
02279   Double_t medianTime=*it;
02280   MAXMSG("NuCuts",Msg::kDebug,200)
02281   <<"Median time="<<medianTime
02282   <<", dBefore="<<(medianTime-earliestTime)/Munits::ns
02283   <<", dAfter="<<(latestTime-medianTime)/Munits::ns<<endl;
02284 
02285   hTimeAfter->Fill((latestTime-medianTime)/Munits::ns);
02286   hTimeBefore->Fill((medianTime-earliestTime)/Munits::ns);
02287   hTimeLength->Fill((latestTime-earliestTime)/Munits::ns);
02288 
02290   //now look at slice times
02292 
02293   //reset variables
02294   earliestTime=999;
02295   latestTime=-999;
02296   times.clear();
02297 
02298   TClonesArray& slcTca=(*ntp.slc);
02299 
02300   //get the slice associated with this event
02301   const NtpSRSlice* pslc=
02302   dynamic_cast<NtpSRSlice*>(slcTca[evt.slc]);
02303   const NtpSRSlice& slc=(*pslc);
02304 
02305   //loop over strips in slc
02306   for (Int_t i=0;i<slc.nstrip;++i) {
02307   const NtpSRStrip* pstp=
02308   dynamic_cast<NtpSRStrip*>(stpTca[slc.stp[i]]);
02309   const NtpSRStrip& stp=(*pstp);
02310 
02311   //get earliest and latest times in snarl
02312   if (stp.time1>=0 && stp.time1>latestTime) latestTime=stp.time1;
02313   if (stp.time0>=0 && stp.time0>latestTime) latestTime=stp.time0;
02314   if (stp.time1>=0 && stp.time1<earliestTime) earliestTime=stp.time1;
02315   if (stp.time0>=0 && stp.time0<earliestTime) earliestTime=stp.time0;
02316 
02317   Double_t time=stp.time0;
02318   if (time<0 || time>1) time=stp.time1;
02319 
02320   if (time>0 && time<=1) {
02321   times.insert(time);
02322   }
02323   }
02324 
02325   //get the median time from the map
02326   it=times.begin();
02327   advance(it,times.size()/2);
02328   medianTime=*it;
02329 
02330   hSlcTimeAfter->Fill((latestTime-medianTime)/Munits::ns);
02331   hSlcTimeBefore->Fill((medianTime-earliestTime)/Munits::ns);
02332   hSlcTimeLength->Fill((latestTime-earliestTime)/Munits::ns);
02333 
02335   //now look at track times
02337 
02338   //reset variables
02339   earliestTime=999;
02340   latestTime=-999;
02341   times.clear();
02342 
02343   TClonesArray& trkTca=(*ntp.trk);
02344   Int_t numTrks=evt.ntrack;
02345 
02346   for (Int_t itrk=0;itrk<numTrks;itrk++){
02347   const NtpSRTrack* ptrk=
02348   dynamic_cast<NtpSRTrack*>(trkTca[evt.trk[itrk]]);
02349   const NtpSRTrack& trk=(*ptrk);
02350 
02351   TClonesArray& stpTca=(*ntp.stp);
02352 
02353   //this loop is just over the tracked strips
02354   for (Int_t i=0;i<trk.nstrip;i++){
02355 
02356   const NtpSRStrip* pstp=
02357   dynamic_cast<NtpSRStrip*>(stpTca[trk.stp[i]]);
02358   const NtpSRStrip& stp=(*pstp);
02359 
02360   //get earliest and latest times in snarl
02361   if (stp.time1>=0 && stp.time1>latestTime) latestTime=stp.time1;
02362   if (stp.time0>=0 && stp.time0>latestTime) latestTime=stp.time0;
02363   if (stp.time1>=0 && stp.time1<earliestTime) earliestTime=
02364   stp.time1;
02365   if (stp.time0>=0 && stp.time0<earliestTime) earliestTime=
02366   stp.time0;
02367 
02368   Double_t time=stp.time0;
02369   if (time<0 || time>1) time=stp.time1;
02370 
02371   if (time>0 && time<=1) {
02372   times.insert(time);
02373   }
02374   }
02375   }
02376 
02377   //get the median time from the map
02378   it=times.begin();
02379   advance(it,times.size()/2);
02380   Double_t medianTimeTrk=*it;
02381 
02382   MAXMSG("NuCuts",Msg::kDebug,500)
02383   <<"Median time for slc and trk difference="
02384   <<(medianTime-medianTimeTrk)/Munits::ns<<endl;
02385 
02386   hMedianTrkSlcDiff->Fill((medianTime-medianTimeTrk)/Munits::ns);
02387 
02388   hTrkTimeAfter->Fill((latestTime-medianTimeTrk)/Munits::ns);
02389   hTrkTimeBefore->Fill((medianTimeTrk-earliestTime)/Munits::ns);
02390   hTrkTimeLength->Fill((latestTime-earliestTime)/Munits::ns);
02391   }
02392 */
02393 //......................................................................
02394 /*
02395   void NuCuts::PrintNtpSt(const NtpStRecord& ntp) const
02396   {
02397   TClonesArray& tcaTk=(*ntp.trk);
02398   Int_t numTrks=tcaTk.GetEntries();
02399   TClonesArray& stpTca=(*ntp.stp);
02400   Int_t numStps=stpTca.GetEntries();
02401 
02402   MAXMSG("NuCuts",Msg::kInfo,200)
02403   <<"PrintNtpSt: numTrks="<<numTrks
02404   <<", total numStps="<<numStps<<endl;
02405 
02406   //Loop over tracks
02407   for (Int_t itrk=0;itrk<numTrks;itrk++){
02408   const NtpSRTrack* ptrk=
02409   dynamic_cast<NtpSRTrack*>(tcaTk[itrk]);
02410   const NtpSRTrack& trk=(*ptrk);
02411 
02412   TClonesArray& stpTca=(*ntp.stp);
02413 
02414   //this loop is just over the tracked strips
02415   for (Int_t i=0;i<trk.nstrip;i++){
02416 
02417   const NtpSRStrip* pstp=
02418   dynamic_cast<NtpSRStrip*>(stpTca[trk.stp[i]]);
02419   const NtpSRStrip& stp=(*pstp);
02420   MAXMSG("NDNuCuts",Msg::kInfo,20000)
02421   <<"Trk: st="<<stp.strip<<", pl="<<stp.plane
02422   <<", sigCor="<<stp.ph1.sigcor<<", tpos="<<stp.tpos<<endl;
02423   }
02424   }
02425 
02426   //this loop is over ALL the strips
02427   for (Int_t i=0;i<numStps;i++){
02428   const NtpSRStrip* pstp=dynamic_cast<NtpSRStrip*>(stpTca[i]);
02429   const NtpSRStrip& stp=(*pstp);
02430 
02431   MAXMSG("NDNuCuts",Msg::kInfo,20000)
02432   <<"All strips: st="<<stp.strip<<", pl="<<stp.plane
02433   <<", sigCor="<<stp.ph1.sigcor<<", tpos="<<stp.tpos<<endl;
02434   }
02435   }
02436 */
02437 //......................................................................
02438 
02439 void NuCuts::CalcTotalPot(Float_t& totalPotHist,
02440                           Float_t& totalPotBadHist) const
02441 {
02442   //calc the total POT
02443   TH1F* hPottortgt=dynamic_cast<TH1F*>(gROOT->FindObject("hPottortgt"));
02444   TH1F* hPotBadtortgt=
02445     dynamic_cast<TH1F*>(gROOT->FindObject("hPotBadtortgt"));
02446 
02447   if (hPottortgt && hPotBadtortgt) {
02448     //hPottortgt->Print();
02449     //hPotBadtortgt->Print();
02450 
02451     for (Int_t i=0;i<hPotBadtortgt->GetNbinsX();i++) {
02452       Float_t num=hPottortgt->GetBinContent(i);
02453       Float_t val=hPottortgt->GetBinLowEdge(i);
02454       val+=hPottortgt->GetBinWidth(i)/2.;
02455       Float_t sum=num*val;
02456       if (sum<0) {
02457         MAXMSG("NuCuts",Msg::kInfo,10)
02458           <<"sum<0, sum="<<sum
02459           <<", num="<<num
02460           <<", val="<<val<<endl;
02461         sum=0;
02462       }
02463       totalPotHist+=sum;
02464 
02465       Float_t numBad=hPotBadtortgt->GetBinContent(i);
02466       Float_t valBad=hPotBadtortgt->GetBinLowEdge(i);
02467       valBad+=hPotBadtortgt->GetBinWidth(i)/2.;
02468       Float_t sumBad=numBad*valBad;
02469       if (sumBad<0) {
02470         MAXMSG("NuCuts",Msg::kInfo,10)
02471           <<"sumBad<0, sumBad="<<sumBad
02472           <<", num="<<numBad
02473           <<", val="<<valBad<<endl;
02474         sumBad=0;
02475       }
02476       totalPotBadHist+=sumBad;
02477 
02478       MSG("NuCuts",Msg::kDebug)
02479         <<"i="<<i<<", Good: num="<<num
02480         <<", val="<<val<<", sum="<<sum
02481         <<", totalPot="<<totalPotHist<<endl;
02482 
02483       MSG("NuCuts",Msg::kDebug)
02484         <<"i="<<i<<", Bad:      num="<<numBad
02485         <<", val="<<valBad<<", sum="<<sumBad
02486         <<", totalPotBad="<<totalPotBadHist<<endl;
02487     }
02488   }
02489   else cout<<"Can't find histograms to calc total POT"<<endl;
02490 }
02491 
02492 //......................................................................
02493 
02494 void NuCuts::CheckTrackDirectionIsPositive(const NuEvent& nu) const
02495 {
02496   if (nu.planeTrkEnd-nu.planeTrkVtx<0) {
02497     //NuPlots plots;
02498     //plots.PrintRunSnarlEvent(cout,nu);
02499     MSG("NuAnalysis",Msg::kWarning)
02500       <<endl<<endl<<endl
02501       <<"Track direction wrong!!!, vtx plane="<<nu.planeTrkVtx
02502       <<", end plane="<<nu.planeTrkEnd
02503       <<endl<<endl<<endl<<endl;
02504   }
02505 }
02506 
02507 //......................................................................
02508 
02509 const Char_t* NuCuts::AsString(NuAnaVersion_t v) const
02510 {
02511   // return char string
02512   switch (v) {
02513   case kCC0093Std: return "Std CC 1.27e20 POT";
02514   case kJJH1:      return "JJH NuMuBar";
02515   case kJJE1:      return "JJE NuMuBar";
02516   case kJJE2:      return "JJE thesis NuMuBar";
02517   case kCC0250Std: return "Std CC 2.50e20 POT";
02518   case kCC0325Std: return "Std CC 3.25e20 POT";
02519   case kCC0720Test: return "Std CC (with JMCUTS) for 2010 analysis";
02520   case kFullDST:   return "Full DST w/ loose cuts";
02521   case kMSRock:    return "Matt Straits Ely2009 Rock muon selection";
02522   case kCC0720Std: return "Std CC 7.20e20 POT";
02523   case kUnknown:   return "Unknown"; break;
02524   default:         return "!?Bad Value Passed?!"; break;
02525   }
02526 }
02527 
02528 //......................................................................
02529 
02530 const Double_t NuCuts::FiducialMass(const NuEvent& nu) const
02531 {
02532   return this->FiducialMass(nu.detector,nu.simFlag,nu.anaVersion);
02533 }
02534 
02535 //......................................................................
02536 
02537 const Double_t NuCuts::FiducialMass(const Int_t detector,
02538                                     const Int_t simFlag,
02539                                     const Int_t anaVersion) const
02540 {
02541   if (detector == Detector::kNear){
02542     if (anaVersion==NuCuts::kJJH1 ||
02543         anaVersion==NuCuts::kJJE1 ||
02544         anaVersion==NuCuts::kJJE2 ||
02545         anaVersion == NuCuts::kCC0325Std ||
02546         anaVersion == NuCuts::kCC0720Std ||
02547         anaVersion == NuCuts::kNMB0325Alpha ||
02548         anaVersion == NuCuts::kNMB0325Bravo ||
02549         anaVersion == NuCuts::kNMB0325BravoTwo ||
02550         anaVersion == NuCuts::kNMB0325Charlie ||
02551         anaVersion == NuCuts::kNMB0325Delta ||
02552         anaVersion == NuCuts::kNMB0325Echo ||
02553         anaVersion == NuCuts::kRM1 ||
02554         anaVersion == NuCuts::kRM2 ||
02555         anaVersion == NuCuts::kNMBFree ||
02556         anaVersion == NuCuts::kRHC){
02557       //return 23.4200178*Munits::tonne;//JJE
02558       if (simFlag==SimFlag::kData) return 23.7217*
02559                                      Munits::tonne;//JJH
02560       else if (simFlag==SimFlag::kMC) return 23.4989*
02561                                         Munits::tonne;//JJH
02562       else {
02563         cout<<"Ahhhh simFlag="<<simFlag<<endl;
02564         return -1;
02565       }
02566     }
02567     else if (anaVersion == NuCuts::kCC0093Std){
02568       return -1.0;
02569     }
02570     else if (anaVersion == NuCuts::kCC0250Std){
02571       return 44.66068761*Munits::tonne;
02572     }
02573     else {
02574       //PittFidVol
02575       return -1.0;
02576     }
02577   }
02578   else if (detector == Detector::kFar){
02579     if (anaVersion==NuCuts::kJJH1 ||
02580         anaVersion==NuCuts::kJJE1 ||
02581         anaVersion==NuCuts::kJJE2 ||
02582         anaVersion == NuCuts::kCC0325Std ||
02583         anaVersion == NuCuts::kCC0720Std ||
02584         anaVersion == NuCuts::kCC0720Test ||
02585         anaVersion == NuCuts::kNMB0325Alpha ||
02586         anaVersion == NuCuts::kNMB0325Bravo ||
02587   anaVersion == NuCuts::kNMB0325BravoTwo ||
02588         anaVersion == NuCuts::kNMB0325Charlie ||
02589         anaVersion == NuCuts::kNMB0325Delta ||
02590         anaVersion == NuCuts::kNMB0325Echo ||
02591         anaVersion == NuCuts::kRM1 ||
02592         anaVersion == NuCuts::kRM2 ||
02593         anaVersion == NuCuts::kNMBFree ||
02594         anaVersion == NuCuts::kRHC) {
02595       //return 4.119215650*Munits::kilotonne;//JJE
02596       if (simFlag==SimFlag::kData) return 4.17235*
02597                                      Munits::kilotonne;//JJH
02598       else if (simFlag==SimFlag::kMC) return 4.13923*
02599                                         Munits::kilotonne;//JJH
02600       else {
02601         cout<<"Ahhhh simFlag="<<simFlag<<endl;
02602         return -1;
02603       }
02604     }
02605     else if (anaVersion == NuCuts::kCC0093Std){
02606       return -1.0;
02607     }
02608     else if (anaVersion == NuCuts::kCC0250Std){
02609       return 4.164776186*Munits::kilotonne;
02610       //Neglecting the existance of the coil hole!
02611     }
02612     else {
02613       //IsInFidVolFDCC0093Std
02614       return -1.0;
02615     }
02616   }
02617   else{
02618     MAXMSG("NuCuts",Msg::kWarning,5)
02619       << "Bad detector: returning 0 fiducial mass." << endl;
02620     return 0;
02621   }
02622 }
02623 
02624 //......................................................................
02625 Bool_t NuCuts::FreeCuts(const NuEvent& nu, const NuXMLConfig* xmlConfig)const{
02626   if(nu.roID<=xmlConfig->RoID()||
02627      nu.jmID<=xmlConfig->JmID()||
02628      nu.jmEventknnID <= xmlConfig->NtID()||
02629      nu.dpID<=xmlConfig->DpID() ||
02630      nu.poIDKin<=xmlConfig->PoKIN() ||
02631      fabs(1./nu.sigqp_qp)<=xmlConfig->Sigqp() ||
02632      fabs(nu.relativeAngle - TMath::Pi())<= xmlConfig->RelativeAngle() ||
02633      nu.trkLength<=xmlConfig->TrackLength() ||
02634      nu.prob<=xmlConfig->Trkpro() ||
02635      nu.smoothMajC<=xmlConfig->MajorityCurvature())
02636     {
02637       MSG("NuCuts",Msg::kInfo)
02638         <<"Inside free cuts true"<<endl;
02639       return false;}
02640   else
02641     {MSG("NuCuts",Msg::kInfo)
02642       <<"Inside free cuts false"<<endl;
02643       return true;}
02644 }
02645 //......................................................................
02646 
02647 // Rock muon cut variables
02648 Bool_t NuCuts::IsGoodCosPr(const NuEvent& nu) const
02649 {
02650   if (nu.anaVersion==NuCuts::kMSRock) {
02651     // Rock-like if cosPrTrkVtx < -0.2
02652     MAXMSG("NuCuts",Msg::kInfo,1)
02653       <<"Making Cut: IsGoodCosPr < -0.2" << endl;
02654     if (nu.cosPrTrkVtx >= -0.2) return false;
02655   }
02656 
02657   return true;
02658 }
02659 
02660 //......................................................................
02661 
02662 Bool_t NuCuts::IsGoodTrackDr(const NuEvent& nu) const
02663 {
02664   if (nu.anaVersion==NuCuts::kMSRock) {
02665     MAXMSG("NuCuts",Msg::kInfo,1)
02666       <<"Making Cut: IsGoodTrackDr < 0.06" << endl;
02667 
02668     // Rock-like if drTrkFidVtx < 0.06
02669     if (nu.drTrkFidvtx >= 0.06) return false;
02670   }
02671 
02672   return true;
02673 }
02674 
02675 //......................................................................
02676 
02677 Bool_t NuCuts::IsGoodNearShowerEn(const NuEvent& nu) const
02678 {
02679   if (nu.anaVersion==NuCuts::kMSRock) {
02680     MAXMSG("NuCuts",Msg::kInfo,1)
02681       <<"Making Cut: IsGoodNearshowerEnergy < 0.5" << endl;
02682 
02683     // Rock-like if trkShwEnNear < 0.5
02684     if (nu.trkShwEnNear >= 0.5) return false;
02685   }
02686 
02687   return true;
02688 }
02689 
02690 //......................................................................
02691 
02692 Bool_t NuCuts::GoodTimeToNearestSpill(const NuEvent &nu, Double_t lower_us, Double_t upper_us)
02693 {
02694   // Convert the timings to microseconds
02695   lower_us *= (Munits::microsecond);
02696   upper_us *= (Munits::microsecond);
02697 
02698   if (nu.timeEvtMin-nu.timeToNearestSpill>lower_us &&
02699       nu.timeEvtMin-nu.timeToNearestSpill<upper_us) {
02700     return true;
02701   }
02702   else return false;
02703 
02704 }

Generated on Mon Feb 15 11:07:10 2010 for loon by  doxygen 1.3.9.1