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

NuCut.cxx

Go to the documentation of this file.
00001 #include <cassert>
00002 #include <iomanip>
00003 
00004 #include "MessageService/MsgService.h"
00005 #include "Conventions/SimFlag.h"
00006 #include "Conventions/Detector.h"
00007 #include "Conventions/Munits.h"
00008 #include "DataUtil/infid.h"
00009 
00010 #include "NtupleUtils/NuEvent.h"
00011 #include "NtupleUtils/NuMCEvent.h"
00012 #include "NtupleUtils/NuCut.h"
00013 
00014 #include "TString.h"
00015 
00016 CVSID("$Id: NuCut.cxx,v 1.14 2010/02/01 14:26:46 bckhouse Exp $");
00017 
00019 
00020 NuCut::NuCut(TString name, const NuPlots *plots) : 
00021   fFidVol(), 
00022   fSelName(name), 
00023   fPlots(plots),
00024   fPassCuts(true)
00025 {
00026   fEventCount = 0;
00027   fAnaVersion = AnaVersionHash(name);
00028 }
00030 
00031 NuCut::~NuCut()
00032 {
00033   
00034 }
00035 
00037 
00038 // Does a full cut
00039 Bool_t NuCut::MakeCuts(const NuEvent &nu)
00040 {
00041   // Since we are asking for a full cut, reset the pass status
00042   ResetStatus();
00043   
00044   MakePreselectionCuts(nu);
00045   MakeSelectionCuts(nu);
00046   
00047   return fPassCuts;
00048 }
00049 
00051 
00052 // Apply just the preselection
00053 Bool_t NuCut::MakePreselectionCuts(const NuEvent &nu)
00054 {
00055   Preselection(nu);
00056   MAXMSG("NuCut",Msg::kDebug,50) << "Passed " << GetName() << " Preselection = " << (fPassCuts ? "Yes" : "No") << endl;
00057   return fPassCuts;
00058 }
00059 
00061 
00062 // apply just the main selection
00063 Bool_t NuCut::MakeSelectionCuts(const NuEvent &nu)
00064 {
00065   Selection(nu);
00066   return fPassCuts;
00067 }
00068 
00070 
00071 // Sets the cutter back to an 'uncut' state
00072 void NuCut::ResetStatus(void)
00073 {
00074   fPassCuts = true;
00075   
00076   // Push back the cut statii onto the central list. This shouldn't go here, probably
00077   // but has for now.
00078   Bool_t passed = true;
00079   for (UInt_t i = 0; i < fCutList.size(); ++i) {
00080     // Take each of these, and push them back onto the cut totals list.
00081     TString &cutname = fCutList[i].first;
00082     Bool_t passcut = fCutList[i].second;
00083     
00084     // Check if it already exists in the vector
00085     UInt_t sumindex;
00086     for (sumindex = 0; sumindex < fCutTotals.size(); ++sumindex)
00087     {
00088       if (fCutTotals[sumindex].first == cutname) break;
00089     }
00090     
00091     // Now check if we have to push_back a new entry
00092     if (sumindex == fCutTotals.size())
00093     {
00094       // We have to push back
00095       fCutTotals.push_back(pair<TString,Int_t>(cutname, 0));
00096     }
00097     
00098     // Now, shall we add to this?
00099     // Add to totals, if we have still passed after this cut
00100     passed = passed && passcut;
00101     if (passed)
00102     {
00103       fCutTotals[sumindex].second++;
00104     }
00105     
00106     
00107     // std::pair<TString,Int_t>
00108   }
00109   
00110   // If the cut list was not empty, add to the event count
00111   if (!fCutList.empty()) fEventCount++;
00112   
00113   // Now, clear the interim list
00114   fCutList.clear();
00115 }
00116 
00118 
00119 Bool_t NuCut::Cut_If(Bool_t condition, const TString &s)
00120 {
00121   fPassCuts = fPassCuts && (!condition);
00122 
00123   // Store this cut, whatever for now
00124   fCutList.push_back(pair<TString,Int_t>(s,!condition));
00125   
00126   return fPassCuts;
00127 }
00128 
00130 
00131 Bool_t NuCut::Keep_If(Bool_t condition, const TString &s)
00132 {
00133   fPassCuts = fPassCuts && condition;
00134 
00135   // Store this cut, whatever for now
00136   fCutList.push_back(pair<TString,Int_t>(s,condition));
00137   
00138   return fPassCuts;
00139 }
00140 
00142 
00143 // Only cuts if data
00144 Bool_t NuCut::Keep_Data_If(Bool_t condition, const NuEvent &nu, const TString &name)
00145 {
00146   // Only cuts if data
00147   if (nu.simFlag == SimFlag::kData)
00148   {
00149     return Keep_If(condition, name);
00150   }
00151   
00152   return fPassCuts;
00153 }
00154 
00156 
00157 // Only cuts if data
00158 Bool_t NuCut::Cut_Data_If(Bool_t condition, const NuEvent &nu, const TString &name)
00159 {
00160   // Only cuts if data
00161   if (nu.simFlag == SimFlag::kData)
00162   {
00163     return Cut_If(condition, name);
00164   }
00165   
00166   return fPassCuts;
00167 }
00168 
00170 
00171 // Set the fiducial volume
00172 void NuCut::SetFidVol(const TString &fidvol)
00173 {
00174   if (fFidVol != "" && fidvol == "") {
00175     MSG("NuCut", Msg::kWarning) << "Setting blank fiducial volume in " << GetName() << ", but one has already been set."
00176       << "Cannot reset - will continue using whatever is set (but not forcing it)" << endl;
00177   }
00178   fFidVol = fidvol;
00179   // Set the fiducial volume
00180   if (FidVol::getName() != fidvol) {
00181     choose_infid_set(fidvol.Data());
00182   }
00183 }
00184 
00186 
00187 Bool_t NuCut::InFidVol(const NuEvent &nu) const
00188 {
00189   // Check we are still in the correct fiducial volume (and we have set one)
00190   if (FidVol::getName() != fFidVol) {
00191     MSG("NuCut",Msg::kInfo) << "Fiducial volume has changed in " << GetName() << ", resetting to \"" << fFidVol << "\"" << endl;
00192     // Reset the fiducial volume to outs
00193     if (FidVol::getName() != fFidVol) {
00194       choose_infid_set(fFidVol.Data());
00195     }
00196   }
00197   
00198   // assert(nu.ntrk > 0);  // No track means the track vertex is meaningless
00199   if (nu.ntrk == 0) {
00200     MAXMSG("NuCut",Msg::kWarning,3) << "Testing vertex against Fiducial volume, but no tracks!" << endl;
00201   }
00202   
00203   return infid(static_cast<Detector::Detector_t>(nu.detector),
00204     static_cast<SimFlag::SimFlag_t>(nu.simFlag),
00205     nu.xTrkVtx,nu.yTrkVtx,nu.zTrkVtx);
00206 }
00207 
00209 
00210 Bool_t NuCut::InFidVolEvt(const NuEvent &nu) const
00211 {
00212   // Check we are still in the correct fiducial volume (and we have set one)
00213   if (FidVol::getName() != fFidVol) {
00214     MSG("NuCut",Msg::kInfo) << "Fiducial volume has changed in " << GetName() << ", resetting to \"" << fFidVol << "\"" << endl;
00215     // Reset the fiducial volume to outs
00216     if (FidVol::getName() != fFidVol) {
00217       choose_infid_set(fFidVol.Data());
00218     }
00219   }
00220 
00221   return infid(Detector::Detector_t(nu.detector),
00222                SimFlag::SimFlag_t(nu.simFlag),
00223                nu.xEvtVtx, nu.yEvtVtx, nu.zEvtVtx);
00224 }
00225   
00227 
00228 Bool_t NuCut::InFidVolTrueEvt(const NuMCEvent& mc)  const
00229 {
00230   // Check we are still in the correct fiducial volume (and we have set one)
00231   if (FidVol::getName() != fFidVol) {
00232     MSG("NuCut",Msg::kInfo) << "Fiducial volume has changed in " << GetName() << ", resetting to \"" << fFidVol << "\"" << endl;
00233     // Reset the fiducial volume to outs
00234     if (FidVol::getName() != fFidVol) {
00235       choose_infid_set(fFidVol.Data());
00236     }
00237   }
00238   
00239   return infid(Detector::Detector_t(mc.detector),
00240                SimFlag::SimFlag_t(mc.simFlag),
00241                mc.vtxxMC,mc.vtxyMC,mc.vtxzMC);
00242 }
00243 
00245 
00246 void NuCut::Defer_Preselection(NuCut &cut, const NuEvent & nu)
00247 {
00248   // Make sure the object is in a fresh state
00249   cut.ResetStatus();
00250   
00251   // Now, run the preselection cut
00252   cut.MakePreselectionCuts(nu);
00253   
00254   // // Now, combine out status - this is currently very simple, as we are
00255   // // not yet tracking named cuts. This will become a bit more involved 
00256   // // at that stage, but for now, this works!
00257   // //fPassCuts = fPassCuts && !cut.Failed();
00258   // 
00259   // 
00260   // // Not yet tracking individual cuts, but in the interm track
00261   // // what the whole deferred selection does
00262   // Keep_If(cut.Passed(), "DeferredPreselection");
00263 
00264   // Now copy out all the selections into our list!
00265   for (UInt_t i = 0; i < cut.fCutList.size(); ++i) {
00266     Keep_If(cut.fCutList[i].second, cut.fCutList[i].first);
00267   }
00268 }
00269 
00271 
00272 void NuCut::Defer_Selection(NuCut &cut, const NuEvent & nu)
00273 {
00274   // Make sure the object is in a fresh state
00275   cut.ResetStatus();
00276   
00277   // Now, run the preselection cut
00278   cut.MakeSelectionCuts(nu);
00279   
00280   // Now copy out all the selections
00281   for (UInt_t i = 0; i < cut.fCutList.size(); ++i) {
00282     Keep_If(cut.fCutList[i].second, cut.fCutList[i].first);
00283   }
00284   
00285   // Now, combine out status - this is currently very simple, as we are
00286   // not yet tracking named cuts. This will become a bit more involved 
00287   // at that stage, but for now, this works!
00288   //fPassCuts = fPassCuts && !cut.Failed();
00289 }
00290 
00292 
00293 Bool_t NuCut::Passed(TString cutname) const
00294 {
00295   for (UInt_t i = 0; i < i < fCutList.size(); ++i) {
00296     if (fCutList[i].first == cutname) {
00297       return fCutList[i].second;
00298     }
00299   }
00300   MSG("NuCut",Msg::kWarning) << "Cut " << cutname << " not found in selection " << GetName() << ".  Assuming failed." << endl;
00301   PrintCurrent();
00302   return false;
00303 }
00304 
00306 
00307 Bool_t NuCut::PassedExcept(TString cutname) const
00308 {
00309   Bool_t found = false;
00310   Bool_t pass = true;
00311   for (UInt_t i = 0; i < fCutList.size(); ++i) {
00312     if (fCutList[i].first != cutname) {
00313       pass = pass && fCutList[i].second;
00314     } else {
00315       found = true;
00316     }
00317   }
00318   if (!found) {
00319     MSG("NuCut",Msg::kWarning) << "Cut " << cutname << " not found in selection " << GetName() << ".  Just returning selection, not N-1." << endl;
00320     PrintCurrent();
00321   }
00322 
00323   return pass;
00324 }
00325 
00327 
00328 void NuCut::PrintCurrent(void) const
00329 {
00330   MSG("NuCut",Msg::kInfo) << "Selection " << GetName() << " has " << fCutList.size() << " cuts:" << endl;
00331   for (UInt_t i = 0; i < fCutList.size(); ++i) {
00332     MSG("NuCut",Msg::kInfo) << "  " << fCutList[i].first << " " << (fCutList[i].second?"Passed":"Failed") << endl;
00333   }
00334   if (Passed()) MSG("NuCut",Msg::kInfo) << "  -- Event Passed" << endl;
00335   else          MSG("NuCut",Msg::kInfo) << "  ** Event Failed" << endl;
00336 
00337 }
00338 
00339 
00341 
00342 void NuCut::PrintSummary(void)
00343 {
00344   // Make sure we are reset and counted
00345   ResetStatus();
00346   
00347   // Find the longest name
00348   Int_t lsize = 12;
00349   for (UInt_t i = 0; i < fCutTotals.size(); ++i)
00350   {
00351     Int_t len = fCutTotals[i].first.Length();
00352     if (len > lsize) lsize = len;
00353   }
00354   // The 'total width'
00355   Int_t width = lsize + 20;
00356   // Print a summary of this events cuts
00357   MSG("NuCut",Msg::kInfo) << setw(width/2) << right << setfill('=') << (" "+GetName()) << setw(width/2+width%2) << left << " Summary " << '\n';
00358   MSG("NuCut",Msg::kInfo) << setw(lsize) << left << setfill(' ') << "Cut" << "  # Passed  % Passed\n";
00359 
00360   MSG("NuCut",Msg::kInfo) << setw(width) << left << setfill('=') << "" << "\n";
00361   MSG("NuCut",Msg::kInfo) << setw(lsize) << left << setfill(' ') << "Total Events" << "  " << setw(8) << right << fEventCount << "   100.00%\n";
00362   for (UInt_t i = 0; i < fCutTotals.size(); ++i)
00363   {
00364     // stat = stat && fCutList[i].second;
00365     MSG("NuCut",Msg::kInfo)
00366       << setw(lsize) << left << fCutTotals[i].first
00367       << "  " << setw(8) << right << fCutTotals[i].second
00368       << "  " << setw(7) << right << fixed << setprecision(2) << fCutTotals[i].second*100./fEventCount << "%\n";
00369   }
00370   MSG("NuCut",Msg::kInfo) << endl;
00371 }
00372 
00374 
00375 Int_t NuCut::AnaVersionHash(const TString name)
00376 {
00377   TString upper(name);
00378   name.Hash();
00379   upper.ToUpper();
00380   Int_t hash = upper.Hash();
00381   // This will reduce the hash space by half, but will ensure that we never
00382   // get any conflict from real (old) anaVersion numbers
00383   if (hash > 0) hash *= -1;
00384   
00385   return hash;
00386 }

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