PhotonTransport Class Reference

#include <PhotonTransport.h>

Inheritance diagram for PhotonTransport:

JobCModule ScintHitToDigiPE List of all members.

Public Member Functions

 PhotonTransport ()
 ~PhotonTransport ()
JobCResult Ana (const MomNavigator *mom)
JobCResult Reco (MomNavigator *mom)
JobCResult Get (MomNavigator *mom)
const RegistryDefaultConfig () const
void Config (const Registry &r)
void BeginJob ()
virtual void Print (Option_t *option="") const

Static Public Member Functions

static int VerifyScintHit (DigiScintHit *hit, UgliStripHandle ustrip)

Private Member Functions

void FillBadHitNtuple (const DigiScintHit *hit, Int_t failmode)
void CreateModelObjects ()
JobCResult ConfirmModelObjects ()
JobCResult SimulateEvent ()
JobCResult SimulateScintHit (DigiScintHit *hit)
JobCResult AddNoise ()
JobCResult AddAfterpulsing ()

Private Attributes

std::string fName_PhotonComputer
std::string fName_BluePhotonTracker
std::string fName_WlsFibreModel
std::string fName_GreenPhotonTracker
std::string fName_NoiseMaker
std::string fName_Afterpulser
std::string fDebugFileName
Int_t fDebugMask
VldContext fContext
const SimSnarlHeaderfSimHeader
const TObjArray * fHitList
TObjArray * fPeList
Int_t fPeTotal
PhotonEventResult fEventResult
Int_t fRandomSeed
TRandom * fRandom
PhotonLookupTable fProtonRangeTable
PhotonLookupTable fElectronRangeTable
Double_t fElectronFudgeThreshEnergy
Double_t fElectronFudgeThreshDist
PhotonTransportModulefPhotonComputer
PhotonTransportModulefBluePhotonTracker
PhotonTransportModulefWlsFibreModel
PhotonTransportModulefGreenPhotonTracker
PhotonTransportModulefNoiseMaker
PhotonTransportModulefAfterpulser
TFile * fDebugFile
TNtuple * fDebugNtuple
TNtupleD * fBadHitNtuple

Detailed Description

Definition at line 28 of file PhotonTransport.h.


Constructor & Destructor Documentation

PhotonTransport::PhotonTransport (  ) 

Definition at line 47 of file PhotonTransport.cxx.

References CreateModelObjects(), and LoadMinosPDG().

00047                                  :
00048   fName_PhotonComputer("photonDefaultModel"),   // These are NOT the true defaults.. See PhotonConfiguration
00049   fName_BluePhotonTracker("photonDefaultModel"),
00050   fName_WlsFibreModel("photonDefaultModel"),
00051   fName_GreenPhotonTracker("photonDefaultModel"),
00052   fName_NoiseMaker("photonDefaultModel"),
00053   fName_Afterpulser("photonDefaultModel"),
00054   fDebugFileName(""),
00055   fDebugMask(0xFFFF),
00056   fRandomSeed(0),
00057   fRandom(new TRandom3),
00058   fProtonRangeTable("PHOTONPROTONRANGE"),
00059   fElectronRangeTable("PHOTONELECTRONRANGE"),
00060   fPhotonComputer(0),
00061   fBluePhotonTracker(0),
00062   fWlsFibreModel(0),
00063   fGreenPhotonTracker(0),
00064   fNoiseMaker(0),
00065   fAfterpulser(0),
00066   fDebugFile(0),
00067   fDebugNtuple(0),
00068   fBadHitNtuple(0)
00069 {
00070 
00071   LoadMinosPDG(); // initialize MINOS specific particles
00072 
00073   CreateModelObjects(); // Create the models.
00074 //======================================================================
00075 // FILL_IN: [Document your code!!]
00076 //======================================================================  
00077 
00078 }

PhotonTransport::~PhotonTransport (  ) 

Definition at line 82 of file PhotonTransport.cxx.

References fAfterpulser, fBadHitNtuple, fBluePhotonTracker, fDebugFile, fDebugNtuple, fGreenPhotonTracker, fNoiseMaker, fPhotonComputer, fRandom, and fWlsFibreModel.

00083 {
00084 //======================================================================
00085 // FILL_IN: [Document your code!!]
00086 //======================================================================
00087   if(fPhotonComputer) delete fPhotonComputer;
00088   if(fBluePhotonTracker) delete fBluePhotonTracker;
00089   if(fWlsFibreModel) delete fWlsFibreModel;
00090   if(fGreenPhotonTracker) delete fGreenPhotonTracker;
00091   if(fNoiseMaker) delete fNoiseMaker;
00092   if(fAfterpulser) delete fAfterpulser;
00093   if(fRandom) delete fRandom;
00094   if(fDebugFile){
00095     TDirectory* savedir = gDirectory;
00096     fDebugFile->cd();
00097     if ( fDebugNtuple ) fDebugNtuple->Write(NULL,TObject::kOverwrite);
00098     if ( fBadHitNtuple ) fBadHitNtuple->Write(NULL,TObject::kOverwrite);
00099     fDebugFile->Close();
00100     delete fDebugFile;
00101     savedir -> cd();
00102   }
00103 }


Member Function Documentation

JobCResult PhotonTransport::AddAfterpulsing (  )  [private]

Definition at line 936 of file PhotonTransport.cxx.

References PhotonEventResult::afterpulsePE, fAfterpulser, fEventResult, fPeList, Msg::kDebug, JobCResult::kPassed, PhotonTransportModule::MakeAfterpulses(), MSG, and PhotonEventResult::totalPE.

Referenced by SimulateEvent().

00937 {
00941 
00942   // Find the times of the hits to get an idea what the window is.
00943   std::vector<DigiPE*> apList;
00944   std::vector<DigiPE*> peList;
00945 
00946   MSG("Photon",Msg::kDebug) << "Calling Afterpulser." << std::endl;
00947 
00948   peList.resize(fPeList->GetEntries(),0);
00949   for(UInt_t i=0; i<peList.size(); i++) {
00950     peList[i] = dynamic_cast<DigiPE*>((*fPeList)[i]);
00951   }
00952 
00953   fAfterpulser->MakeAfterpulses(peList,apList);
00954 
00955   for(UInt_t i=0;i<apList.size();i++) {
00956     fPeList->Add(apList[i]);
00957   }
00958   fEventResult.afterpulsePE += apList.size();
00959   fEventResult.totalPE      += apList.size();
00960 
00961 
00962   return JobCResult::kPassed;
00963 }

JobCResult PhotonTransport::AddNoise (  )  [private]

Definition at line 896 of file PhotonTransport.cxx.

References fEventResult, fHitList, fNoiseMaker, fPeList, Msg::kDebug, JobCResult::kFailed, JobCResult::kPassed, PhotonTransportModule::MakeNoise(), MSG, PhotonEventResult::noisePE, DigiScintHit::T1(), DigiScintHit::T2(), and PhotonEventResult::totalPE.

Referenced by SimulateEvent().

00897 {
00901 
00902   // Find the times of the hits to get an idea what the window is.
00903   const double kBig = 1e99;
00904   Double_t tstart = kBig;
00905   Double_t tend   = -kBig;
00906   TObject* tobj;
00907   TIter hitarrayIter(fHitList);
00908   while( (tobj = hitarrayIter.Next()) ) {
00909     DigiScintHit* scinthit = dynamic_cast<DigiScintHit*>(tobj);
00910     if(scinthit) {
00911       if(scinthit->T1()<tstart) tstart = scinthit->T1();
00912       if(scinthit->T2()>tend)   tend   = scinthit->T2();
00913     }
00914   }  
00915 
00916   // Couldn't find a reasonable time to put the noise in:
00917   if(tstart== kBig) return JobCResult::kFailed;
00918   if(tend  ==-kBig) return JobCResult::kFailed;
00919 
00920   std::vector<DigiPE*> peNoiseList;
00921 
00922   MSG("Photon",Msg::kDebug) << "Calling NoiseMaker  t=(" << tstart << ", " << tend << ")\n";
00923   fNoiseMaker->MakeNoise(peNoiseList,tstart,tend);
00924 
00925   for(UInt_t i=0;i<peNoiseList.size();i++) {
00926     fPeList->Add(peNoiseList[i]);
00927   }
00928   fEventResult.noisePE += peNoiseList.size();
00929   fEventResult.totalPE += peNoiseList.size();
00930 
00931 
00932   return JobCResult::kPassed;
00933 }

JobCResult PhotonTransport::Ana ( const MomNavigator mom  )  [virtual]

Implement this for read only access to the MomNavigator

Reimplemented from JobCModule.

Definition at line 107 of file PhotonTransport.cxx.

References RecDataRecord< T >::FindComponent(), MomNavigator::GetFragment(), JobCResult::kFailed, JobCResult::kPassed, Msg::kWarning, MSG, and PhotonEventResult::Print().

Referenced by Reco().

00108 {
00109   SimSnarlRecord* simrec = dynamic_cast<SimSnarlRecord*>
00110     (mom->GetFragment("SimSnarlRecord"));
00111   if ( !simrec ) {
00112     MSG("Photon",Msg::kWarning) << "No SimSnarlRecord in Mom" << endl;
00113     return JobCResult::kFailed;
00114   }
00115   
00116   const PhotonEventResult* per = dynamic_cast<const PhotonEventResult*>(simrec->FindComponent("PhotonEventResult"));
00117   if(per) per->Print();
00118   else MSG("Photon",Msg::kWarning) << "Can't find PhotonEventResult" << endl;
00119   // pass record to mom to own
00120 
00121 
00122 
00123   return JobCResult::kPassed; // kNoDecision, kFailed, etc.
00124 }

void PhotonTransport::BeginJob (  )  [virtual]

Implement for notification of begin of job

Reimplemented from JobCModule.

Definition at line 296 of file PhotonTransport.cxx.

References fBadHitNtuple, fDebugFile, fDebugFileName, fDebugMask, and fDebugNtuple.

00297 {
00298 //======================================================================
00299 // Handle job module initialization
00300 //======================================================================
00301   
00302   if(fDebugFileName.length()>0) {
00303     if (fDebugFile) delete fDebugFile;
00304       TDirectory* savedir = gDirectory;
00305       fDebugFile = new TFile(fDebugFileName.c_str(),"RECREATE");
00306       if ( fDebugMask & 1 ) fDebugNtuple = new TNtuple("pes","pes",
00307                 "plane:strip:end:thit:tblue:tgreen:tpe:gcosx:gx");
00308       if ( fDebugMask & 2 ) fBadHitNtuple = new TNtupleD("badhit","badhit",
00309                 "pE:pId:pln:stp:t0:xl0:yl0:zl0:xg0:yg0:zg0:dS:dE:failmode");
00310       savedir -> cd();
00311   }
00312 }

void PhotonTransport::Config ( const Registry r  )  [virtual]

Return the actual configuration. If your module directly pulls its configuration from the fConfig Registry, you don't need to override this. Override if you have local config variables.

Reimplemented from JobCModule.

Definition at line 240 of file PhotonTransport.cxx.

References PhotonTransportModule::Configure(), CreateModelObjects(), fAfterpulser, fBluePhotonTracker, fDebugFileName, fDebugMask, fElectronFudgeThreshDist, fElectronFudgeThreshEnergy, fGreenPhotonTracker, fName_Afterpulser, fName_BluePhotonTracker, fName_GreenPhotonTracker, fName_NoiseMaker, fName_PhotonComputer, fName_WlsFibreModel, fNoiseMaker, fPhotonComputer, fRandomSeed, fWlsFibreModel, Registry::Get(), Msg::kDebug, and MSG.

00241 {
00242 //======================================================================
00243 // Configure the module given the Registry r
00244 //======================================================================
00245 
00246   MSG("Photon",Msg::kDebug) << "PhotonTransport::Config" << endl;
00247 
00248   r.Get("randomSeed",fRandomSeed);
00249 
00250   const char* str;
00251   Bool_t modelChanged = false;
00252   if( r.Get("PhotonComputer",    str))
00253     if(fName_PhotonComputer != std::string(str))
00254       { modelChanged=true; fName_PhotonComputer = str; }
00255 
00256   if( r.Get("BluePhotonTracker", str))
00257     if(fName_BluePhotonTracker != std::string(str))
00258       { modelChanged=true; fName_BluePhotonTracker = str; }
00259   
00260   if( r.Get("WlsFibreModel",     str))
00261     if(fName_WlsFibreModel != std::string(str))
00262       { modelChanged=true; fName_WlsFibreModel = str; }
00263   
00264   if( r.Get("GreenPhotonTracker",str))
00265     if(fName_GreenPhotonTracker != std::string(str))
00266       { modelChanged=true; fName_GreenPhotonTracker = str; }
00267 
00268   if( r.Get("NoiseMaker",str))
00269     if(fName_NoiseMaker != std::string(str))
00270       { modelChanged=true; fName_NoiseMaker = str; }
00271 
00272   if( r.Get("Afterpulser",str))
00273     if(fName_Afterpulser != std::string(str))
00274       { modelChanged=true; fName_Afterpulser = str; }
00275 
00276   if(modelChanged) CreateModelObjects();
00277 
00278   fPhotonComputer->    Configure(r);
00279   fBluePhotonTracker-> Configure(r);
00280   fWlsFibreModel->     Configure(r);
00281   fGreenPhotonTracker->Configure(r);
00282   fNoiseMaker->        Configure(r);
00283   fAfterpulser->       Configure(r);
00284 
00285   r.Get("ElectronFudgeThreshEnergy",fElectronFudgeThreshEnergy);
00286   r.Get("ElectronFudgeThreshDist",  fElectronFudgeThreshDist);
00287 
00288   r.Get("DebugMask",fDebugMask);
00289   r.Get("DebugFileName",str);
00290   fDebugFileName = str;
00291   
00292 }

JobCResult PhotonTransport::ConfirmModelObjects (  )  [private]

Definition at line 350 of file PhotonTransport.cxx.

References fAfterpulser, fBluePhotonTracker, fGreenPhotonTracker, fName_Afterpulser, fName_BluePhotonTracker, fName_GreenPhotonTracker, fName_NoiseMaker, fName_PhotonComputer, fName_WlsFibreModel, fNoiseMaker, fPhotonComputer, fWlsFibreModel, JobCResult::kAOK, Msg::kError, JobCResult::kFatal, and MSG.

Referenced by SimulateEvent().

00351 {  
00352   // Check for success.
00353   if(!fPhotonComputer) {
00354     MSG("Photon",Msg::kError) << "Photon Transport Model PhotonComputer = " 
00355                               << fName_PhotonComputer 
00356                               << " is not registed. Aborting!"
00357                               << endl;
00358     return JobCResult::kFatal;
00359   }
00360 
00361   if(!fBluePhotonTracker) {
00362     MSG("Photon",Msg::kError) << "Photon Transport Model BluePhotonTracker = " 
00363                               << fName_BluePhotonTracker
00364                               << " is not registed. Aborting!"
00365                               << endl;
00366     return JobCResult::kFatal;
00367   }
00368 
00369   if(!fWlsFibreModel) {
00370     MSG("Photon",Msg::kError) << "Photon Transport Model WlsFibreModel = " 
00371                               << fName_WlsFibreModel
00372                               << " is not registed. Aborting!"
00373                               << endl;
00374     return JobCResult::kFatal;
00375   }
00376   
00377   if(!fGreenPhotonTracker) {
00378     MSG("Photon",Msg::kError) << "Photon Transport Model GreenPhotonTracker = " 
00379                               << fName_GreenPhotonTracker
00380                               << " is not registed. Aborting!"
00381                               << endl;
00382     return JobCResult::kFatal;
00383   }
00384 
00385   if(!fNoiseMaker) {
00386     MSG("Photon",Msg::kError) << "Photon Transport Model NoiseMaker = " 
00387                               << fName_NoiseMaker
00388                               << " is not registed. Aborting!"
00389                               << endl;
00390     return JobCResult::kFatal;
00391   }
00392 
00393   if(!fAfterpulser) {
00394     MSG("Photon",Msg::kError) << "Photon Transport Model Afterpulser = " 
00395                               << fName_Afterpulser
00396                               << " is not registed. Aborting!"
00397                               << endl;
00398     return JobCResult::kFatal;
00399   }
00400 
00401   return JobCResult::kAOK;
00402 }

void PhotonTransport::CreateModelObjects (  )  [private]

Definition at line 316 of file PhotonTransport.cxx.

References PhotonTransportMaker::Create(), fAfterpulser, fBluePhotonTracker, fGreenPhotonTracker, fName_Afterpulser, fName_BluePhotonTracker, fName_GreenPhotonTracker, fName_NoiseMaker, fName_PhotonComputer, fName_WlsFibreModel, fNoiseMaker, fPhotonComputer, fRandom, fWlsFibreModel, Msg::kFatal, MSG, and PhotonTransportModule::SetRandom().

Referenced by Config(), and PhotonTransport().

00317 {
00318   if(fPhotonComputer) delete fPhotonComputer;
00319   if(fBluePhotonTracker) delete fBluePhotonTracker;
00320   if(fWlsFibreModel) delete fWlsFibreModel;
00321   if(fGreenPhotonTracker) delete fGreenPhotonTracker;
00322   if(fNoiseMaker)         delete fNoiseMaker;
00323   if(fAfterpulser)        delete fAfterpulser;
00324   
00325   fPhotonComputer     = PhotonTransportMaker::Create(fName_PhotonComputer);
00326   fBluePhotonTracker  = PhotonTransportMaker::Create(fName_BluePhotonTracker);
00327   fWlsFibreModel      = PhotonTransportMaker::Create(fName_WlsFibreModel);
00328   fGreenPhotonTracker = PhotonTransportMaker::Create(fName_GreenPhotonTracker);
00329   fNoiseMaker         = PhotonTransportMaker::Create(fName_NoiseMaker);
00330   fAfterpulser        = PhotonTransportMaker::Create(fName_Afterpulser);
00331 
00332   if(!fPhotonComputer)     { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_PhotonComputer << endl; exit(1);};
00333   if(!fBluePhotonTracker)  { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_BluePhotonTracker << endl; exit(1);};
00334   if(!fWlsFibreModel)      { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_WlsFibreModel << endl; exit(1);};
00335   if(!fGreenPhotonTracker) { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_GreenPhotonTracker << endl; exit(1);};
00336   if(!fNoiseMaker)         { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_NoiseMaker << endl; exit(1);};
00337   if(!fAfterpulser)        { MSG("Photon",Msg::kFatal) << "FATAL: No such module: " << fName_Afterpulser << endl; exit(1);};
00338 
00339 
00340   fPhotonComputer->    SetRandom(fRandom);
00341   fBluePhotonTracker-> SetRandom(fRandom);
00342   fWlsFibreModel->     SetRandom(fRandom);
00343   fGreenPhotonTracker->SetRandom(fRandom);
00344   fNoiseMaker->        SetRandom(fRandom);
00345   fAfterpulser->       SetRandom(fRandom);
00346 }

const Registry & PhotonTransport::DefaultConfig (  )  const [virtual]

Get the default configuration registry. This should normally be overridden. One useful idiom is to implement it like:

const Registry& MyModule::DefaultConfig() const { static Registry cfg; // never is destroyed if (cfg.Size()) return cfg; // already filled it // set defaults: cfg.Set("TheAnswer",42); cfg.Set("Units","unknown"); return cfg; }

Reimplemented from JobCModule.

Definition at line 229 of file PhotonTransport.cxx.

References PhotonConfiguration().

00230 {
00231 //======================================================================
00232 // Supply the default configuration for the module
00233 //======================================================================
00234 
00235   return PhotonConfiguration();
00236 }

void PhotonTransport::FillBadHitNtuple ( const DigiScintHit hit,
Int_t  failmode 
) [private]

Definition at line 978 of file PhotonTransport.cxx.

References DigiScintHit::DE(), DigiScintHit::DS(), fBadHitNtuple, fContext, UgliGeomHandle::GetStripHandle(), UgliStripHandle::LocalToGlobal(), DigiScintHit::ParticleEnergy(), DigiScintHit::ParticleId(), DigiScintHit::Plane(), DigiScintHit::Strip(), DigiScintHit::StripEndId(), DigiScintHit::T1(), DigiScintHit::X1(), DigiScintHit::Y1(), and DigiScintHit::Z1().

Referenced by SimulateScintHit().

00979                                                        {
00982   
00983   // Convert local to global coordinates
00984   UgliGeomHandle ugli = UgliGeomHandle(fContext);
00985   const UgliStripHandle& uglistp = ugli.GetStripHandle(hit->StripEndId());
00986   TVector3 vlocal0(hit->X1(),hit->Y1(),hit->Z1());
00987   const TVector3& vglobal0 = uglistp.LocalToGlobal(vlocal0);
00988 
00989   fBadHitNtuple -> Fill(hit->ParticleEnergy(),
00990                         hit->ParticleId(),hit->Plane(),hit->Strip(),
00991                         hit->T1(),hit->X1(),hit->Y1(),hit->Z1(),
00992                         (Float_t)(vglobal0.X()),(Float_t)vglobal0.Y(),
00993                         (Float_t)vglobal0.Z(),
00994                         hit->DS(),hit->DE(),failmode);
00995 
00996   return;
00997 }

JobCResult PhotonTransport::Get ( MomNavigator mom  )  [virtual]

Implement if your module needs to read data from some external source and fill mom

Reimplemented from JobCModule.

Definition at line 138 of file PhotonTransport.cxx.

References RecDataRecord< T >::AdoptComponent(), RecDataRecord< T >::AdoptTemporary(), RecJobHistory::CreateJobRecord(), fContext, fEventResult, fHitList, RecDataRecord< T >::FindComponent(), RecDataRecord< T >::FindTemporary(), fPeList, fPeTotal, MomNavigator::FragmentIter(), fRandom, fRandomSeed, fSimHeader, VldContext::GetDetector(), RecRecordImp< T >::GetJobHistory(), RecDataHeader::GetRun(), SimSnarlRecord::GetSimSnarlHeader(), RecPhysicsHeader::GetSnarl(), VldContext::GetTimeStamp(), RecHeader::GetVldContext(), Calibrator::Instance(), Msg::kError, JobCResult::kFailed, SimFlag::kMC, RecJobHistory::kPhotonTransport, Msg::kSynopsis, MSG, PhotonEventResult::Reset(), CalScheme::Reset(), and SimulateEvent().

00139 {
00140 //======================================================================
00141 // Does the work. 
00142 // Creates photons at the scintHit vertex, then propagates them to the 
00143 // phototube.
00144 //======================================================================
00145   SimSnarlRecord* simsnarl = 0;
00146   TObject* tobj;
00147   TIter    fragiter = mom->FragmentIter();
00148 
00149   fPeTotal = 0;
00150 
00151   // Get the simsnarl.
00152   while( ( tobj = fragiter.Next() ) ) {
00153     simsnarl = dynamic_cast<SimSnarlRecord*>(tobj);
00154     if(simsnarl) break;
00155   }
00156   
00157   // Verify there IS a simsnarl.
00158   if(!simsnarl) {
00159     MSG("Photon",Msg::kError) << "No SimSnarl found. You must run RerootToTruthModule()!" << endl;
00160     return JobCResult::kFailed;
00161   }
00162 
00163   RecJobHistory& jobhist 
00164                = const_cast<RecJobHistory&>(simsnarl->GetJobHistory());
00165   jobhist.CreateJobRecord(RecJobHistory::kPhotonTransport);
00166 
00167   fSimHeader = simsnarl->GetSimSnarlHeader();
00168   if(fSimHeader ==0){
00169     MSG("Photon",Msg::kError) << "Cannot find SimSnarlHeader in SimSnarl." << endl;
00170     return JobCResult::kFailed;
00171   }
00172 
00173   // Set the random seed to match the event.
00174   // Also add some user-configurable randomness, in case they want to
00175   // generate the same event with a different outcome.
00176   fRandom->SetSeed( fSimHeader->GetRun() 
00177                     + fSimHeader->GetSnarl() 
00178                     + fRandomSeed );
00179   
00180   // We need a context to do table lookups
00181   VldContext simContext = fSimHeader->GetVldContext();
00182 
00183   // But.. we want our context to be "MC" not "Reroot". Ensure that's correct.
00184   fContext = VldContext(simContext.GetDetector(),SimFlag::kMC,simContext.GetTimeStamp());
00185 
00186   Calibrator::Instance().Reset(fContext);
00187 
00188   // Create the stat report.
00189   fEventResult.Reset();
00190 
00191   JobCResult res;
00192 
00193   // Get the DigiScintHits.
00194   fHitList = 
00195     dynamic_cast<const TObjArray*>(simsnarl->FindComponent(0,"DigiScintHits"));
00196   if(fHitList) {
00197 
00198     // Delete any pre-existing array of DigiPE.
00199     if( dynamic_cast<const TObjArray*>(simsnarl->FindTemporary(0,"DigiListPe")) != 0) {
00200       MSG("Photon",Msg::kError) << "Found pre-existing DigPE list. Aborting." << std::endl;
00201       return JobCResult::kFailed;
00202     } else {
00203       fPeList = new TObjArray(0);
00204       fPeList->SetName("DigiListPe");
00205       fPeList->SetOwner(true);
00206     }
00207     
00208     // Do the actual work.
00209     res = SimulateEvent();
00210 
00211   } else {
00212 
00213     MSG("Photon",Msg::kError) << "Can't find scint hit array.\n"; 
00214     return JobCResult::kFailed;  
00215     
00216   };
00217 
00218   simsnarl->AdoptTemporary(fPeList);
00219 
00220   // Add the event result.
00221   simsnarl->AdoptComponent(new PhotonEventResult(fEventResult));
00222   MSG("Photon",Msg::kSynopsis) << fEventResult;
00223 
00224   return res; // kNoDecision, kFailed, etc.
00225 }

void PhotonTransport::Print ( Option_t *  option = ""  )  const [virtual]

Definition at line 966 of file PhotonTransport.cxx.

References fAfterpulser, fBluePhotonTracker, fGreenPhotonTracker, fNoiseMaker, fPhotonComputer, fWlsFibreModel, Nav::kInfo, MSG, and PhotonTransportModule::Print().

00967 {
00968   MSG("Photon",kInfo) << "PhotonTransport Configuration:" << endl;
00969   if(fPhotonComputer) fPhotonComputer->Print("c");
00970   if(fBluePhotonTracker) fBluePhotonTracker->Print("b");
00971   if(fWlsFibreModel) fWlsFibreModel->Print("w");
00972   if(fGreenPhotonTracker) fWlsFibreModel->Print("g");
00973   if(fNoiseMaker) fNoiseMaker->Print("n");
00974   if(fAfterpulser) fAfterpulser->Print("n");
00975 }

JobCResult PhotonTransport::Reco ( MomNavigator mom  )  [virtual]

Implement this for read-write access to the MomNavigator

Reimplemented from JobCModule.

Definition at line 128 of file PhotonTransport.cxx.

References Ana().

00129 {
00133   return Ana(mom);
00134 }

JobCResult PhotonTransport::SimulateEvent (  )  [private]

Definition at line 406 of file PhotonTransport.cxx.

References AddAfterpulsing(), AddNoise(), ConfirmModelObjects(), PhotonTransportModule::DoReset(), PhotonEventResult::energyDiscardedBad, PhotonEventResult::energyDiscardedGeom, fAfterpulser, fBluePhotonTracker, fContext, fElectronRangeTable, fEventResult, fGreenPhotonTracker, fHitList, fNoiseMaker, fPhotonComputer, PhotonEventResult::fPixelsHit, fProtonRangeTable, fSimHeader, PhotonEventResult::fStripsHit, fWlsFibreModel, RecDataHeader::GetRun(), RecPhysicsHeader::GetSnarl(), JobCResult::HaveError(), Msg::kError, JobCResult::kPassed, Munits::MeV, MSG, PhotonLookupTable::Reset(), SimulateScintHit(), PhotonEventResult::totalHitEnergy, PhotonEventResult::totalPixels, and PhotonEventResult::totalStripsHit.

Referenced by Get().

00407 {
00408   JobCResult res = JobCResult::kPassed;
00409   res = ConfirmModelObjects();
00410   if(res.HaveError()) return res;
00411 
00412   fProtonRangeTable.Reset(fContext);
00413   fElectronRangeTable.Reset(fContext);
00414 
00415   // Set up the modules.
00416   fPhotonComputer->    DoReset(fContext);
00417   fBluePhotonTracker-> DoReset(fContext);
00418   fWlsFibreModel->     DoReset(fContext);
00419   fGreenPhotonTracker->DoReset(fContext);
00420   fNoiseMaker        ->DoReset(fContext);
00421   fAfterpulser       ->DoReset(fContext);
00422 
00423   TObject* tobj;
00424   TIter hitarrayIter(fHitList);
00425   while( (tobj = hitarrayIter.Next()) ) {
00426     DigiScintHit* scinthit = dynamic_cast<DigiScintHit*>(tobj);
00427     if(scinthit) {
00428       JobCResult hitRes = SimulateScintHit(scinthit); // Add up all the errors.
00429       res |= hitRes;
00430     }
00431   }  
00432 
00433   res |= AddNoise();
00434 
00435   res |= AddAfterpulsing();
00436 
00437   if((fEventResult.energyDiscardedGeom+
00438       fEventResult.energyDiscardedBad) > 1.0*Munits::MeV) 
00439     MSG("Photon",Msg::kError) 
00440       << "Run: " << fSimHeader->GetRun()
00441       << "  Event: " << fSimHeader->GetSnarl() 
00442       << " Threw out " 
00443       << fEventResult.energyDiscardedGeom/Munits::MeV << " MeV (bad geom) and "
00444       << fEventResult.energyDiscardedBad/Munits::MeV << " MeV (bad hits) of a total " 
00445       << fEventResult.totalHitEnergy/Munits::MeV << " MeV in the event" 
00446       << endl;
00447   
00448   fEventResult.totalStripsHit = fEventResult.fStripsHit.size();
00449   fEventResult.totalPixels    = fEventResult.fPixelsHit.size();
00450 
00451   return res;
00452 }

JobCResult PhotonTransport::SimulateScintHit ( DigiScintHit hit  )  [private]

Definition at line 500 of file PhotonTransport.cxx.

References PlexStripEndId::AsString(), PhotonEventResult::bluePhotons, PhotonEventResult::bluePhotons_nonprescaled, PlexStripEndId::Build18BitPlnStripKey(), Munits::cm, DigiScintHit::DE(), MinosMaterial::Density(), done(), DigiScintHit::DS(), PhotonEventResult::energyDiscardedBad, PhotonEventResult::energyDiscardedGeom, MinosMaterial::ePolystyreneMinos, fBadHitNtuple, fBluePhotonTracker, fContext, fDebugNtuple, fElectronFudgeThreshDist, fElectronFudgeThreshEnergy, fElectronRangeTable, fEventResult, fGreenPhotonTracker, PhotonTransportModule::FibreHitToGreenPhoton(), FillBadHitNtuple(), Form(), fPeList, fPhotonComputer, PhotonEventResult::fPixelsHit, fProtonRangeTable, PhotonEventResult::fStripsHit, fWlsFibreModel, PhotonCount::GetBlue_Neg(), PhotonCount::GetBlue_Pos(), PhotonCount::GetBlue_Total(), PhotonTransportModule::GetBluePrescaleFactor(), DigiPhoton::GetCosX(), PhotonCount::GetGreen_Neg(), PhotonCount::GetGreen_Pos(), PhotonCount::GetGreen_Total(), PhotonTransportModule::GetGreenPrescaleFactor(), UgliStripHandle::GetHalfLength(), UgliStripHandle::GetHalfThickness(), UgliStripHandle::GetHalfWidth(), PhotonCount::GetPe_Neg(), PhotonCount::GetPe_Pos(), PhotonCount::GetPe_Total(), DigiPE::GetPixelSpotId(), PlexHandle::GetPixelSpotId(), UgliGeomHandle::GetStripHandle(), DigiPE::GetTime(), PlexPixelSpotId::GetUniquePixelEncodedValue(), PhotonTransportModule::GetWlsPrescaleFactor(), Munits::GeV, PhotonEventResult::greenPhotons, PhotonEventResult::greenPhotons_nonprescaled, PhotonTransportModule::GreenPhotonToPe(), PhotonEventResult::hitsDiscardedBad, PhotonEventResult::hitsDiscardedGeom, PhotonLookupTable::Interpolate(), PhotonCount::IsDirectional(), PlexPixelSpotId::IsValid(), UgliStripHandle::IsValid(), JobCResult::kAOK, DigiScintHit::kBadGeom, kBoundaryString, Msg::kDebug, DigiScintHit::kInvalidStrip, StripEnd::kNegative, DigiScintHit::kNegEnergy, DigiScintHit::kNullEnergy, DigiScintHit::kNullPath, JobCResult::kPassed, DigiScintHit::kPhotonComputer, StripEnd::kPositive, StripEnd::kUnknown, Msg::kVerbose, JobCResult::kWarning, Msg::kWarning, MAXMSG, Munits::MeV, Munits::mm, MSG, DigiScintHit::ParticleEnergy(), DigiScintHit::ParticleId(), DigiScintHit::ParticleKineticEnergy(), DigiScintHit::Plane(), PhotonTransportModule::ScintPhotonToFibreHit(), PhotonCount::SetBlueTotal(), DigiScintHit::Strip(), DigiScintHit::StripEndId(), DigiPhoton::T(), DigiScintHit::T1(), DigiScintHit::T2(), PhotonEventResult::totalHitEnergy, PhotonEventResult::totalHits, PhotonEventResult::totalPE, DigiScintHit::TrackId(), VerifyScintHit(), DigiPhoton::X(), DigiScintHit::X1(), DigiScintHit::X2(), DigiScintHit::Y1(), DigiScintHit::Y2(), DigiScintHit::Z1(), and DigiScintHit::Z2().

Referenced by SimulateEvent().

00501 {
00503   // Does all the real work.
00504 
00505   if(!hit) {
00506     MSG("Photon",Msg::kWarning) << "SimulateScintHit got null ScintHit." << endl;
00507     return JobCResult::kWarning; // Null hit.. shouldn't happen.
00508   }
00509   // Set up ugli.
00510   UgliGeomHandle ugli = UgliGeomHandle(fContext);
00511 
00512   // Get the goods on this strip.
00513   UgliStripHandle ustrip = ugli.GetStripHandle(hit->StripEndId());
00514 
00515   // Check to see if this strip is valid.
00516   // This error crops up from PTSim where it generates veto shield hits, but Ugli can't cope
00517   if(! ustrip.IsValid()) {
00518     MAXMSG("Photon",Msg::kWarning,10) << "Throwing out hit with no Ugli info: " << hit->StripEndId().AsString() << std::endl;
00519     hit -> SetFailBit(DigiScintHit::kInvalidStrip);
00520     return JobCResult::kWarning;
00521   }
00522 
00523   // Check for some validity things on the hit. Fix them up if neccessary.
00524   if(hit->DE()<0.) {
00525     MAXMSG("Photon",Msg::kWarning,5) 
00526       << "DigiScintHit has negative energy (" 
00527       << hit->DE()/Munits::GeV 
00528       << " GeV). Throwing it out." << endl;    
00529     hit -> SetFailBit(DigiScintHit::kNegEnergy);
00530     return JobCResult::kWarning;
00531   }
00532 
00533   if(hit->DE()==0.) {
00534     MAXMSG("Photon",Msg::kWarning,5) 
00535       << "DigiScintHit has zero energy. Throwing it out." << endl;
00536     hit -> SetFailBit(DigiScintHit::kNullEnergy);
00537     return JobCResult::kWarning;
00538   }
00539 
00540   fEventResult.totalHits +=1;
00541   fEventResult.totalHitEnergy += hit->DE();
00542   fEventResult.fStripsHit.insert(hit->StripEndId().Build18BitPlnStripKey());
00543 
00544   DigiScintHit* computerHit = hit; // A pointer used only for the Computer.
00545 
00546   // Verify that this hit is on a strip that can eventually read out somewhere.
00547   // NB. Up 0-3 and Vp 64-69 in the ND have scintillator but no readout.
00548   PlexHandle plex(fContext);
00549   PlexStripEndId seid1(hit->StripEndId()); seid1.SetEnd(StripEnd::kPositive);
00550   PlexStripEndId seid2(hit->StripEndId()); seid2.SetEnd(StripEnd::kNegative);
00551   int numEndsReadOut = 0;
00552   if(plex.GetPixelSpotId(seid1).IsValid()) numEndsReadOut++;
00553   if(plex.GetPixelSpotId(seid2).IsValid()) numEndsReadOut++;
00554   if(numEndsReadOut==0) return JobCResult::kPassed;  // Everything is fine, but don't bother with this hit
00555 
00556   // Verify the geometry in this scint hit makes sense.
00557   int badBoundary = VerifyScintHit(hit,ustrip);
00558 
00559   if(badBoundary>0) {
00560     MAXMSG("Photon",Msg::kWarning,20) 
00561       << "DigiScintHit geometry inconsistency: is not contained in strip " << endl 
00562       << "   Boundary violation: " << badBoundary 
00563       << "  " << kBoundaryString[badBoundary] << endl
00564       << "   Strip: " <<hit->StripEndId().AsString() 
00565       << " dE = " << hit->DE()/Munits::MeV << " MeV  "
00566       << " dx = " << hit->DS()/Munits::cm << " cm  " << endl
00567       << "   ScintHit coords: " 
00568       << Form("(%.2f,%.2f,%.2f) cm ",hit->X1()/Munits::cm,hit->Y1()/Munits::cm,hit->Z1()/Munits::cm)
00569       << "to" 
00570       << Form("(%.2f,%.2f,%.2f) cm",hit->X2()/Munits::cm,hit->Y2()/Munits::cm,hit->Z2()/Munits::cm)
00571       << endl
00572       << "   Ugli Geometry: " 
00573       << Form("(+/-%.2f, +/-%.2f,+/-%.2f) cm",ustrip.GetHalfLength()/Munits::cm,ustrip.GetHalfWidth()/Munits::cm,ustrip.GetHalfThickness()/Munits::cm)
00574       << ".. skipping it." << endl;
00575     if ( fBadHitNtuple ) {
00576       Int_t failmode = 1; // => failed geometry
00577       FillBadHitNtuple(hit,failmode);
00578     }
00579     hit -> SetFailBit(DigiScintHit::kBadGeom);
00580     fEventResult.hitsDiscardedGeom +=1;
00581     fEventResult.energyDiscardedGeom += hit->DE();
00582     return JobCResult::kWarning;
00583   }     
00584 
00585   if(hit->DS()<=0.) {
00586     // Zero range! 
00587     // Try to do a fix.
00588 
00589     if(hit->ParticleId()==2212) {
00590       // It's a proton. Attempt to do make our own range determination.
00591       double range = fProtonRangeTable.Interpolate(hit->ParticleKineticEnergy()/Munits::MeV);
00592       MinosMaterial::StdMaterial_t fStdMatSc=MinosMaterial::ePolystyreneMinos;
00593       double fRoSc=MinosMaterial::Density(fStdMatSc);//Was 1.06;
00594 
00595       double dx = range / fRoSc * Munits::cm; 
00596       
00597       MSG("Photon",Msg::kDebug) << "dx==0 for a proton. Table lookup gives range of " 
00598                                 << dx/Munits::mm << " mm for KE of " 
00599                                 << hit->ParticleKineticEnergy()/Munits::MeV << " MeV" << endl;
00600       
00601       if(dx<=0.0) {
00602         MSG("Photon",Msg::kDebug) << "dx<=0 for a proton, after table lookup!";
00603         if ( fBadHitNtuple ) {
00604           Int_t failmode = 3; // => proton dS is zero even after table lookup 
00605           FillBadHitNtuple(hit,failmode);
00606         }
00607         hit -> SetFailBit(DigiScintHit::kNullPath);
00608         fEventResult.hitsDiscardedBad+=1;
00609         fEventResult.energyDiscardedBad+=hit->DE();
00610         return JobCResult::kWarning;
00611       }
00612 
00613       // Make a new, temporary ScintHit that the Computer can use
00614       // that has an adjusted track length.
00615       static DigiScintHit* tempHit = 0;
00616       if(tempHit) delete tempHit;
00617       tempHit = new DigiScintHit(hit->TrackId(),hit->ParticleId(),
00618                                  hit->ParticleEnergy(), hit->StripEndId(),
00619                                  hit->T1(), hit->X1(), hit->Y1(), hit->Z1(),
00620                                  hit->T2(), hit->X2(), hit->Y2(), hit->Z2(),
00621                                  dx, hit->DE());
00622       computerHit = tempHit;
00623 
00624     } else {
00625 
00626       MAXMSG("Photon",Msg::kWarning,5) 
00627         << "DigiScintHit has zero path length. Throwing it out." << endl;
00628 
00629       if ( fBadHitNtuple ) {
00630         Int_t failmode = 2; // => zero pathlength and not proton
00631         FillBadHitNtuple(hit,failmode);
00632       }
00633 
00634       hit -> SetFailBit(DigiScintHit::kNullPath);
00635       fEventResult.hitsDiscardedBad+=1;
00636       fEventResult.energyDiscardedBad+=hit->DE();
00637       return JobCResult::kAOK;
00638     }
00639   }
00640 
00641   // Hack for low-energy electrons.
00642   if(abs(hit->ParticleId())==11) {
00643     // Is it below threshold?
00644     if((hit->ParticleKineticEnergy() < fElectronFudgeThreshEnergy) ||
00645        (hit->DS()                    < fElectronFudgeThreshDist) ) {
00646       // We're in the fudge regime. Do it.
00647 
00648       // Find the start/stop energy.
00649       double E1 = hit->ParticleKineticEnergy();
00650       double E2 = E1 - hit->DE();
00651       if(E2<0) E2 = 0;
00652       double dE = E1-E2;
00653 
00654       // Compute the range from the tables.      
00655       double Range1 = fElectronRangeTable.Interpolate(E1);
00656       double Range2 = fElectronRangeTable.Interpolate(E2);
00657       double dX = Range1-Range2;
00658 
00659       // Make a new, temporary ScintHit that the Computer can use
00660       // that has an adjusted track length.
00661       static DigiScintHit* tempHit = 0;
00662       if(tempHit) delete tempHit;
00663       tempHit = new DigiScintHit(hit->TrackId(),hit->ParticleId(),
00664                                  hit->ParticleEnergy(), hit->StripEndId(),
00665                                  hit->T1(), hit->X1(), hit->Y1(), hit->Z1(),
00666                                  hit->T2(), hit->X2(), hit->Y2(), hit->Z2(),
00667                                  dX, dE);
00668       computerHit = tempHit;
00669     }
00670   }
00671 
00672   // First, ask the photon computer for how many hits we're going to demand.
00673   PhotonCount demand;
00674   
00675   // Set a 'null' demand value.
00676   demand.SetBlueTotal(0);
00677   
00678 
00679   // Ask the computer.
00680   // Note that we give it what each of the modules says is it's 
00681   // own prescale factor. For instance, the green tracker will usually
00682   // be prescaled by 0.13, or 13% for the photocathode quantum efficiency.
00683   // This indicates to the computer that it only needs to generate 
00684   // 13% of the photons it would otherwise need.  The GreenTracker, in 
00685   // turn, scales up the quantum efficiency by a factor of 1/0.13.
00686   // This is used as a trick to speed up the simulation by several factors.
00687   Bool_t hitOK = fPhotonComputer->
00688     ComputePhotons(computerHit,
00689                    fBluePhotonTracker->GetBluePrescaleFactor(),
00690                    fWlsFibreModel->GetWlsPrescaleFactor(),
00691                    fGreenPhotonTracker->GetGreenPrescaleFactor(),
00692                    demand);
00693 
00694   if(!hitOK) {
00695     if ( fBadHitNtuple ) {
00696       Int_t failmode = 4;  // failed by PhotonComputer
00697       FillBadHitNtuple(hit,failmode);
00698     }
00699     hit -> SetFailBit(DigiScintHit::kPhotonComputer);
00700     fEventResult.hitsDiscardedBad+=1;
00701     fEventResult.energyDiscardedBad+=hit->DE();
00702     return JobCResult::kAOK;
00703   }
00704   // The photon computer will have asked us for one of:
00705   // 1) A total number of blue photons
00706   // 2) A number of blue photons to be made for the +ve end readout
00707   //   and -ve end readout
00708   // 3) A total number of green photons to be made
00709   // 4) A number of green photons to be made (+,-)
00710   // 5) A total number of photoelectrons (usually used for mirrored strips)
00711   // 6) A number of final photoelectrons to be mad (+,-)
00712 
00713   // Our job now is to keep simulating photons until we reach 
00714   // the desired number, whichever it is.
00715   // The unused demand numbers are automatically set to -1, so we can simply 
00716   // start and zero and continue until something matches.
00717 
00718   Int_t nBlue_Total=0;
00719   Int_t nBlue_Pos=0;
00720   Int_t nBlue_Neg=0;
00721   Int_t nGreen_Total=0;
00722   Int_t nGreen_Pos=0;
00723   Int_t nGreen_Neg=0;
00724   Int_t nPe_Total = 0;
00725   Int_t nPe_Pos=0;
00726   Int_t nPe_Neg=0;
00727   
00728   DigiPhoton* bluePhoton =0;
00729   DigiPhoton* greenPhoton =0;
00730   DigiPE*     pe =0;
00731   
00732   bool done = false;
00733   while(!done) {
00734 
00735     // --------------------------------------
00736     // Clean up from last pass.
00737     if(bluePhoton) delete bluePhoton;
00738     if(greenPhoton) delete greenPhoton;
00739     if(pe) delete pe;
00740     bluePhoton = 0;
00741     greenPhoton = 0;
00742     pe = 0;
00743 
00744     
00745     // --------------------------------------
00746     // Are we done?
00747 
00748     // Deal with finish condition (1) above (the simplest):
00749     // if we have made enough blue photons, this is the last one.
00750     if(nBlue_Total == demand.GetBlue_Total()) done = true; // We reached demand.
00751         
00752     // Finish condition (2):
00753     if( (nBlue_Pos == demand.GetBlue_Pos()) && 
00754         (nBlue_Neg == demand.GetBlue_Neg()) ) done = true; // We reached demand.
00755 
00756     // Deal with finish condition (3) above
00757     // if we have made enough green photons.
00758     if(demand.GetGreen_Total() == nGreen_Total) done = true; // We reached demand.
00759     
00760     // Finish condition (4):
00761     if( (nGreen_Pos == demand.GetGreen_Pos()) && 
00762         (nGreen_Neg == demand.GetGreen_Neg()) ) done = true; // We reached demand.
00763     
00764     // Finish condition (5): we got enough PE.
00765     if(nPe_Total == demand.GetPe_Total()) done = true;
00766     
00767     // Condition (6)
00768     if( (nPe_Pos == demand.GetPe_Pos()) && 
00769         (nPe_Neg == demand.GetPe_Neg()) ) done = true; // We reached demand.
00770     
00771     if(done) break;
00772 
00773 
00774     // ----------------------------------------------------------
00775     // Choose which direction this photon will go.
00776 
00777     // By default, we don't know which end this thing should go to.
00778     // i.e. cases (1) and (3) above.
00779     StripEnd::StripEnd_t direction = StripEnd::kUnknown; 
00780 
00781     // Deal with cases (2),(4),and(5) to choose direction:
00782     if(demand.IsDirectional()) {
00783       // If we don't have enough positives, go that way.
00784       // If we do, go the other way.
00785       if( (nBlue_Pos  < demand.GetBlue_Pos()) ||
00786           (nGreen_Pos < demand.GetGreen_Pos()) ||
00787           (nPe_Pos    < demand.GetPe_Pos()) ) {
00788         direction = StripEnd::kPositive;
00789       } else {
00790         direction = StripEnd::kNegative;
00791       }
00792     }
00793 
00794     //---------------------------------------
00795     // Step I::Simulate scintillator photons
00796     Bool_t blue_hit = fBluePhotonTracker->ScintPhotonToFibreHit(hit,
00797                                                                 ustrip,
00798                                                                 bluePhoton);
00799 
00800     if(!bluePhoton) continue; // Didn't actually make a blue photon.. tracking error or somesuch.
00801     
00802     nBlue_Total++; // We made a blue photon.
00803     if(direction==StripEnd::kPositive) nBlue_Pos++; // Blue +ve going photon
00804     if(direction==StripEnd::kNegative) nBlue_Neg++; // Blue -ve going photon
00805 
00806     // Don't bother with the rest of the steps if it didn't even hit the fibre.
00807     if(!blue_hit) continue;
00808 
00809     // ------------------------------------------------
00810     // Step II:Convert from blue photon to a fibre hit.
00811     Bool_t fibre_hit = 
00812       fWlsFibreModel->FibreHitToGreenPhoton(ustrip,
00813                                             direction,
00814                                             bluePhoton,
00815                                             greenPhoton);
00816 
00817     if(!fibre_hit) continue; // Didn't successfully make a green photon..
00818     
00819     nGreen_Total++;
00820     if(direction==StripEnd::kPositive) nGreen_Pos++; // Green +ve going photon
00821     if(direction==StripEnd::kNegative) nGreen_Neg++; // Green -ve going photon
00822     
00823     
00824     // ------------------------------------------------
00825     // Step III: Track the green photon to the phototube.
00826 
00827     Bool_t greenSurvived = 
00828       fGreenPhotonTracker->GreenPhotonToPe( ustrip,
00829                                             greenPhoton,
00830                                             pe,
00831                                             direction);
00832     
00833     
00834     if((!greenSurvived)||(!pe)) continue; // green photon didn't make it to the photocathode.
00835 
00836     nPe_Total++;
00837     if(direction==StripEnd::kPositive) nPe_Pos++; // Blue +ve going photon
00838     if(direction==StripEnd::kNegative) nPe_Neg++; // Blue -ve going photon
00839 
00840     
00841     
00842     // Finally! We have made a photoelectron. Tack it onto the list...
00843     // if it's a valid pixel.
00844     if(pe->GetPixelSpotId().IsValid()) {
00845       fEventResult.totalPE += 1;
00846       fEventResult.fPixelsHit.insert(pe->GetPixelSpotId().GetUniquePixelEncodedValue());
00847       fPeList->Add(pe);
00848 
00849       if(fDebugNtuple)
00850         fDebugNtuple->Fill(hit->Plane(),hit->Strip(),(float)direction,
00851                            hit->T1(), bluePhoton->T(), 
00852                            greenPhoton->T(), pe->GetTime(),
00853                            greenPhoton->GetCosX(),
00854                            greenPhoton->X()
00855                            );
00856 
00857       pe = 0; // So it doesn't get deleted.
00858     }
00859   };
00860 
00861   MSG("Photon",Msg::kDebug) << "Hit: " 
00862                               << hit->DE()/Munits::MeV << " MeV -> " 
00863                               << nBlue_Total << " blue -> "
00864                               << nGreen_Total << " green -> "
00865                               << nPe_Total << " pe"
00866                               << endl;
00867 
00868   MSG("Photon",Msg::kVerbose) << "Hit result:" << endl 
00869                             << "Blue photons:    Total ( " << nBlue_Total << " / " << demand.GetBlue_Total() << " ) "
00870                             << " +ve ( "<< nBlue_Pos << " / " << demand.GetBlue_Pos() << " ) "
00871                             << " -ve ( "<< nBlue_Neg << " / " << demand.GetBlue_Neg() << " ) " << endl
00872                             << "Green photons:   Total ( " << nGreen_Total << " / " << demand.GetGreen_Total() << " ) "
00873                             << " +ve ( "<< nGreen_Pos << " / " << demand.GetGreen_Pos() << " ) "
00874                             << " -ve ( "<< nGreen_Neg << " / " << demand.GetGreen_Neg() << " ) " << endl
00875                             << "Photoelectrons:  Total ( " << nPe_Total << " / " << demand.GetPe_Total() << " ) "
00876                             << " +ve ( "<< nPe_Pos << " / " << demand.GetPe_Pos() << " ) "
00877                             << " -ve ( "<< nPe_Neg << " / " << demand.GetPe_Neg() << " ) " << endl;
00878     
00879   fEventResult.bluePhotons+=nBlue_Total;
00880   fEventResult.greenPhotons+=nGreen_Total;
00881   
00882   fEventResult.bluePhotons_nonprescaled += (Int_t)(nBlue_Total/(fBluePhotonTracker->GetBluePrescaleFactor()
00883                                                           *fWlsFibreModel->GetWlsPrescaleFactor()
00884                                                           *fGreenPhotonTracker->GetGreenPrescaleFactor() ) );
00885   fEventResult.greenPhotons_nonprescaled += (Int_t)(nGreen_Total/fGreenPhotonTracker->GetGreenPrescaleFactor());
00886 
00887 
00888   // Cleanup.
00889   if(bluePhoton) delete bluePhoton;
00890   if(greenPhoton) delete greenPhoton;
00891   if(pe) delete pe;
00892  
00893   return JobCResult::kPassed;
00894 }

int PhotonTransport::VerifyScintHit ( DigiScintHit hit,
UgliStripHandle  ustrip 
) [static]

Definition at line 472 of file PhotonTransport.cxx.

References Munits::cm, UgliStripHandle::GetHalfLength(), UgliStripHandle::GetHalfThickness(), UgliStripHandle::GetHalfWidth(), kInsideBypass, StripEnd::kNegative, StripEnd::kPositive, kX1OffEnd, kX2OffEnd, kY1OffWidth, kY2OffWidth, kZ1OffThick, kZ2OffThick, UgliStripHandle::PartialLength(), UgliStripHandle::WlsBypass(), DigiScintHit::X1(), DigiScintHit::X2(), DigiScintHit::Y1(), DigiScintHit::Y2(), DigiScintHit::Z1(), and DigiScintHit::Z2().

Referenced by SimulateScintHit().

00473 {
00474   // Look at the scint hit and see if it's bogus.
00475   // Return 0 if it's OK
00476   // Return an integer corresponding to the coordinate violated if not.
00477   
00478   if(fabs(hit->X1()) > (ustrip.GetHalfLength()+0.1*Munits::cm)) return kX1OffEnd;
00479   if(fabs(hit->X2()) > (ustrip.GetHalfLength()+0.1*Munits::cm)) return kX2OffEnd;
00480 
00481   // Length checking: it may be on a two-part strip. Which end is it on?
00482   if(ustrip.WlsBypass()>0.) {
00483     float x01 = hit->X1() +  ustrip.GetHalfLength();
00484     float x02 = hit->X2() +  ustrip.GetHalfLength();
00485     float p_neg = ustrip.PartialLength(StripEnd::kNegative);
00486     float p_pos = ustrip.GetHalfLength()*2.0 - ustrip.PartialLength(StripEnd::kPositive);
00487     bool good = false;
00488     if((x01<p_neg) && (x02<p_neg)) good = true; // They're both on the neg side
00489     if((x01>p_pos) && (x02>p_pos)) good = true; // They're both on the pos side
00490      if(good==false) return kInsideBypass;
00491   }
00492 
00493   if(fabs(hit->Y1()) > ustrip.GetHalfWidth()) return kY1OffWidth;
00494   if(fabs(hit->Y2()) > ustrip.GetHalfWidth()) return kY2OffWidth;
00495   if(fabs(hit->Z1()) > ustrip.GetHalfThickness()) return kZ1OffThick;
00496   if(fabs(hit->Z2()) > ustrip.GetHalfThickness()) return kZ2OffThick;
00497   return 0;
00498 }


Member Data Documentation

PhotonTransportModule* PhotonTransport::fAfterpulser [private]

Definition at line 86 of file PhotonTransport.h.

Referenced by AddAfterpulsing(), Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), and ~PhotonTransport().

TNtupleD* PhotonTransport::fBadHitNtuple [private]

Definition at line 90 of file PhotonTransport.h.

Referenced by BeginJob(), FillBadHitNtuple(), SimulateScintHit(), and ~PhotonTransport().

PhotonTransportModule* PhotonTransport::fBluePhotonTracker [private]

Definition at line 82 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), SimulateScintHit(), and ~PhotonTransport().

VldContext PhotonTransport::fContext [private]

Definition at line 65 of file PhotonTransport.h.

Referenced by FillBadHitNtuple(), Get(), SimulateEvent(), and SimulateScintHit().

TFile* PhotonTransport::fDebugFile [private]

Definition at line 88 of file PhotonTransport.h.

Referenced by BeginJob(), and ~PhotonTransport().

std::string PhotonTransport::fDebugFileName [private]

Definition at line 61 of file PhotonTransport.h.

Referenced by BeginJob(), and Config().

Int_t PhotonTransport::fDebugMask [private]

Definition at line 62 of file PhotonTransport.h.

Referenced by BeginJob(), and Config().

TNtuple* PhotonTransport::fDebugNtuple [private]

Definition at line 89 of file PhotonTransport.h.

Referenced by BeginJob(), SimulateScintHit(), and ~PhotonTransport().

Double_t PhotonTransport::fElectronFudgeThreshDist [private]

Definition at line 78 of file PhotonTransport.h.

Referenced by Config(), and SimulateScintHit().

Double_t PhotonTransport::fElectronFudgeThreshEnergy [private]

Definition at line 77 of file PhotonTransport.h.

Referenced by Config(), and SimulateScintHit().

PhotonLookupTable PhotonTransport::fElectronRangeTable [private]

Definition at line 76 of file PhotonTransport.h.

Referenced by SimulateEvent(), and SimulateScintHit().

PhotonEventResult PhotonTransport::fEventResult [private]

Definition at line 70 of file PhotonTransport.h.

Referenced by AddAfterpulsing(), AddNoise(), Get(), SimulateEvent(), and SimulateScintHit().

PhotonTransportModule* PhotonTransport::fGreenPhotonTracker [private]

Definition at line 84 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), SimulateScintHit(), and ~PhotonTransport().

const TObjArray* PhotonTransport::fHitList [private]

Definition at line 67 of file PhotonTransport.h.

Referenced by AddNoise(), Get(), and SimulateEvent().

std::string PhotonTransport::fName_Afterpulser [private]

Definition at line 60 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

std::string PhotonTransport::fName_BluePhotonTracker [private]

Definition at line 56 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

std::string PhotonTransport::fName_GreenPhotonTracker [private]

Definition at line 58 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

std::string PhotonTransport::fName_NoiseMaker [private]

Definition at line 59 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

std::string PhotonTransport::fName_PhotonComputer [private]

Definition at line 55 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

std::string PhotonTransport::fName_WlsFibreModel [private]

Definition at line 57 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), and CreateModelObjects().

PhotonTransportModule* PhotonTransport::fNoiseMaker [private]

Definition at line 85 of file PhotonTransport.h.

Referenced by AddNoise(), Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), and ~PhotonTransport().

TObjArray* PhotonTransport::fPeList [private]

Definition at line 68 of file PhotonTransport.h.

Referenced by AddAfterpulsing(), AddNoise(), Get(), and SimulateScintHit().

Int_t PhotonTransport::fPeTotal [private]

Definition at line 69 of file PhotonTransport.h.

Referenced by Get().

PhotonTransportModule* PhotonTransport::fPhotonComputer [private]

Definition at line 81 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), SimulateScintHit(), and ~PhotonTransport().

PhotonLookupTable PhotonTransport::fProtonRangeTable [private]

Definition at line 75 of file PhotonTransport.h.

Referenced by SimulateEvent(), and SimulateScintHit().

TRandom* PhotonTransport::fRandom [private]

Definition at line 74 of file PhotonTransport.h.

Referenced by CreateModelObjects(), Get(), and ~PhotonTransport().

Int_t PhotonTransport::fRandomSeed [private]

Definition at line 73 of file PhotonTransport.h.

Referenced by Config(), and Get().

const SimSnarlHeader* PhotonTransport::fSimHeader [private]

Definition at line 66 of file PhotonTransport.h.

Referenced by Get(), and SimulateEvent().

PhotonTransportModule* PhotonTransport::fWlsFibreModel [private]

Definition at line 83 of file PhotonTransport.h.

Referenced by Config(), ConfirmModelObjects(), CreateModelObjects(), Print(), SimulateEvent(), SimulateScintHit(), and ~PhotonTransport().


The documentation for this class was generated from the following files:
Generated on Thu Apr 10 23:03:28 2014 for loon by  doxygen 1.4.7