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

Blinder.cxx

Go to the documentation of this file.
00001 
00002 // $Id: Blinder.cxx,v 1.12 2007/11/11 07:29:53 rhatcher Exp $
00003 //
00004 // Module to apply blindness for physics analysis.
00005 //
00006 // Blinder::Ana returns kPassed for events that should be in the open dataset
00007 // and kFailed for events that should be only in the blind dataset.
00008 //
00009 // It returns kPassed for all events in the ND, and uses
00010 // the algorithm presented at the Jan 2005 collab meeting to
00011 // select events from the FD.
00012 //
00013 // Nathaniel Tagg
00014 // n.tagg1@physics.ox.ac.uk
00016 #include "Filtration/Blinder.h"
00017 #include "MessageService/MsgService.h"
00018 #include "MinosObjectMap/MomNavigator.h"
00019 #include "JobControl/JobCModuleRegistry.h" // For JOBMODULE macro
00020 #include "RawData/RawRecord.h"
00021 #include "RawData/RawDaqSnarlHeader.h"
00022 #include "RawData/RawDigitDataBlock.h"
00023 #include "RawData/RawDigit.h"
00024 #include "Plex/PlexHandle.h"
00025 
00026 #include "Record/SimSnarlRecord.h"
00027 #include "REROOT_Classes/REROOT_NeuKin.h"
00028 
00029 #include <TFile.h>
00030 #include <TNtuple.h>
00031 #include <TTree.h>
00032 #include <TRandom3.h>
00033 #include <TClonesArray.h>
00034 
00035 #include <vector>
00036 #include <cassert>
00037 #include <cmath>
00038 
00039 JOBMODULE(Blinder, "Blinder",
00040           "Blinds events away");
00041 
00042 
00043 CVSID(" $Id: Blinder.cxx,v 1.12 2007/11/11 07:29:53 rhatcher Exp $ ");
00044 
00045 
00046 Blinder::BlindingFunction::BlindingFunction()
00047 {
00048   fLFreq  = 0;
00049   fEFreq  = 0;
00050   fLPhase = 0;
00051   fEPhase = 0;
00052 }
00053 
00054 void
00055 Blinder::BlindingFunction::SetParameters( TRandom* paramChooser, Int_t seed )
00056 {
00057   assert(paramChooser);
00058   paramChooser->SetSeed(seed);
00059   
00060   fLFreq  = paramChooser->Uniform(1.0/15.0, 1.0/500.0); // Lphase. 5-200 planes.
00061   fEFreq  = paramChooser->Uniform(1.0/0.8, 1.0/2.0) / 10000; // efreq. 10000 ~= 1GeV
00062   fLPhase = paramChooser->Uniform(0,3.14); // phase
00063   fEPhase = 3.14-fLPhase; 
00064 }
00065 
00066 Float_t 
00067 Blinder::BlindingFunction::EventBlindProb( Float_t length, 
00068                                           Float_t energy )
00069 {
00070   float b1 = 0.5*(sin(length*fLFreq + fLPhase)+1.);
00071   float b2 = 0.5*(sin(energy*fEFreq + fEPhase)+1.);
00072   float f = 0.25 + b1*b2;
00073   if(f>1.0) f=1.0;
00074   return f; 
00075 
00076 }
00077 
00078 
00079 //......................................................................
00080 
00081 Blinder::Blinder() 
00082 {
00083   fSeed = 0;
00084   fFile = 0;
00085   fTree = 0;
00086 
00087   fRandom = new TRandom3;
00088   fParameterChooser = new TRandom3;
00089   fBlindingFunction.SetParameters(fParameterChooser,fSeed);
00090 }
00091 
00092 //......................................................................
00093 
00094 Blinder::~Blinder()
00095 {
00096   if(fFile) {
00097     fFile->cd();
00098     fTree->Write();
00099     fFile->Write();
00100     fFile->Close();
00101   }
00102   if(fRandom) delete fRandom;
00103   if(fParameterChooser) delete fParameterChooser;
00104 }
00105 
00106 //......................................................................
00107 
00108 JobCResult Blinder::Ana(const MomNavigator* mom)
00109 {
00116   Int_t run;
00117   Int_t snarl;
00118   Int_t epoch;
00119   Float_t length;
00120   Float_t energy;
00121 
00122 
00123   if(GetInfo(mom,run,snarl,epoch,length,energy)) {
00124     // Set the parameters from the epoch:
00125     fBlindingFunction.SetParameters(fParameterChooser,fSeed + 3 * epoch);
00126     
00127     // Find the probability of blinding this event:
00128     Float_t prob = fBlindingFunction.EventBlindProb(length,energy);
00129 
00130     // Get a pseudo-random number specific for this event:
00131     fRandom->SetSeed(run*1000 + snarl);
00132     Float_t r = fRandom->Rndm();
00133     
00134     // Allow event to be open if r<prob
00135     if(r<=prob) return JobCResult::kPassed;
00136     else        return JobCResult::kFailed;
00137   };
00138 
00139   // No blindness info obtained; return default. (This is probably a monitoring block.)
00140   return JobCResult::kPassed;
00141 }
00142 
00143 
00144 Bool_t Blinder::GetInfo(const MomNavigator* mom,
00145                         Int_t &run,
00146                         Int_t &snarl,
00147                         Int_t &epoch,
00148                         Float_t &length,
00149                         Float_t &energy)
00150 {
00151   //
00152   // This function pulls the neccessary info from the current Mom to find
00153   // the run, snarl, event length (with a basic clustering algorithm) and 
00154   // event energy (in raw ADC counts).
00155   //
00156   run = 0; 
00157   snarl = 0;
00158   length = 0;
00159   energy = 0;
00160   epoch = 0;
00161   
00162   // Find raw data.
00163   const RawRecord* rr = dynamic_cast<const RawRecord*>(mom->GetFragment("RawRecord"));
00164   if(rr==0) return false;
00165 
00166   const RawDaqSnarlHeader* snarlHead= dynamic_cast<const RawDaqSnarlHeader*>(rr->GetRawHeader());
00167   if(snarlHead==0)  return false;
00168 
00169 
00170   TIter rdbit = rr->GetRawBlockIter();
00171   TObject *tob;
00172   const RawDigitDataBlock *rddb = 0;
00173   while ((tob = rdbit())) {
00174     if (tob->InheritsFrom("RawDigitDataBlock")) {
00175       rddb = (const RawDigitDataBlock *) tob;
00176     }
00177   }
00178   if(rddb==0) return false;
00179 
00180   if(snarlHead->GetVldContext().GetDetector()!=Detector::kFar) return false;
00181 
00182   if(snarlHead->GetVldContext().GetSimFlag()!=SimFlag::kData) epoch = 10;
00183 
00184   // Put epoch here:
00185   // These lines change the blinding function at certain
00186   // watershed dates.
00187   const VldTimeStamp kShutdown2006(2006,4,15,0,0,0); // April 15, 2006, midnight
00188   if(snarlHead->GetVldContext().GetTimeStamp() > kShutdown2006) epoch +=1;
00189 
00190   MAXMSG("Blinder",Msg::kInfo,1) << "Blinding FD data. Epoch = " << epoch << endl;
00191   
00192   // Get plex info.
00193   PlexHandle plex(snarlHead->GetVldContext());
00194 
00195   // Get the header data.
00196   run = snarlHead->GetRun();
00197   snarl = snarlHead->GetSnarl();
00198  
00199   // Map of the planes.
00200   std::vector<int> planes(500,0);
00201 
00202   // Loop the digits.
00203   TIter rdit = rddb->GetDatumIter();
00204   const RawDigit *digit;
00205   Int_t rawdigitindex = -1;
00206   while ((digit = (const RawDigit *) rdit())) {
00207     ++rawdigitindex;
00208     
00209     if(plex.GetReadoutType(digit->GetChannel()) != ReadoutType::kScintStrip) 
00210       continue;
00211 
00212     // Find plane.
00213     PlexSEIdAltL altl = plex.GetSEIdAltL(digit->GetChannel());
00214     Int_t plane = altl.GetPlane();
00215 
00216     // Find energy.
00217     Int_t adc = digit->GetADC();
00218 
00219     // add it up.
00220     if((plane>=0)&&(plane<490))
00221       planes[plane] ++;
00222 
00223     energy+=(float)adc;
00224   }
00225 
00226   // do the number-of-planes matching.  Look for the largest 'cluster' 
00227   int start = 0;
00228   int end = 0;
00229   int longest = 0;
00230   while(start<500) {
00231     if(planes[start]==0) {
00232       start++;
00233       continue;
00234     };
00235     
00236     // Found a starting place.
00237     end = start;
00238     int gap = 0;
00239     int thislen = 0;
00240     while(end<490) {
00241       end++;
00242       if(planes[end]==0) gap++;
00243       else thislen = end-start;
00244       if(gap>2) break;
00245     }
00246     
00247     if(thislen > longest) longest = thislen;
00248 
00249     start=end;    
00250   }
00251   length = longest;
00252 
00253   return true;
00254 }
00255 
00256 
00257 //......................................................................
00258 // The stuff below is used only for studies of the blindness itself, not
00259 // for the actual blinding routine.
00260 //......................................................................
00261 
00262 JobCResult Blinder::Reco(MomNavigator* mom)
00263 {
00268   Int_t run;
00269   Int_t snarl;
00270   Int_t epoch;
00271   Float_t length;
00272   Float_t energy;
00273 
00274   if(GetInfo(mom,run,epoch,snarl,length,energy)) {
00275     float prob = fBlindingFunction.EventBlindProb(length,energy);
00276 
00277     fRandom->SetSeed(run*1000 + snarl);
00278     Float_t r = fRandom->Rndm();
00279 
00280     float blind = 0;
00281     if(r<=prob) blind = 1;
00282 
00283     float enu=0;
00284     float evis=0;
00285     float cc=0;
00286     float emu=0;
00287     float esh=0;
00288     float nu=0;
00289 
00290     const REROOT_NeuKin* truth = GetTruth(mom);
00291     if(truth) {
00292       enu = fabs(truth->P4Neu()[3]);
00293       cc  = truth->IAction();
00294       emu = fabs(truth->P4Mu1()[3]) + fabs(truth->P4Mu2()[3]);
00295       esh = fabs(truth->P4Shw()[3]);
00296       evis = emu + esh 
00297         + fabs(truth->P4El1()[3])
00298         + fabs(truth->P4El2()[3])
00299         + fabs(truth->P4Tau()[3]);      
00300       nu = truth->INu();
00301     }
00302 
00303     if(!fTree) {
00304       fFile = new TFile("blind.root","RECREATE");
00305       fTree = new TNtuple("blind","blind",
00306                           "run:snarl:len:energy"
00307                           ":enu:evis:cc:nu:emu:esh"
00308                           ":prob:blind"
00309                           );      
00310     }
00311 
00312     if(fTree) {
00313       fTree->Fill(run,snarl,length,energy
00314                   ,enu,evis,cc,nu,emu,esh
00315                   ,prob,blind
00316                   );      
00317     }
00318   };
00319   
00320   return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00321 }
00322 
00323 const REROOT_NeuKin* Blinder::GetTruth(const MomNavigator* mom)
00324 {
00325     // Look for the simSnarl in Mom.
00326   SimSnarlRecord* simsnarl = 0;
00327   TObject* tobj;
00328   TIter    fragiter = mom->FragmentIter();
00329   while( ( tobj = fragiter.Next() ) ) {
00330     simsnarl = dynamic_cast<SimSnarlRecord*>(tobj);
00331     if(simsnarl) break;
00332   }
00333 
00334   if(simsnarl==0) return 0;
00335 
00336   // Get the NeuKin list.
00337   const TClonesArray* neuKins = dynamic_cast<const TClonesArray*>(simsnarl->FindComponent("TClonesArray","NeuKinList"));
00338   if(neuKins==0) return 0;
00339 
00340   return dynamic_cast<const REROOT_NeuKin*>((*neuKins)[0]); 
00341 }
00342 
00343 
00344 
00345 
00346 //......................................................................
00347 
00348 const Registry& Blinder::DefaultConfig() const
00349 {
00350 //======================================================================
00351 // Supply the default configuration for the module
00352 //======================================================================
00353   static Registry r; // Default configuration for module
00354 
00355   // Set name of config
00356   std::string name = this->GetName();
00357   name += ".config.default";
00358   r.SetName(name.c_str());
00359 
00360   // Set values in configuration
00361   r.UnLockValues();
00362   r.Set("Seed", 10127);  // Seed with Nathaniel's fnal ID number.. that's pretty random.
00363   r.LockValues();
00364 
00365   return r;
00366 }
00367 
00368 //......................................................................
00369 
00370 void Blinder::Config(const Registry& r)
00371 {
00372   //======================================================================
00373   // Configure the module given the Registry r
00374   //======================================================================
00375   
00376   r.Get("Seed",fSeed);
00377   
00378   // reset the paramaters:
00379   fBlindingFunction.SetParameters(fParameterChooser,fSeed);
00380 }
00381 

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