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

SimPmtM64Full.cxx

Go to the documentation of this file.
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   // Constructor.
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   // Calculates the fraction of charge 
00039   // from a single PE peak that will leak into the 
00040   // next PMT bucket, if the next pmt bucket is time (x) from
00041   // the time of the PE hit.
00042 
00043   // Assumes a functional form of t*t*t*exp(-t*1.6), with t in ns. 
00044   // See NUMI-L-757
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   // This smushes charge into the next and previous QIE buckets.
00060   
00061   // It's assumed that digiPE occours at the peak of the pulse,
00062   // which has a shape of t^3 exp(-t*1.6).
00063   // Some of the charge gets put into the next and previous buckets.
00064   // Note that the truth info is lost: you will now get digits with 
00065   // no signal info... but that's the way it goes, I'm afraid.
00066 
00067   fTotalCharge = 0;
00068   // Iterate over all time buckets.
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     // Iterate over pixels.
00078     for(Int_t pix = 1; pix <= fNPixels; pix++) {      
00079       SimPixelTimeBucket& pixelBucket   = bucket.GetPixelBucket(pix);
00080       
00081       // Important: only look for next and prev buckets if there's 
00082       // something in here. The problem is that looking for the buckets
00083       // CREATES them, so if you always pull a ref to the next bucket,
00084       // the loop never exits.  But, if there is no work to do,
00085       // it doesn't create another bucket so we're safe.
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           // Time to do it right.         
00096           // Loop over all the DigiPEs in this spot. Generate a charge for each.
00097           // Then put some of that charge in the previous or next time buckets,
00098           // depending on when the DigiPE hit relative to this bucket.
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             // Generate a charge.
00110             Float_t q = q_per_pe;
00111             
00112             // How much charge goes into the next bucket?
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             // Add charge to next bucket, and set truth bits if there
00119             // is a non-trivial amount.
00120             nextPixBucket.AddCharge( qnext );
00121             if(qnext > 1.0*Munits::fC) 
00122               nextPixBucket.SetTruthBit(DigiSignal::kLeakFromPrevBucket);
00123 
00124             // Add charge to prev bucket, and set truth bits if there 
00125             // is a non-trivial amount.
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           } // pes
00134         } // spots
00135       } // if
00136     } // pixels
00137   } // buckets.
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); // call parent configuration.
00146 }

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