00001 #include "SimPmtM64Full.h"
00002 #include "SimPmtM64CrosstalkTable.h"
00003 #include "SimPmtMaker.h"
00004 #include "MessageService/MsgService.h"
00005
00006 CVSID("$Id: SimPmtM64Full.cxx,v 1.10 2007/03/01 17:22:11 rhatcher Exp $");
00007
00008 SimPmtMakerProxy<SimPmtM64Full> gSimPmtM64FullProxy("SimPmtM64Full");
00009
00010 ClassImp(SimPmtM64Full)
00011
00012 double SimPmtM64Full::fsChargeSlop = 1.6;
00013
00014 SimPmtM64Full::SimPmtM64Full(PlexPixelSpotId tube,
00015 VldContext context,
00016 TRandom* random ) :
00017 SimPmtM64(tube,context,random)
00018 {
00019
00020 }
00021
00022 Float_t SimPmtM64Full::PrevBucketFraction( Float_t dt )
00023 {
00024 Float_t x = dt/Munits::ns;
00025 if(x > 3./fsChargeSlop) return 0;
00026 Float_t sx = x*fsChargeSlop;
00027 const Float_t k1 = -13.*exp(-3.);
00028 Float_t retval = k1 + exp(-sx) *
00029 ( 1 + sx * ( 1 + sx*(0.5 + sx/6.) ) );
00030 if((retval<0)||(retval>1))
00031 MSG("DetSim",Msg::kError) << "Prev Bucket leakage returned nonphysical value! Report this bug!" << endl;
00032
00033 return retval;
00034 }
00035
00036 Float_t SimPmtM64Full::NextBucketFraction( Float_t dt )
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046 Float_t x = (dt/Munits::ns + 3./fsChargeSlop);
00047
00048 Float_t sx = fsChargeSlop*x;
00049 Float_t retval = exp(-sx) * ( 6. + sx*(6. + sx*(3. + sx) ) ) / 6.;
00050
00051 if((retval<0)||(retval>1))
00052 MSG("DetSim",Msg::kError) << "Prev Bucket leakage returned nonphysical value! Report this bug!" << endl;
00053
00054 return retval;
00055 }
00056
00057 void SimPmtM64Full::SimulateCharges()
00058 {
00059
00060
00061
00062
00063
00064
00065
00066
00067 fTotalCharge = 0;
00068
00069 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00070 Int_t bucket_id = it.BucketId();
00071 SimPmtTimeBucket& bucket = it.Bucket();
00072
00073 Float_t start_time = BucketToStartTime(bucket_id);
00074 Float_t stop_time = BucketToStopTime(bucket_id);
00075
00076
00077
00078 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00079 SimPixelTimeBucket& pixelBucket = bucket.GetPixelBucket(pix);
00080
00081
00082
00083
00084
00085
00086 if(pixelBucket.GetTotalPEXtalk() >0) {
00087
00088 SimPmtTimeBucket& nextBucket = GetBucket(bucket_id + 1);
00089 SimPixelTimeBucket& nextPixBucket = nextBucket.GetPixelBucket(pix);
00090 SimPmtTimeBucket& prevBucket = GetBucket(bucket_id - 1);
00091 SimPixelTimeBucket& prevPixBucket = prevBucket.GetPixelBucket(pix);
00092
00093 for(Int_t spot = 1; spot <= fNSpots; spot++) {
00094
00095
00096
00097
00098
00099
00100 SimPixelTimeBucket::PeList_t& pe_list =
00101 pixelBucket.GetDigiPEXtalk(spot);
00102
00103 float npe = pixelBucket.GetPEXtalk(spot);
00104 float qtot = GenChargeFromPE(pix,spot,npe);
00105 float q_per_pe = qtot/npe;
00106
00107 SimPixelTimeBucket::PeList_t::iterator pe_itr;
00108 for(pe_itr = pe_list.begin(); pe_itr!=pe_list.end(); pe_itr++) {
00109
00110 Float_t q = q_per_pe;
00111
00112
00113 Float_t frac_next = NextBucketFraction( stop_time - (pe_itr->first) );
00114 Float_t frac_prev = PrevBucketFraction( (pe_itr->first) - start_time );
00115 Float_t qnext = q* frac_next;
00116 Float_t qprev = q* frac_prev;
00117
00118
00119
00120 nextPixBucket.AddCharge( qnext );
00121 if(qnext > 1.0*Munits::fC)
00122 nextPixBucket.SetTruthBit(DigiSignal::kLeakFromPrevBucket);
00123
00124
00125
00126 prevPixBucket.AddCharge( qprev );
00127 if(qprev > 1.0*Munits::fC)
00128 prevPixBucket.SetTruthBit(DigiSignal::kLeakFromNextBucket);
00129
00130 pixelBucket.AddCharge( q - qnext - qprev );
00131 bucket.AddTotalCharge(q);
00132 fTotalCharge += q;
00133 }
00134 }
00135 }
00136 }
00137 }
00138 }
00139
00140
00141 void SimPmtM64Full::Config( Registry& config )
00142 {
00143 double dtmp;
00144 if(config.Get("pmtChargeSlop",dtmp)) fsChargeSlop = dtmp;
00145 SimPmtM64::Config(config);
00146 }