PhotonCalibratedPeComputer Class Reference

#include <PhotonCalibratedPeComputer.h>

Inheritance diagram for PhotonCalibratedPeComputer:
PhotonTransportModule

List of all members.

Public Member Functions

 PhotonCalibratedPeComputer ()
virtual ~PhotonCalibratedPeComputer ()
virtual void Configure (const Registry &r)
virtual void Reset (const VldContext &cx)
virtual Bool_t ComputePhotons (const DigiScintHit *inHit, Double_t inBluePrescale, Double_t inWlsPrescale, Double_t inGreenPrescale, PhotonCount &outCount)

Private Member Functions

virtual Double_t ClipFraction (double x) const
 ClassDef (PhotonCalibratedPeComputer, 0)

Private Attributes

Double_t fOverallLightOutput
Double_t fBirksConstant
Double_t fGeVPerMip
Int_t fScintillatorClipping
Double_t fMaxPePerHit

Detailed Description

Definition at line 13 of file PhotonCalibratedPeComputer.h.


Constructor & Destructor Documentation

PhotonCalibratedPeComputer::PhotonCalibratedPeComputer (  ) 

Definition at line 16 of file PhotonCalibratedPeComputer.cxx.

References PhotonConfiguration().

00017 {
00018   Configure(PhotonConfiguration());
00019 }

PhotonCalibratedPeComputer::~PhotonCalibratedPeComputer (  )  [virtual]

Definition at line 23 of file PhotonCalibratedPeComputer.cxx.

00024 {
00025  
00026 }


Member Function Documentation

PhotonCalibratedPeComputer::ClassDef ( PhotonCalibratedPeComputer  ,
 
) [private]
Double_t PhotonCalibratedPeComputer::ClipFraction ( double  x  )  const [private, virtual]

Definition at line 280 of file PhotonCalibratedPeComputer.cxx.

Referenced by ComputePhotons().

00281 {
00282   // Returns the integral of the double-lorentzian blue photon profile
00283   // from -inf to x.
00284   
00285   // Same parameters as in PhotonFastBlueModel.
00286 
00287   const double kLorentzWidth1 = 0.017853;
00288   const double kArea1 = 8.178052;
00289   const double kLorentzWidth2 = 0.001309;
00290   const double kArea2 = 0.864215;
00291 
00292   const double kArea = kArea1+kArea2;
00293 
00294   double frac = kArea1 * atan(x/kLorentzWidth1)
00295     + kArea2 * atan(x/kLorentzWidth2);
00296   frac = frac / (kArea * TMath::Pi());
00297   frac += 0.5;
00298 
00299   // Bonus extra fudge-factor:
00300   // We don't want this effect to be seen outside ~20 cm 
00301   // (where the effect is already down around 1%)
00302   // So, supress by an additional amount:
00303   if (x>0.2) frac = 1-(1-frac)*exp(-(x-0.2)*20.);
00304 
00305   return frac;
00306 }

Bool_t PhotonCalibratedPeComputer::ComputePhotons ( const DigiScintHit inHit,
Double_t  inBluePrescale,
Double_t  inWlsPrescale,
Double_t  inGreenPrescale,
PhotonCount outCount 
) [virtual]

Reimplemented from PhotonTransportModule.

Definition at line 59 of file PhotonCalibratedPeComputer.cxx.

References PlexStripEndId::AsString(), ClipFraction(), DigiScintHit::DE(), Calibrator::DecalAttenCorrected(), Calibrator::DecalDrift(), Calibrator::DecalMIP(), Calibrator::DecalStripToStrip(), DigiScintHit::DS(), fBirksConstant, PhotonTransportModule::fContext, fGeVPerMip, fMaxPePerHit, fOverallLightOutput, PhotonTransportModule::fRandom, fScintillatorClipping, PlexStripEndId::GetEnd(), UgliStripHandle::GetHalfLength(), PhotonCount::GetPe_Neg(), PhotonCount::GetPe_Pos(), Calibrator::GetPhotoElectrons(), UgliGeomHandle::GetStripHandle(), Calibrator::Instance(), UgliStripHandle::IsMirrored(), Msg::kDebug, Msg::kError, StripEnd::kNegative, StripEnd::kPositive, Munits::MeV, MSG, UgliStripHandle::PartialLength(), PlexStripEndId::SetEnd(), PhotonCount::SetPeNegPos(), DigiScintHit::StripEndId(), UgliStripHandle::WlsBypass(), DigiScintHit::X1(), and DigiScintHit::X2().

00064 {
00065   // Number of photons made:
00066   if (!inHit) return false;
00067   double dE = inHit->DE();
00068   double dx = inHit->DS();
00069   double dEdx = dE/dx;
00070 
00071   // Get position.
00072   double x = 0.5*(inHit->X1() + inHit->X2());
00073   
00074   double clippedfrac = 1.0;
00075 
00076   UgliGeomHandle ugli(fContext);
00077   UgliStripHandle ustrip=ugli.GetStripHandle(inHit->StripEndId());
00078 
00079   if (fScintillatorClipping) {
00080     // Clip the photon response by shaving off photons lost out the
00081     // ends of the scintillator either at the planed edges or the bore hole.
00082 
00083     // To do this, we cheat a bit: we assume that ALL strip ends play a role
00084     // in diminishing the return. 
00085    
00086     double distToEnd;
00087     
00088     distToEnd = ustrip.GetHalfLength()-x; // +ve end.
00089     clippedfrac *= ClipFraction( distToEnd ); // End1
00090 
00091     distToEnd = x+ustrip.GetHalfLength(); // -ve end.
00092     clippedfrac *= ClipFraction( distToEnd ); // End2
00093 
00094     if (ustrip.WlsBypass() > 0.) {
00095       // There is a coil bypass, so look at coil stripends.
00096       // Where is the coil center?
00097       double coilpos = 0.5*(ustrip.PartialLength(StripEnd::kNegative) - ustrip.PartialLength(StripEnd::kPositive));
00098       if (x<coilpos) {
00099         distToEnd = (-x) - ( ustrip.GetHalfLength() - ustrip.PartialLength(StripEnd::kNegative));
00100         clippedfrac *= ClipFraction( distToEnd );
00101 
00102       } else {
00103         distToEnd = (x) - ( ustrip.GetHalfLength() - ustrip.PartialLength(StripEnd::kPositive));
00104         clippedfrac *= ClipFraction( distToEnd );
00105       }
00106     }
00107   }
00108 
00109   if (clippedfrac < 0.49) {
00110     MSG("Photon",Msg::kError) << "Error: saw clipfrac less than 0.5: " << clippedfrac<< endl;
00111     clippedfrac = 0.5;
00112   }
00113  
00114   PlexStripEndId end[2];
00115   end[0] = inHit->StripEndId(); end[0].SetEnd(StripEnd::kNegative);
00116   end[1] = inHit->StripEndId(); end[1].SetEnd(StripEnd::kPositive);
00117 
00118   // Energy->MIP
00119   // Apply normalization and birks' constant.
00120   double emips = 
00121     clippedfrac                       // Light that didnt' leak out ends of strip                   
00122     * fOverallLightOutput             // Tuning parameter.
00123     * dE/(1. + fBirksConstant*dEdx)   // Birk's law
00124     / fGeVPerMip;                     // Convert from energy to mips
00125 
00126   
00127   // Useful for deugging:
00128   //MSG("Photon",Msg::kInfo) << "dE: " << dE << "  fGeVPerMip: " << fGeVPerMip << "  Birk suppress: " << 1.0/(1. + fBirksConstant*dEdx) << "  clippfrac: " << clippedfrac
00129   //     << " gives emips = " << emips << endl;
00130 
00131   const Calibrator& cal = Calibrator::Instance();
00132   // MIP->SigMap.  These two values should be the same (in principle)
00133   // but we may as well be pedantic.
00134   double sigmap[2] = {0,0};
00135   double sigcorr[2]= {0,0};
00136   double siglin[2] = {0,0};
00137   double adc[2]    = {0,0};
00138   double meanpe[2] = {0,0};
00139   double pe[2]     = {0,0};
00140   int npe[2]       = {0,0};
00141 
00142   if (ustrip.IsMirrored(StripEnd::kNegative) || ustrip.IsMirrored(StripEnd::kPositive) ) {
00143     // All of the energy goes to one end.
00144   } else {
00145     // The energy is split so that light goes both ways.
00146     emips *= 0.5;
00147   }
00148 
00149   for (int i=0;i<2;i++) {
00150     if ( ustrip.IsMirrored(end[i].GetEnd()) ) {
00151       // This end doesn't read out. Set the output to zero.
00152       sigmap[i] = sigcorr[i] = siglin[i] = pe[i] = 0;
00153       npe[i] = 0;
00154     } else {
00155       // Go through the decalibrtation chain:
00156 
00157       // Mips -> sigmaps.
00158       sigmap[i] =  cal.DecalMIP( emips , end[i]);
00159 
00160       // SigMap->SigCorr
00161       sigcorr[i] = cal.DecalAttenCorrected(sigmap[i],x,end[i]);
00162 
00163       // SigCorr->SigLin (siglin = ADCs for no drift, no linearity)
00164       siglin[i] = cal.DecalStripToStrip(sigcorr[i],end[i]);
00165 
00166       // SigLin->ADCs (Correct for drift. Linearity is applied during PMT simulation.)
00167       adc[i] = cal.DecalDrift(siglin[i],end[i]);
00168 
00169       // SigLin->Pe
00170       meanpe[i] = cal.GetPhotoElectrons(adc[i],end[i]);
00171 
00172       if (isnan(meanpe[i])) {
00173         MSG("Photon",Msg::kError) 
00174           << "Got an expectation value of NaN photons in CalibratedPeComputer.\n"
00175           << "\tHit on stripend " << end[i].AsString() << endl
00176           << "\tPosition: " << x << " m (in strip coords) " << endl
00177           << "\t" << dE/Munits::MeV  << " MeV,  "<< endl
00178           << "\t" << emips      << " MIP,   "<< endl
00179           << "\t" << sigmap[0]  << " / " << sigmap[1]  << " SigMap, "<< endl
00180           << "\t" << sigcorr[0] << " / " << sigcorr[1] << " SigCorr, "<< endl
00181           << "\t" << siglin[0]  << " / " << siglin[1]  << " SigLin, "<< endl
00182           << "\t" << adc[0]  << " / " << adc[1]  << " ADC, "<< endl
00183           << "\t" << meanpe[0]  << " / " << meanpe[1]  << " PE" << endl;
00184         outCount.SetPeNegPos(0,0); // Explicitly do nothing.  
00185         return false;              // and give up on this hit.
00186       }
00187 
00188       // Set to a poisson number about this mean.
00189       pe[i] = fRandom->PoissonD(meanpe[i]);
00190 
00191       // Handle some error conditions:
00192       if (isnan(pe[i])) {
00193         MSG("Photon",Msg::kError)
00194           << "Got a random poisson value of NaN photons in CalibratedPeComputer.\n"
00195           << "\tHit on stripend " << end[i].AsString() << endl
00196           << "\tPosition: " << x << " m (in strip coords) " << endl
00197           << "\t" << dE/Munits::MeV  << " MeV,  "<< endl
00198           << "\t" << emips      << " MIP,   "<< endl
00199           << "\t" << sigmap[0]  << " / " << sigmap[1]  << " SigMap, "<< endl
00200           << "\t" << sigcorr[0] << " / " << sigcorr[1] << " SigCorr, "<< endl
00201           << "\t" << siglin[0]  << " / " << siglin[1]  << " SigLin, "<< endl
00202           << "\t" << adc[0]  << " / " << adc[1]  << " ADC, "<< endl
00203           << "\t" << meanpe[0]  << " / " << meanpe[1]  << " PE" << endl;
00204         outCount.SetPeNegPos(0,0); // Explicitly do nothing.  
00205         return false;              // and give up on this hit.
00206       }
00207         
00208       if (pe[i] < 0) {
00209         MSG("Photon",Msg::kError) 
00210           << "Got -ve PEs on end " << i << endl
00211           << "\tHit on stripend " << end[i].AsString() << endl
00212           << "\tPosition: " << x << " m (in strip coords) " << endl
00213           << "\t" << dE/Munits::MeV  << " MeV,  "<< endl
00214           << "\t" << emips      << " MIP,   "<< endl
00215           << "\t" << sigmap[0]  << " / " << sigmap[1]  << " SigMap, "<< endl
00216           << "\t" << sigcorr[0] << " / " << sigcorr[1] << " SigCorr, "<< endl
00217           << "\t" << siglin[0]  << " / " << siglin[1]  << " SigLin, "<< endl
00218           << "\t" << adc[0]  << " / " << adc[1]  << " ADC, "<< endl
00219           << "\t" << meanpe[0]  << " / " << meanpe[1]  << " PE" << endl;
00220         pe[i] = 0;
00221       }
00222   
00223       if (pe[i] > fMaxPePerHit) {
00224         MSG("Photon",Msg::kError) 
00225           << "Got huge pulse on end " << i << endl
00226           << "\tHit on stripend " << end[i].AsString() << endl
00227           << "\tPosition: " << x << " m (strip coords) " << endl
00228           << "\t" << dE/Munits::MeV  << " MeV,  "<< endl
00229           << "\t" << emips      << " MIP,   "<< endl
00230           << "\t" << sigmap[0]  << " / " << sigmap[1]  << " SigMap, "<< endl
00231           << "\t" << sigcorr[0] << " / " << sigcorr[1] << " SigCorr, "<< endl
00232           << "\t" << siglin[0]  << " / " << siglin[1]  << " SigLin, "<< endl
00233           << "\t" << adc[0]  << " / " << adc[1]  << " ADC, "<< endl
00234           << "\t" << meanpe[0]  << " / " << meanpe[1]  << " PE" << endl
00235           << "\t ... Truncating to " << fMaxPePerHit << " pes." << endl;
00236         pe[i] = fMaxPePerHit;
00237       }
00238       npe[i] = (int) pe[i];
00239     }
00240   }
00241 
00242 
00243   // Set the output.
00244   outCount.SetPeNegPos( npe[0], npe[1] );
00245 
00246   /*
00247    // Consistency check. Disabled in production.
00248   float recomip[2];
00249   for (int i=0;i<2;i++) {
00250     float gain, width;
00251     cal.DecalGainAndWidth(gain, width, end[i]);
00252     float q = (float)(meanpe[i])*gain;
00253     q = cal.GetStripToStripCorrected(q,end[i]);
00254     q = cal.GetAttenCorrected(q,x,end[i]);
00255     q = cal.GetMIP(q,end[i]);
00256     recomip[i] = q;
00257   }
00258   MSG("Photon",Msg::kInfo) 
00259     << "Input mip: " << emips << "  Output: " << recomip[0] << "  " << recomip[1] << endl;
00260   */
00261 
00262   MSG("Photon",Msg::kDebug) << "CalibratedPeComputer: " 
00263                            << dE/Munits::MeV  << " MeV,  "
00264                            << emips << " MIP,   "
00265                            << sigmap[0] + sigmap[1] << " SigMap, "
00266                            << sigcorr[0] + sigcorr[1] << " SigCorr, "
00267                            << siglin[0] + siglin[1] << " SigLin, "
00268                            << meanpe[0] + meanpe[1] << " PE" 
00269                            << endl;
00270   MSG("Photon",Msg::kDebug) << "                      " 
00271                            << outCount.GetPe_Neg() 
00272                            << " (" << pe[0] << ") pe Neg   " 
00273                            << outCount.GetPe_Pos() 
00274                            << " (" << pe[1] << ") pe Pos" 
00275                            << endl;
00276 
00277   return true;
00278 }

void PhotonCalibratedPeComputer::Configure ( const Registry r  )  [virtual]

Reimplemented from PhotonTransportModule.

Definition at line 31 of file PhotonCalibratedPeComputer.cxx.

References fBirksConstant, fGeVPerMip, fMaxPePerHit, fOverallLightOutput, fScintillatorClipping, Registry::Get(), Msg::kDebug, Msg::kError, and MSG.

00032 {
00033   MSG("Photon",Msg::kDebug) << "Configuring CalibratedPeComputer." << std::endl;
00034 
00035   bool ok = true;
00036   ok = ok && r.Get("OverallLightOutput",fOverallLightOutput);
00037   ok = ok && r.Get("BirksConstant",fBirksConstant);
00038   ok = ok && r.Get("GeVPerMip",fGeVPerMip);
00039   ok = ok && r.Get("ScintillatorClipping",fScintillatorClipping);
00040   ok = ok && r.Get("MaxPePerHit",fMaxPePerHit);
00041   if (!ok) MSG("Photon",Msg::kError)
00042              << "Trouble configuring PhotonCalibratedPeComputer." << endl;
00043 }

void PhotonCalibratedPeComputer::Reset ( const VldContext cx  )  [virtual]

Reimplemented from PhotonTransportModule.

Definition at line 48 of file PhotonCalibratedPeComputer.cxx.

00049 {
00050 }


Member Data Documentation

Definition at line 32 of file PhotonCalibratedPeComputer.h.

Referenced by ComputePhotons(), and Configure().

Definition at line 33 of file PhotonCalibratedPeComputer.h.

Referenced by ComputePhotons(), and Configure().

Definition at line 35 of file PhotonCalibratedPeComputer.h.

Referenced by ComputePhotons(), and Configure().

Definition at line 31 of file PhotonCalibratedPeComputer.h.

Referenced by ComputePhotons(), and Configure().

Definition at line 34 of file PhotonCalibratedPeComputer.h.

Referenced by ComputePhotons(), and Configure().


The documentation for this class was generated from the following files:

Generated on 2 Nov 2017 for loon by  doxygen 1.6.1