--- PamelaDigitizer/Digitizer.cxx 2007/11/28 18:54:31 1.5 +++ PamelaDigitizer/Digitizer.cxx 2007/12/05 13:02:50 1.6 @@ -18,6 +18,7 @@ #include "TLeafI.h" #include "TH1.h" #include "TH2.h" +#include "TF1.h" #include "TMath.h" #include "TRandom.h" #include "TSQLServer.h" @@ -40,6 +41,7 @@ fhBookTree = tree; fFilename = file_raw; fCounter = 0; + fCounterPhys = 0; // SO 5/12/'07 fOBT = 0; // @@ -229,16 +231,19 @@ DigitizeTrackCalib(1); UInt_t length=fTracklength*2; - DigitizePSCU(length,0x12); + DigitizePSCU(length,0x12,fDataPSCU); AddPadding(); WriteTrackCalib(); DigitizeTrackCalib(2); length=fTracklength*2; - DigitizePSCU(length,0x13); + DigitizePSCU(length,0x13,fDataPSCU); AddPadding(); WriteTrackCalib(); - + + DigitizeRunHeader(); + WriteRunHeader(); + LoadMipCor(); // some initialization of parameters -not used now- // end loading, digitizing and writing tracker calibration @@ -253,34 +258,175 @@ nbytes += fhBookTree->GetEntry(i); // read detectors sequentially: // http://www.ts.infn.it/fileadmin/documents/physics/experiments/wizard/cpu/gen_arch/RM_Acquisition.pdf - // on pamelatov: - // /cvs/yoda/techmodel/physics/NeutronDetectorReader.cpp - DigitizeTRIGGER(); + // on pamelatov: /cvs/yoda/techmodel/physics/NeutronDetectorReader.cpp + //DigitizeTRIGGER(); DigitizeTOF(); DigitizeAC(); DigitizeCALO(); DigitizeTrack(); DigitizeS4(); DigitizeND(); - // + // // Add padding to 64 bits // AddPadding(); -// + // // Create CPU header, we need packet type (0x10 = physics data) and packet length. // UInt_t length=2*(fCALOlength+fACbuffer+fTracklength+fNDbuffer+fS4buffer)+fPadding+fTOFbuffer+fTRIGGERbuffer; //UInt_t length=2*(fCALOlength+fACbuffer+fTracklength+fNDbuffer)+fPadding+fTOFbuffer+fTRIGGERbuffer; - DigitizePSCU(length,0x10); + DigitizePSCU(length,0x10,fDataPSCU); if ( !i%100 ) std::cout << "writing event " << i << endl; WriteData(); }; + DigitizeRunTrailer(); + WriteRunTrailer(); + fOutputfile.close(); std::cout << "files closed" << endl << flush; }; +void Digitizer::DigitizeRunHeader(){ + const Int_t lenRH = fRunHeaderbuffer*2; + UChar_t buffRH[lenRH]; + UShort_t buffPSCU[8]; + UChar_t *p; + p=buffRH; + + // header: 16 bytes + DigitizePSCU(fRunHeaderbuffer*2,0x20,buffPSCU); + memcpy(p,buffPSCU,16*sizeof(UChar_t)); + p+=16; + + // time stamp (uint32): 0x82569c97 + *(p++) = 0x82; + *(p++) = 0x56; + *(p++) = 0x9C; + *(p++) = 0x97; + + // acq_setting_mode (uint8) + *(p++) = 2; + + // obt (uint32) + ULong64_t obt = fOBT + 30LL; + while ( obt > 4294967295LL ) + obt -= 4294967295LL; + fOBT = (UInt_t)obt; + // + *(p++) = (UChar_t)(fOBT >> 24); + *(p++) = (UChar_t)(fOBT >> 16); + *(p++) = (UChar_t)(fOBT >> 8); + *(p++) = (UChar_t)fOBT; + + // last time_sync_info (uint32) (from file 000_001_00110) + *(p++) = 0x00; + *(p++) = 0x08; + *(p++) = 0x68; + *(p++) = 0xEF; + + // fav. working schedule (uint8) + *(p++) = 0; + + // eff. working schedule (uint8) + *(p++) = 0; + + // trigger_mode_A (uint32) + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0x01; + + // trigger_mode_B (uint32) + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0x03; + + // acq_after_calib (0,1) (uint8) + *(p++) = 0; + + // trk_calib_used (uint32) + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0x68; + + // acq_build_info (4 zero bits + 28 1's) (uint32) + *(p++) = 0x3F; + *(p++) = 0xFF; + *(p++) = 0xFF; + *(p++) = 0xFF; + + // acq_var_info (11 bits) (uint16) + *(p++) = 0x23; + *(p++) = 0x7F; + + // cal_dsp_mask (uint8) + *(p++) = 0; + + // crc (uint16) + UShort_t crcRH = (UShort_t)CM_Compute_CRC16((UINT16)0, (BYTE*)&buffRH, (UINT32)(fRunHeaderbuffer*2-2)); + *(p++) = (UChar_t)(crcRH << 8); + *p = (UChar_t)crcRH; + + memcpy(fDataRunHeader,buffRH,fRunHeaderbuffer*sizeof(UShort_t)); +}; + +void Digitizer::DigitizeRunTrailer(){ + UChar_t buffRT[fRunTrailerbuffer*2]; + UShort_t buffPSCU[8]; + UChar_t *p; + p=buffRT; + + // header: 16 bytes + DigitizePSCU(fRunHeaderbuffer*2,0x21,buffPSCU); + memcpy(p,buffPSCU,16*sizeof(UChar_t)); + p+=16; + + // pkt_counter (uint32) + fCounterPhys++; + fCounter++; + while ( fCounterPhys > 16777215 ) + fCounterPhys -= 16777215; + // + *(p++) = (UChar_t)(fCounterPhys >> 24); + *(p++) = (UChar_t)(fCounterPhys >> 16); + *(p++) = (UChar_t)(fCounterPhys >> 8); + *(p++) = (UChar_t)fCounterPhys; + + // pkt_readyCounter: valid packets in the run (uint32) + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + + // obt (uint32) + ULong64_t obt = fOBT + 30LL; + while ( obt > 4294967295LL ) + obt -= 4294967295LL; + fOBT = (UInt_t)obt; + // + *(p++) = (UChar_t)(fOBT >> 24); + *(p++) = (UChar_t)(fOBT >> 16); + *(p++) = (UChar_t)(fOBT >> 8); + *(p++) = (UChar_t)fOBT; + + // last time_sync_info (uint32) + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + + // crc (uint16) + UShort_t crcRT = (UShort_t)CM_Compute_CRC16((UINT16)0, (BYTE*)(buffRT), (UINT32)(fRunTrailerbuffer*2-2)); + *(p++) = (UChar_t)(crcRT << 8); + *p = (UChar_t)crcRT; + + memcpy(fDataRunTrailer,buffRT,fRunTrailerbuffer*sizeof(UShort_t)); +}; + void Digitizer::AddPadding(){ // Float_t pd0 = (fLen+16)/64.; @@ -303,7 +449,7 @@ }; -void Digitizer::DigitizePSCU(UInt_t length, UChar_t type) { +void Digitizer::DigitizePSCU(UInt_t length, UChar_t type, UShort_t *pPSCU) { // UChar_t buff[16]; // @@ -355,7 +501,8 @@ // buff[15] = (BYTE)CM_Compute_CRC16((UINT16)0, (BYTE*)&buff, (UINT32)15); // - memcpy(fDataPSCU,buff,16*sizeof(UChar_t)); + //memcpy(fDataPSCU,buff,16*sizeof(UChar_t)); + memcpy(pPSCU,buff,16*sizeof(UChar_t)); // }; @@ -605,7 +752,7 @@ fCALOlength++; // UInt_t length=fCALOlength*2; - DigitizePSCU(length,0x18); + DigitizePSCU(length,0x18,fDataPSCU); // // Add padding to 64 bits // @@ -1028,11 +1175,12 @@ // }; -void Digitizer::DigitizeTRIGGER() { - //fDataTrigger: 153 bytes - for (Int_t j=0; j < 153; j++) - fDataTrigger[j]=0x00; -}; +//void Digitizer::DigitizeTRIGGER() { + //fDataTrigger: 152 bytes + // corrected 30/11/'07 SO (was 153) + //for (Int_t j=0; j < 152; j++) + // fDataTrigger[j]=0x00; +//}; Int_t Digitizer::DigitizeTOF() { //fDataTof: 12 x 23 bytes (=276 bytes) @@ -1204,7 +1352,7 @@ else ipad=0; - if (ip<6) { + if (ip<6) { Paddle2Pmt(ip, ipad, &pmtleft, &pmtright); // DC: evaluates mean position and path inside the paddle @@ -1389,11 +1537,11 @@ cout<<"-----------"<SetBranchStatus("Ievnt",&Ievnt); + UInt_t cTrg = (UInt_t)Ievnt; //counter + UInt_t cTrg2 = 0; //counter with bits inverted, according to document + //"formato dati provenienti dalla trigger board" + for (Int_t i=0; i < 24; i++){ // Use the first 24 bits + if (cTrg & (0x1 << i) ) + cTrg2 = cTrg2 | (0x1 << (24-i)); + }; + fDataTrigger[7] = (UChar_t)(cTrg2 >> 16); // 8 MSbits (out of 24) + fDataTrigger[8] = (UChar_t)(cTrg2 >> 8); // 8 "middle" bits + fDataTrigger[9] = (UChar_t)(cTrg2); // 8 LSbits + pTrg=fDataTrigger+7; + fDataTrigger[10]=EvaluateCrcTrigger(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; i < 48; i++) + //if (ADCtof[i]>thrTrg) + if (tdc1[channelmap[i]]!=0) + fDataTrigger[147-(Int_t)((PatternTrigMap[i]+1)/8)]=fDataTrigger[147-(Int_t)((PatternTrigMap[i]+1)/8)] | (0x1 << (PatternTrigMap[i]%8)); + pTrg=fDataTrigger+141; + fDataTrigger[148]=EvaluateCrcTrigger(pTrg, 7); + + // TB_READ_TRIGGER_CONF : set always acq.mode TOF4 + // + // TOF1: S1-S2-S3 (&,|) + // TOF4: S2-S3 (&,&) + fDataTrigger[149]=0x02; + fDataTrigger[150]=0x0; + pTrg=fDataTrigger+149; + fDataTrigger[151]=EvaluateCrcTrigger(pTrg, 2); + return(0); }; @@ -1498,6 +1709,19 @@ return(crcTof); } +UChar_t Digitizer::EvaluateCrcTrigger(UChar_t *pTrg, Int_t nb) { + Bool_t DEBUG=false; + if (DEBUG) + return(0x00); + + UChar_t crcTrg=0x00; + UChar_t *pc=&crcTrg, *pc2; + pc2=pTrg; + for (Int_t jp=0; jp < nb; jp++) + Crc8Tof(pc2++,pc); + return(crcTrg); +} + void Digitizer::Crc8Tof(UChar_t *oldCRC, UChar_t *crcTof){ union crctof_data { UChar_t word; @@ -1569,7 +1793,51 @@ // created: J. Conrad, KTH // modified: S. Orsi, INFN Roma2 // fDataAC[0-63]: main AC board - // fDataAC[64-127]: extra AC board + // fDataAC[64-127]: extra AC board (identical to main board, for now) + + // We activate all branches. Once the digitization algorithm is determined + // only the branches that involve needed information will be activated + + fhBookTree->SetBranchStatus("Ievnt",&Ievnt); + fhBookTree->SetBranchStatus("Nthcat",1); + fhBookTree->SetBranchStatus("Iparcat",1); + fhBookTree->SetBranchStatus("Icat",1); + fhBookTree->SetBranchStatus("Xincat",1); + fhBookTree->SetBranchStatus("Yincat",1); + fhBookTree->SetBranchStatus("Zincat",1); + fhBookTree->SetBranchStatus("Xoutcat",1); + fhBookTree->SetBranchStatus("Youtcat",1); + fhBookTree->SetBranchStatus("Zoutcat",1); + fhBookTree->SetBranchStatus("Erelcat",1); + fhBookTree->SetBranchStatus("Timecat",1); + fhBookTree->SetBranchStatus("Pathcat",1); + fhBookTree->SetBranchStatus("P0cat",1); + fhBookTree->SetBranchStatus("Nthcas",1); + fhBookTree->SetBranchStatus("Iparcas",1); + fhBookTree->SetBranchStatus("Icas",1); + fhBookTree->SetBranchStatus("Xincas",1); + fhBookTree->SetBranchStatus("Yincas",1); + fhBookTree->SetBranchStatus("Zincas",1); + fhBookTree->SetBranchStatus("Xoutcas",1); + fhBookTree->SetBranchStatus("Youtcas",1); + fhBookTree->SetBranchStatus("Zoutcas",1); + fhBookTree->SetBranchStatus("Erelcas",1); + fhBookTree->SetBranchStatus("Timecas",1); + fhBookTree->SetBranchStatus("Pathcas",1); + fhBookTree->SetBranchStatus("P0cas",1); + fhBookTree->SetBranchStatus("Nthcard",1); + fhBookTree->SetBranchStatus("Iparcard",1); + fhBookTree->SetBranchStatus("Icard",1); + fhBookTree->SetBranchStatus("Xincard",1); + fhBookTree->SetBranchStatus("Yincard",1); + fhBookTree->SetBranchStatus("Zincard",1); + fhBookTree->SetBranchStatus("Xoutcard",1); + fhBookTree->SetBranchStatus("Youtcard",1); + fhBookTree->SetBranchStatus("Zoutcard",1); + fhBookTree->SetBranchStatus("Erelcard",1); + fhBookTree->SetBranchStatus("Timecard",1); + fhBookTree->SetBranchStatus("Pathcard",1); + fhBookTree->SetBranchStatus("P0card",1); fDataAC[0] = 0xACAC; fDataAC[64]= 0xACAC; @@ -1595,8 +1863,10 @@ // shift registers (moved to the end of the routine) - Int_t evntLSB=Ievnt%65536; - Int_t evntMSB=(Int_t)(Ievnt/65536); + //Int_t evntLSB=Ievnt%65536; + //Int_t evntMSB=(Int_t)(Ievnt/65536); + Int_t evntLSB=(UShort_t)Ievnt; + Int_t evntMSB=Ievnt >> 16; // singles counters are dummy for (UInt_t i=0; i<=15; i++){ //SO Oct '07: // for (UInt_t i=0; i<=16; i++){ @@ -1653,50 +1923,6 @@ fDataAC[i+119] = 0x1A13; } - // We activate all branches. Once the digitization algorithm is determined - // only the branches that involve needed information will be activated - - fhBookTree->SetBranchAddress("Ievnt",&Ievnt); - fhBookTree->SetBranchStatus("Nthcat",1); - fhBookTree->SetBranchStatus("Iparcat",1); - fhBookTree->SetBranchStatus("Icat",1); - fhBookTree->SetBranchStatus("Xincat",1); - fhBookTree->SetBranchStatus("Yincat",1); - fhBookTree->SetBranchStatus("Zincat",1); - fhBookTree->SetBranchStatus("Xoutcat",1); - fhBookTree->SetBranchStatus("Youtcat",1); - fhBookTree->SetBranchStatus("Zoutcat",1); - fhBookTree->SetBranchStatus("Erelcat",1); - fhBookTree->SetBranchStatus("Timecat",1); - fhBookTree->SetBranchStatus("Pathcat",1); - fhBookTree->SetBranchStatus("P0cat",1); - fhBookTree->SetBranchStatus("Nthcas",1); - fhBookTree->SetBranchStatus("Iparcas",1); - fhBookTree->SetBranchStatus("Icas",1); - fhBookTree->SetBranchStatus("Xincas",1); - fhBookTree->SetBranchStatus("Yincas",1); - fhBookTree->SetBranchStatus("Zincas",1); - fhBookTree->SetBranchStatus("Xoutcas",1); - fhBookTree->SetBranchStatus("Youtcas",1); - fhBookTree->SetBranchStatus("Zoutcas",1); - fhBookTree->SetBranchStatus("Erelcas",1); - fhBookTree->SetBranchStatus("Timecas",1); - fhBookTree->SetBranchStatus("Pathcas",1); - fhBookTree->SetBranchStatus("P0cas",1); - fhBookTree->SetBranchStatus("Nthcard",1); - fhBookTree->SetBranchStatus("Iparcard",1); - fhBookTree->SetBranchStatus("Icard",1); - fhBookTree->SetBranchStatus("Xincard",1); - fhBookTree->SetBranchStatus("Yincard",1); - fhBookTree->SetBranchStatus("Zincard",1); - fhBookTree->SetBranchStatus("Xoutcard",1); - fhBookTree->SetBranchStatus("Youtcard",1); - fhBookTree->SetBranchStatus("Zoutcard",1); - fhBookTree->SetBranchStatus("Erelcard",1); - fhBookTree->SetBranchStatus("Timecard",1); - fhBookTree->SetBranchStatus("Pathcard",1); - fhBookTree->SetBranchStatus("P0card",1); - // In this simpliefied approach we will assume that once // a particle releases > 0.5 mip in one of the 12 AC detectors it // will fire. We will furthermore assume that both cards read out @@ -1725,9 +1951,17 @@ // 6.41609e-01 +- 2.65846e-02 // 9.81177e+00 +- 1.21284e+00 // hp: 1 minimum ionising particle at 35cm from the PMT releases 1mip - // - // NB: the PMT positions are needed! + TF1 *attenAC = new TF1("fAttAC",".825+.64*atan(9.8/x)",0.,45.); + + // PMT positions: x,y,z: (average position of the 2 PMTs) + Float_t posCasPmt[4][3]={{28.308, -17.168, 63.644}, // 1 - CAS CPU: x,y,z + {18.893, 24.913, 63.644}, // 2 - CAS DCDC + {-24.307, 17.162, 63.644}, // 3 - CAS VME + {-17.765, -28.300, 63.644}}; // 4 - CAS IPM + + Float_t dAC=0.; // distance from PMT + // look in CAT // for (UInt_t k= 0;k<50;k++){ for (Int_t k= 0;k0) - SumEcas[Icas[k]] += Erelcas[k]; + if (Erelcas[k] >0) { + dAC=sqrt(pow((Xincas[k]+Xoutcas[k])/2 - posCasPmt[Icas[k]-1][0],2) + pow((Yincas[k]+Youtcas[k])/2 - posCasPmt[Icas[k]-1][1],2) + pow((Zincas[k]+Zoutcas[k])/2 - posCasPmt[Icas[k]-1][2],2)); + SumEcas[Icas[k]] += Erelcas[k]*attenAC->Eval(dAC); + } }; // look in CARD for (Int_t k= 0;k0) + if (Erelcard[k] >0) SumEcard[Icard[k]] += Erelcard[k]; }; @@ -1975,6 +2211,13 @@ } }; +void Digitizer::WriteRunHeader(){ + fOutputfile.write(reinterpret_cast(fDataRunHeader),sizeof(UShort_t)*fRunHeaderbuffer); +}; + +void Digitizer::WriteRunTrailer(){ + fOutputfile.write(reinterpret_cast(fDataRunTrailer),sizeof(UShort_t)*fRunTrailerbuffer); +}; void Digitizer::WriteData(){ @@ -1982,9 +2225,9 @@ // PSCU data are already swapped fOutputfile.write(reinterpret_cast(fDataPSCU),sizeof(UShort_t)*fPSCUbuffer); // TRG - fOutputfile.write(reinterpret_cast(fDataTrigger),sizeof(UChar_t)*153); + fOutputfile.write(reinterpret_cast(fDataTrigger),sizeof(UChar_t)*fTRIGGERbuffer); //30/11/07 SO; it was 153 // TOF - fOutputfile.write(reinterpret_cast(fDataTof),sizeof(UChar_t)*276); + fOutputfile.write(reinterpret_cast(fDataTof),sizeof(UChar_t)*fTOFbuffer); // AC UShort_t temp[1000000]; memset(temp,0,sizeof(UShort_t)*1000000);