00001 #include "SimPmt.h"
00002 #include "Calibrator/Calibrator.h"
00003 #include "MessageService/MsgService.h"
00004 #include "SimAfterpulseModel.h"
00005 #include <fstream>
00006
00007 CVSID("$Id: SimPmt.cxx,v 1.31 2008/11/18 17:31:02 rhatcher Exp $");
00008 ClassImp(SimPmt)
00009
00010
00011 Bool_t SimPmt::fsPmtDoOpticalCrosstalk = true;
00012 Bool_t SimPmt::fsPmtDoChargeCrosstalk = true;
00013 Bool_t SimPmt::fsPmtDoNonlinearity = true;
00014 Bool_t SimPmt::fsPmtDoDarkNoise = true;
00015 Double_t SimPmt::fsPmtScaleOpticalCrosstalk = 1.0;
00016 Double_t SimPmt::fsPmtScaleChargeCrosstalk = 1.0;
00017
00018 Double_t SimPmt::fsPmtScaleAdjacentChargeCrosstalk = 1.0;
00019 Double_t SimPmt::fsPmtScaleDiagonalChargeCrosstalk = 1.0;
00020 Double_t SimPmt::fsPmtScaleAdjacentOpticalCrosstalk = 1.0;
00021 Double_t SimPmt::fsPmtScaleDiagonalOpticalCrosstalk = 1.0;
00022 Bool_t SimPmt::fsPmtApplyGainDrift = true;
00023 Bool_t SimPmt::fsPmtHamamatsuPixelNumbering = false;
00024 Double_t SimPmt::fsVaGain;
00025 Double_t SimPmt::fsQieDacCharge;
00026 Bool_t SimPmt::fsRebuildGainMap = true;
00027
00028 SimPmt::SimPmt ( PlexPixelSpotId tube,
00029 VldContext context,
00030 TRandom* random,
00031 Int_t nPixels, Int_t nSpots
00032 )
00033 : fNPixels(nPixels),
00034 fNSpots(nSpots),
00035 fTube(tube),
00036 fContext(context),
00037 fRandom(random),
00038 fSimAfterpulseModel(0)
00039 {
00040 if(random == NULL) fRandom = gRandom;
00041
00042 SimPmt::Reset(context);
00043 }
00044
00045
00046 SimPmt::~SimPmt()
00047 {
00048 BucketMap_t::iterator itr(fTimeBuckets.begin()),itrEnd(fTimeBuckets.end());
00049 for (; itr != itrEnd; ++itr)
00050 delete itr->second;
00051 fTimeBuckets.clear();
00052
00053 UInt_t n= fCreatedDigiPEs.size();
00054 for(UInt_t i=0;i<n;i++) delete fCreatedDigiPEs[i];
00055 }
00056
00057 void SimPmt::Reset(const VldContext& newContext)
00058 {
00059
00060
00061
00062 MSG("DetSim",Msg::kVerbose) << "SimPmt::Reset() " << fTube.AsString() << endl;
00063 fContext = newContext;
00064 fTotalCharge = 0;
00065 fDynodeTime = kPmtTime_Never;
00066 BucketMap_t::iterator itr(fTimeBuckets.begin()),itrEnd(fTimeBuckets.end());
00067 for (; itr != itrEnd; ++itr)
00068 delete itr->second;
00069 fTimeBuckets.clear();
00070 UInt_t num= fCreatedDigiPEs.size();
00071 for(UInt_t i=0;i<num;i++) delete fCreatedDigiPEs[i];
00072 }
00073
00074
00075
00076 void SimPmt::AddDigiPE( const DigiPE* digipe )
00077 {
00078
00079
00080
00081
00082 if(!digipe) return;
00083
00084 double time = digipe->GetTime();
00085
00086 int bucket = this->TimeToBucket(time);
00087
00088
00089
00090
00091
00092 int pix = GetPixelNumber(digipe->GetPixelSpotId());
00093 int spot = GetSpotNumber(digipe->GetPixelSpotId());
00094 GetBucket(bucket).AddDigiPE(digipe, pix, spot);
00095
00096
00097 GetBucket(bucket).SetDynodeTime(time);
00098 if(time<fDynodeTime) fDynodeTime = time;
00099 }
00100
00101
00102
00103 Float_t SimPmt::GetPe( int pixel, int spot, int bucket ) const
00104 {
00105
00106
00107
00108
00109 if(spot == 0 ) {
00110
00111 return GetBucket(bucket).GetPixelBucket(pixel).GetTotalPE();
00112 }
00113
00114 return GetBucket(bucket).GetPixelBucket(pixel).GetPE(spot);
00115 }
00116
00117 Float_t SimPmt::GetPeXtalk( int pixel, int spot, int bucket ) const
00118 {
00119
00120
00121
00122
00123 if(spot == 0 ) {
00124
00125 return GetBucket(bucket).GetPixelBucket(pixel).GetTotalPEXtalk();
00126 }
00127
00128 return GetBucket(bucket).GetPixelBucket(pixel).GetPEXtalk(spot);
00129 }
00130
00131
00132
00133 Float_t SimPmt::GetCharge( int pixel, int bucket ) const
00134 {
00135
00136
00137
00138
00139 return GetBucket(bucket).GetPixelBucket(pixel).GetCharge();
00140 }
00141
00142
00143 Float_t SimPmt::GetTime( int pixel, int bucket ) const
00144 {
00145
00146
00147
00148
00149 return GetBucket(bucket).GetPixelBucket(pixel).GetTime();
00150 }
00151
00152 DigiSignal* SimPmt::CreateSignal( int pixel, int bucket ) const
00153 {
00154 return GetBucket(bucket).GetPixelBucket(pixel).CreateSignal();
00155 }
00156
00157
00158 Int_t SimPmt::GetTotalHitPixels( Bool_t with_xtalk ) const
00159 {
00164 int tot = 0;
00165 int tot_xtalk = 0;
00166
00167
00168 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00169 SimPmtTimeBucket& pmttb = it.Bucket();
00170
00171 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00172 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00173
00174 if(pixtb.GetTotalPE() >0) tot++;
00175 if(pixtb.GetTotalPEXtalk() >0) tot_xtalk++;
00176 }
00177 }
00178 if(with_xtalk) return tot_xtalk;
00179 return tot;
00180 }
00181
00182 Float_t SimPmt::GetTotalPe( void ) const
00183 {
00187
00188 Float_t tot = 0;
00189
00190
00191 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00192 SimPmtTimeBucket& pmttb = it.Bucket();
00193
00194 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00195 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00196
00197 tot += pixtb.GetTotalPE();
00198 }
00199 }
00200
00201 return tot;
00202 }
00203
00204 Float_t SimPmt::GetTotalCharge( void ) const
00205 {
00209
00210 Float_t tot = 0;
00211
00212
00213 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00214 SimPmtTimeBucket& pmttb = it.Bucket();
00215
00216 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00217 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00218
00219 tot += pixtb.GetCharge();
00220 }
00221 }
00222
00223 return tot;
00224 }
00225
00226
00227
00228
00229
00230 Float_t SimPmt::GenPoisson( Float_t lambda, Float_t x )
00231 {
00245
00246
00247
00248
00249
00250 return exp(-lambda + x*log(lambda)-TMath::LnGamma(x+1.0));
00251 }
00252
00253
00254 Float_t SimPmt::RandomGenPoisson( Float_t lambda )
00255 {
00266
00267
00268 if(lambda<=0) return 0;
00269
00270
00271 if (lambda > 88) {
00272 return fRandom->Gaus(0,1)*TMath::Sqrt(lambda) + lambda;
00273 }
00274
00275
00276
00277 Float_t rp = fRandom->Poisson(lambda);
00278
00279
00280
00281 Float_t ri = TMath::Nint(rp);
00282 Float_t a = ri - 0.5;
00283 Float_t b = ri + 0.5;
00284
00285
00286
00287 Float_t fmax;
00288 if((lambda>a)&&(lambda<b)) {
00289 fmax = GenPoisson(lambda,lambda);
00290 } else {
00291
00292 Float_t fa = GenPoisson(lambda,a);
00293 Float_t fb = GenPoisson(lambda,b);
00294 if(fa>fb) fmax = fa;
00295 else fmax = fb;
00296 }
00297
00298
00299 while(true) {
00300 Float_t x = fRandom->Rndm();
00301 x = x + a;
00302
00303
00304
00305 Float_t f = GenPoisson(lambda,x);
00306
00307
00308
00309
00310
00311 Float_t r = fRandom->Rndm();
00312 r = r*fmax;
00313
00314 if(r < f) return x;
00315 }
00316 }
00317
00318
00319 Bool_t SimPmt::GetGainAndWidth(int pixel, int spot, Double_t& outGain, Double_t &outWidth)
00320 {
00324
00325 PlexPixelSpotId psid = GetPixelSpotId(pixel,spot);
00326 FloatErr adcgain, adcwidth;
00327 Calibrator::Instance().DecalGainAndWidth(adcgain,adcwidth,psid);
00328
00329
00330 outWidth =adcwidth/adcgain;
00331
00332 float driftedGain = adcgain;
00333 if(fsPmtApplyGainDrift) {
00334 PlexHandle plex(fContext);
00335 PlexStripEndId seid = plex.GetStripEndId(psid);
00336 if(seid.IsValid()) {
00337 driftedGain = Calibrator::Instance().GetDriftCorrected(adcgain,seid);
00338 if(driftedGain != adcgain)
00339 MSG("DetSim",Msg::kDebug) << "Drifted gain on " << psid.AsString()
00340 << " " << seid.AsString()
00341 << " by " << driftedGain/adcgain << endl;
00342 }
00343 }
00344
00345
00346 float elecgain = 1.0/fsVaGain;
00347 if(GetTubeId().GetElecType()==ElecType::kQIE) elecgain = fsQieDacCharge;
00348 outGain = driftedGain * elecgain / Munits::e_SI;
00349
00350 return true;
00351 }
00352
00353
00355
00357
00358 void SimPmt::SimulatePmt(void)
00359 {
00360
00361
00362
00363
00364 if(fsPmtDoOpticalCrosstalk) SimulateOpticalXtalk();
00365 else CopyPEtoPEXtalk();
00366 SimulateCharges();
00367 if(fsPmtDoDarkNoise) SimulateDarkNoise();
00368 if(fsPmtDoNonlinearity) SimulateNonlinearity();
00369 if(fsPmtDoChargeCrosstalk) SimulateChargeCrosstalk();
00370 }
00371
00372
00373 void SimPmt::SimulateAfterpulsing()
00374 {
00375
00376
00377
00378
00379 if(fSimAfterpulseModel==0) return;
00380
00381
00382 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00383 SimPmtTimeBucket& pmttb = it.Bucket();
00384
00385
00386 for(Int_t injPix = 1; injPix <= fNPixels; injPix++) {
00387 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(injPix);
00388
00389
00390 for(Int_t injSpot = 1; injSpot <= fNSpots; injSpot++ ) {
00391 Float_t npe = pixtb.GetPE(injSpot);
00392
00393 if(npe>0) {
00394
00395 SimPixelTimeBucket::PeList_t pelist = pixtb.GetDigiPE(injSpot);
00396 SimPixelTimeBucket::PeList_t::iterator it = pelist.begin();
00397 SimPixelTimeBucket::PeList_t::iterator end = pelist.end();
00398 for( ; it!=end; it++ ) {
00399 const DigiPE* sourcePe = it->second;
00400
00401 if(sourcePe->IsAfterpulse()) continue;
00402
00403 Float_t prob = fSimAfterpulseModel->ComputeAfterpulseProb(sourcePe->GetPixelSpotId(),npe);
00404 if(fRandom->Uniform() < prob) {
00405 PlexPixelSpotId outpsid;
00406 Double_t outtime;
00407 fSimAfterpulseModel->ComputeAfterpulsePixelAndTime(
00408 sourcePe->GetPixelSpotId(),
00409 sourcePe->GetTime(),
00410 outpsid, outtime );
00411 DigiPE* newpe = new DigiPE(outtime, outpsid, DigiSignal::kAfterpulse );
00412 this->AddDigiPE(newpe);
00413 fCreatedDigiPEs.push_back(newpe);
00414 }
00415 }
00416
00417 }
00418 }
00419 }
00420 }
00421 }
00422
00423 void SimPmt::SimulateOpticalXtalk()
00424 {
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00435 SimPmtTimeBucket& pmttb = it.Bucket();
00436
00437
00438 for(Int_t xpix = 1; xpix<=fNPixels; xpix++) {
00439 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(xpix);
00440
00441
00442 for(Int_t injPix = 1; injPix <= fNPixels; injPix++) {
00443 if(injPix!=xpix) {
00444 SimPixelTimeBucket& pixtb_inj = pmttb.GetPixelBucket(injPix);
00445
00446
00447 for(Int_t injSpot = 1; injSpot <= fNSpots; injSpot++ ) {
00448 if( pixtb_inj.GetPE(injSpot) > 0) {
00449
00450 Float_t pe = GenOpticalCrosstalk(injPix,
00451 injSpot,
00452 xpix,
00453 pixtb_inj.GetPE(injSpot) );
00454
00455
00456
00457
00458 if(pe>0){
00459
00460 Int_t toSpot = fRandom->Integer(fNSpots)+1;
00461 MoveOpticalPE(TMath::Nint(pe),
00462 pixtb_inj,injSpot,
00463 pixtb, toSpot );
00464
00465 pixtb.SetTruthBit(DigiSignal::kCrosstalkOptical);
00466 }
00467 }
00468 }
00469
00470 }
00471 }
00472 }
00473
00474
00475 }
00476
00477
00478
00479 CopyPEtoPEXtalk();
00480 }
00481
00482 void SimPmt::SimulateCharges()
00483 {
00484 fTotalCharge = 0;
00485
00486 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00487 SimPmtTimeBucket& pmttb = it.Bucket();
00488
00489
00490 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00491 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00492
00493 pixtb.SetCharge(0);
00494
00495 for(Int_t spot = 1; spot <= fNSpots; spot++) {
00496
00497
00498
00499 Float_t charge = GenChargeFromPE(pix,spot, pixtb.GetPEXtalk(spot));
00500 pixtb.AddCharge(charge);
00501 }
00502 fTotalCharge += pixtb.GetCharge();
00503 pmttb.AddTotalCharge(pixtb.GetCharge());
00504 }
00505 }
00506 }
00507
00508
00509 void SimPmt::SimulateDarkNoise()
00510 {
00511 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00512 Int_t ibucket = it.BucketId();
00513 SimPmtTimeBucket& pmttb = it.Bucket();
00514
00515 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00516 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00517
00518 Float_t darkcharge = GenDarkNoiseCharge( pix, GetBucketDuration(ibucket) );
00519 pixtb.AddCharge(darkcharge);
00520 }
00521 }
00522
00523 }
00524
00525
00526 void SimPmt::SimulateNonlinearity()
00527 {
00528
00529
00530
00531
00532
00533 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00534 SimPmtTimeBucket& pmttb = it.Bucket();
00535
00536 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00537 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00538
00539 Float_t nonlin = GenNonlinearCharge( pix, pixtb.GetCharge() );
00540 pixtb.SetCharge(nonlin);
00541
00542 }
00543 }
00544 }
00545
00546
00547 void SimPmt::SimulateChargeCrosstalk()
00548 {
00549
00550
00551
00552
00553
00554
00555 static float sCharge[101];
00556 assert(fNPixels<100);
00557
00558 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00559 SimPmtTimeBucket& pmttb = it.Bucket();
00560
00561
00562 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00563 sCharge[pix] = pmttb.GetPixelBucket(pix).GetCharge();
00564 }
00565
00566
00567 for( Int_t xpix = 1; xpix <= fNPixels; xpix++ ) {
00568 for( Int_t injPix = 1; injPix <=fNPixels; injPix++ ) {
00569
00570 SimPixelTimeBucket& thePixel = pmttb.GetPixelBucket(xpix);
00571 Float_t xcharge = GenElectricalCrosstalk( injPix, xpix, sCharge[injPix] );
00572 thePixel.AddCharge(xcharge);
00573
00574 if(xcharge>1.0*Munits::fC)
00575 thePixel.SetTruthBit(DigiSignal::kCrosstalk);
00576
00577 }
00578 }
00579 }
00580 }
00581
00582
00584
00585
00586
00587
00588 Float_t SimPmt::GenChargeFromPE( Int_t pixel, Int_t spot, Float_t pe )
00589 {
00590
00591
00592
00593
00594
00595
00596
00597 if(pe<=0) return 0;
00598
00599
00600 Float_t secemm = GetPixelSecondaryEmmisionRatio(pixel,spot);
00601
00602
00603 Float_t mean2ndaryPe = pe * secemm;
00604 Float_t secondary_pe = RandomGenPoisson(mean2ndaryPe);
00605
00606
00607 return (secondary_pe / secemm)
00608 * GetPixelGain(pixel,spot)
00609 * 1.6e2;
00610
00611 }
00612
00613 Float_t SimPmt::GenDarkNoiseCharge( Int_t ,
00614 Float_t )
00615 {
00616
00617
00618
00619
00620
00621
00622
00623
00624 return 0;
00625 }
00626
00627
00628 Float_t SimPmt::GenNonlinearCharge( Int_t ,
00629 Float_t inCharge)
00630 {
00631
00632
00633
00634
00635
00636
00637
00638
00639 return inCharge;
00640 }
00641
00642 Float_t SimPmt::GenOpticalCrosstalk( Int_t ,
00643 Int_t ,
00644 Int_t ,
00645 Float_t )
00646 {
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 return 0;
00658
00659 }
00660
00661 Float_t SimPmt::GenElectricalCrosstalk( Int_t ,
00662 Int_t ,
00663 Float_t )
00664 {
00665
00666
00667
00668
00669
00670
00671
00672 return 0;
00673 }
00674
00675
00676 void SimPmt::MoveOpticalPE( UInt_t npe,
00677 SimPixelTimeBucket& fromPixel,
00678 Int_t fromSpot,
00679 SimPixelTimeBucket& toPixel,
00680 Int_t toSpot)
00681 {
00682
00683
00684
00685
00686
00687 if(npe<=0) return;
00688
00689
00690
00691
00692 if(fromPixel.GetPE(fromSpot)<npe) {
00693 MSG("DetSim",Msg::kDebug) << "SimPmt::MoveOpticalPe() Optical crosstalk is bigger than injected light!" << endl;
00694 npe = (UInt_t)(fromPixel.GetPE(fromSpot));
00695 }
00696
00697
00698 SimPixelTimeBucket::PeList_t &fromPeList = fromPixel.GetDigiPE(fromSpot);
00699 SimPixelTimeBucket::PeList_t &toPeList = toPixel.GetDigiPEXtalk(toSpot);
00700
00701
00702
00703
00704
00705
00706 if(fromPeList.size() < npe) {
00707 MSG("DetSim",Msg::kDebug) << "SimPmt::MoveOpticalPe() Too much crosstalk! "
00708 << fromPeList.size() << "pe available, "
00709 << npe << " crosstalk requested." << endl;
00710 npe = fromPeList.size();
00711 }
00712
00713
00714
00715 for(UInt_t i=0; i<npe; i++) {
00716
00717 Int_t whichPe = fRandom->Integer(fromPeList.size());
00718
00719
00720 SimPixelTimeBucket::PeList_t::iterator it;
00721 it=fromPeList.begin();
00722 for(int i=0;i<whichPe;i++) ++it;
00723
00724 if(it!=fromPeList.end()) {
00725 toPeList.insert(*it);
00726 toPixel.AddPEXtalk(toSpot,1);
00727
00728 fromPeList.erase(it);
00729 }
00730 }
00731 }
00732
00733 void SimPmt::CopyPEtoPEXtalk(void)
00734 {
00735
00736 for(SimPmtBucketIterator it(*this); !it.End(); it.Next()) {
00737 SimPmtTimeBucket& pmttb = it.Bucket();
00738
00739
00740 for(Int_t pix = 1; pix <= fNPixels; pix++) {
00741 SimPixelTimeBucket& pixtb = pmttb.GetPixelBucket(pix);
00742
00743
00744 for(Int_t spot = 1; spot<= fNSpots; spot++) {
00745 SimPixelTimeBucket::PeList_t &fromPeList = pixtb.GetDigiPE(spot);
00746 SimPixelTimeBucket::PeList_t &toPeList = pixtb.GetDigiPEXtalk(spot);
00747
00748 pixtb.AddPEXtalk(spot,(Float_t)(fromPeList.size()));
00749 toPeList.insert(fromPeList.begin(),fromPeList.end());
00750 }
00751 }
00752 }
00753 }
00754
00756
00757 void SimPmt::Config( Registry& config )
00758 {
00759 Int_t tbool;
00760 if(config.Get("pmtDoOpticalCrosstalk",tbool)) fsPmtDoOpticalCrosstalk = tbool;
00761 if(config.Get("pmtDoChargeCrosstalk",tbool)) fsPmtDoChargeCrosstalk = tbool;
00762 if(config.Get("pmtDoNonlinearity",tbool)) fsPmtDoNonlinearity = tbool;
00763 if(config.Get("pmtDoDarkNoise",tbool)) fsPmtDoDarkNoise = tbool;
00764 if(config.Get("pmtApplyGainDrift",tbool)) fsPmtApplyGainDrift = tbool;
00765
00766 config.Get("pmtScaleOpticalCrosstalk",fsPmtScaleOpticalCrosstalk);
00767 config.Get("pmtScaleChargeCrosstalk", fsPmtScaleChargeCrosstalk);
00768
00769 config.Get("pmtScaleAdjacentChargeCrosstalk", fsPmtScaleAdjacentChargeCrosstalk);
00770 config.Get("pmtScaleDiagonalChargeCrosstalk", fsPmtScaleDiagonalChargeCrosstalk);
00771 config.Get("pmtScaleAdjacentOpticalCrosstalk", fsPmtScaleAdjacentOpticalCrosstalk);
00772 config.Get("pmtScaleDiagonalOpticalCrosstalk", fsPmtScaleDiagonalOpticalCrosstalk);
00773
00774 config.Get("vaGain",fsVaGain);
00775 config.Get("qieDacCharge",fsQieDacCharge);
00776
00777 if(config.Get("pmtRebuildGainMap",tbool)) fsRebuildGainMap = tbool;
00778
00779 if(config.Get("pmtHamamatsuPixelNumbering",tbool)) fsPmtHamamatsuPixelNumbering = tbool;
00780
00781 }
00782
00783 void SimPmt::PrintConfig(Option_t*)
00784 {
00785 printf("SimPmt Config: pmtDoOpticalCrosstalk %s\n",fsPmtDoOpticalCrosstalk?"true":"false");
00786 printf(" pmtDoChargeCrosstalk %s\n",fsPmtDoChargeCrosstalk?"true":"false");
00787 printf(" pmtDoNonlinearity %s\n",fsPmtDoNonlinearity?"true":"false");
00788 printf(" pmtDoDarkNoise %s\n",fsPmtDoDarkNoise?"true":"false");
00789 printf(" pmtScaleOpticalCrosstalk %f\n",fsPmtScaleOpticalCrosstalk);
00790 printf(" pmtScaleChargeCrosstalk %f\n",fsPmtScaleChargeCrosstalk );
00791
00792 printf(" pmtScaleAdjacentChargeCrosstalk %f\n",fsPmtScaleAdjacentChargeCrosstalk );
00793 printf(" pmtScaleDiagonalChargeCrosstalk %f\n",fsPmtScaleDiagonalChargeCrosstalk );
00794 printf(" pmtScaleAdjacentOpticalCrosstalk %f\n",fsPmtScaleAdjacentOpticalCrosstalk );
00795 printf(" pmtScaleDiagonalOpticalCrosstalk %f\n",fsPmtScaleDiagonalOpticalCrosstalk );
00796 printf(" pmtApplyGainDrift %s\n",fsPmtApplyGainDrift?"true":"false" );
00797 printf(" pmtHamamatsuPixelNumbering %s\n",fsPmtHamamatsuPixelNumbering?"true":"false");
00798 printf(" vaGain %f ADC/fC\n",fsVaGain*Munits::fC);
00799 printf(" qieDacCharge %f fC/DAC\n",fsQieDacCharge/Munits::fC);
00800 printf(" pmtRebuildGainMap %s\n",fsRebuildGainMap?"true":"false");
00801 }
00802