SimPmtM64 Class Reference

#include <SimPmtM64.h>

Inheritance diagram for SimPmtM64:
SimPmt SimPmtGenericM64 SimPmtM64Full SimPmtM64Oxford SimPmtM64ToyNL

List of all members.

Public Member Functions

 SimPmtM64 (PlexPixelSpotId tube, VldContext context, TRandom *random=NULL)
virtual ~SimPmtM64 ()
virtual void Reset (const VldContext &context)
virtual Pmt_t GetType () const
virtual void Print (Option_t *option="") const
virtual Int_t TimeToBucket (Double_t time)
virtual Double_t BucketToStartTime (Int_t bucket)
virtual Double_t BucketToStopTime (Int_t bucket)
virtual Float_t GetBucketDuration (Int_t bucket=0)
virtual Float_t GetDynodeGain () const
virtual void SimulateOpticalXtalk ()
virtual Float_t GenDarkNoiseCharge (Int_t pixel, Float_t timeWindow)
virtual Float_t GenNonlinearCharge (Int_t pixel, Float_t inCharge)
virtual Float_t GenChargeFromPE (Int_t pixel, Int_t spot, Float_t pe)
virtual Float_t GenElectricalCrosstalk (Int_t injPixel, Int_t xtalkPixel, Float_t injCharge)

Public Attributes

SimQieClock fQieClock
float fPixelGains [65]
float fPixelSecEmm [65]

Static Public Attributes

static SimPmtM64CrosstalkTablefsCrosstalkTable = NULL

Detailed Description

Definition at line 9 of file SimPmtM64.h.


Constructor & Destructor Documentation

SimPmtM64::SimPmtM64 ( PlexPixelSpotId  tube,
VldContext  context,
TRandom *  random = NULL 
)

Definition at line 16 of file SimPmtM64.cxx.

References Munits::g.

00018                               :
00019   SimPmt(tube,context,random,64,1),
00020   fQieClock(context)
00021 {
00022   // Constructor.
00023   
00024   // Single global reference to the crosstalk table.
00025   // This assumes that the crosstalk table has no validity 
00026   // changes; may need to change this in the future.
00027   //
00028   // Note that this is a global memory leak, too. Really should 
00029   // think about fixing it.
00030   if(fsCrosstalkTable == NULL) {
00031     fsCrosstalkTable = new SimPmtM64CrosstalkTable(context);
00032   };
00033 
00034 
00035   // Build cache of gains/widths.
00036   Double_t g, w;
00037   for(Int_t pix = 1; pix <= fNPixels; pix++) {      
00038     GetGainAndWidth(pix, 1, g, w);
00039     // Protect against crazy widths:
00040     if(w>0.8) w = 0.8;    
00041 
00042     // The secondary emmission ratio is directly related 
00043     // to the width of the 1pe peak.
00044     // In fact, this is 1/(w^2) where w is the fractional
00045     // width of the 1pe peak.
00046     Float_t secemm = 1.0/(w*w);  if(w>0.8) w = 0.8;
00047     
00048     fPixelGains[pix] = g; // Gain
00049     fPixelSecEmm[pix] = secemm; // secondary emmission ratio.
00050   };
00051 }

virtual SimPmtM64::~SimPmtM64 (  )  [inline, virtual]

Definition at line 15 of file SimPmtM64.h.

00015 {};


Member Function Documentation

Double_t SimPmtM64::BucketToStartTime ( Int_t  bucket  )  [virtual]

Reimplemented from SimPmt.

Definition at line 73 of file SimPmtM64.cxx.

References fQieClock, and SimQieClock::GetTimeOfBucket().

Referenced by SimPmtM64Oxford::SimulateAnodeEffects(), and SimPmtM64Full::SimulateCharges().

00074 {
00075   // Use the QIE clock to assign time buckets.
00076   return fQieClock.GetTimeOfBucket(bucket);
00077 }

Double_t SimPmtM64::BucketToStopTime ( Int_t  bucket  )  [virtual]

Reimplemented from SimPmt.

Definition at line 79 of file SimPmtM64.cxx.

References fQieClock, and SimQieClock::GetTimeOfBucket().

Referenced by SimPmtM64Oxford::SimulateAnodeEffects(), and SimPmtM64Full::SimulateCharges().

00080 {
00081   // Use the QIE clock to assign time buckets.
00082   return fQieClock.GetTimeOfBucket(bucket+1);
00083 }

Float_t SimPmtM64::GenChargeFromPE ( Int_t  pixel,
Int_t  spot,
Float_t  pe 
) [virtual]

Reimplemented from SimPmt.

Reimplemented in SimPmtM64Oxford.

Definition at line 128 of file SimPmtM64.cxx.

References Munits::e_SI, fPixelGains, fPixelSecEmm, Msg::kVerbose, MSG, and SimPmt::RandomGenPoisson().

Referenced by SimPmtM64Full::SimulateCharges().

00129 {
00130   //
00131   // Does a single charge simulation.
00132   //
00133   
00134   // First version, by Nathaniel.
00135   // Uses the generalized poisson to get the job done.
00136 
00137   // Shortcut: saves a lot of unneccessary random number generation.
00138   // Note that there is no intrinsic charge resolution in the PMT
00139   // with this method.
00140   if(pe<=0) return 0;
00141 
00142   Float_t gain = fPixelGains[pixel];
00143   Float_t secemm = fPixelSecEmm[pixel];
00144 
00145   // Choose a random number from the spectrum with a peak at the number of expected 2nary pes.
00146   Float_t mean2ndaryPe = pe * secemm;
00147   Float_t secondary_pe = RandomGenPoisson(mean2ndaryPe);
00148 
00149   MSG("DetSim",Msg::kVerbose) << "Rolled: " << pe << " pe -> " << secondary_pe / secemm << " charge" << " with " << gain << " gain" << endl;
00150 
00151   // convert this into charge.
00152   Float_t q = (secondary_pe / secemm)  // charge in pe at anode
00153     * gain                        // Gain of pixel (unitless)
00154     * Munits::e_SI;               // e to charge
00155   
00156   return q;
00157 }

Float_t SimPmtM64::GenDarkNoiseCharge ( Int_t  pixel,
Float_t  timeWindow 
) [virtual]

Reimplemented from SimPmt.

Definition at line 159 of file SimPmtM64.cxx.

00160 {
00161   //
00162   // Dark noise simulation.
00163   //
00164   // Return the charge (in fC) that results from opening an integration gate of duration timeWindow (in Munits).
00165   // (This should return zero most of the time).
00166   //
00167   
00168   // No simulation yet.
00169   return 0; 
00170 }

Float_t SimPmtM64::GenElectricalCrosstalk ( Int_t  injPixel,
Int_t  xtalkPixel,
Float_t  injCharge 
) [virtual]

Reimplemented from SimPmt.

Definition at line 263 of file SimPmtM64.cxx.

References Munits::fC, SimPmtM64CrosstalkTable::fElecFrac, SimPmtM64CrosstalkTable::fElecK, SimPmt::fRandom, fsCrosstalkTable, and SimPmt::fsPmtScaleChargeCrosstalk.

00265 {
00266   //
00267   // Electrical crosstalk simulation.
00268   //
00269   // If inCharge femtoCoulombs of charge are seen on the anode of injPixel, then
00270   // this returns the quantity of charge that will be leaked to xtalkPixel.
00271   // This may be a random quantity, or a fixed fraction, depending on the model.
00272 
00273   // If no charge, do nothing:
00274   if(injCharge <= 0) return 0;
00275 
00276   float frac = fsCrosstalkTable->fElecFrac[injPixel][xPixel];
00277   float k    = fsCrosstalkTable->fElecK[injPixel][xPixel];
00278 
00279   frac *= fsPmtScaleChargeCrosstalk;
00280 
00281   // A fraction of the charge leaks.
00282   float charge = frac*injCharge;
00283   
00284   // The fraction might be variable, rather than constant.
00285   // If so, choose it from a distribution of width
00286   // proportional to the square root of the charge.
00287 
00288   // Don't bother with variability if it won't matter at the ~ 2 ADC level.
00289   const float kMinVariance2 = (2.0*Munits::fC)*(2.0*Munits::fC);
00290 
00291   float width2 = fabs(k*charge);
00292   if(width2 > kMinVariance2 ){
00293     float width = sqrt(width2); 
00294     return fRandom->Gaus(charge,width);
00295   };
00296 
00297   return charge;
00298 }

Float_t SimPmtM64::GenNonlinearCharge ( Int_t  pixel,
Float_t  inCharge 
) [virtual]

Reimplemented from SimPmt.

Reimplemented in SimPmtM64Oxford, and SimPmtM64ToyNL.

Definition at line 173 of file SimPmtM64.cxx.

00175 {
00176   //
00177   // Nonlinearity Simulation.
00178   //
00179   // Given a charge on the anode, this routine applies
00180   // the nonlinearity for the PMT to give a new output charge.
00181   // 
00182   // For a completely linear response, return inCharge.
00183   
00184   return inCharge; 
00185 }

Float_t SimPmtM64::GetBucketDuration ( Int_t  bucket = 0  )  [virtual]

Reimplemented from SimPmt.

Definition at line 86 of file SimPmtM64.cxx.

References SimQieClock::fNDTick, and fQieClock.

00087 {
00088   return fQieClock.fNDTick;
00089 }

virtual Float_t SimPmtM64::GetDynodeGain (  )  const [inline, virtual]

Reimplemented from SimPmt.

Definition at line 29 of file SimPmtM64.h.

00029 { return 0.8; }; // Gain relative to anode.

virtual Pmt_t SimPmtM64::GetType (  )  const [inline, virtual]

Reimplemented from SimPmt.

Definition at line 19 of file SimPmtM64.h.

References SimPmt::kM64.

00019 { return SimPmt::kM64; };

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

Reimplemented from SimPmt.

Definition at line 91 of file SimPmtM64.cxx.

References PlexPixelSpotId::AsString(), Munits::fC, SimPmt::fTube, SimPmt::GetCharge(), SimPmt::GetPe(), and it.

00092 {
00093   printf("  SimPmtM64::Print()  -- Tube: %s\n",fTube.AsString("t"));
00094   
00095   SimPmtBucketIterator it(*(SimPmt*)this);
00096   printf("      Photoelectrons(Npe)                        Charge (fC)   \n");
00097   for( ; !it.End(); it.Next() ) {
00098     int ibucket = it.BucketId();
00099     printf("  ---------------------------Time bucket %d----------------------\n",ibucket);
00100     for(int row=0; row < 8; row++) {
00101       printf("  %3.0f %3.0f %3.0f %3.0f %3.0f %3.0f %3.0f %3.0f",
00102              GetPe(row*8+1,1,ibucket),
00103              GetPe(row*8+2,1,ibucket),
00104              GetPe(row*8+3,1,ibucket),
00105              GetPe(row*8+4,1,ibucket),
00106              GetPe(row*8+5,1,ibucket),
00107              GetPe(row*8+6,1,ibucket),
00108              GetPe(row*8+7,1,ibucket),
00109              GetPe(row*8+8,1,ibucket));
00110       
00111       printf(" |  %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f %5.0f",
00112              GetCharge(row*8+1,ibucket)/Munits::fC, 
00113              GetCharge(row*8+2,ibucket)/Munits::fC,
00114              GetCharge(row*8+3,ibucket)/Munits::fC,
00115              GetCharge(row*8+4,ibucket)/Munits::fC,
00116              GetCharge(row*8+5,ibucket)/Munits::fC,
00117              GetCharge(row*8+6,ibucket)/Munits::fC,
00118              GetCharge(row*8+7,ibucket)/Munits::fC,
00119              GetCharge(row*8+8,ibucket)/Munits::fC);
00120       
00121       printf("\n");
00122     }
00123   }
00124   printf("\n");
00125 }

void SimPmtM64::Reset ( const VldContext context  )  [virtual]

Reimplemented from SimPmt.

Reimplemented in SimPmtM64Oxford.

Definition at line 53 of file SimPmtM64.cxx.

References fQieClock, fsCrosstalkTable, SimPmtM64CrosstalkTable::Reset(), and SimQieClock::Reset().

00054 {
00055   // Reset the PMT for a new event.
00056   // Reset the clock:
00057   fQieClock.Reset(context);
00058 
00059   // Make sure database is up-to-date
00060   if(fsCrosstalkTable) fsCrosstalkTable->Reset(context);
00061   else fsCrosstalkTable = new SimPmtM64CrosstalkTable(context);
00062   // Reset the data:
00063   SimPmt::Reset(context);
00064 
00065 }

void SimPmtM64::SimulateOpticalXtalk (  )  [virtual]

Reimplemented from SimPmt.

Definition at line 189 of file SimPmtM64.cxx.

References SimPmt::CopyPEtoPEXtalk(), SimPmt::fNPixels, SimPmtM64CrosstalkTable::fOptTotProb, SimPmt::fRandom, fsCrosstalkTable, SimPmt::fsPmtScaleOpticalCrosstalk, SimPixelTimeBucket::GetPE(), SimPmtTimeBucket::GetPixelBucket(), it, DigiSignal::kCrosstalkOptical, Msg::kWarning, SimPmt::MoveOpticalPE(), MSG, and SimPixelTimeBucket::SetTruthBit().

Referenced by SimPmtM64Oxford::SimulatePmt().

00190 {
00191   //
00192   // Puts extra PE into pixels they don't belong.
00193   //
00194  
00195   // Hack!
00196   // This can be uncommented to make a big dump file of the crosstalk.
00197   //static ofstream ofile("m64xtalk.dat");
00198 
00199   // Iterate over all time buckets.
00200   for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00201     SimPmtTimeBucket& pmttb = it.Bucket();
00202 
00203     // Iterate over talking pixels.
00204     for(Int_t injPix = 1; injPix <= fNPixels; injPix++) {      
00205       SimPixelTimeBucket& pixtb_inj = pmttb.GetPixelBucket(injPix);
00206         
00207       // Only one spot (spot 1) per pixel.
00208       
00209       float injPE = pixtb_inj.GetPE(1);
00210       if( injPE > 0) { // There is charge in this spot.
00211 
00212           // Roll how many pe get crosstalked out of this pixel.
00213 
00214           float prob = fsCrosstalkTable->fOptTotProb[injPix];
00215           prob *= fsPmtScaleOpticalCrosstalk;         // Scale factor.
00216           float ttalk = fRandom->Poisson(prob*injPE); // Number of photons talked out
00217           int   ntalk = TMath::Nint(ttalk);           // ditto, as an integer
00218 
00219           for(int ipe=0;ipe<ntalk;ipe++) {
00220             // Move the photons around.
00221             
00222             // Choose the talked-to pixel.
00223             int whichPix = injPix;
00224             float r = fRandom->Uniform();
00225             for(Int_t xPix = 1; xPix <= fNPixels; xPix++) {      
00226               if(r<fsCrosstalkTable->fOptDist[injPix][xPix]) { 
00227                 whichPix=xPix; 
00228                 break;
00229                 }
00230             }
00231             if(whichPix==injPix){
00232               MSG("DetSim",Msg::kWarning) << "Random number error choosing xtalk pixel.";
00233               continue;
00234             }
00235             
00236             // Debugging hack continued.
00237             //ofile << injPix << "\t" 
00238             //      << xpix << "\t" << pixtb_inj.GetPE(injSpot) << endl;
00239             
00240             SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(whichPix);
00241 
00242             // Move a photoelectron.
00243             MoveOpticalPE(1,  // move 1 pe
00244                           pixtb_inj,1,   // from pix, spot
00245                           pixtb,    1 ); // to pix, spot
00246             
00247             pixtb.SetTruthBit(DigiSignal::kCrosstalkOptical);
00248 
00249           } // Itr over talked pe 
00250          
00251         }
00252     } // Itr over inj pixel
00253      
00254     // Now we're done with all pixels in the bucket.
00255   } // it over buckets
00256   // whew!
00257   
00258   // Copy whatever didn't crosstalk.
00259   CopyPEtoPEXtalk();
00260 }

Int_t SimPmtM64::TimeToBucket ( Double_t  time  )  [virtual]

Reimplemented from SimPmt.

Definition at line 67 of file SimPmtM64.cxx.

References fQieClock, and SimQieClock::GetBucketForTime().

00068 {
00069   // Use the QIE clock to assign time buckets.
00070   return fQieClock.GetBucketForTime(time);
00071 }


Member Data Documentation

Definition at line 43 of file SimPmtM64.h.

Referenced by GenChargeFromPE().

Definition at line 44 of file SimPmtM64.h.

Referenced by GenChargeFromPE().

Definition at line 47 of file SimPmtM64.h.

Referenced by GenElectricalCrosstalk(), Reset(), and SimulateOpticalXtalk().


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

Generated on 21 Oct 2017 for loon by  doxygen 1.6.1