X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=ZDC%2FAliZDC.cxx;h=220a0bc54ced55cd721cde935e2713f346f89a4e;hb=2e096a1e149a43d5ebe00c0a3717a1b2801186e6;hp=215961c46c9efb20fc5a4926950e6487dc0eadad;hpb=866ab5a2482a5b4c1493a28727bb0e8753d7777c;p=u%2Fmrichter%2FAliRoot.git diff --git a/ZDC/AliZDC.cxx b/ZDC/AliZDC.cxx index 215961c46c9..220a0bc54ce 100644 --- a/ZDC/AliZDC.cxx +++ b/ZDC/AliZDC.cxx @@ -13,124 +13,99 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ -/* -$Log$ -Revision 1.9 2000/10/02 21:28:20 fca -Removal of useless dependecies via forward declarations - -Revision 1.8 2000/07/10 13:58:01 fca -New version of ZDC from E.Scomparin & C.Oppedisano - -Revision 1.7 2000/01/19 17:17:40 fca - -Revision 1.6 1999/09/29 09:24:35 fca -Introduction of the Copyright and cvs Log - -*/ +/* $Id$ */ /////////////////////////////////////////////////////////////////////////////// // // -// Zero Degree Calorimeter // -// This class contains the basic functions for the Time Of Flight // -// detector. Functions specific to one particular geometry are // -// contained in the derived classes // +// Zero Degree Calorimeter // +// This class contains the basic functions for the ZDCs; // +// functions specific to one particular geometry are // +// contained in the derived classes // // // /////////////////////////////////////////////////////////////////////////////// -#include -#include -#include "TGeometry.h" +// --- ROOT system +#include +#include +#include +#include +#include +#include -#include "AliZDC.h" +// --- AliRoot header files +#include "AliDetector.h" +#include "AliRawDataHeaderSim.h" +#include "AliRawReader.h" +#include "AliLoader.h" #include "AliRun.h" -#include "AliCallf77.h" -#include "AliConst.h" #include "AliMC.h" +#include "AliLog.h" +#include "AliDAQ.h" +#include "AliZDC.h" +#include "AliZDCHit.h" +#include "AliZDCSDigit.h" +#include "AliZDCDigit.h" +#include "AliZDCDigitizer.h" +#include "AliZDCRawStream.h" +#include "AliZDCPedestals.h" +#include "AliZDCEnCalib.h" +#include "AliZDCTowerCalib.h" +#include "AliFstream.h" ClassImp(AliZDC) - + //_____________________________________________________________________________ -AliZDC::AliZDC() +AliZDC::AliZDC() : + AliDetector(), + fNoShower(0), + fPedCalib(0), + fEnCalibData(0), + fTowCalibData(0), + fZDCCalibFName(""), + fSpectatorTracked(1) { // // Default constructor for the Zero Degree Calorimeter base class // + fIshunt = 1; + fNhits = 0; fHits = 0; + fDigits = 0; + fNdigits = 0; + } //_____________________________________________________________________________ -AliZDC::AliZDC(const char *name, const char *title) - : AliDetector(name,title) +AliZDC::AliZDC(const char *name, const char *title) : + AliDetector(name,title), + fNoShower (0), + fPedCalib(0), + fEnCalibData(0), + fTowCalibData(0), + fZDCCalibFName(""), + fSpectatorTracked(1) { // // Standard constructor for the Zero Degree Calorimeter base class // - - // - // Allocate the array of hits - fHits = new TClonesArray("AliZDChit", 405); - gAlice->AddHitList(fHits); - - fIshunt = 1; - - fDimZN[0] = 3.52; - fDimZN[1] = 3.52; - fDimZN[2] = 50.; - fDimZP[0] = 11.2; - fDimZP[1] = 6.; - fDimZP[2] = 75.; - fPosZN[0] = 0.; - fPosZN[1] = 0.; - fPosZN[2] = 11650.; - fPosZP[0] = -23.; - fPosZP[1] = 0.; - fPosZP[2] = 11600.; - fFibZN[0] = 0.; - fFibZN[1] = 0.01825; - fFibZN[2] = 50.; - fFibZP[0] = 0.; - fFibZP[1] = 0.0275; - fFibZP[2] = 75.; - fGrvZN[0] = 0.03; - fGrvZN[1] = 0.03; - fGrvZN[2] = 50.; - fGrvZP[0] = 0.04; - fGrvZP[1] = 0.04; - fGrvZP[2] = 75.; - fDivZN[0] = 11; - fDivZN[1] = 11; - fDivZN[2] = 0; - fDivZP[0] = 7; - fDivZP[1] = 15; - fDivZP[2] = 0; - fTowZN[0] = 2; - fTowZN[1] = 2; - fTowZP[0] = 4; - fTowZP[1] = 1; + + fIshunt = 1; + fNhits = 0; + fDigits = 0; + fNdigits = 0; + + fHits = new TClonesArray("AliZDCHit",1000); + gAlice->GetMCApp()->AddHitList(fHits); - // EM Calorimeter - fDimZEMPb = 0.15*(TMath::Sqrt(2.)); - fDimZEMAir = 0.001; - fFibRadZEM = 0.0315; - fDivZEM[0] = 92; - fDivZEM[1] = 0; - fDivZEM[2] = 20; - fDimZEM[0] = 2*fDivZEM[2]*(fDimZEMPb+fDimZEMAir+fFibRadZEM*(TMath::Sqrt(2.))); - fDimZEM[1] = 3.5; - fDimZEM[2] = 3.5; - fDimZEM[3] = 45.; - fDimZEM[4] = 0.; - fDimZEM[5] = 0.; - fFibZEM[0] = 0.; - fFibZEM[1] = 0.0275; - fFibZEM[2] = fDimZEM[2]/TMath::Sin(fDimZEM[3]*kDegrad)-fFibRadZEM; - fPosZEM[0] = 0.; - fPosZEM[1] = 5.8; - fPosZEM[2] = 11600.; + char sensname[5],senstitle[25]; + sprintf(sensname,"ZDC"); + sprintf(senstitle,"ZDC dummy"); + SetName(sensname); SetTitle(senstitle); } + //____________________________________________________________________________ AliZDC::~AliZDC() { @@ -138,129 +113,702 @@ AliZDC::~AliZDC() // ZDC destructor // - fIshunt = 0; - delete fHits; + fIshunt = 0; + if(fPedCalib) delete fPedCalib; + if(fEnCalibData) delete fEnCalibData; + if(fEnCalibData) delete fEnCalibData; + } + +//_____________________________________________________________________________ +AliZDC::AliZDC(const AliZDC& ZDC) : +AliDetector("ZDC","ZDC"), +fNoShower(ZDC.fNoShower), +fPedCalib(ZDC.fPedCalib), +fEnCalibData(ZDC.fEnCalibData), +fTowCalibData(ZDC.fTowCalibData), +fZDCCalibFName(ZDC.fZDCCalibFName), +fSpectatorTracked(ZDC.fSpectatorTracked) +{ + // copy constructor +} + +//_____________________________________________________________________________ +AliZDC& AliZDC::operator=(const AliZDC& ZDC) +{ + // assignement operator + if(this!=&ZDC){ + fNoShower = ZDC.fNoShower; + fPedCalib = ZDC.fPedCalib; + fEnCalibData = ZDC.fEnCalibData; + fTowCalibData = ZDC.fTowCalibData; + fZDCCalibFName = ZDC.fZDCCalibFName; + } return *this; +} + //_____________________________________________________________________________ void AliZDC::AddHit(Int_t track, Int_t *vol, Float_t *hits) { // - // Add a ZDC hit - // - static Float_t primKinEn, xImpact, yImpact, sFlag; + // Add a ZDC hit to the hit list. + + static Float_t trackTime=0., primKinEn=0., xImpact=0., yImpact=0., sFlag=0.; + static Int_t pcPDGcode, motPDGcode; + AliZDCHit *newquad, *curprimquad; + newquad = new AliZDCHit(fIshunt, track, vol, hits); TClonesArray &lhits = *fHits; - - AliZDChit *newquad, *curquad; - newquad = new AliZDChit(fIshunt, track, vol, hits); - Int_t i; - for(i=0; iPrint(""); - return; - } - } - - //Otherwise create a new hit. - if(fNhits==0){ + + if(fNhits==0){ // First hit -> setting flag for primary or secondary particle - Int_t primary = gAlice->GetPrimary(track); - if(track != primary){ - newquad->fSFlag = 1; // Hit created by secondary particle entering the ZDC + TParticle * p = gAlice->GetMCApp()->Particle(track); + Int_t imo = p->GetFirstMother(); + // + if(track != imo){ + newquad->SetSFlag(1); // SECONDARY particle entering the ZDC + } + else if(track == imo){ + newquad->SetSFlag(0); // PRIMARY particle entering the ZDC } - else if(track == primary){ - newquad->fSFlag = 0; // Hit created by PRIMARY particle entering the ZDC - } - sFlag = newquad->fSFlag; - primKinEn = newquad->fPrimKinEn; - xImpact = newquad->fXImpact; - yImpact = newquad->fYImpact; + // + sFlag = newquad->GetSFlag(); + primKinEn = newquad->GetPrimKinEn(); + xImpact = newquad->GetXImpact(); + yImpact = newquad->GetYImpact(); + pcPDGcode = newquad->GetPDGCode(); + motPDGcode = newquad->GetMotherPDGCode(); + trackTime = newquad->GetTrackTOF(); } else{ - newquad->fPrimKinEn = primKinEn; - newquad->fXImpact = xImpact; - newquad->fYImpact = yImpact; - newquad->fSFlag = sFlag; + newquad->SetPrimKinEn(primKinEn); + newquad->SetXImpact(xImpact); + newquad->SetYImpact(yImpact); + newquad->SetSFlag(sFlag); + newquad->SetPDGCode(pcPDGcode); + newquad->SetMotherPDGCode(motPDGcode); + newquad->SetTrackTOF(trackTime); } -// printf("\n"); -// fHits->Print(""); - new(lhits[fNhits++]) AliZDChit(newquad); - delete newquad; + + Int_t j; + for(j=0; jPrint(""); + // + delete newquad; + return; + } } + + //Otherwise create a new hit + new(lhits[fNhits]) AliZDCHit(*newquad); + fNhits++; + // Ch. debug + //printf("\n\t New ZDC hit added! fNhits = %d\n", fNhits); + //newquad->Print(""); + + delete newquad; +} + +//____________________________________________________________________________ +Float_t AliZDC::ZMin(void) const +{ + // Minimum dimension of the ZDC module in z + return -11600.; +} + +//____________________________________________________________________________ +Float_t AliZDC::ZMax(void) const +{ + // Maximum dimension of the ZDC module in z + return 11750.; +} + //_____________________________________________________________________________ -void AliZDC::ResetHits() +void AliZDC::MakeBranch(Option_t *opt) { // - // Reset number of hits and the hits array + // Create Tree branches for the ZDC // - AliDetector::ResetHits(); + + char branchname[10]; + sprintf(branchname,"%s",GetName()); + + const char *cH = strstr(opt,"H"); + + if(cH && fLoader->TreeH()) { + if (fHits) { + fHits->Clear(); + fNhits = 0; + } + else { + fHits = new TClonesArray("AliZDCHit",1000); + if (gAlice && gAlice->GetMCApp()) + gAlice->GetMCApp()->AddHitList(fHits); + } + } + + AliDetector::MakeBranch(opt); } + //_____________________________________________________________________________ -void AliZDC::BuildGeometry() +void AliZDC::Hits2SDigits() { + // Create summable digits from hits + + AliDebug(1,"\n AliZDC::Hits2SDigits() "); + + fLoader->LoadHits("read"); + fLoader->LoadSDigits("recreate"); + AliRunLoader* runLoader = fLoader->GetRunLoader(); + AliZDCSDigit sdigit; + AliZDCSDigit* psdigit = &sdigit; + + // Event loop + for(Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) { + Float_t pmZNC[5], pmZPC[5], pmZNA[5], pmZPA[5], pmZEM1=0., pmZEM2=0.; + for(Int_t i=0; i<5; i++) pmZNC[i] = pmZPC[i] = pmZNA[i] = pmZPA[i] = 0; + + runLoader->GetEvent(iEvent); + TTree* treeH = fLoader->TreeH(); + Int_t ntracks = (Int_t) treeH->GetEntries(); + ResetHits(); + + // Tracks loop + Int_t sector[2]; Float_t trackTime = 0.; + for(Int_t itrack = 0; itrack < ntracks; itrack++) { + treeH->GetEntry(itrack); + for(AliZDCHit* zdcHit = (AliZDCHit*)FirstHit(-1); zdcHit; + zdcHit = (AliZDCHit*)NextHit()) { + + sector[0] = zdcHit->GetVolume(0); + sector[1] = zdcHit->GetVolume(1); + if((sector[1] < 1) || (sector[1]>5)) { + Error("Hits2SDigits", "sector[0] = %d, sector[1] = %d", sector[0], sector[1]); + continue; + } + Float_t lightQ = zdcHit->GetLightPMQ(); + Float_t lightC = zdcHit->GetLightPMC(); + trackTime = zdcHit->GetTrackTOF(); + // Signals from ZEM are delayed to arrive in time with ZDC signals + if(sector[0] == 3) trackTime += 320; + // Ch. debug + //printf("\t det %d vol %d trackTOF %f lightQ %1.0f lightC %1.0f\n", + // sector[0], sector[1], trackTime, lightQ, lightC); + + if(sector[0] == 1) { //ZNC + pmZNC[0] += lightC; + pmZNC[sector[1]] += lightQ; + } + else if(sector[0] == 2) { //ZPC + pmZPC[0] += lightC; + pmZPC[sector[1]] += lightQ; + } + else if(sector[0] == 3) { //ZEM + if(sector[1] == 1) pmZEM1 += lightC; + else pmZEM2 += lightQ; + } + if(sector[0] == 4) { //ZNA + pmZNA[0] += lightC; + pmZNA[sector[1]] += lightQ; + } + else if(sector[0] == 5) { //ZPA + pmZPA[0] += lightC; + pmZPA[sector[1]] += lightQ; + } + }//Hits loop + }//Tracks loop + + // create the output tree + fLoader->MakeTree("S"); + TTree* treeS = fLoader->TreeS(); + const Int_t kBufferSize = 4000; + treeS->Branch(GetName(), "AliZDCSDigit", &psdigit, kBufferSize); + + // Create sdigits for ZNC + sector[0] = 1; // Detector = ZNC + for(Int_t j = 0; j < 5; j++) { + sector[1] = j; + if(pmZNC[j]>0){ + new(psdigit) AliZDCSDigit(sector, pmZNC[j], trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZNC[%d] %1.0f trackTOF %f\n", + // sector[0], sector[1], j, pmZNC[j], trackTime); + } + } + + // Create sdigits for ZPC + sector[0] = 2; // Detector = ZPC + for(Int_t j = 0; j < 5; j++) { + sector[1] = j; // Towers PM ADCs + if(pmZPC[j]>0){ + new(psdigit) AliZDCSDigit(sector, pmZPC[j], trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZPC[%d] %1.0f trackTOF %f\n", + // sector[0], sector[1], j, pmZPC[j], trackTime); + } + } + + // Create sdigits for ZEM + sector[0] = 3; + sector[1] = 1; // Detector = ZEM1 + if(pmZEM1>0){ + new(psdigit) AliZDCSDigit(sector, pmZEM1, trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZEM1 %1.0f trackTOF %f\n", + // sector[0], sector[1], pmZEM1, trackTime); + } + sector[1] = 2; // Detector = ZEM2 + if(pmZEM2>0){ + new(psdigit) AliZDCSDigit(sector, pmZEM2, trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZEM2 %1.0f trackTOF %f\n", + // sector[0], sector[1], pmZEM2, trackTime); + } + + // Create sdigits for ZNA + sector[0] = 4; // Detector = ZNA + for(Int_t j = 0; j < 5; j++) { + sector[1] = j; // Towers PM ADCs + if(pmZNA[j]>0){ + new(psdigit) AliZDCSDigit(sector, pmZNA[j], trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZNA[%d] %1.0f trackTOF %f\n", + // sector[0], sector[1], j, pmZNA[j], trackTime); + } + } + + // Create sdigits for ZPA + sector[0] = 5; // Detector = ZPA + sector[1] = 0; // Common PM ADC + for(Int_t j = 0; j < 5; j++) { + sector[1] = j; // Towers PM ADCs + if(pmZPA[j]>0){ + new(psdigit) AliZDCSDigit(sector, pmZPA[j], trackTime); + treeS->Fill(); + // Ch. debug + //printf("\t SDigit created: det %d quad %d pmZPA[%d] %1.0f trackTOF %f\n", + // sector[0], sector[1], j, pmZPA[j], trackTime); + } + } + + // write the output tree + fLoader->WriteSDigits("OVERWRITE"); + } + + fLoader->UnloadHits(); + fLoader->UnloadSDigits(); +} + +//_____________________________________________________________________________ +AliDigitizer* AliZDC::CreateDigitizer(AliRunDigitizer* manager) const +{ + // Create the digitizer for ZDC + AliZDCDigitizer *zdcDigitizer = new AliZDCDigitizer(manager); + if(fSpectatorTracked==0) zdcDigitizer->SetSpectators2Track(); + //printf("\n**************************ZDC digitizer created with Spectators2Track = %d\n\n", fSpectatorTracked); + return zdcDigitizer; +} + +//_____________________________________________________________________________ +void AliZDC::Digits2Raw() +{ + // Convert ZDC digits to raw data + + // Format: 24 int values -> ZN1(C+Q1-4), ZP1(C+Q1-4), ZEM1, ZEM2, ZN(C+Q1-4), ZP2(C+Q1-4), 2 Ref PMs + // + 24 int values for the corresponding out of time channels + // For the CAEN module V965 we have an Header, the Data Words and an End Of Block + // 12 channels x 2 gain chains read from 1st ADC module + // 12 channels x 2 gain chains read from 2nd ADC module + // 12 channels x 2 gain chains read from 3rd ADC module (o.o.t.) + // 12 channels x 2 gain chains read from 4rth ADC module (o.o.t.) + // + const int knADCData1=12, knADCData2=12; + const int knADCData3=12, knADCData4=12; + // + UInt_t lADCHeader1; + UInt_t lADCHeader2; + UInt_t lADCHeader3; + UInt_t lADCHeader4; // - // Build the ROOT TNode geometry for event display - // in the Zero Degree Calorimeter - // This routine is dummy for the moment + UInt_t lADCData1[2*knADCData1]; + UInt_t lADCData2[2*knADCData2]; + UInt_t lADCData3[2*knADCData3]; + UInt_t lADCData4[2*knADCData4]; // + UInt_t lADCEndBlock; - TNode *node, *top; - TBRIK *brik; - const int kColorZDC = kRed; + // load the digits + fLoader->LoadDigits("read"); + AliZDCDigit digit; + AliZDCDigit* pdigit = &digit; + TTree* treeD = fLoader->TreeD(); + if(!treeD) return; + treeD->SetBranchAddress("ZDC", &pdigit); + //printf("\t AliZDC::Digits2Raw -> TreeD has %d entries\n",(Int_t) treeD->GetEntries()); + + // Reading channel map + //printf("\n\t Reading ADC mapping from OCDB\n"); + AliZDCChMap * chMap = GetChMap(); + const int nCh = knADCData1+knADCData2+knADCData3+knADCData4; + Int_t mapADC[nCh][4]; + for(Int_t i=0; iGetADCModule(i); + mapADC[i][1] = chMap->GetADCChannel(i); + mapADC[i][2] = chMap->GetDetector(i); + mapADC[i][3] = chMap->GetSector(i); + // Ch. debug + //printf(" mapADC[%d] = (%d %d %d %d)\n", i, + // mapADC[i][0],mapADC[i][1],mapADC[i][2],mapADC[i][3]); + } + + // *** Fill data array + // ** ADC header + UInt_t lADCHeaderGEO1 = 0; + UInt_t lADCHeaderGEO2 = 1; + UInt_t lADCHeaderGEO3 = 2; + UInt_t lADCHeaderGEO4 = 3; + UInt_t lADCHeaderCRATE = 0; + UInt_t lADCHeaderCNT1 = knADCData1; + UInt_t lADCHeaderCNT2 = knADCData2; + UInt_t lADCHeaderCNT3 = knADCData3; + UInt_t lADCHeaderCNT4 = knADCData4; + + lADCHeader1 = lADCHeaderGEO1 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT1 << 8 ; + lADCHeader2 = lADCHeaderGEO2 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT2 << 8 ; + lADCHeader3 = lADCHeaderGEO3 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT3 << 8 ; + lADCHeader4 = lADCHeaderGEO4 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT4 << 8 ; + + // ** ADC data word + UInt_t lADCDataGEO = 0; + // + UInt_t lADCDataValue1[2*knADCData1]; + UInt_t lADCDataValue2[2*knADCData2]; + UInt_t lADCDataValue3[2*knADCData3]; + UInt_t lADCDataValue4[2*knADCData4]; + // + UInt_t lADCDataOvFlwHG = 0; + UInt_t lADCDataOvFlwLG = 0; + // + for(Int_t i=0; i<2*knADCData1 ; i++) lADCDataValue1[i] = 0; + for(Int_t i=0; i<2*knADCData2 ; i++) lADCDataValue2[i] = 0; + for(Int_t i=0; i<2*knADCData3 ; i++) lADCDataValue3[i] = 0; + for(Int_t i=0; i<2*knADCData4 ; i++) lADCDataValue4[i] = 0; + // + UInt_t lADCDataChannel = 0; + // loop over digits + for(Int_t iDigit=0; iDigitGetEntries(); iDigit++){ + treeD->GetEntry(iDigit); + if(!pdigit) continue; + //digit.Print(""); + + // *** ADC data + // Scan of the map to assign the correct ADC module-channel + for(Int_t k=0; kknADCData1+knADCData2) break; + } + } + } + // Ch. debug + //printf(" det %d sec %d -> lADCDataGEO %d lADCDataChannel %d\n", + // digit.GetSector(0),digit.GetSector(1),lADCDataGEO,lADCDataChannel); + + if(lADCDataGEO==0){ + Int_t indHG = iDigit; + Int_t indLG = indHG+knADCData1; + // High gain ADC ch. + if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1; + lADCDataValue1[indHG] = digit.GetADCValue(0); + lADCData1[indHG] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlwHG << 12 | (lADCDataValue1[indHG] & 0xfff); + // Low gain ADC ch. + if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1; + lADCDataValue1[indLG] = digit.GetADCValue(1); + lADCData1[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlwLG << 12 | (lADCDataValue1[indLG] & 0xfff); + // Ch. debug + //printf(" lADCDataGEO %d lADCDataValue1[%d] = %d lADCDataValue1[%d] = %d\n", + // lADCDataGEO,iDigit,lADCDataValue1[indLG],indLG,lADCDataValue1[indLG]); + } + else if(lADCDataGEO==1){ + Int_t indHG = iDigit-knADCData1; + Int_t indLG = indHG+knADCData2; + // High gain ADC ch. + if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1; + lADCDataValue2[indHG] = digit.GetADCValue(0); + lADCData2[indHG] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlwHG << 12 | (lADCDataValue2[indHG] & 0xfff); + // Low gain ADC ch. + if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1; + lADCDataValue2[indLG] = digit.GetADCValue(1); + lADCData2[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlwLG << 12 | (lADCDataValue2[indLG] & 0xfff); + //Ch. debug + //printf(" lADCDataGEO %d lADCDataValue2[%d] = %d lADCDataValue2[%d] = %d\n", + // lADCDataGEO,indHG,lADCDataValue2[indHG],indLG,lADCDataValue2[indLG]); + } + else if(lADCDataGEO==2){ + Int_t indHG = iDigit-knADCData1-knADCData2; + Int_t indLG = indHG+knADCData3; + // High gain ADC ch. + if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1; + lADCDataValue3[indHG] = digit.GetADCValue(0); + lADCData3[indHG] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlwHG << 12 | (lADCDataValue3[indHG] & 0xfff); + // Low gain ADC ch. + if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1; + lADCDataValue3[indLG] = digit.GetADCValue(1); + lADCData3[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlwLG << 12 | (lADCDataValue3[indLG] & 0xfff); + //Ch. debug + //printf(" lADCDataGEO %d lADCDataValue3[%d] = %d lADCDataValue3[%d] = %d\n", + // lADCDataGEO,indHG,lADCDataValue3[indHG],indLG,lADCDataValue3[indLG]); + } + else if(lADCDataGEO==3){ + Int_t indHG = iDigit-knADCData1-knADCData2-knADCData3; + Int_t indLG = indHG+knADCData4; + // High gain ADC ch. + if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1; + lADCDataValue4[indHG] = digit.GetADCValue(0); + lADCData4[indHG] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlwHG << 12 | (lADCDataValue4[indHG] & 0xfff); + // Low gain ADC ch. + if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1; + lADCDataValue4[indLG] = digit.GetADCValue(1); + lADCData4[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlwLG << 12 | (lADCDataValue4[indLG] & 0xfff); + // Ch. debug + //printf(" lADCDataGEO %d lADCDataValue4[%d] = %d lADCDataValue4[%d] = %d\n", + // lADCDataGEO,indHG,lADCDataValue4[indHG],indLG,lADCDataValue4[indLG]); + } + + } + // + /*for(Int_t i=0;i<2*knADCData1;i++) printf("\t ADCData1[%d] = %x\n",i,lADCData1[i]); + for(Int_t i=0;i<2*knADCData2;i++) printf("\t ADCData2[%d] = %x\n",i,lADCData2[i]); + for(Int_t i=0;i<2*knADCData3;i++) printf("\t ADCData3[%d] = %x\n",i,lADCData3[i]); + for(Int_t i=0;i<2*knADCData4;i++) printf("\t ADCData4[%d] = %x\n",i,lADCData4[i]);*/ + + // End of Block + UInt_t lADCEndBlockGEO = 0; + // Event counter in ADC EOB -> getting no. of events in run from AliRunLoader + // get run loader + AliRunLoader* runLoader = fLoader->GetRunLoader(); + UInt_t lADCEndBlockEvCount = runLoader->GetEventNumber(); + // + lADCEndBlock = lADCEndBlockGEO << 27 | 0x1 << 26 | lADCEndBlockEvCount; + //printf("\t AliZDC::Digits2Raw -> ADCEndBlock = %d\n",lADCEndBlock); + + // open the output file + char fileName[30]; + strcpy(fileName,AliDAQ::DdlFileName("ZDC",0)); + + AliFstream* file = new AliFstream(fileName); + + // write the DDL data header + AliRawDataHeaderSim header; + header.fSize = sizeof(header) + + sizeof(lADCHeader1) + sizeof(lADCData1) + sizeof(lADCEndBlock) + + sizeof(lADCHeader2) + sizeof(lADCData2) + sizeof(lADCEndBlock) + + sizeof(lADCHeader3) + sizeof(lADCData3) + sizeof(lADCEndBlock) + + sizeof(lADCHeader4) + sizeof(lADCData4) + sizeof(lADCEndBlock); // - top=gAlice->GetGeometry()->GetNode("alice"); + /*printf("sizeof header = %d, ADCHeader1 = %d, ADCData1 = %d, ADCEndBlock = %d\n", + sizeof(header),sizeof(lADCHeader1),sizeof(lADCData1),sizeof(lADCEndBlock)); + printf("sizeof header = %d, ADCHeader2 = %d, ADCData2 = %d, ADCEndBlock = %d\n", + sizeof(header),sizeof(lADCHeader2),sizeof(lADCData2),sizeof(lADCEndBlock)); + printf("sizeof header = %d, ADCHeader3 = %d, ADCData3 = %d, ADCEndBlock = %d\n", + sizeof(header),sizeof(lADCHeader1),sizeof(lADCData1),sizeof(lADCEndBlock)); + printf("sizeof header = %d, ADCHeader4 = %d, ADCData4 = %d, ADCEndBlock = %d\n", + sizeof(header),sizeof(lADCHeader2),sizeof(lADCData2),sizeof(lADCEndBlock));*/ - // ZDC - brik = new TBRIK("S_ZDC","ZDC box","void",300,300,5); - top->cd(); - node = new TNode("ZDC","ZDC","S_ZDC",0,0,600,""); - node->SetLineColor(kColorZDC); - fNodes->Add(node); + header.SetAttribute(0); // valid data + file->WriteBuffer((char*)(&header), sizeof(header)); + // write the raw data and close the file + file->WriteBuffer((char*) &lADCHeader1, sizeof (lADCHeader1)); + file->WriteBuffer((char*) &lADCData1, sizeof(lADCData1)); + file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file->WriteBuffer((char*) &lADCHeader2, sizeof (lADCHeader2)); + file->WriteBuffer((char*) (lADCData2), sizeof(lADCData2)); + file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file->WriteBuffer((char*) &lADCHeader3, sizeof (lADCHeader3)); + file->WriteBuffer((char*) (lADCData3), sizeof(lADCData3)); + file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file->WriteBuffer((char*) &lADCHeader4, sizeof (lADCHeader4)); + file->WriteBuffer((char*) (lADCData4), sizeof(lADCData4)); + file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + delete file; + + // unload the digits + fLoader->UnloadDigits(); } //_____________________________________________________________________________ -Int_t AliZDC::DistancetoPrimitive(Int_t , Int_t ) +Bool_t AliZDC::Raw2SDigits(AliRawReader* rawReader) { + // Convert ZDC raw data to Sdigits + const int kNch = 48; + AliLoader* loader = (AliRunLoader::Instance())->GetLoader("ZDCLoader"); + if(!loader) { + AliError("no ZDC loader found"); + return kFALSE; + } + + // Create the output digit tree + TTree* treeS = loader->TreeS(); + if(!treeS){ + loader->MakeTree("S"); + treeS = loader->TreeS(); + } // - // Distance from the mouse to the Zero Degree Calorimeter - // Dummy routine + AliZDCSDigit sdigit; + AliZDCSDigit* psdigit = &sdigit; + const Int_t kBufferSize = 4000; + treeS->Branch("ZDC", "AliZDCSDigit", &psdigit, kBufferSize); // - return 9999; + AliZDCRawStream rawStream(rawReader); + Int_t sector[2], resADC, rawADC, corrADC, nPheVal; + Int_t jcount = 0; + while(rawStream.Next()){ + if(rawStream.IsADCDataWord()){ + //For the moment only in-time SDigits are foreseen (1st 48 raw values) + if(jcount < kNch){ + for(Int_t j=0; j<2; j++) sector[j] = rawStream.GetSector(j); + rawADC = rawStream.GetADCValue(); + resADC = rawStream.GetADCGain(); + //printf("\t RAw2SDigits raw%d -> RawADC[%d, %d, %d] read\n", + // jcount, sector[0], sector[1], rawADC); + // + corrADC = rawADC - Pedestal(sector[0], sector[1], resADC); + if(corrADC<0) corrADC=0; + nPheVal = ADCch2Phe(sector[0], sector[1], corrADC, resADC); + // + //printf("\t \t -> SDigit[%d, %d, %d] created\n", + // sector[0], sector[1], nPheVal); + // + new(psdigit) AliZDCSDigit(sector, (Float_t) nPheVal, 0.); + treeS->Fill(); + jcount++; + } + }//IsADCDataWord + }//rawStream.Next + // write the output tree + fLoader->WriteSDigits("OVERWRITE"); + fLoader->UnloadSDigits(); + + return kTRUE; } - + //_____________________________________________________________________________ -void AliZDC::StepManager() +Int_t AliZDC::Pedestal(Int_t Det, Int_t Quad, Int_t Res) const { + // Returns a pedestal for detector det, PM quad, channel with res. // - // Routine called at every step in the Zero Degree Calorimeter + // Getting calibration object for ZDC set + AliCDBManager *man = AliCDBManager::Instance(); + AliCDBEntry *entry = man->Get("ZDC/Calib/Pedestals"); + AliZDCPedestals *calibPed = (AliZDCPedestals*) entry->GetObject(); // + if(!calibPed){ + printf("\t No calibration object found for ZDC!"); + return -1; + } + // + Int_t index=0, kNch=24; + if(Quad!=5){ + if(Det==1) index = Quad+kNch*Res; // ZN1 + else if(Det==2) index = Quad+5+kNch*Res; // ZP1 + else if(Det==3) index = Quad+9+kNch*Res; // ZEM + else if(Det==4) index = Quad+12+kNch*Res; // ZN2 + else if(Det==5) index = Quad+17+kNch*Res; // ZP2 + } + else index = (Det-1)/3+22+kNch*Res; // Reference PMs + // + // + Float_t meanPed = calibPed->GetMeanPed(index); + Float_t pedWidth = calibPed->GetMeanPedWidth(index); + Float_t pedValue = gRandom->Gaus(meanPed,pedWidth); + // + //printf("\t AliZDC::Pedestal - det(%d, %d) - Ped[%d] = %d\n",Det, Quad, index,(Int_t) pedValue); // Chiara debugging! + + + + return (Int_t) pedValue; } -ClassImp(AliZDChit) - + //_____________________________________________________________________________ -AliZDChit::AliZDChit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits): - AliHit(shunt, track) +Int_t AliZDC::ADCch2Phe(Int_t Det, Int_t Quad, Int_t ADCVal, Int_t Res) const { + // Evaluation of the no. of phe produced + Float_t pmGain[6][5]; + Float_t resADC[2]; + for(Int_t j = 0; j < 5; j++){ + pmGain[0][j] = 50000.; + pmGain[1][j] = 100000.; + pmGain[2][j] = 100000.; + pmGain[3][j] = 50000.; + pmGain[4][j] = 100000.; + pmGain[5][j] = 100000.; + } + // ADC Caen V965 + resADC[0] = 0.0000008; // ADC Resolution high gain: 200 fC/adcCh + resADC[1] = 0.0000064; // ADC Resolution low gain: 25 fC/adcCh // - // Add a ZDC hit + Int_t nPhe = (Int_t) (ADCVal / (pmGain[Det-1][Quad] * resADC[Res])); // - Int_t i; - for(i=0; i<2; i++) fVolume[i] = vol[i]; - fX = hits[0]; - fY = hits[1]; - fZ = hits[2]; - fPrimKinEn = hits[3]; - fXImpact = hits[4]; - fYImpact = hits[5]; - fSFlag = hits[6]; - fLightPMQ = hits[7]; - fLightPMC = hits[8]; - fEnergy = hits[9]; + //printf("\t AliZDC::ADCch2Phe -> det(%d, %d) - ADC %d phe %d\n",Det,Quad,ADCVal,nPhe); + + return nPhe; +} + +//______________________________________________________________________ +void AliZDC::SetTreeAddress(){ + + // Set branch address for the Trees. + if(fLoader->TreeH() && (fHits == 0x0)) + fHits = new TClonesArray("AliZDCHit",1000); + + AliDetector::SetTreeAddress(); +} + +//_____________________________________________________________________________ +AliZDCChMap* AliZDC::GetChMap() const +{ + + // Getting calibration object for ZDC + + AliCDBEntry *entry = AliCDBManager::Instance()->Get("ZDC/Calib/ChMap"); + if(!entry) AliFatal("No calibration data loaded!"); + + AliZDCChMap *calibdata = dynamic_cast (entry->GetObject()); + if(!calibdata) AliFatal("Wrong calibration object in calibration file!"); + + return calibdata; }