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
Int_t fFailWhenNoTimeRange
Double_t fTStartNoRange
Double_t fTEndNoRange
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   fFailWhenNoTimeRange(0),
00057   fTStartNoRange(0),
00058   fTEndNoRange(20.0e-6),
00059   fRandomSeed(0),
00060   fRandom(new TRandom3),
00061   fProtonRangeTable("PHOTONPROTONRANGE"),
00062   fElectronRangeTable("PHOTONELECTRONRANGE"),
00063   fPhotonComputer(0),
00064   fBluePhotonTracker(0),
00065   fWlsFibreModel(0),
00066   fGreenPhotonTracker(0),
00067   fNoiseMaker(0),
00068   fAfterpulser(0),
00069   fDebugFile(0),
00070   fDebugNtuple(0),
00071   fBadHitNtuple(0)
00072 {
00073 
00074   LoadMinosPDG(); // initialize MINOS specific particles
00075 
00076   CreateModelObjects(); // Create the models.
00077 //======================================================================
00078 // FILL_IN: [Document your code!!]
00079 //======================================================================  
00080 
00081 }

PhotonTransport::~PhotonTransport (  ) 

Definition at line 85 of file PhotonTransport.cxx.

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

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


Member Function Documentation

JobCResult PhotonTransport::AddAfterpulsing (  )  [private]

Definition at line 948 of file PhotonTransport.cxx.

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

Referenced by SimulateEvent().

00949 {
00953 
00954   // Find the times of the hits to get an idea what the window is.
00955   std::vector<DigiPE*> apList;
00956   std::vector<DigiPE*> peList;
00957 
00958   MSG("Photon",Msg::kDebug) << "Calling Afterpulser." << std::endl;
00959 
00960   peList.resize(fPeList->GetEntries(),0);
00961   for(UInt_t i=0; i<peList.size(); i++) {
00962     peList[i] = dynamic_cast<DigiPE*>((*fPeList)[i]);
00963   }
00964 
00965   fAfterpulser->MakeAfterpulses(peList,apList);
00966 
00967   for(UInt_t i=0;i<apList.size();i++) {
00968     fPeList->Add(apList[i]);
00969   }
00970   fEventResult.afterpulsePE += apList.size();
00971   fEventResult.totalPE      += apList.size();
00972 
00973 
00974   return JobCResult::kPassed;
00975 }

JobCResult PhotonTransport::AddNoise (  )  [private]

Definition at line 903 of file PhotonTransport.cxx.

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

Referenced by SimulateEvent().

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

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

Implement this for read only access to the MomNavigator

Reimplemented from JobCModule.

Definition at line 110 of file PhotonTransport.cxx.

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

Referenced by Reco().

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

void PhotonTransport::BeginJob (  )  [virtual]

Implement for notification of begin of job

Reimplemented from JobCModule.

Definition at line 303 of file PhotonTransport.cxx.

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

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

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 243 of file PhotonTransport.cxx.

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

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

JobCResult PhotonTransport::ConfirmModelObjects (  )  [private]

Definition at line 357 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().

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

void PhotonTransport::CreateModelObjects (  )  [private]

Definition at line 323 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().

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

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 232 of file PhotonTransport.cxx.

References PhotonConfiguration().

00233 {
00234 //======================================================================
00235 // Supply the default configuration for the module
00236 //======================================================================
00237 
00238   return PhotonConfiguration();
00239 }

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

Definition at line 990 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().

00991                                                        {
00994   
00995   // Convert local to global coordinates
00996   UgliGeomHandle ugli = UgliGeomHandle(fContext);
00997   const UgliStripHandle& uglistp = ugli.GetStripHandle(hit->StripEndId());
00998   TVector3 vlocal0(hit->X1(),hit->Y1(),hit->Z1());
00999   const TVector3& vglobal0 = uglistp.LocalToGlobal(vlocal0);
01000 
01001   fBadHitNtuple -> Fill(hit->ParticleEnergy(),
01002                         hit->ParticleId(),hit->Plane(),hit->Strip(),
01003                         hit->T1(),hit->X1(),hit->Y1(),hit->Z1(),
01004                         (Float_t)(vglobal0.X()),(Float_t)vglobal0.Y(),
01005                         (Float_t)vglobal0.Z(),
01006                         hit->DS(),hit->DE(),failmode);
01007 
01008   return;
01009 }

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 141 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().

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

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

Definition at line 978 of file PhotonTransport.cxx.

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

00979 {
00980   MSG("Photon",kInfo) << "PhotonTransport Configuration:" << endl;
00981   if(fPhotonComputer) fPhotonComputer->Print("c");
00982   if(fBluePhotonTracker) fBluePhotonTracker->Print("b");
00983   if(fWlsFibreModel) fWlsFibreModel->Print("w");
00984   if(fGreenPhotonTracker) fWlsFibreModel->Print("g");
00985   if(fNoiseMaker) fNoiseMaker->Print("n");
00986   if(fAfterpulser) fAfterpulser->Print("n");
00987 }

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

Implement this for read-write access to the MomNavigator

Reimplemented from JobCModule.

Definition at line 131 of file PhotonTransport.cxx.

References Ana().

00132 {
00136   return Ana(mom);
00137 }

JobCResult PhotonTransport::SimulateEvent (  )  [private]

Definition at line 413 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().

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

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

Definition at line 507 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().

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

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

Definition at line 479 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().

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


Member Data Documentation

PhotonTransportModule* PhotonTransport::fAfterpulser [private]

Definition at line 89 of file PhotonTransport.h.

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

TNtupleD* PhotonTransport::fBadHitNtuple [private]

Definition at line 93 of file PhotonTransport.h.

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

PhotonTransportModule* PhotonTransport::fBluePhotonTracker [private]

Definition at line 85 of file PhotonTransport.h.

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

VldContext PhotonTransport::fContext [private]

Definition at line 68 of file PhotonTransport.h.

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

TFile* PhotonTransport::fDebugFile [private]

Definition at line 91 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 92 of file PhotonTransport.h.

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

Double_t PhotonTransport::fElectronFudgeThreshDist [private]

Definition at line 81 of file PhotonTransport.h.

Referenced by Config(), and SimulateScintHit().

Double_t PhotonTransport::fElectronFudgeThreshEnergy [private]

Definition at line 80 of file PhotonTransport.h.

Referenced by Config(), and SimulateScintHit().

PhotonLookupTable PhotonTransport::fElectronRangeTable [private]

Definition at line 79 of file PhotonTransport.h.

Referenced by SimulateEvent(), and SimulateScintHit().

PhotonEventResult PhotonTransport::fEventResult [private]

Definition at line 73 of file PhotonTransport.h.

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

Int_t PhotonTransport::fFailWhenNoTimeRange [private]

Definition at line 63 of file PhotonTransport.h.

Referenced by AddNoise(), and Config().

PhotonTransportModule* PhotonTransport::fGreenPhotonTracker [private]

Definition at line 87 of file PhotonTransport.h.

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

const TObjArray* PhotonTransport::fHitList [private]

Definition at line 70 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 88 of file PhotonTransport.h.

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

TObjArray* PhotonTransport::fPeList [private]

Definition at line 71 of file PhotonTransport.h.

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

Int_t PhotonTransport::fPeTotal [private]

Definition at line 72 of file PhotonTransport.h.

Referenced by Get().

PhotonTransportModule* PhotonTransport::fPhotonComputer [private]

Definition at line 84 of file PhotonTransport.h.

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

PhotonLookupTable PhotonTransport::fProtonRangeTable [private]

Definition at line 78 of file PhotonTransport.h.

Referenced by SimulateEvent(), and SimulateScintHit().

TRandom* PhotonTransport::fRandom [private]

Definition at line 77 of file PhotonTransport.h.

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

Int_t PhotonTransport::fRandomSeed [private]

Definition at line 76 of file PhotonTransport.h.

Referenced by Config(), and Get().

const SimSnarlHeader* PhotonTransport::fSimHeader [private]

Definition at line 69 of file PhotonTransport.h.

Referenced by Get(), and SimulateEvent().

Double_t PhotonTransport::fTEndNoRange [private]

Definition at line 65 of file PhotonTransport.h.

Referenced by AddNoise(), and Config().

Double_t PhotonTransport::fTStartNoRange [private]

Definition at line 64 of file PhotonTransport.h.

Referenced by AddNoise(), and Config().

PhotonTransportModule* PhotonTransport::fWlsFibreModel [private]

Definition at line 86 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 Mon Nov 10 00:56:15 2014 for loon by  doxygen 1.4.7