#include <SimVaElectronics.h>
Inheritance diagram for SimVaElectronics:

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 CalVaLinearity * | fCalVaLinearity |
|
||||||||||||
|
Definition at line 17 of file SimVaElectronics.cxx. 00018 : SimElectronics( context, random ), 00019 fVaGain(0.375/Munits::fC), 00020 fVaPedWidth(2.8), 00021 fTimeSmearingMode(SimTimeSmearingMode::kBreitWigner), 00022 fTimingWidth(0.0), 00023 fVaSparsifyThresh(17), 00024 fVaDynodeThresh(57), 00025 fVaNonlinearity(1), 00026 fVaLinearityP0(24), 00027 fVaLinearityP1(16091.3), 00028 fVaLinearityP2(4.63), 00029 fVaLinearityP3(13683.9), 00030 fVaLinearityP4(6650.11), 00031 fVarcTriggerMode(SimVarcTriggerMode::k2of36), 00032 fVarcTriggerWindow(400.*Munits::ns), 00033 fVaChipRandomDeadRate(700*Munits::hertz), 00034 fVaChipDeadTime(5.*Munits::microsecond), 00035 fDoLookupNonlinearity(0), 00036 fCalVaLinearity(0) 00037 { 00038 fCalVaLinearity = new CalVaLinearity(RawChannelId(), 00039 fVaLinearityP0, fVaLinearityP1, 00040 fVaLinearityP2, fVaLinearityP3, 00041 fVaLinearityP4 00042 ); 00043 }
|
|
|
Definition at line 46 of file SimVaElectronics.cxx. 00047 {
00048 if(fCalVaLinearity) delete fCalVaLinearity;
00049 }
|
|
||||||||||||
|
|
|
|
Reimplemented from SimElectronics. Reimplemented in SimVaTimedElectronics. Definition at line 343 of file SimVaElectronics.cxx. References SimElectronics::Config(), fCalVaLinearity, fDoLookupNonlinearity, fTimeSmearingMode, fTimingWidth, fVaChipDeadTime, fVaChipRandomDeadRate, fVaDynodeThresh, fVaGain, fVaLinearityP0, fVaLinearityP1, fVaLinearityP2, fVaLinearityP3, fVaLinearityP4, fVaNonlinearity, fVaPedWidth, fVarcTriggerMode, fVarcTriggerWindow, fVaSparsifyThresh, Registry::Get(), and MSG. Referenced by SimVaTimedElectronics::Config(). 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 }
|
|
|
Definition at line 236 of file SimVaElectronics.cxx. 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 }
|
|
||||||||||||||||
|
Definition at line 264 of file SimVaElectronics.cxx. References Calibrator::DecalLinearity(), fCalVaLinearity, fVaPedWidth, PlexHandle::GetStripEndId(), Calibrator::Instance(), PlexStripEndId::IsValid(), and CalVaLinearity::UnLinearize(). Referenced by SimVaTimedElectronics::ReadoutPmt(), and 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 }
|
|
||||||||||||
|
Definition at line 287 of file SimVaElectronics.cxx. References fTimeSmearingMode, fTimingWidth, Calibrator::GetTDCFromTime(), Calibrator::Instance(), and MSG. Referenced by SimVaTimedElectronics::ReadoutPmt(), and 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 }
|
|
|
Reimplemented from SimElectronics. Reimplemented in SimVaTimedElectronics. Definition at line 325 of file SimVaElectronics.cxx. References fDoLookupNonlinearity, fTimingWidth, fVaChipDeadTime, fVaChipRandomDeadRate, fVaDynodeThresh, fVaGain, fVaLinearityP0, fVaLinearityP1, fVaLinearityP2, fVaLinearityP3, fVaLinearityP4, fVaNonlinearity, fVaPedWidth, fVarcTriggerMode, fVarcTriggerWindow, and fVaSparsifyThresh. Referenced by SimVaTimedElectronics::Print(). 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 }
|
|
|
Reimplemented from SimElectronics. Reimplemented in SimVaTimedElectronics. Definition at line 52 of file SimVaElectronics.cxx. References DynodeTrigger(), fVaChipRandomDeadRate, fVarcTriggerMode, RawChannelId::GetCrate(), SimPmt::GetDynodeCharge(), SimPmt::GetDynodeTime(), RawChannelId::GetElecType(), SimPmt::GetPixelSpotId(), PlexHandle::GetRawChannelId(), RawChannelId::GetVarcId(), RawChannelId::GetVmm(), 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 }
|
|
||||||||||||||||
|
Definition at line 169 of file SimVaElectronics.cxx. References SimElectronics::AddAdcsAfterFETrigger(), SimElectronics::AddAdcsAfterSpars(), SimElectronics::AddDigit(), SimElectronics::AddDigitsAfterFETrigger(), SimElectronics::AddDigitsAfterSpars(), SimElectronics::AddSignal(), DigiSignal::AsString(), PlexPixelSpotId::AsString(), SimPmt::CreateSignal(), 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(), 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 }
|
|
|
Definition at line 83 of file SimVaElectronics.h. Referenced by Config(), and GenSimulatedADC(). |
|
|
Definition at line 81 of file SimVaElectronics.h. |
|
|
Definition at line 67 of file SimVaElectronics.h. Referenced by Config(), and GenSimulatedTDC(). |
|
|
Definition at line 68 of file SimVaElectronics.h. Referenced by Config(), GenSimulatedTDC(), and Print(). |
|
|
Definition at line 80 of file SimVaElectronics.h. |
|
|
Definition at line 79 of file SimVaElectronics.h. Referenced by Config(), Print(), and ReadoutDetector(). |
|
|
Definition at line 70 of file SimVaElectronics.h. |
|
|
Definition at line 65 of file SimVaElectronics.h. |
|
|
Definition at line 72 of file SimVaElectronics.h. |
|
|
Definition at line 73 of file SimVaElectronics.h. |
|
|
Definition at line 74 of file SimVaElectronics.h. |
|
|
Definition at line 75 of file SimVaElectronics.h. |
|
|
Definition at line 76 of file SimVaElectronics.h. |
|
|
Definition at line 71 of file SimVaElectronics.h. |
|
|
Definition at line 66 of file SimVaElectronics.h. Referenced by Config(), GenSimulatedADC(), and Print(). |
|
|
Definition at line 77 of file SimVaElectronics.h. Referenced by Config(), Print(), and ReadoutDetector(). |
|
|
Definition at line 78 of file SimVaElectronics.h. |
|
|
Definition at line 69 of file SimVaElectronics.h. |
1.3.9.1