SimVaTimedElectronics Class Reference

#include <SimVaTimedElectronics.h>

Inheritance diagram for SimVaTimedElectronics:
SimVaElectronics SimElectronics

List of all members.

Public Member Functions

 SimVaTimedElectronics (VldContext context, TRandom *random=NULL)
virtual ~SimVaTimedElectronics (void)
void Config (Registry &config)
void ReadoutDetector (SimPmtList &pmtList)
virtual void Print (Option_t *option) const

Protected Member Functions

 ClassDef (SimVaTimedElectronics, 1)

Protected Attributes

Double_t fVaShapingTime

Private Member Functions

void ReadoutVarc (std::vector< SimPmt * > &list)
void ReadoutPmt (SimPmt *pmt, Double_t dynodeTrigTime)

Detailed Description

Id
SimVaTimedElectronics.h,v 1.3 2004/08/25 18:05:28 tagg Exp

SimVAElectronics

Simple implimentation of the VA front-end.

n.tagg1@physics.ox.ac.uk

Definition at line 17 of file SimVaTimedElectronics.h.


Constructor & Destructor Documentation

SimVaTimedElectronics::SimVaTimedElectronics ( VldContext  context,
TRandom *  random = NULL 
)

Definition at line 15 of file SimVaTimedElectronics.cxx.

00016   : SimVaElectronics( context, random ),
00017     fVaShapingTime(500.*Munits::ns)
00018 {
00019 }

virtual SimVaTimedElectronics::~SimVaTimedElectronics ( void   )  [inline, virtual]

Definition at line 23 of file SimVaTimedElectronics.h.

00023 {};


Member Function Documentation

SimVaTimedElectronics::ClassDef ( SimVaTimedElectronics  ,
 
) [protected]

Reimplemented from SimElectronics.

void SimVaTimedElectronics::Config ( Registry config  )  [virtual]

Reimplemented from SimVaElectronics.

Definition at line 21 of file SimVaTimedElectronics.cxx.

References fVaShapingTime, and Registry::Get().

00022 {
00023   // Modify the configuration.
00024   //
00025   // Use this method to set static members with the class configuration.
00026   config.Get("vaShapingTime",fVaShapingTime);
00027   SimVaElectronics::Config(config);
00028 }

void SimVaTimedElectronics::Print ( Option_t *  option  )  const [virtual]

Reimplemented from SimVaElectronics.

Definition at line 293 of file SimVaTimedElectronics.cxx.

References fVaShapingTime, and Munits::ns.

00294 {
00295   SimVaElectronics::Print(option);
00296   printf("Timing:        fVaShapingTime        %f ns\n",fVaShapingTime/Munits::ns);
00297 } 

void SimVaTimedElectronics::ReadoutDetector ( SimPmtList pmtList  )  [virtual]

Reimplemented from SimVaElectronics.

Definition at line 31 of file SimVaTimedElectronics.cxx.

References SimVaElectronics::DynodeTrigger(), SimElectronics::fContext, SimVaElectronics::fVarcTriggerMode, RawChannelId::GetCrate(), SimPmt::GetDynodeCharge(), RawChannelId::GetElecType(), SimPmt::GetPixelSpotId(), PlexHandle::GetRawChannelId(), RawChannelId::GetVarcId(), RawChannelId::GetVmm(), it, SimVarcTriggerMode::k2of6, Msg::kDebug, ElecType::kVA, MSG, and ReadoutVarc().

00032 {
00033   PlexHandle plex(fContext);
00034   
00035   // For timing-cut version of varc pretrigger.
00036   std::map<int,std::vector<double> > varcTrigTimes;
00037   std::map<int,std::vector<double> >::iterator it;
00038   
00039   // Put our PMTs into pseudo-VARCs (vmms), then deal with each varc (or vmm).
00040   std::map<int,vector<SimPmt*> > varcs;
00041   std::map<int,vector<SimPmt*> >::iterator varcItr;
00042 
00043   SimPmtList::iterator PmtIt;
00044   for(PmtIt = pmtList.begin(); PmtIt!= pmtList.end(); PmtIt++)  {
00045     SimPmt* pmt = PmtIt->second;
00046     if(pmt) {
00047       RawChannelId rcid = plex.GetRawChannelId(pmt->GetPixelSpotId(1));
00048       if ( (rcid.GetElecType()==ElecType::kVA) ) {
00049         if(DynodeTrigger(pmt->GetDynodeCharge())>0.) { 
00050           // PMT has at least 1 trigger.
00051           int crate = rcid.GetCrate();
00052           int varc  = rcid.GetVarcId();
00053           int vmm   = rcid.GetVmm();
00054           int index = crate*100 + varc*10;
00055           if(fVarcTriggerMode == SimVarcTriggerMode::k2of6) {
00056             index += vmm;
00057           }
00058           varcs[index].push_back(pmt);
00059         }
00060       }
00061     }
00062   }
00063   
00064   // Now read out each varc.
00065   for(varcItr=varcs.begin();varcItr!=varcs.end();varcItr++) {
00066     // Start with the first 
00067     MSG("DetSim",Msg::kDebug) << "Reading out varc " << varcItr->first << endl;
00068     ReadoutVarc(varcItr->second);
00069   }
00070 }

void SimVaTimedElectronics::ReadoutPmt ( SimPmt pmt,
Double_t  dynodeTrigTime 
) [private]

Definition at line 185 of file SimVaTimedElectronics.cxx.

References SimElectronics::AddAdcsAfterFETrigger(), SimElectronics::AddAdcsAfterSpars(), SimElectronics::AddDigit(), SimElectronics::AddDigitsAfterFETrigger(), SimElectronics::AddDigitsAfterSpars(), SimElectronics::AddSignal(), PlexPixelSpotId::AsString(), RawChannelId::AsString(), SimPmtBucketIterator::BucketId(), SimPmt::BucketToStartTime(), SimPmt::BucketToStopTime(), SimPixelTimeBucket::CreateSignal(), SimPmtBucketIterator::End(), Munits::fC, SimElectronics::fContext, SimVaElectronics::fVaChipDeadTime, SimVaElectronics::fVaGain, fVaShapingTime, SimVaElectronics::fVaSparsifyThresh, SimVaElectronics::GenSimulatedADC(), SimVaElectronics::GenSimulatedTDC(), SimPmt::GetBucket(), SimPixelTimeBucket::GetCharge(), SimPmt::GetNumberOfPixels(), SimPmt::GetNumberOfSpots(), SimPixelTimeBucket::GetPEXtalk(), SimPmtTimeBucket::GetPixelBucket(), SimPmt::GetPixelSpotId(), PlexHandle::GetRawChannelId(), SimPmt::GetTotalCharge(), SimPmt::GetTotalHitPixels(), SimPmt::GetTubeId(), SimPmt::GetType(), RawChannelId::IsNull(), it, Msg::kDebug, Msg::kVerbose, DigiSignal::Merge(), MSG, and SimPmtBucketIterator::Next().

Referenced by ReadoutVarc().

00187 {
00188  MSG("DetSim",Msg::kDebug) << "SimVaTimedElectronics::ReadoutPmt " 
00189                            << pmt->GetTubeId().AsString() 
00190                            << " type " << pmt->GetType()
00191                            << " at time " << dynodeTrigTime
00192                            << endl;
00193 
00194   PlexHandle plex(fContext);
00195 
00196   // Interesting statistics:
00197   AddDigitsAfterFETrigger( pmt->GetTotalHitPixels(true) );
00198   AddAdcsAfterFETrigger( pmt->GetTotalCharge() * fVaGain );
00199  
00200   for(int ipixel = 1; ipixel<= pmt->GetNumberOfPixels(); ipixel++) {
00201     RawChannelId rcid = plex.GetRawChannelId(pmt->GetPixelSpotId(ipixel));
00202     
00203    int errorbits = 0;
00204 
00205     if(!(rcid.IsNull())) {
00206       //
00207       //  This stuff adds up all the buckets for a pixel into a single
00208       //  response. The charge is shaped by the VA shaping circuit.
00209       //
00210 
00211       DigiSignal* totalSignal = new DigiSignal();
00212       AddSignal(totalSignal);
00213 
00214       std::vector<Float_t> spotpe(pmt->GetNumberOfSpots()+1,0);
00215       
00216       // Find effective charge by convoluting signal with shaping curve.
00217       double qeff = 0;
00218       double qtot = 0;
00219       SimPmtBucketIterator it(*pmt);  
00220       for( ;  !it.End(); it.Next() ) { 
00221         int bucketId = it.BucketId(); 
00222         SimPmtTimeBucket& pmttb = pmt->GetBucket(bucketId);
00223         SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(ipixel);
00224 
00225         // Which spot was hit?
00226         for(int ispot=0;ispot<=pmt->GetNumberOfSpots();ispot++)
00227           spotpe[ispot]+=pixtb.GetPEXtalk(ispot);
00228         
00229         double dt = pmt->BucketToStartTime(bucketId) - dynodeTrigTime;
00230         
00231         // Skip buckets before this hit.
00232         if(pmt->BucketToStopTime(bucketId) <= dynodeTrigTime) continue;
00233         
00234         // Skip buckets that happen long after this hit.
00235         if(dt > fVaChipDeadTime) break;
00236         
00237         // Add the signal for this bucket.
00238         DigiSignal* signal = pixtb.CreateSignal();
00239         totalSignal->Merge(*signal);
00240         delete signal;
00241 
00242         double q = pixtb.GetCharge();    
00243         double resp = 1.0;
00244         if(dt>0) {
00245           // PHillip Litchfield tells me this is a good function form for the 
00246           // shaping of the VA circuit: t^2 exp(-2t/T)
00247           double t = dt+fVaShapingTime;
00248           resp = t*t*exp(-2*t/fVaShapingTime)/(fVaShapingTime*fVaShapingTime*exp(-2.0));      
00249         }
00250         qeff += q*resp;
00251         qtot += q;
00252       }
00253       
00254       MSG("DetSim",Msg::kDebug) << "Shaped readout of " << rcid.AsString() 
00255                                 << " TrueQ = " << qtot/Munits::fC
00256                                 << " fC.  Shaped Q = " << qeff/Munits::fC 
00257                                 << endl; 
00258 
00259       // Which spot was the best one for nonlinearity?
00260       int bigspot = 1;
00261       for(int ispot=1;ispot<=pmt->GetNumberOfSpots();ispot++)
00262         if(spotpe[ispot] > spotpe[bigspot]) bigspot = ispot;
00263 
00264       PlexPixelSpotId bestPsid = pmt->GetPixelSpotId(ipixel,bigspot);
00265 
00266       int adc = GenSimulatedADC( qeff, rcid, bestPsid );
00267       int tdc = GenSimulatedTDC( dynodeTrigTime, rcid );
00268       
00269       SimDigit d(  pmt->GetPixelSpotId(ipixel),
00270                    rcid,
00271                    adc,
00272                    tdc,
00273                    totalSignal,
00274                    errorbits
00275                    );
00276       MSG("DetSim",Msg::kVerbose) << "ReadoutPmt: " << d.AsString() << std::endl;    
00277 
00278       // Sparsify and record.
00279       if(d.GetADC() > fVaSparsifyThresh) { 
00280         AddDigit(d);
00281         
00282         // Stats:
00283         AddDigitsAfterSpars(1);
00284         AddAdcsAfterSpars(d.GetADC());
00285       }
00286     }
00287   }
00288 
00289 }

void SimVaTimedElectronics::ReadoutVarc ( std::vector< SimPmt * > &  list  )  [private]

Read out a complete varc (in the case of 2/36 trigger or no trigger) or vmm (in the case of 2/6 trigger)

Definition at line 72 of file SimVaTimedElectronics.cxx.

References SimPmtBucketIterator::BucketId(), SimVaElectronics::DynodeTrigger(), MuELoss::e, SimPmtBucketIterator::End(), SimVaElectronics::fVaChipDeadTime, SimVaElectronics::fVarcTriggerMode, SimVaElectronics::fVarcTriggerWindow, Msg::kDebug, SimVarcTriggerMode::kNone, MSG, SimPmtBucketIterator::Next(), Munits::ns, and ReadoutPmt().

Referenced by ReadoutDetector().

00073 {
00078   
00079   // Efficient precheck: there must be at least two pmts fired to make it go.
00080   if(fVarcTriggerMode != SimVarcTriggerMode::kNone) {
00081     if(pmts.size()<2) return; 
00082   };
00083 
00084 
00085   // Make a recording of when any dynode triggers happened.
00086 
00087   std::vector<double> vDynodeTimes;
00088   for(UInt_t i=0; i<pmts.size(); i++) {
00089     if(pmts[i]==0) continue; // Sanity check.
00090     
00091     // Go through all buckets in order.
00092     // Record dynode hits as they happen. No dead-chip time here, 
00093     // this is just when the ASD-Lite fires.
00094         
00095     double lastHitTime = -1e9;
00096 
00097     SimPmtBucketIterator bIt( *(pmts[i]) );
00098     for( ; !bIt.End(); bIt.Next() ) {
00099       Int_t bucket = bIt.BucketId();
00100       double bucketcharge = pmts[i]->GetDynodeCharge(bucket);
00101       if(DynodeTrigger(bucketcharge)) {
00102         double t = pmts[i]->GetDynodeTime(bucket);
00103         if((t-lastHitTime)>fVaChipDeadTime) {
00104           lastHitTime = t;
00105           vDynodeTimes.push_back(t);
00106           MSG("DetSim",Msg::kDebug) << "Dynode trigger at " << t << endl;
00107         }
00108       }
00109     }
00110   }
00111   
00112   // Now we can construct the varc trigger times.
00113 
00114   // Sort them.
00115   std::sort(vDynodeTimes.begin(),vDynodeTimes.end());
00116 
00117   // Vector of varc trigger times.
00118   std::vector<double> vVarcTrigTimes;
00119 
00120   if(fVarcTriggerMode != SimVarcTriggerMode::kNone) {
00121     for(UInt_t i=0; i<(vDynodeTimes.size() - 1); i++) {
00122       if((vDynodeTimes[i+1]-vDynodeTimes[i])<fVarcTriggerWindow) {
00123         vVarcTrigTimes.push_back(vDynodeTimes[i]);
00124       }
00125     }
00126   } else {
00127     // No trigger being asserted, so let everything sail through.
00128     vVarcTrigTimes = vDynodeTimes; 
00129   }
00130 
00131   // No go through the process again, looking for valid pmt triggers:
00132   for(UInt_t i=0; i<pmts.size(); i++) {
00133     if(pmts[i]==0) continue; // Sanity check.
00134     
00135     // Go through all buckets in order.
00136     // Do readouts as they happen, applying chip-recovery-time
00137     
00138     // Start off randomly dead, according to the formula given:
00139     double lastHitTime = -1e9;    
00140 
00141     SimPmtBucketIterator bIt( *(pmts[i]) );
00142     for( ; !bIt.End(); bIt.Next() ) {
00143       Int_t bucket = bIt.BucketId();
00144       double bucketcharge = pmts[i]->GetDynodeCharge(bucket);
00145       
00146       // Did it have enough charge to fire?
00147       if(DynodeTrigger(bucketcharge)) {
00148         double t = pmts[i]->GetDynodeTime(bucket);
00149 
00150         // Has it fired recently?
00151         if((t-lastHitTime)>fVaChipDeadTime) {
00152 
00153           // The chip was alive. 
00154           // Was there a valid varc trigger recently?
00155           bool fired = false;
00156           if(fVarcTriggerMode == SimVarcTriggerMode::kNone) {
00157             fired=true;
00158           }
00159           else {
00160             for(UInt_t j=0;j<vVarcTrigTimes.size();j++) {
00161               Double_t dt = t - vVarcTrigTimes[j];
00162               // if dt==0, we have the first hit that triggered the 2/36,
00163               // which should be read out. Use the "dt > -epsilon"
00164               // comparison to avoid using "==" with floats
00165               if ( ( dt > -1e-12 ) && ( dt < fVarcTriggerWindow ) ) {
00166                 fired = true;
00167               }
00168             }
00169           }
00170           if(fired) {
00171             MSG("DetSim",Msg::kDebug) << "Chip fired. " << t/Munits::ns << endl;
00172             lastHitTime = t;
00173             ReadoutPmt(pmts[i],t);                       
00174           }
00175         }
00176       }
00177     }
00178   }
00179   
00180   
00181 }


Member Data Documentation

Definition at line 36 of file SimVaTimedElectronics.h.

Referenced by Config(), Print(), and ReadoutPmt().


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

Generated on 22 Nov 2017 for loon by  doxygen 1.6.1