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

NuCutImps.cxx

Go to the documentation of this file.
00001 
00002 // NuCutImplementations
00003 // This holds the actual cut implementations i.e. the actual cuts
00005 
00006 #include "NtupleUtils/NuEvent.h"
00007 #include "NtupleUtils/NuCuts.h"
00008 
00009 #include "MessageService/MsgService.h"
00010 
00011 #include "NuCutImps.h"
00012 
00013 #include "Conventions/Munits.h"
00014 #include "Conventions/Detector.h"
00015 #include "Conventions/BeamType.h"
00016 #include "Conventions/SimFlag.h"
00017 #include "DataUtil/infid.h"
00018 
00019 #include "TFile.h"
00020 #include "TDirectory.h"
00021 #include "TTree.h"
00022 #include "TMath.h"
00023 
00024 CVSID("$Id: NuCutImps.cxx,v 1.24 2010/02/08 18:08:54 bckhouse Exp $");
00025 
00026 // Do everything in an embedded namespace, because we don't want to
00027 // pollute the global namespace with cut names
00028 namespace NuCutImps {
00029 
00031 // CC 'Standard' selection
00032 
00033   CC0325Std::CC0325Std(const NuPlots *plots) : 
00034     NuCut("CC0325Std", plots)
00035   {
00036     SetFidVol("cc2008");
00037     SetAnaVersion(6);
00038   }
00039   
00040   // The CC selection uses a slightly altered definition of fiducial volume
00041   // origin: NuCuts::IsInFidVolTrk circa Sept '09
00042   Bool_t CC0325Std::InFidVol(const NuEvent &nu) const
00043   {
00044     // Move trk vtx upstream by 3.92cm from scintillator to steel
00045     // for this analysis version
00046     NuEvent nuc = nu;
00047     nuc.zTrkVtx = nu.zTrkVtx - (0.0392*Munits::m);
00048     
00049     return NuCut::InFidVol(nuc);
00050   }
00051   
00052   // The Preselection //////////////////////////////////////////////////
00053   void CC0325Std::Preselection(const NuEvent &nu)
00054   {
00055     if (nu.simFlag==SimFlag::kData) {
00056       MAXMSG("CC0325Std",Msg::kWarning, 10)
00057         << "NuCut derivative CC0325Std has not been validated against data. "
00058         << "Use at your own risk! (Or validate it then remove this warning!)" << endl;
00059     }
00060     // Good tracks
00061     Keep_If(nu.ntrk >= 1, "GoodNumberofTracks");
00062     
00063     // Filter out LI events
00064     Cut_If(nu.isLI || nu.litime != -1, "LICut");
00065     
00066     // Is the coil okay? Only cut if we have the cutOnDataQuality flag
00067     // Keep_Data_If(fNuCuts.IsCoilOk(nu), nu);
00068     Keep_Data_If(!nu.cutOnDataQuality || nu.coilIsOk, nu, "IsCoilOkay");
00069   
00070     // IsGoodBeamDetPOTCountingStage
00071     // This can mess up POT counting apparently, so be careful!
00072     Keep_Data_If(nu.goodBeamSntp && nu.coilIsOk, nu,"GoodBeamDetPOT");
00073     
00074     // Cut on good beam (IsGoodBeam)
00075     Keep_Data_If(!nu.cutOnBeamInfo || IsGoodBeam(nu), nu, "GoodBeam");
00076     
00077     // Is it in the fiducial volume?
00078     Keep_If(InFidVol(nu), "FidVol");
00079     
00080     // Per-detector cuts
00081     if (nu.detector == Detector::kFar)
00082     {
00083       // TrackFitPass
00084       Keep_If(nu.trkfitpass == 1, "trackfitpass");
00085       
00086       // Data Quality
00087       Keep_Data_If(nu.isGoodDataQuality || !nu.cutOnDataQuality, nu, "DataQuality");
00088       
00089       // IsGoodTimeToNearestSpill (FD only)
00090       // CC0325Std Uses -20us, +30us
00091       Keep_Data_If(NuCuts::GoodTimeToNearestSpill(nu, -20, +30) || !nu.cutOnSpillTiming, nu, "SpillTime");
00092       
00093       // Cut on track direction angle
00094       Keep_If(nu.dirCosNu > 0.6, "dirCosNu"); 
00095     }
00096     else if (nu.detector == Detector::kNear)
00097     {
00098       // Need to implement ND Trackfitpass (uses reclamation)
00099       // See Zeynep talk DocDB-6382 - mentions 'Nikis Reclamation'
00100       Keep_If(NuCuts::IsGoodTrackFitPassReclamation(nu), "trackfitreclamation");
00101       
00102       // Cut on the coil current
00103       Keep_Data_If(nu.coilCurrent < -1000 || !nu.cutOnDataQuality, nu, "CoilCurrent");
00104       
00105     } // End of per-detector cuts
00106   } // Eend of preselection function
00107   
00108   // The Main Selection ////////////////////////////////////////////////
00109   void CC0325Std::Selection(const NuEvent &nu)
00110   {
00111     Float_t cutValue=0.3;
00112     // Cut on RoID
00113     Keep_If(nu.roID > cutValue, "RoID");
00114     
00115   }
00116   
00117   Bool_t CC0325Std::IsGoodBeam(const NuEvent &nu)
00118   {
00119     // Don't measure this unless we have data
00120     if (nu.simFlag!=SimFlag::kData) {
00121       // MAXMSG("NuCuts",Msg::kInfo,1)
00122       //   <<"Not cutting on GoodBeam for simFlag="<<nu.simFlag<<endl;
00123       return true;
00124     }
00125 
00126     // Don't cut on this if we've set not to
00127     if (!nu.cutOnBeamInfo) {
00128       MAXMSG("CC0325Std",Msg::kWarning,1)
00129         <<"Not cutting on BeamInfo (flag set to not cut)"<<endl;
00130       return true;
00131     }
00132     
00133     // Assume we are good, and start from there
00134     bool isGood = true;
00135 
00136     // Check current
00137     if (!nu.goodBeam) 
00138       isGood = false;
00139     if (nu.hornCur==-999999) 
00140       isGood = false;
00141 
00142     if (nu.hornCur < -10) {
00143       if (nu.beamTypeDB != BeamType::kL010z185i &&
00144           nu.beamTypeDB != BeamType::kL010z170i && 
00145           nu.beamTypeDB != BeamType::kL010z200i &&
00146           nu.beamTypeDB != BeamType::kL250z200i) {
00147         isGood = false;            
00148       }
00149       if (nu.hornIsReverse) {
00150         MAXMSG("CC0325Std",Msg::kError,1000)
00151         << "nu.hornIsReverse is true but it shouldn't be for beamTypeDB=" 
00152         << nu.beamTypeDB << endl;
00153       }
00154     }
00155     else if (nu.hornCur >  10) {
00156       if (nu.beamTypeDB != BeamType::kL010z185i_rev) 
00157         isGood = false;
00158       if (!nu.hornIsReverse) {
00159         MAXMSG("CC0325Std",Msg::kError,1000)
00160         << "nu.hornIsReverse is false but it shouldn't be for beamTypeDB=" 
00161         << nu.beamTypeDB << endl;
00162       }
00163     }
00164     else {
00165       if (nu.beamTypeDB != BeamType::kL010z000i) 
00166         isGood = false;
00167     }
00168 
00169 
00170     if (!isGood) {
00171       MAXMSG("CC0325Std",Msg::kInfo,100)
00172       <<"Bad beam: goodBeam="<<nu.goodBeam
00173       <<", goodBeamSntp="<<nu.goodBeamSntp
00174       <<", hornCur="<<nu.hornCur
00175       <<", nu.beamTypeDB="<<nu.beamTypeDB
00176       <<", hornIsReverse="<< (nu.hornIsReverse?"Yes":"No")
00177       << endl;
00178       if (nu.detector==Detector::kNear) {
00179         MAXMSG("CC0325Std",Msg::kError,1000)
00180         <<"IsGoodBeam: cutting on Bad beam here messes"
00181         <<" up POT counting.  Event: " << nu.run << "/" << nu.subRun << ", " <<  nu.snarl <<endl;
00182       }
00183       return false;
00184     }
00185     
00186     //Make sure we're not getting mixed beam
00187     static Bool_t firstGoodEvent = true;
00188     static Int_t firstType = 0;
00189 
00190     if (firstGoodEvent){
00191       firstGoodEvent = false;
00192       firstType = nu.beamTypeDB;
00193       // Treat le10 170, 185, 200 as all the same
00194       if (firstType == BeamType::kL010z170i || 
00195           firstType == BeamType::kL010z200i) {
00196         firstType = BeamType::kL010z185i;
00197       }
00198     }
00199     else{
00200       Int_t thisType = nu.beamTypeDB;
00201       // Treat le10 170, 185, 200 as all the same
00202       if (nu.simFlag==SimFlag::kData && nu.detector==Detector::kFar){
00203         if (thisType == BeamType::kL010z170i || 
00204             thisType == BeamType::kL010z200i) {
00205           thisType = BeamType::kL010z185i;
00206         }
00207       }
00208       
00209       if (thisType != firstType) {
00210         MAXMSG("CC0325Std",Msg::kWarning,100)
00211         << "Seeing mixed beam: firstType=" << firstType 
00212         << ", thisType=" << thisType 
00213         << ", beamTypeDB=" << nu.beamTypeDB << endl;
00214         if (nu.detector==Detector::kNear) {
00215           MAXMSG("NuCuts",Msg::kError,1000)
00216           <<"IsGoodBeam: cutting on Bad beam here messes"
00217           <<" up POT counting..."<<endl;
00218         }
00219         return false;
00220       }
00221     }
00222     //Beam consistent with first event in DST, so we can let it pass
00223     return true;
00224     
00225   }
00228   // 
00229   
00230   CC0720Test::CC0720Test(const NuPlots *plots):
00231     NuCut("CC0325Test",plots),
00232     fNuCutsSelection(NuCuts::kCC0720Test, plots)
00233   {
00234     SetFidVol("cc2008");
00235   }
00236                 
00237   void CC0720Test::Preselection(const NuEvent &nu)
00238   {
00239     // Use old preselection 
00240     Defer_Preselection(fNuCutsSelection, nu);
00241 
00242   } // end of preselection function   
00243   void CC0720Test::Selection(const NuEvent &nu)
00244   {
00245     Float_t cutValue1=0.3;
00246     Float_t cutValue2=0.5;
00247     Float_t cutValue3=0.8;
00248     // Cut on RoID                                                                                                   
00249     Keep_If((nu.roID > cutValue1)||
00250             (nu.jmID > cutValue2)||
00251             (nu.jmEventknnID > cutValue3)  , "RoID");
00252 
00253   }
00254   
00256 // NuBar Bravo Selection
00257   
00258   Bravo::Bravo(const NuPlots *plots) :
00259     NuCut("Bravo", plots), 
00260     fNuCutsSelection(NuCuts::kNMB0325Bravo, plots)
00261   {
00262     SetFidVol("cc2008");
00263     SetAnaVersion(9);
00264   }
00265   
00266   // The Preselection //////////////////////////////////////////////////
00267   void Bravo::Preselection(const NuEvent &nu)
00268   {
00269     // Use old preselection
00270     Defer_Preselection(fNuCutsSelection, nu);
00271 
00272   } // Eend of preselection function
00273   
00274   // The Main Selection ////////////////////////////////////////////////
00275   void Bravo::Selection(const NuEvent &nu)
00276   {
00277     if (nu.charge != +1) { 
00278       Defer_Selection(fCC0325Std, nu);
00279     }
00280     else {
00281       Keep_If(nu.dpID > 0.25, "DpID");
00282       Keep_If(1./nu.sigqp_qp > 3.5, "SigmaQP_QP");
00283       Keep_If(TMath::Abs(nu.relativeAngle - TMath::Pi()) > 2.12, "RelativeAngle");
00284     }
00285   }
00286 
00288 // NuBar Bravo Selection
00289   
00290   BravoPrime::BravoPrime(const NuPlots *plots) : 
00291     NuCut("BravoPrime", plots), 
00292     fNuCutsSelection(NuCuts::kNMB0325Bravo, plots)
00293   {
00294     SetFidVol("cc2008");
00295     SetAnaVersion(9);
00296   }
00297   
00298   // The Preselection //////////////////////////////////////////////////
00299   void BravoPrime::Preselection(const NuEvent &nu)
00300   {
00301     // Use old preselection
00302     Defer_Preselection(fNuCutsSelection, nu);
00303 
00304   } // Eend of preselection function
00305   
00306   // The Main Selection ////////////////////////////////////////////////
00307   void BravoPrime::Selection(const NuEvent &nu)
00308   {
00309     if (nu.charge != +1) { 
00310       Defer_Selection(fCC0325Std, nu);
00311     }
00312     else {
00313       Keep_If(nu.dpID > 0.25, "DpID");
00314       Keep_If(1./nu.sigqp_qp > 3.6, "SigmaQP_QP");
00315       Keep_If(TMath::Abs(nu.relativeAngle - TMath::Pi()) > 2.14, "RelativeAngle");
00316     }
00317   }
00318   
00319   
00321   // NuBar Charlie Selection
00322   
00323   Charlie::Charlie(const NuPlots *plots) :
00324     NuCut("Charlie", plots),
00325     fNuCutsSelection(NuCuts::kNMB0325Charlie, plots)
00326   {
00327     SetFidVol("cc2008");
00328     SetAnaVersion(8);
00329   }
00330   
00331   // The Preselection //////////////////////////////////////////////////
00332   void Charlie::Preselection(const NuEvent &nu)
00333   {
00334     // Use old preselection
00335     Defer_Preselection(fNuCutsSelection, nu);
00336 
00337   }
00338   
00339   // The Main Selection ////////////////////////////////////////////////
00340   void Charlie::Selection(const NuEvent &nu)
00341   {
00342     Float_t cutValue=0.625;
00343     if (nu.charge != +1) { 
00344       Defer_Selection(fCC0325Std, nu);
00345     }
00346     else {
00347       Keep_If(nu.roID > cutValue, "RoID");
00348       Keep_If(nu.smoothMajC > -0.22, "MajorityCurv");
00349       Keep_If(nu.trkLength > 35, "TrackLength");
00350     }
00351   }
00352   
00353   
00354   
00355   
00357 // NuBar Delta Selection
00358   
00359   Delta::Delta(const NuPlots *plots) : 
00360     NuCut("Delta", plots),
00361     fNuCutsSelection(NuCuts::kNMB0325Delta, plots)
00362   {
00363     SetFidVol("cc2008");
00364     SetAnaVersion(7);
00365   }
00366   
00367   // The Preselection //////////////////////////////////////////////////
00368   void Delta::Preselection(const NuEvent &nu)
00369   {
00370     // Use old preselection
00371     Defer_Preselection(fNuCutsSelection, nu);
00372 
00373   } // Eend of preselection function
00374   
00375   // The Main Selection ////////////////////////////////////////////////
00376   void Delta::Selection(const NuEvent &nu)
00377   {
00378     Float_t cutValue=0.55;
00379     if (nu.charge != +1) { 
00380       Defer_Selection(fCC0325Std, nu);
00381     }
00382     else {
00383       Keep_If(nu.roID > cutValue, "RoID");
00384       Keep_If(nu.prob > 0.003, "FitProb");
00385       Keep_If(nu.trkLength > 37, "TrackLength");
00386     }
00387   }
00388   
00390 // A common Preselection for CC and NC in the CC2010 analysis
00391 
00392   CCAPresel::CCAPresel(const NuPlots *plots) : 
00393     NuCut("CCAPresel", plots)
00394   {
00395 
00396   }
00397   
00398   // The Preselection //////////////////////////////////////////////////
00399   void CCAPresel::Preselection(const NuEvent &nu)
00400   {
00401     // IsGoodBeamDetPOTCountingStage
00402     // This can mess up POT counting apparently, so be careful!
00403     Keep_Data_If(nu.goodBeamSntp && nu.coilIsOk, nu, "GoodBeamDetPOTCounting");
00404     
00405     // Is the coil okay? Only cut if we have the cutOnDataQuality flag
00406     // This seems to be redundant with the GoodBeamDetPOT, but this is what
00407     // seems to have been implemented.
00408     Keep_Data_If(nu.coilIsOk || !nu.cutOnDataQuality, nu, "CoilIsOkay");
00409 
00410     // Filter out LI events
00411     Cut_If(nu.isLI || nu.litime != -1, "IsLI");    
00412   
00413     // Cut on good beam (IsGoodBeam)
00414     Keep_Data_If(CC0325Std::IsGoodBeam(nu) || !nu.cutOnBeamInfo, nu, "IsGoodBeam");
00415     
00416     // Per-detector cuts
00417     if (nu.detector == Detector::kFar)
00418     {
00419       // Data Quality
00420       Keep_Data_If(nu.isGoodDataQuality || !nu.cutOnDataQuality, nu, "DataQuality");
00421       
00422       // IsGoodTimeToNearestSpill
00423       // Use the improved JJE cut here
00424       Keep_Data_If(NuCuts::GoodTimeToNearestSpill(nu, -2, +12) || !nu.cutOnSpillTiming, nu, "SpillTime");
00425     
00426     }
00427     else if (nu.detector == Detector::kNear)
00428     {
00429       // Cut on the coil current
00430       Keep_Data_If(nu.coilCurrent < -1000 || !nu.cutOnDataQuality, nu, "CoilCurrent");
00431       
00432     } // End of per-detector cuts    
00433   }
00434   
00435   // The Main Selection ////////////////////////////////////////////////
00436   void CCAPresel::Selection(const NuEvent &)
00437   {
00438     // Since this is a preselection only class, we have no selection
00439   }
00440 
00442 // A Base CC selection for the CC2010 analysis
00443   CCA::CCA(const NuPlots *plots, TString ana) : 
00444     NuCut("CCA", plots), rescuts(0), cutstring("")
00445   {
00446     SetFidVol("cc2008");
00447     cutstring=ana;
00448     SetCutFile("/minos/data/users/sjc/kNN_MicroDST/cuts_numu_D07d3.root");
00449     MSG("NuCutImps",Msg::kInfo)
00450       <<"Initializing resolution binning for "<<cutstring<<endl;
00451   }
00452   
00453   void CCA::SetCutFile(const char* filename)
00454   {
00455     TDirectory *tmpd = gDirectory; //get the right path
00456     TFile *cutfile = new TFile(filename,"READ");
00457     gDirectory = tmpd;
00458     if(cutfile->IsZombie()){
00459       MSG("NuCutImps",Msg::kWarning)<<"cutfile does not exist" << endl;
00460       return;
00461     }
00462     rescuts = (TTree *)cutfile->Get("cuts");
00463     MSG("NuCutImps",Msg::kWarning)<<"cutfile exists: "
00464                                   <<rescuts->GetEntries()<<" entries"<<endl;
00465   }
00466   
00467   // The CC selection uses a slightly altered definition of fiducial volume
00468   // origin: NuCuts::IsInFidVolTrk circa Sept '09
00469   Bool_t CCA::InFidVol(const NuEvent &nu) const
00470   {
00471     // Move trk vtx upstream by 3.92cm from scintillator to steel
00472     // for this analysis version
00473     NuEvent nuc = nu;
00474     nuc.zTrkVtx = nu.zTrkVtx - (0.0392*Munits::m);
00475     
00476     return NuCut::InFidVol(nuc);
00477   }
00478   
00479   // The Preselection //////////////////////////////////////////////////
00480   void CCA::Preselection(const NuEvent &nu)
00481   {
00482     // Do the base preselection (shared between CC and NC)
00483     Defer_Preselection(fCCAPresel, nu);
00484     
00485     // Now do the rest of the preselection
00486     
00487     // Good tracks
00488     Keep_If(nu.ntrk >= 1, "GoodNumberofTracks");
00489     
00490     // Is it in the fiducial volume?
00491     // ntrk cut to suppress warnings
00492     Keep_If(nu.ntrk > 0 && InFidVol(nu), "FidVol");
00493 
00494     // Per-detector cuts
00495     if (nu.detector == Detector::kFar)
00496     {
00497       // TrackFitPass
00498       Keep_If(nu.trkfitpass == 1, "trackfitpass");
00499       
00500       // Cut on track direction angle
00501       Keep_If(nu.dirCosNu > 0.6);
00502       
00503     }  
00504     else if (nu.detector == Detector::kNear)
00505     {
00506       // Need to implement ND Trackfitpass (uses reclamation)
00507       // See Zeynep talk DocDB-6382 - mentions 'Nikis Reclamation'
00508       Keep_If(NuCuts::IsGoodTrackFitPassReclamation(nu), "trackfitreclamation");
00509     }
00510   }
00511   
00512   // The Main Selection ////////////////////////////////////////////////
00513   void CCA::Selection(const NuEvent &nu)
00514   {
00515     Keep_If(nu.roID>0.3);
00516     
00517     if(cutstring=="CCA") return;
00518     
00519     if(cutstring=="CCA_NUBAR"){
00520       Keep_If(nu.charge>0);
00521     }
00522     
00523     else{
00524       if(nu.detector == Detector::kFar/* && nu.charge<0*/){
00525         Resolution(nu);
00526       }
00527     }
00528   }
00529   
00530   void CCA::Resolution(const NuEvent &nu)
00531   {
00532     Double_t low_en_edge=0.0;
00533     Double_t high_en_edge=0.0;
00534     Double_t low_res_edge=0.0;
00535     Double_t high_res_edge=0.0;
00536     Double_t quantiles[6];
00537     
00538     rescuts->SetBranchAddress("quantiles",quantiles);
00539     rescuts->SetBranchAddress("lowedge",&low_en_edge);
00540     rescuts->SetBranchAddress("highedge",&high_en_edge);
00541     
00542     rescuts->GetEntry(rescuts->GetEntries());
00543     
00544 
00545     for(Int_t i=0;i<rescuts->GetEntries();i++){
00546       rescuts->GetEntry(i);
00547       
00548       if(cutstring=="CCA_0"){
00549         low_res_edge=0.0;
00550         high_res_edge=quantiles[1];
00551       }
00552       if(cutstring=="CCA_1"){
00553         low_res_edge=quantiles[1];
00554         high_res_edge=quantiles[2];
00555       }
00556       if(cutstring=="CCA_2"){
00557         low_res_edge=quantiles[2];
00558         high_res_edge=quantiles[3];
00559       }
00560       if(cutstring=="CCA_3"){
00561         low_res_edge=quantiles[3];
00562         high_res_edge=quantiles[4];
00563       }
00564       if(cutstring=="CCA_4"){
00565         low_res_edge=quantiles[4];
00566         high_res_edge=9999999;
00567       }
00568       
00569       if(nu.energy>low_en_edge && nu.energy<high_en_edge){
00570         MAXMSG("NuCutImps",Msg::kInfo,20)
00571           <<"Entry:"<<i<<" Energy:"<<nu.energy<<" sigma/E:"<<(nu.resolution/nu.energy)<<endl
00572           <<"Keep if between "<<low_res_edge<<" and "<<high_res_edge<<endl;
00573         Keep_If((nu.resolution/nu.energy)>low_res_edge && (nu.resolution/nu.energy)<high_res_edge,"resolution");
00574         return;
00575       }
00576     }
00577   }
00578 
00580   // A Base NC selection for the CC2010 analysis
00581 
00582   CCA_NC::CCA_NC(const NuPlots* plots) : 
00583     NuCut("CCA_NC", plots)
00584   {
00585     // Match CC fiducial volume for simplicity
00586     // TODO CJB - will this try to use the track vertex? Is that bad?
00587     SetFidVol("cc2008");
00588   }
00589   
00590   // Fiducial Volume ///////////////////////////////////////////////////
00591   Bool_t CCA_NC::InFidVol(const NuEvent& nu) const
00592   {
00593     // If there's a track and it's longer than the shower then use its
00594     // vertex, otherwise use the event vertex. This is what is done in
00595     // the NC analysis.
00596     // TODO CJB - is this maximally consistent with the CC analysis?
00597     if(nu.ntrk > 0 && nu.trknplane > nu.nplaneShw){
00598       // Move trk vtx upstream by 3.92cm from scintillator to steel
00599       NuEvent nuc = nu;
00600       nuc.zTrkVtx = nu.zTrkVtx - (0.0392*Munits::m);
00601       return NuCut::InFidVol(nuc);
00602     }
00603     return NuCut::InFidVolEvt(nu);
00604   }
00605 
00606   // The Preselection //////////////////////////////////////////////////
00607   void CCA_NC::Preselection(const NuEvent& nu)
00608   {
00609     Defer_Preselection(fCCAPresel, nu);
00610 
00611     // Now do the rest of the preselection
00612 
00613     // No good track cut
00614 
00615     // Is it in the fiducial volume?
00616     Keep_If(InFidVol(nu), "FidVol");
00617 
00618     // No track fit pass or direction cosines or track reclamation
00619 
00620     // TODO CJB - check CC cuts don't overcut these
00621     if(nu.detector == Detector::kFar ) FDCleaning(nu);
00622     if(nu.detector == Detector::kNear) NDCleaning(nu);
00623   }
00624   
00625   // The Main Selection ////////////////////////////////////////////////
00626   void CCA_NC::Selection(const NuEvent& nu)
00627   {
00628     Keep_If(nu.roID < 0.3, "RoID");
00629   }
00630   
00631   // FD Cleaning ///////////////////////////////////////////////////////
00632   void CCA_NC::FDCleaning(const NuEvent& nu)
00633   {
00634     // See NCUtils/Cuts/NCAnalysisCutsNC for original version
00635 
00636     Cut_If(nu.nevt == 0, "NumEvents");
00637 
00638     const double phFrac = nu.evtphsigcor/max(nu.snarlPulseHeight, 1e-10);
00639       Cut_If(nu.nevt > 2 || (nu.nevt == 2 && phFrac < .75), "PHfrac");
00640 
00641     FDCosmics(nu); // Cut out cosmics
00642 
00643     Cut_If(nu.evtphsigcor < 5000 && nu.nstripEvt <= 4, "FibreNoise");
00644 
00645     // Timing cut. Data only
00646     const double dt_spill = nu.trigtime*Munits::s - nu.nearestSpillNanosec*Munits::ns;
00647 
00648     Cut_Data_If(dt_spill < -2*Munits::microsecond ||
00649                 dt_spill > 12*Munits::microsecond,
00650                 nu, "Timing");
00651   }
00652 
00653   template<class T> inline T SQR(T t){return t*t;}
00654 
00655   // FD Cleaning : cosmics ///////////////////////////////////////////////
00656   void CCA_NC::FDCosmics(const NuEvent& nu)
00657   {
00658     //Ultra-steep showers
00659     Cut_If(nu.planeEvtN == 0 || nu.nstripEvt >= SQR(nu.planeEvtN),
00660            "UltraSteep");
00661 
00662     //Steep showers
00663     const double tRMS = TMath::Sqrt(SQR(nu.transverseRMSU)+
00664                                     SQR(nu.transverseRMSV));
00665     Cut_If(nu.nshw > 0 && tRMS > .3+.1901*TMath::Log10(nu.planeEvtN), "Steep");
00666 
00667       //Track angle
00668     Cut_If(nu.ntrk > 0 && nu.trkvtxdcosz < 0.4, "TrkDCosZ");
00669 
00670       const bool upExitTrack = ((nu.zTrkEnd > 28.78 ||
00671                                  nu.endMetersToCloseEdge < .5) &&
00672                                 nu.yTrkEnd > -1.657);
00673 
00674     Cut_If(nu.ntrk > 0 && upExitTrack && nu.dtdz < -.5 && nu.trkvtxdcosy < -.4,
00675              "UpExitTrack");
00676   }
00677 
00678   // ND Cleaning ///////////////////////////////////////////////////////
00679   void CCA_NC::NDCleaning(const NuEvent& nu)
00680   {
00681     // See NCUtils/Cuts/NCAnalysisCuts::IsMultiCutsClean for original version
00682 
00683     // 35ns timing cut
00684     Cut_If(TMath::Abs(nu.minTimeSeparation) < 35e-9, "TimeSep");
00685 
00686     // tiny events are mostly junk
00687     Cut_If(nu.nstripEvt < 5, "TotalStrips");
00688 
00689     // this cuts very steep showers, leaking in
00690     Cut_If(nu.nstripEvt > 1.15*SQR(nu.planeEvtN), "Steep");
00691 
00692     // this cuts leakage which leaves activity in partially instrumented
00693     // region
00694     Cut_If(nu.edgeActivityStrips > 2 &&
00695            nu.edgeActivityPH > 1000 &&
00696            nu.energy < 5 &&
00697            nu.nplaneShw > nu.trknplane,
00698            "Leakage");
00699 
00700     Cut_If(nu.oppEdgeStrips > 2 &&
00701            nu.energy < 5.0 &&
00702            nu.nplaneShw > nu.trknplane,
00703            "OppositeEdge");
00704 
00705     // make additional deltaZ cuts if (|minDeltaT|<175ns)
00706     Cut_If(TMath::Abs(nu.closeTimeDeltaZ) < 1.0 &&
00707            TMath::Abs(nu.minTimeSeparation) < 175e-9,
00708            "dz&dt");
00709   }
00710 
00712 // NuBar front face rock event cross check by Matt Strait 2009-10
00713   ChairSound::ChairSound(const NuPlots * plots):
00714     NuCut("ChairSound", plots)
00715     // fNuCutsSelection(NuCuts::kNMB0325ChairSound, plots)
00716   {
00717     SetFidVol("cc2008");
00718   }
00719 
00720   // Recalculate the region of the detector!
00721   Int_t ChairSound::GetRegion(const NuEvent &nu)
00722   {
00723     // An enum for the rock detector region - this probably shouldn't go here,
00724     // but for now it will have to do (would rather use an enum than plain numbers)
00725     enum Rock_DetectorRegion {
00726       kNoTrack   = -1,
00727       kFiducial  = 0,
00728       kFront     = 1,
00729       kBack      = 2,
00730       kGap       = 3,
00731       kEdge      = 4,
00732       kCoilHole  = 5,
00733       kCorner    = 6,
00734       kUnknown   = 7
00735     };
00736   
00737     // Placeholder to avoid nesting if's in this function
00738     Bool_t inFid = false, nearFront = false, nearEdge = false;
00739     Bool_t nearGap = false, nearCoil = false, nearBack = false;
00740     Double_t radius2 = nu.xTrkVtx*nu.xTrkVtx + nu.yTrkVtx*nu.yTrkVtx;
00741     Double_t z = nu.zTrkVtx - FidVol::getTrkVtxZOffset();
00742     // Get the detector
00743     Detector::Detector_t det = (Detector::Detector_t)nu.detector;
00744   
00745     // If we are the near detector, we can't calculate the region - return unknown
00746     if (det == Detector::kNear) return kUnknown;
00747 
00748     // Now - examine each of the regions and determine if the vertex is in there
00749     // 0 = Fiducial
00750     inFid = infid((Detector::Detector_t)nu.detector, (SimFlag::SimFlag_t)nu.simFlag,
00751                   nu.xTrkVtx, nu.yTrkVtx, z);
00752     if (inFid) return kFiducial;
00753   
00754     // 1 = Front, non-edge
00755     nearFront = z < FidVol::getFarZMC(0);
00756     nearEdge = radius2 >= (FidVol::getFarRouter()*FidVol::getFarRouter());
00757     nearCoil = radius2 < FidVol::getFarRinner()*FidVol::getFarRinner();
00758   
00759     if(nearFront && !nearEdge && !nearCoil) return kFront;
00760 
00761     // 2 = Back, anywhere (no corners at back)
00762     nearBack = z > FidVol::getFarZMC(3);
00763     if(nearBack) return kBack;
00764 
00765     // 3 = Supermodule gap, non-edge
00766     nearGap = z > FidVol::getFarZMC(1) && z < FidVol::getFarZMC(2);
00767     if(nearGap && !nearEdge && !nearCoil) return kGap;
00768 
00769     // 4 = edge, non-end
00770     if(nearEdge && !nearBack && !nearFront && !nearGap) return kEdge;
00771 
00772     // 5 = coil hole, non-end
00773     if(nearCoil && !nearBack && !nearFront && !nearGap) return kCoilHole;
00774 
00775     // 6 = corner cases
00776     // No other cases have been matched, it must (?) be a corner case?
00777     return kCorner;
00778   }
00779   
00780   void ChairSound::Preselection(const NuEvent &nu)
00781   {
00782     // can't use CC0325Std::Preselection because it has a fiducial cut and
00783     // an overly tight angle cut.  This is copied from there except for those.
00784 
00785     Keep_If(nu.ntrk >= 1, "GoodNumberofTracks");    // Good tracks
00786     Cut_If(nu.isLI || nu.litime != -1, "LICut");    // Filter out LI events
00787     Keep_Data_If(!nu.cutOnDataQuality || nu.coilIsOk, nu, "IsCoilOkay");
00788     Keep_Data_If(nu.goodBeamSntp && nu.coilIsOk, nu,"GoodBeamDetPOT");
00789     Keep_Data_If(!nu.cutOnBeamInfo || CC0325Std::IsGoodBeam(nu),nu,"GoodBeam");
00790 
00791     // Keep only front face events that are neither near the edge nor coil hole
00792     // Keep_If(nu.regionTrkVtx == 1, "front_face");
00793     Keep_If(GetRegion(nu) == 1, "front_face");
00794 
00795     // Per-detector cuts
00796     if (nu.detector == Detector::kFar){
00797       Keep_If(nu.trkfitpass == 1, "trackfitpass");
00798       Keep_Data_If(nu.isGoodDataQuality||!nu.cutOnDataQuality,nu,"DataQuality");
00799 
00800       // [-2, 12] microseconds
00801       Keep_Data_If(NuCuts::GoodTimeToNearestSpill(nu, -2, +12) 
00802                    || !nu.cutOnSpillTiming, nu, "SpillTime");
00803       // Cosmic cut?
00804       Keep_If(TMath::Abs(nu.trkvtxdcosy) < 0.4, "CosY");
00805     }
00806     else if (nu.detector == Detector::kNear){
00807       MAXMSG("CC0325Std",Msg::kWarning, 1) << "Front face numubar selection "
00808          " called on near detector. I doubt that this works properly.\n";
00809       Keep_If(NuCuts::IsGoodTrackFitPassReclamation(nu), "trackfitreclamation");
00810       Keep_Data_If(nu.coilCurrent<-1000||!nu.cutOnDataQuality,nu,"CoilCurrent");
00811     }
00812   }
00813 
00814   // The Main Selection ////////////////////////////////////////////////
00815   void ChairSound::Selection(const NuEvent &nu)
00816   {
00817     // Other selectors have a Defer_Selection to CC0325Std here, but I 
00818     // don't think it makes sense here since we don't share a preselection.
00819     // However, I honestly have no clear idea what it's even supposed to do, 
00820     // so I could be wrong.
00821 
00822     Keep_If(nu.roID >= 0.25, "RoID"); // Note: >= is not the same as >
00823     Keep_If(1/nu.sigqp_qp > 3.5, "SigmaQP_QP");
00824     Keep_If(TMath::Abs(nu.relativeAngle - TMath::Pi()) > 2.08, "RelativeAngle");
00825   }
00826 
00828 // NuBar front face rock event cross check by Matt Strait 2009-10
00829   MSRock_Nov09::MSRock_Nov09(const NuPlots * plots):
00830     NuCut("MSRock_Nov09", plots)
00831   {
00832     SetFidVol("cc2008");
00833   }
00834 
00835   void MSRock_Nov09::Preselection(const NuEvent &nu)
00836   {
00837     // can't use CC0325Std::Preselection because it has a fiducial cut and
00838     // an overly tight angle cut.  This is copied from there except for those.
00839 
00840     Keep_If(nu.ntrk >= 1, "GoodNumberofTracks");    // Good tracks
00841     Cut_If(nu.isLI || nu.litime != -1, "LICut");    // Filter out LI events
00842     Keep_Data_If(!nu.cutOnDataQuality || nu.coilIsOk, nu, "IsCoilOkay");
00843     Keep_Data_If(nu.goodBeamSntp && nu.coilIsOk, nu,"GoodBeamDetPOT");
00844     Keep_Data_If(!nu.cutOnBeamInfo || CC0325Std::IsGoodBeam(nu),nu,"GoodBeam");
00845 
00846     // Per-detector cuts
00847     if (nu.detector == Detector::kFar){
00848       // Matt's rock selection does not use Trackfitpass at the moment
00849       // Keep_If(nu.trkfitpass == 1, "trackfitpass");
00850       Keep_Data_If(nu.isGoodDataQuality||!nu.cutOnDataQuality,nu,"DataQuality");
00851 
00852       // [-2, 12] microseconds
00853       Keep_Data_If(NuCuts::GoodTimeToNearestSpill(nu, -2, +12) 
00854                    || !nu.cutOnSpillTiming, nu, "SpillTime");
00855       // Cosmic cut?
00856       Keep_If(TMath::Abs(nu.trkvtxdcosy) < 0.4, "CosY");
00857     }
00858     else if (nu.detector == Detector::kNear){
00859       MAXMSG("CC0325Std",Msg::kWarning, 1)
00860         << "Rock Muon Selection being called on ND. You probably don't want to be doing this."
00861         << endl;
00862       Keep_If(NuCuts::IsGoodTrackFitPassReclamation(nu), "trackfitreclamation");
00863       Keep_Data_If(nu.coilCurrent<-1000||!nu.cutOnDataQuality,nu,"CoilCurrent");
00864     }
00865     
00866     // Make a fiducial cut
00867     // Keep_If(nu.regionTrkVtx == 1, "front_face");
00868     // Keep_If(GetRegion(nu) == 1, "front_face");
00869     Keep_If(ChairSound::GetRegion(nu) > 0 && ChairSound::GetRegion(nu) < 7, "Antifiducial");
00870   }
00871 
00872   // The Main Selection ////////////////////////////////////////////////
00873   void MSRock_Nov09::Selection(const NuEvent &nu)
00874   {
00875     // Other selectors have a Defer_Selection to CC0325Std here, but I 
00876     // don't think it makes sense here since we don't share a preselection.
00877     // However, I honestly have no clear idea what it's even supposed to do, 
00878     // so I could be wrong.
00879     // Keep_If(nu.roID >= 0.25, "RoID"); // Note: >= is not the same as >
00880     // Keep_If(1/nu.sigqp_qp > 3.5, "SigmaQP_QP");
00881     // Keep_If(TMath::Abs(nu.relativeAngle - TMath::Pi()) > 2.08, "RelativeAngle");
00882 
00883     Keep_If(nu.roID >= 0.1, "RoID");
00884   }
00885 
00886 
00887 
00888 
00889 } // Closes the namespace
00890 
00891 /*
00892 
00893 
00894 */

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