#include "PamVMCTofDig.h" #include "TDatabasePDG.h" #include #include using TMath::Power; using TMath::Exp; using TMath::Abs; ClassImp(PamVMCTofDig) void PamVMCTofDig::LoadCalib(){ cout<<"Loading Tof Calibrations..."<Query_GL_PARAM(time,type); fquery.str(""); fquery << fsql->GetPAR()->PATH.Data() << "/"; fquery << fsql->GetPAR()->NAME.Data(); ThrowCalFileUsage("TOF",fquery.str().c_str()); fcfile.open(fquery.str().c_str()); // fcfile.open("/opt/pamela-5.21/calib/tof-param/ToFCalibParam.txt"); if(!fcfile) ThrowCalFileWarning("TOF"); else { Int_t temp; for(Int_t i=0; i> temp; fcfile >> fatte1[i]; fcfile >> flambda1[i]; fcfile >> fatte2[i]; fcfile >> flambda2[i]; fcfile >> temp; } } fcfile.close(); } void PamVMCTofDig::DigitizeTOF(Int_t EventNo, Int_t PrimaryPDG){ fDEBUG = kFALSE; // pC < 800 const Float_t ADC_pC0A = -4.437616e+01; const Float_t ADC_pC1A = 1.573329e+00; const Float_t ADC_pC2A = 2.780518e-04; const Float_t ADC_pC3A = -2.302160e-07; // pC > 800: const Float_t ADC_pC0B = -2.245756e+02; const Float_t ADC_pC1B = 2.184156e+00; const Float_t ADC_pC2B = -4.171825e-04; const Float_t ADC_pC3B = 3.789715e-08; const Float_t pCthres=40.; // threshold in charge const Int_t ADClast=4095; // no signal --> ADC ch=4095 const Int_t ADCsat=3100; // saturation value for the ADCs const Int_t TDClast=4095; for(Int_t i =0; i 800.) && (fQevePmt_pC[i] <= 2485.)) fADCtof[i]= (Int_t)(ADC_pC0B + ADC_pC1B*fQevePmt_pC[i] + ADC_pC2B*Power(fQevePmt_pC[i],2) + ADC_pC3B*Power(fQevePmt_pC[i],3)); if (fQevePmt_pC[i] > 2485.) fADCtof[i]= (Int_t)(1758. + 0.54*fQevePmt_pC[i]); //assuming a fictional 0.54 ch/pC above ADCsat if (fADCtof[i]>ADCsat) fADCtof[i]=ADCsat; if (fQevePmt_pC[i] < pCthres) fADCtof[i]= ADClast; if (fADCtof[i] < 0) fADCtof[i]=ADClast; if (fADCtof[i] > ADClast) fADCtof[i]=ADClast; } // ====== TDC coincidence ====== Float_t t_coinc = 0; Int_t ilast = 100; for (Int_t ii=0; ii t_coinc) { t_coinc = ftdc[ii]; ilast = ii; } for (Int_t ii=0; ii4093) fTDCint[i]=TDClast; // 18-oct WM if (fDEBUG)cout<<"PMT: "<> 16); // 8 MSbits (out of 24) DataTrigger[8] = (UChar_t)(cTrg2 >> 8); // 8 "middle" bits DataTrigger[9] = (UChar_t)(cTrg2); // 8 LSbits pTrg=DataTrigger+7; DataTrigger[10]=EvaluateCrc(pTrg, 3); // TB_READ_PATTERN_TRIGGER: bytes 141-148: // PatternTrigMap[i] corresponds to bit i in TB_READ_PATTERN_TRIGGER: // mapping according to documents: // 1. "formato dati provenienti dalla trigger board" // 2. "The ToF quicklook software", Appendix A (Campana, Nagni) Int_t PatternTrigMap[]={29,42,43,1,16,7,17,28,33,41,46,2,15,8,18,27, 30,40,44,3,14,9,19,26,32,37,47,4,13,10,20,25, 34,31,38,45,5,12,21,24,36,35,39,48,6,11,22,23}; for (Int_t i=0; iGetParticle(PrimaryPDG))->Charge()/3.); Float_t dt1 = 1.e-12*time_res[0]; // single PMT resolution for Z=1 (WM, Nov'07) if ((Z > 1) && (Z < 9)) dt1=1.e-12*time_res[(Z-1)]; if (Z > 8) dt1=120.e-12; return dt1; } void PamVMCTofDig::DigitizeTofPlane(Int_t planeNo, TClonesArray* HitColl, Int_t PrimaryPDG){ PamVMCDetectorHit * hit = 0; const Float_t veff0 = 100.*1.0e8;//(m/s) light velocity in scintillator const Float_t veff1 = 100.*1.5e8;//(m/s) light velocity in lightguide const Float_t FGeo[2] = {0.5, 0.5}; //geometrical factor const Float_t Pho_keV = 10.;// photons per keV in scintillator const Float_t effi = 0.21; //photocathofe efficiency const Float_t pmGain = 3.5e6; //PMT Gain: the same for all PMTs const Float_t echarge = 1.6e-19; // electron charge const Float_t thresh=20.; // to be defined better... (Wolfgang) const Float_t dimel[6] = {33.0, 40.8 ,18.0, 15.0, 15.0, 18.0}; //(cm) TOF paddles dimensions // S11 8 paddles 33.0 x 5.1 cm // S12 6 paddles 40.8 x 5.5 cm // S21 2 paddles 18.0 x 7.5 cm // S22 2 paddles 15.0 x 9.0 cm // S31 3 paddles 15.0 x 6.0 cm // S32 3 paddles 18.0 x 5.0 cm const Float_t s_l_g[6] = {8.0, 8.0, 20.9, 22.0, 9.8, 8.3 }; //(cm) length of the lightguide const Float_t ScaleFact[48]={0.39, 0.49, 0.38, 0.40, 0.65, 0.51, 0.43, 0.49, 0.58, 0.38, 0.53, 0.57, 0.53, 0.45, 0.49, 0.16, 0.15, 0.44, 0.28, 0.57, 0.26, 0.72, 0.37, 0.29, 0.30, 0.89, 0.37, 0.08, 0.27, 0.23, 0.12, 0.22, 0.15, 0.16, 0.21, 0.19, 0.41, 0.32, 0.39, 0.38, 0.28, 0.66, 0.28, 0.40, 0.39, 0.40, 0.37, 0.35 }; Float_t t1, t2, tpos, Npho; Float_t path[2], knorm[2], Atten[2], QhitPad_pC[2], QhitPmt_pC[2]; Int_t padNo, pmtleft, pmtright; //LOOP for(Int_t i =0; iGetEntriesFast(); i++){ hit = (PamVMCDetectorHit*)HitColl->At(i); t1=t2 = hit->GetTOF(); padNo = hit->GetPOS()-1; pmtleft=pmtright=0; if(planeNo==2) if(padNo==0) padNo=1; else padNo=0; Paddle2Pmt(planeNo,padNo, &pmtleft, &pmtright); switch(planeNo){ case 0: case 3: case 4: tpos = (hit->GetYIN()+hit->GetYOUT())/2.; //Y-planes break; case 1: case 2: case 5: tpos = (hit->GetXIN()+hit->GetXOUT())/2.; //X-planes break; default: cout<<"PamVMCTofDig::DigitizeTOFPlane wrong plane no "<GetEREL()*Pho_keV*1.0e6; //calculation of photons number for(Int_t j=0; j<2; j++){ QhitPad_pC[j]= Npho*FGeo[j]*effi*pmGain*echarge*1.E12*ScaleFact[pmtleft+j]; knorm[j]=fatte1[pmtleft+j]*Exp(flambda1[pmtleft+j]*dimel[planeNo]/2.*Power(-1,j+1)) + fatte2[pmtleft+j]*Exp(flambda2[pmtleft+j]*dimel[planeNo]/2.*Power(-1,j+1)); Atten[j]=fatte1[pmtleft+j]*Exp(tpos*flambda1[pmtleft+j]) + fatte2[pmtleft+j]*Exp(tpos*flambda2[pmtleft+j]) ; QhitPmt_pC[j]= QhitPad_pC[j]*Atten[j]/knorm[j]; if (fDEBUG) { cout<<"pmtleft:"<GetEREL()*1.e6<<" Npho:"< t1 += Abs(path[0]/veff0) + s_l_g[planeNo]/veff1; t2 += Abs(path[1]/veff0) + s_l_g[planeNo]/veff1; // Signal reaches PMT t1 = rnd->Gaus(t1,TimeRes(PrimaryPDG)); //apply gaussian error dt t2 = rnd->Gaus(t2,TimeRes(PrimaryPDG)); //apply gaussian error dt t1 += fc1_S[pmtleft] ; // Signal reaches Discriminator ,TDC starts to run t2 += fc1_S[pmtright] ; // check if signal is above threshold // then check if tdcpmt is already filled by another hit... // only re-fill if time is smaller if (QhitPmt_pC[0] > thresh) { if (ftdcpmt[pmtleft] == 1000.) { // fill for the first time ftdcpmt[pmtleft] = t1; ftdc[pmtleft] = t1 + fc2_S[pmtleft] ; // Signal reaches Coincidence } if (ftdcpmt[pmtleft] < 1000.) // is already filled! if (t1 < ftdcpmt[pmtleft]) { ftdcpmt[pmtleft] = t1; t1 += fc2_S[pmtleft] ; // Signal reaches Coincidence ftdc[pmtleft] = t1; } } if (QhitPmt_pC[1] > thresh) { if (ftdcpmt[pmtright] == 1000.) { // fill for the first time ftdcpmt[pmtright] = t2; ftdc[pmtright] = t2 + fc2_S[pmtright] ; // Signal reaches Coincidence } if (ftdcpmt[pmtright] < 1000.) // is already filled! if (t2 < ftdcpmt[pmtright]) { ftdcpmt[pmtright] = t2; t2+= fc2_S[pmtright] ; ftdc[pmtright] = t2; } } if(fDEBUG)cout<<"Time(s):"<GetTOF()<<" t1:"<