SimVaElectronics Class Reference

#include <SimVaElectronics.h>

Inheritance diagram for SimVaElectronics:
SimElectronics SimVaTimedElectronics

List of all members.

Public Member Functions

 SimVaElectronics (VldContext context, TRandom *random=NULL)
virtual ~SimVaElectronics (void)
virtual void ReadoutDetector (SimPmtList &fPmtList)
virtual void Print (Option_t *option="") const
virtual void Config (Registry &config)
void ReadoutPmt (SimPmt *pmt, bool trig, bool isdead)
Bool_t DynodeTrigger (double dynCharge)
int GenSimulatedADC (double inCharge, const RawChannelId &rcid, const PlexPixelSpotId &psid)
int GenSimulatedTDC (double inTime, const RawChannelId &rcid)

Protected Member Functions

 ClassDef (SimVaElectronics, 0)

Protected Attributes

Double_t fVaGain
Double_t fVaPedWidth
Int_t fTimeSmearingMode
Double_t fTimingWidth
Int_t fVaSparsifyThresh
Int_t fVaDynodeThresh
Int_t fVaNonlinearity
Double_t fVaLinearityP0
Double_t fVaLinearityP1
Double_t fVaLinearityP2
Double_t fVaLinearityP3
Double_t fVaLinearityP4
Int_t fVarcTriggerMode
Double_t fVarcTriggerWindow
Double_t fVaChipRandomDeadRate
Double_t fVaChipDeadTime
Int_t fDoLookupNonlinearity
const CalVaLinearityfCalVaLinearity

Detailed Description

Definition at line 43 of file SimVaElectronics.h.


Constructor & Destructor Documentation

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

Definition at line 17 of file SimVaElectronics.cxx.

SimVaElectronics::~SimVaElectronics ( void   )  [virtual]

Definition at line 46 of file SimVaElectronics.cxx.

References fCalVaLinearity.

00047 {
00048   if(fCalVaLinearity) delete fCalVaLinearity;
00049 }


Member Function Documentation

SimVaElectronics::ClassDef ( SimVaElectronics  ,
 
) [protected]
void SimVaElectronics::Config ( Registry config  )  [virtual]

Reimplemented from SimElectronics.

Reimplemented in SimVaTimedElectronics.

Definition at line 343 of file SimVaElectronics.cxx.

References fCalVaLinearity, fDoLookupNonlinearity, fTimeSmearingMode, fTimingWidth, fVaChipDeadTime, fVaChipRandomDeadRate, fVaDynodeThresh, fVaGain, fVaLinearityP0, fVaLinearityP1, fVaLinearityP2, fVaLinearityP3, fVaLinearityP4, fVaNonlinearity, fVaPedWidth, fVarcTriggerMode, fVarcTriggerWindow, fVaSparsifyThresh, Registry::Get(), Msg::kWarning, and MSG.

00344 {
00345   // Modify the configuration.
00346   //
00347   // Use this method to set static members with the class configuration.
00348   config.Get("vaGain",fVaGain);
00349   config.Get("vaPedWidth",fVaPedWidth);
00350   config.Get("vaTimeSmearingMode",fTimeSmearingMode);
00351   config.Get("vaTimingWidth",fTimingWidth);
00352   config.Get("vaSparsifyThresh",fVaSparsifyThresh);
00353   config.Get("vaDynodeThresh",fVaDynodeThresh);
00354   config.Get("vaNonlinearity",fVaNonlinearity);
00355   config.Get("vaLinearityP0",fVaLinearityP0);
00356   config.Get("vaLinearityP1",fVaLinearityP1);
00357   config.Get("vaLinearityP2",fVaLinearityP2);
00358   config.Get("vaLinearityP3",fVaLinearityP3);
00359   config.Get("vaLinearityP4",fVaLinearityP4);  
00360   config.Get("varcTriggerMode",fVarcTriggerMode);
00361   config.Get("varcTriggerWindow",fVarcTriggerWindow);
00362   config.Get("vaChipRandomDeadRate",fVaChipRandomDeadRate);
00363   config.Get("vaChipDeadTime",fVaChipDeadTime);
00364   config.Get("doLookupNonlinearity",fDoLookupNonlinearity);
00365   
00366   if(fCalVaLinearity) delete fCalVaLinearity;
00367   fCalVaLinearity = new CalVaLinearity(RawChannelId(),
00368                                        fVaLinearityP0,
00369                                        fVaLinearityP1,
00370                                        fVaLinearityP2,
00371                                        fVaLinearityP3,
00372                                        fVaLinearityP4
00373                                        );
00374 
00375   if(fVaSparsifyThresh<=0) 
00376     MSG("DetSim",Msg::kWarning) << "WARNING: The VA sparsification threshold " << std::endl
00377                                 << "         is less than zero!" << std::endl;                 
00378   SimElectronics::Config(config);
00379 }

Bool_t SimVaElectronics::DynodeTrigger ( double  dynCharge  ) 

Definition at line 236 of file SimVaElectronics.cxx.

References fVaDynodeThresh, and fVaGain.

Referenced by SimVaTimedElectronics::ReadoutDetector(), ReadoutDetector(), and SimVaTimedElectronics::ReadoutVarc().

00237 {
00238   // Returns true if the PMT would fire the dynode trigger.
00239   
00240   // ASDLite DAC setttings: (snip email by Roy Lee)
00241   //The DAC setting for FD dynode thresholds go from 63 (no threshold) to 0
00242   //(maximum thresold), where the maximum corresponds to 160 fC +- 10%,
00243   //assuming linearity over full scale.
00244 
00245   // According to Alfons, from dynode trigger scans, 1 dynode trigger count ~= 2.4 ADC counts.
00246   // Remember that the charge on the dynode is 0.8 of the charge on the anode, so 
00247   // the the maximum corresponds to 63 * 2.4 * 0.8 ADCs.
00248 
00249   // These two numbers seem to disagree. This is resolved because Roy forgot to mention that the
00250   // dynode charge is split into TWO capacitors on the base, so the trigger level of the ASDLite
00251   // is effectively 1/2 of what he said.
00252 
00253   // Thus, the full-scale trigger threshold is 322 fC (dynode) or ~160 fC (on the asdlite cap)
00254   
00255   // Threshold for max settting:
00256   const float kThresh0 = 63.0 * 2.4 *0.8 /(fVaGain); // fC
00257   
00258   double thresh = (double)(63 - fVaDynodeThresh)/63. * kThresh0;
00259 
00260   if(dynCharge > thresh) return true;
00261   else return false;
00262 }

int SimVaElectronics::GenSimulatedADC ( double  inCharge,
const RawChannelId rcid,
const PlexPixelSpotId psid 
)

Definition at line 264 of file SimVaElectronics.cxx.

References Calibrator::DecalLinearity(), fCalVaLinearity, SimElectronics::fContext, fDoLookupNonlinearity, SimElectronics::fRandom, fVaGain, fVaNonlinearity, fVaPedWidth, PlexHandle::GetStripEndId(), Calibrator::Instance(), PlexStripEndId::IsValid(), and CalVaLinearity::UnLinearize().

Referenced by ReadoutPmt(), and SimVaTimedElectronics::ReadoutPmt().

00267 {
00268   // Apply nonlinearity.
00269   double adc = inCharge * fVaGain;
00270 
00271   if(fDoLookupNonlinearity) {
00272     PlexHandle plex(fContext);
00273     PlexStripEndId seid = plex.GetStripEndId(psid);
00274     if(seid.IsValid()) {
00275       adc = Calibrator::Instance().DecalLinearity(adc, seid);
00276     }
00277   }
00278   else if(fVaNonlinearity) {
00279     if(adc > 16384) adc = 16384; // Truncate to region where UnLinearize doesn't work.
00280     adc = fCalVaLinearity->UnLinearize(adc);
00281   }
00282 
00283   double x = fRandom->Gaus(adc, fVaPedWidth);
00284   return (int)(TMath::Floor(x));
00285 }

int SimVaElectronics::GenSimulatedTDC ( double  inTime,
const RawChannelId rcid 
)

Definition at line 287 of file SimVaElectronics.cxx.

References SimElectronics::fRandom, fTimeSmearingMode, fTimingWidth, Calibrator::GetTDCFromTime(), Calibrator::Instance(), SimTimeSmearingMode::kBreitWigner, SimTimeSmearingMode::kGaussian, kPmtTime_Never, SimTimeSmearingMode::kUniform, Msg::kWarning, MSG, and Munits::ns.

Referenced by ReadoutPmt(), and SimVaTimedElectronics::ReadoutPmt().

00288 {
00289   
00290   // VA electronics, tick = 1.5625 ns (640MHz)
00291   if(inTime>=kPmtTime_Never) {
00292     MSG("DetSim",Msg::kWarning) << "GenSimulatedTDC got a hit with a PMT that never fired!" << endl;
00293     // Return a false number so this hit doesn't correlate with anything real.
00294     return 650000000;
00295   }
00296 
00297   // smear the raw time by fTimingWidth (in nanoseconds)
00298   double deltaTime = 0.0;
00299   if( fTimeSmearingMode>0 && fTimingWidth>0.0 ) {
00300 
00301     // smearing with Breit-Wigner function
00302     if( fTimeSmearingMode==SimTimeSmearingMode::kBreitWigner ){
00303       deltaTime = ( fRandom->BreitWigner( 0.0, fTimingWidth ) )*Munits::ns;
00304     }
00305 
00306     // smearing with Gaussian function
00307     else if( fTimeSmearingMode==SimTimeSmearingMode::kGaussian ){
00308       deltaTime = ( fRandom->Gaus( 0.0, fTimingWidth ) )*Munits::ns;
00309     }
00310 
00311     // smearing with Uniform function
00312     else if( fTimeSmearingMode==SimTimeSmearingMode::kUniform ){
00313       deltaTime = ( fRandom->Uniform( -fTimingWidth, +fTimingWidth ) )*Munits::ns;
00314     }
00315     
00316   }
00317 
00318   //const double tdc_convert = 1.0/1.5625e-9;
00319   double x = Calibrator::Instance().GetTDCFromTime(inTime+deltaTime,rcid);
00320 
00321   return (int)(TMath::Floor(x));
00322 }

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

Reimplemented from SimElectronics.

Reimplemented in SimVaTimedElectronics.

Definition at line 325 of file SimVaElectronics.cxx.

References Munits::fC, fDoLookupNonlinearity, fTimingWidth, fVaChipDeadTime, fVaChipRandomDeadRate, fVaDynodeThresh, fVaGain, fVaLinearityP0, fVaLinearityP1, fVaLinearityP2, fVaLinearityP3, fVaLinearityP4, fVaNonlinearity, fVaPedWidth, fVarcTriggerMode, fVarcTriggerWindow, fVaSparsifyThresh, and Munits::microsecond.

00326 {
00327   printf("VA Front End:  vaGain               %f ADC/fC\n",fVaGain*Munits::fC);
00328   printf("               vaPedWidth           %f ADCs\n",fVaPedWidth);
00329   printf("               vaTimingWidth        %f ns\n",fTimingWidth);
00330   printf("               vaSparsifyThresh     %d ADCs\n",fVaSparsifyThresh);
00331   printf("               vaDynodeThresh       %d DACs\n",fVaDynodeThresh);
00332   printf("               vaNoninearity        %d (%s)\n",fVaNonlinearity,(fVaNonlinearity)?"Nonlinear":"Linear");
00333   printf("               vaLinearityParams:   %f %.1f %.1f %.1f %.1f\n",fVaLinearityP0, fVaLinearityP1,fVaLinearityP2,fVaLinearityP3,fVaLinearityP4);
00334   printf("VA Back End:   varcTriggerMode      %d (0=none, 1=2/6, 2=2/36)\n",fVarcTriggerMode);
00335   printf("               varcTriggerWindow    %f ns\n",fVarcTriggerWindow);
00336   printf("               vaChipRandomDeadRate %f Hz\n",fVaChipRandomDeadRate);
00337   printf("               vaChipDeadTime       %f us\n",fVaChipDeadTime/Munits::microsecond);
00338   printf("               doLookupNonlinearity  %s \n",fDoLookupNonlinearity?("on"):("off") );
00339 
00340 } 

void SimVaElectronics::ReadoutDetector ( SimPmtList fPmtList  )  [virtual]

Reimplemented from SimElectronics.

Reimplemented in SimVaTimedElectronics.

Definition at line 52 of file SimVaElectronics.cxx.

References DynodeTrigger(), SimElectronics::fContext, SimElectronics::fRandom, fVaChipDeadTime, fVaChipRandomDeadRate, fVarcTriggerMode, fVarcTriggerWindow, RawChannelId::GetCrate(), SimPmt::GetDynodeCharge(), SimPmt::GetDynodeTime(), RawChannelId::GetElecType(), SimPmt::GetPixelSpotId(), PlexHandle::GetRawChannelId(), RawChannelId::GetVarcId(), RawChannelId::GetVmm(), it, SimVarcTriggerMode::k2of6, SimVarcTriggerMode::kNone, ElecType::kVA, and ReadoutPmt().

00053 {
00054   PlexHandle plex(fContext);
00055 
00056   // For timing-cut version of varc pretrigger.
00057   std::map<int,std::vector<double> > varcTrigTimes;
00058   std::map<int,std::vector<double> >::iterator it;
00059   
00060   // For Dead Chips.
00061   std::map<int,bool> deadChips;
00062   
00063   // Do the dead chips:
00064   if(fVaChipRandomDeadRate>0.) { // don't bother if turned off
00065     SimPmtList::iterator PmtIt;
00066     for(PmtIt = pmtList.begin(); PmtIt!= pmtList.end(); PmtIt++)  {
00067       // how likely is this pmt to be dead at this time?
00068       // Ignores finite event length
00069       double deadProb = fVaChipRandomDeadRate*fVaChipDeadTime;
00070       // Roll the dice:
00071       bool isDead = false;
00072       if(fRandom->Rndm()<deadProb) isDead = true;
00073       // Remember this result:
00074       deadChips[PmtIt->first] = isDead;
00075     }
00076   }
00077 
00078   Int_t  crate, varc, vmm;
00079   
00080   if(fVarcTriggerMode != SimVarcTriggerMode::kNone) {    
00081     // First pass: find dynode trigger times
00082     
00083     SimPmtList::iterator PmtIt;
00084     for(PmtIt = pmtList.begin(); PmtIt!= pmtList.end(); PmtIt++)  {
00085       SimPmt* pmt = PmtIt->second;
00086       if(pmt) {
00087         // Make sure the PMT reads out to VA electronics:
00088         RawChannelId rcid = plex.GetRawChannelId(pmt->GetPixelSpotId(1));
00089         if ( (rcid.GetElecType()==ElecType::kVA) ) {
00090 
00091           // Apply dynode trigger; don't read out if below thresh.
00092           // Don't read out if dead chip, either.
00093           if((DynodeTrigger(pmt->GetDynodeCharge())) && (!deadChips[PmtIt->first])) {
00094             crate = rcid.GetCrate();
00095             varc  = rcid.GetVarcId();
00096             vmm   = rcid.GetVmm();
00097             
00098             // Compose a unique index for this varc (or vmm)
00099             int index = crate*100 + varc*10;
00100             if(fVarcTriggerMode == SimVarcTriggerMode::k2of6) {
00101               index += vmm;
00102             }
00103             
00104             Double_t time = pmt->GetDynodeTime();
00105             varcTrigTimes[index].push_back(time);
00106           }
00107         }      
00108       }
00109     }
00110         
00111     // For each varc or vmm:
00112     for(it = varcTrigTimes.begin(); it!=varcTrigTimes.end(); it++) {
00113       sort(it->second.begin(),it->second.end()); // Sort the trigger times.
00114       // Debugging output...
00115       //for(UInt_t i=0;i<it->second.size();i++) {
00116       //        cout << it->first << "\t" 
00117       //             << it->second[i]*1e9 << endl;
00118       //}
00119     }    
00120   }
00121   
00122 
00123   // Apply pretrigger and read out
00124   SimPmtList::iterator PmtIt;
00125   for(PmtIt = pmtList.begin(); PmtIt!= pmtList.end(); PmtIt++)  {
00126     SimPmt* pmt = PmtIt->second;
00127     if(pmt) {
00128       // Make sure the PMT reads out to VA electronics:
00129       RawChannelId rcid = plex.GetRawChannelId(pmt->GetPixelSpotId(1));
00130       if ( rcid.GetElecType()==ElecType::kVA ) {
00131         // Apply dynode trigger; don't read out if below thresh.
00132         crate = rcid.GetCrate();
00133         varc  = rcid.GetVarcId();
00134         vmm   = rcid.GetVmm();
00135         
00136         bool trig = true;
00137 
00138         if(fVarcTriggerMode != SimVarcTriggerMode::kNone) {
00139           // Compose a unique index for this varc (or vmm)
00140           int index = crate*100 + varc*10;
00141           if(fVarcTriggerMode == SimVarcTriggerMode::k2of6) {
00142             index += vmm;
00143           }
00144           
00145           // Assume it's bad
00146           trig = false;
00147           
00148           std::vector<double> &tVec = varcTrigTimes[index];
00149           // Look for another hit within the trigger window.
00150           int nhits = 0;
00151           for(UInt_t i=0; i<tVec.size(); i++) {
00152             double dt = tVec[i] - pmt->GetDynodeTime();
00153             if(fabs(dt)<fVarcTriggerWindow)  // There's another trigger in the window
00154               nhits++;
00155           }
00156           if(nhits>1) trig=true; // Don't count itself
00157         }
00158         
00159         if(DynodeTrigger(pmt->GetDynodeCharge()))
00160           ReadoutPmt(pmt,trig, deadChips[PmtIt->first]);          
00161       }
00162     }
00163   }
00164   
00165 }

void SimVaElectronics::ReadoutPmt ( SimPmt pmt,
bool  trig,
bool  isdead 
)

Definition at line 169 of file SimVaElectronics.cxx.

References SimElectronics::AddAdcsAfterFETrigger(), SimElectronics::AddAdcsAfterSpars(), SimElectronics::AddDigit(), SimElectronics::AddDigitsAfterFETrigger(), SimElectronics::AddDigitsAfterSpars(), SimElectronics::AddSignal(), PlexPixelSpotId::AsString(), SimPmt::CreateSignal(), SimElectronics::fContext, fVaGain, fVaSparsifyThresh, GenSimulatedADC(), GenSimulatedTDC(), SimPmt::GetCharge(), SimPmt::GetDynodeTime(), SimPmt::GetNumberOfPixels(), SimPmt::GetNumberOfSpots(), SimPmt::GetPeXtalk(), SimPmt::GetPixelSpotId(), PlexHandle::GetRawChannelId(), SimPmt::GetTotalCharge(), SimPmt::GetTotalHitPixels(), SimPmt::GetTubeId(), SimPmt::GetType(), RawChannelId::IsNull(), Msg::kDebug, Msg::kVerbose, and MSG.

Referenced by ReadoutDetector().

00170 {
00171   // Reads out a single PMT.
00172   // Adds all readout to the list of SimDigits.
00173 
00174   MSG("DetSim",Msg::kDebug) << "SimVaElectronics::ReadoutPmt " 
00175                             << pmt->GetTubeId().AsString() 
00176                             << " type " << pmt->GetType()
00177                             << endl;
00178 
00179   PlexHandle plex(fContext);
00180 
00181   // Interesting statistics:
00182   if((trig)&&(!isDead)) {
00183     AddDigitsAfterFETrigger( pmt->GetTotalHitPixels(true) );
00184     AddAdcsAfterFETrigger( pmt->GetTotalCharge() * fVaGain );
00185   }
00186 
00187   for(int ipixel = 1; ipixel<= pmt->GetNumberOfPixels(); ipixel++) {
00188     RawChannelId rcid = plex.GetRawChannelId(pmt->GetPixelSpotId(ipixel));
00189 
00190     // Find which spot had the biggest charge.
00191     // We use this spot to look up the nonlinearity calibration.
00192     Float_t bigpe=0;
00193     Int_t   bigspot=1;
00194     for(int ispot=1;ispot<=pmt->GetNumberOfSpots();ispot++) {
00195       float pe = pmt->GetPeXtalk(ipixel, ispot);
00196       if(pe > bigpe) {
00197         bigpe = pe;
00198         bigspot = ispot;
00199       }
00200     }
00201 
00202     DigiSignal* signal = pmt->CreateSignal(ipixel);
00203     AddSignal(signal);
00204     int errorbits = 0;
00205     if(!trig) errorbits+=1;   // Pretrigger failed
00206     if(isDead) errorbits+=2;  // Dead chip
00207 
00208     if(!(rcid.IsNull())) {
00209       Int_t adc = GenSimulatedADC(pmt->GetCharge(ipixel),
00210                                   rcid, 
00211                                   pmt->GetPixelSpotId(ipixel, bigspot) );
00212       Int_t tdc = GenSimulatedTDC(pmt->GetDynodeTime(), rcid);
00213       
00214       SimDigit d(  pmt->GetPixelSpotId(ipixel),
00215                    rcid,
00216                    adc,
00217                    tdc,
00218                    signal,
00219                    errorbits
00220                    );
00221       MSG("DetSim",Msg::kVerbose) << "ReadoutPmt: " << d.AsString() << std::endl;    
00222       
00223       // Sparsify and record.
00224       if(d.GetADC() > fVaSparsifyThresh) { 
00225         AddDigit(d);
00226         
00227         // Stats:
00228         AddDigitsAfterSpars(1);
00229         AddAdcsAfterSpars(d.GetADC());
00230       }
00231     }
00232   }
00233 }


Member Data Documentation

Definition at line 83 of file SimVaElectronics.h.

Referenced by Config(), GenSimulatedADC(), and ~SimVaElectronics().

Definition at line 81 of file SimVaElectronics.h.

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

Definition at line 67 of file SimVaElectronics.h.

Referenced by Config(), and GenSimulatedTDC().

Double_t SimVaElectronics::fTimingWidth [protected]

Definition at line 68 of file SimVaElectronics.h.

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

Double_t SimVaElectronics::fVaChipDeadTime [protected]

Definition at line 79 of file SimVaElectronics.h.

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

Definition at line 70 of file SimVaElectronics.h.

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

Double_t SimVaElectronics::fVaGain [protected]
Double_t SimVaElectronics::fVaLinearityP0 [protected]

Definition at line 72 of file SimVaElectronics.h.

Referenced by Config(), and Print().

Double_t SimVaElectronics::fVaLinearityP1 [protected]

Definition at line 73 of file SimVaElectronics.h.

Referenced by Config(), and Print().

Double_t SimVaElectronics::fVaLinearityP2 [protected]

Definition at line 74 of file SimVaElectronics.h.

Referenced by Config(), and Print().

Double_t SimVaElectronics::fVaLinearityP3 [protected]

Definition at line 75 of file SimVaElectronics.h.

Referenced by Config(), and Print().

Double_t SimVaElectronics::fVaLinearityP4 [protected]

Definition at line 76 of file SimVaElectronics.h.

Referenced by Config(), and Print().

Definition at line 71 of file SimVaElectronics.h.

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

Double_t SimVaElectronics::fVaPedWidth [protected]

Definition at line 66 of file SimVaElectronics.h.

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

Definition at line 69 of file SimVaElectronics.h.

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


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

Generated on 22 Nov 2017 for loon by  doxygen 1.6.1