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

PhotonCalibratedBlueComputer.cxx

Go to the documentation of this file.
00001 #include "PhotonCalibratedBlueComputer.h"
00002 #include "PhotonTransportMaker.h"
00003 #include "PhotonUtil.h"
00004 #include "MessageService/MsgService.h"
00005 #include "UgliGeometry/UgliGeomHandle.h"
00006 #include "Calibrator/Calibrator.h"
00007 
00008 CVSID( " $Id: PhotonCalibratedBlueComputer.cxx,v 1.5 2006/12/01 20:12:11 rhatcher Exp $" );
00009 
00010 ClassImp(PhotonCalibratedBlueComputer)
00011 PhotonTransportMakerProxy<PhotonCalibratedBlueComputer>
00012         gPhotonCalibratedBlueComputerProxy("photonCalibratedBlueComputer"); 
00013 
00014 
00016 // Constructor
00017 PhotonCalibratedBlueComputer::PhotonCalibratedBlueComputer() 
00018 {
00019   Configure(PhotonConfiguration());
00020 }
00021 
00023 // Destructor
00024 PhotonCalibratedBlueComputer::~PhotonCalibratedBlueComputer()
00025 {
00026  
00027 }
00028 
00030 // Configure the model.
00031 void 
00032 PhotonCalibratedBlueComputer::Configure( const Registry& r )
00033 {
00034   MSG("Photon",Msg::kDebug) << "Configuring CalibratedBlueComputer." << std::endl;
00035 
00036   r.Get("OverallLightOutput",fOverallLightOutput);
00037   r.Get("BirksConstant",fBirksConstant);
00038   r.Get("ClearFibreAttenN1",fClearFibreAttenN1);
00039   r.Get("ClearFibreAttenN2",fClearFibreAttenN2);
00040   r.Get("ClearFibreAttenLength1",fClearFibreAttenLength1);
00041   r.Get("ClearFibreAttenLength2",fClearFibreAttenLength2);
00042  }
00043 
00045 // Reset the model.
00046 void 
00047 PhotonCalibratedBlueComputer::Reset( const VldContext&  )
00048 {
00049 }
00050 
00051 
00053 // Computes the number of photons we'll need to track for the 
00054 // hit. See the PhotonCount class for the various ways this
00055 // can be calculated.
00056 
00057 Bool_t 
00058 PhotonCalibratedBlueComputer::ComputePhotons( const DigiScintHit* inHit,
00059                                               Double_t inBluePrescale,
00060                                               Double_t inWlsPrescale,
00061                                               Double_t inGreenPrescale,
00062                                               PhotonCount& outCount )
00063 {
00064   // Number of photons made:
00065   if(!inHit) return false;
00066   double dE = inHit->DE();
00067   double dx = inHit->DS();
00068   double dEdx = dE/dx;
00069   
00070   double lightYield = ( 1/100.  // photons/eV
00071                         * 1e9 // GeV/ev
00072                         * inBluePrescale
00073                         * inWlsPrescale
00074                         * inGreenPrescale
00075                         * .0431 // fudge factor to tune to other methods.
00076                         );
00077   
00078 
00079   PlexStripEndId pos = inHit->StripEndId(); pos.SetEnd(StripEnd::kPositive);
00080   PlexStripEndId neg = inHit->StripEndId(); neg.SetEnd(StripEnd::kNegative);
00081         
00082   // Energy->MIP
00083   // Apply normalization and birks' constant.
00084   double mblue =  
00085     fOverallLightOutput             // Tuning parameter.
00086     * dE/(1. + fBirksConstant*dEdx) // Birk's law
00087     * lightYield;                   // photons/GeV
00088 
00089   const Calibrator& cal = Calibrator::Instance();
00090 
00091   // Now we need to adjust only for the strip-to-strip variation.
00092   // To get this, we ask for MIP correction, strip correction, 
00093   // and attenuation correction, but corrected to zero green fibre length
00094   // and zero clear fibre length.
00095   
00096   UgliGeomHandle ugli(fContext);
00097   UgliStripHandle ustrip = ugli.GetStripHandle(inHit->StripEndId());
00098   float greenLen[2];
00099   greenLen[0] = ustrip.GetHalfLength() + ustrip.WlsPigtail(StripEnd::kNegative);
00100   greenLen[1] = ustrip.GetHalfLength() + ustrip.WlsPigtail(StripEnd::kPositive);
00101 
00102   float clearLen[2];
00103   clearLen[0] = ustrip.ClearFiber(StripEnd::kNegative);
00104   clearLen[1] = ustrip.ClearFiber(StripEnd::kPositive);
00105 
00106   
00107   // Correct for MIPs (overall detector scale)
00108   double sigmap[2];
00109   sigmap[0] = cal.DecalMIP( mblue * 0.5, neg); // Send half the light left
00110   sigmap[1] = cal.DecalMIP( mblue * 0.5, pos); // and half to the right
00111 
00112   // Get the scintillator light output.
00113   
00114   // The following does a 'no correction' correction: it
00115   // tells you now much to correct for a hit at the very end of the WLS fibre.
00116   float sigcorr[2];
00117   sigcorr[0] = cal.DecalAttenCorrected(sigmap[0],-greenLen[0],neg);
00118   sigcorr[1] = cal.DecalAttenCorrected(sigmap[1], greenLen[1],pos);
00119 
00120 
00121   // Correct for clear fibre attenuation.. i.e. what if ethere were none.
00122   sigcorr[0]= sigcorr[0] / PhotonUtil::DoubleExp( clearLen[0], 
00123                                                   fClearFibreAttenN1,      fClearFibreAttenN2,
00124                                                   fClearFibreAttenLength1, fClearFibreAttenLength2 );
00125   sigcorr[1]= sigcorr[1] / PhotonUtil::DoubleExp( clearLen[1], 
00126                                                   fClearFibreAttenN1,      fClearFibreAttenN2,
00127                                                   fClearFibreAttenLength1, fClearFibreAttenLength2 );
00128   
00129   // SigCorr->SigLin (siglin = ADCs, because no drift, no linearity)
00130   double siglin[2];
00131   siglin[0] = cal.DecalStripToStrip(sigcorr[0],neg);
00132   siglin[1] = cal.DecalStripToStrip(sigcorr[1],pos);
00133   
00134   // Remove gain part of the strip-to-strip calibration.
00135   // These aren't really photo-electrons.
00136   double blue[2];
00137   blue[0] = cal.GetPhotoElectrons(siglin[0],neg);
00138   blue[1] = cal.GetPhotoElectrons(siglin[1],pos);
00139 
00140   // Half the photons go each way.
00141   if(isnan(blue[0])||isnan(blue[1])) {
00142     // Feh? How did this happen?
00143     MSG("Photon",Msg::kFatal) << "Got an expectation value of NaN photons in CalibratedBlueComputer.\n";
00144     outCount.SetPeNegPos(0,0); // Explicitly do nothing.  
00145     return false;
00146   }
00147   
00148   // Set to a poisson number about this mean.
00149   outCount.SetBlueNegPos( (int)fRandom->PoissonD(blue[0]),
00150                           (int)fRandom->PoissonD(blue[1])
00151                         );
00152     
00153   MSG("Photon",Msg::kInfo) << "CalibratedBlueComputer: " 
00154                            << dE/Munits::MeV  << " MeV,  "
00155                            << mblue << " Blue nominal,   "
00156                            << sigmap[0] + sigmap[1] << " SigMap, "
00157                            << sigcorr[0] + sigcorr[1] << " SigCorr, "
00158                            << siglin[0] + siglin[1] << " SigLin, "
00159                            << blue[0] + blue[1] << " PE" << endl;
00160   MSG("Photon",Msg::kInfo) << "                      " 
00161                            << outCount.GetBlue_Neg() 
00162                            << " (" << blue[0] << ") pe Neg" 
00163                            << outCount.GetBlue_Pos() 
00164                            << " (" << blue[1] << ") pe Pos" 
00165                            << endl;
00166   return true;
00167 
00168 }
00169 

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