X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=ZDC%2FAliZDC.cxx;h=8a6148ce346ec31e614bab65e0764727ea3afe5f;hb=36f43fdfeea3a0bd7bd6b78d5be6e51fd7eb7810;hp=1a0ba7bc8e7ff1b84b863162b100f5a61ab365a3;hpb=ad51aeb0c02b3e46da92b7c5d59c38d3518352f2;p=u%2Fmrichter%2FAliRoot.git
diff --git a/ZDC/AliZDC.cxx b/ZDC/AliZDC.cxx
index 1a0ba7bc8e7..8a6148ce346 100644
--- a/ZDC/AliZDC.cxx
+++ b/ZDC/AliZDC.cxx
@@ -1,99 +1,215 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $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 //
-// //
-//Begin_Html
-/*
-
-
- The responsible person for this module is
-Eugenio Scomparin.
-
-
-
-*/ -//End_Html -// // +// Zero Degree Calorimeter // +// This class contains the basic functions for the ZDCs; // +// functions specific to one particular geometry are // +// contained in the derived classes // // // /////////////////////////////////////////////////////////////////////////////// +// --- ROOT system #include+#include +#include #include +#include +#include +#include +#include -#include "AliZDC.h" +// --- AliRoot header files +#include "AliDetector.h" +#include "AliRawDataHeader.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 "AliZDCCalibData.h" -#ifndef WIN32 -# define zdc_init zdc_init_ -# define zdc_step zdc_step_ -# define zdc_setbeam zdc_setbeam_ -# define zdc_sethijing zdc_sethijing_ -# define zdc_setvenus zdc_setvenus_ -# define zdc_setkine zdc_setkine_ -#else -# define zdc_step ZDC_STEP -# define zdc_setbeam ZDC_SETBEAM -# define zdc_sethijing ZDC_SETHIJING -# define zdc_setvenus ZDC_SETVENUS -# define zdc_setkine ZDC_SETKINE -#endif - -extern "C" void type_of_call zdc_init(); -extern "C" void type_of_call zdc_step(); -extern "C" void type_of_call zdc_setbeam(Int_t beam, Float_t fx, Float_t fy, - Float_t sx, Float_t sy, Float_t div, - Float_t angle, Int_t cross); -extern "C" void type_of_call zdc_sethijing(Int_t hij, Int_t hijf, Int_t hijsp, - DEFCHARD DEFCHARL); -extern "C" void type_of_call zdc_setvenus(Int_t hiv, Int_t hivf, Int_t hivsp, - DEFCHARD DEFCHARL); -extern "C" void type_of_call zdc_setkine(Int_t code, Float_t pmom, Float_t cx, - Float_t cy, Float_t cz, Int_t type, - Int_t fermi); ClassImp(AliZDC) + +AliZDC *gAliZDC; //_____________________________________________________________________________ -AliZDC::AliZDC() +AliZDC::AliZDC() : + AliDetector(), + fNoShower (0), + fCalibData (0) + { // // Default constructor for the Zero Degree Calorimeter base class // - fIshunt = 0; + + 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), + fCalibData (0) + { // // Standard constructor for the Zero Degree Calorimeter base class // + + fIshunt = 1; + fNhits = 0; + fDigits = 0; + fNdigits = 0; + + fHits = new TClonesArray("AliZDCHit",1000); + gAlice->GetMCApp()->AddHitList(fHits); + + char sensname[5],senstitle[25]; + sprintf(sensname,"ZDC"); + sprintf(senstitle,"ZDC dummy"); + SetName(sensname); SetTitle(senstitle); + + gAliZDC = this; + +} +//____________________________________________________________________________ +AliZDC::~AliZDC() +{ // - // Allocate the array of hits - fHits = new TClonesArray("AliZDChit", 405); - - fIshunt = 1; + // ZDC destructor + // + + fIshunt = 0; + gAliZDC = 0; + + delete fCalibData; + } - + +//_____________________________________________________________________________ +AliZDC::AliZDC(const AliZDC& ZDC) : + AliDetector("ZDC","ZDC") +{ + // copy constructor + fNoShower = ZDC.fNoShower; + fCalibData = ZDC.fCalibData; + fZDCCalibFName = ZDC.fZDCCalibFName; +} + +//_____________________________________________________________________________ +AliZDC& AliZDC::operator=(const AliZDC& ZDC) +{ + // assignement operator + if(this!=&ZDC){ + fNoShower = ZDC.fNoShower; + fCalibData = ZDC.fCalibData; + fZDCCalibFName = ZDC.fZDCCalibFName; + } return *this; +} + //_____________________________________________________________________________ void AliZDC::AddHit(Int_t track, Int_t *vol, Float_t *hits) { // - // Add a Zero Degree Calorimeter hit + // Add a ZDC hit to the hit list. + // -> We make use of 2 array of hits: + // [1] fHits (the usual one) that contains hits for each PRIMARY + // [2] fStHits that contains hits for each EVENT and is used to + // obtain digits at the end of each event // + + static Float_t primKinEn, xImpact, yImpact, sFlag; + + AliZDCHit *newquad, *curprimquad; + newquad = new AliZDCHit(fIshunt, track, vol, hits); TClonesArray &lhits = *fHits; - new(lhits[fNhits++]) AliZDChit(fIshunt,track,vol,hits); -} + + if(fNhits==0){ + // First hit -> setting flag for primary or secondary particle + Int_t primary = gAlice->GetMCApp()->GetPrimary(track); + if(track != primary){ + newquad->SetSFlag(1); // SECONDARY particle entering the ZDC + } + else if(track == primary){ + newquad->SetSFlag(0); // PRIMARY particle entering the ZDC + } + sFlag = newquad->GetSFlag(); + primKinEn = newquad->GetPrimKinEn(); + xImpact = newquad->GetXImpact(); + yImpact = newquad->GetYImpact(); + } + else{ + newquad->SetPrimKinEn(primKinEn); + newquad->SetXImpact(xImpact); + newquad->SetYImpact(yImpact); + newquad->SetSFlag(sFlag); + } + Int_t j; + for(j=0; j GetEnergy() != 0. || newquad->GetLightPMC() != 0. || + newquad->GetLightPMQ() != 0.){ + printf("\n\t --- Equal hits found\n"); + curprimquad->Print(""); + newquad->Print(""); + printf("\t --- Det. %d, Quad. %d: X = %f, E = %f, LightPMC = %f, LightPMQ = %f\n", + curprimquad->GetVolume(0),curprimquad->GetVolume(1),curprimquad->GetXImpact(), + curprimquad->GetEnergy(), curprimquad->GetLightPMC(), curprimquad->GetLightPMQ()); + }*/ + // + 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); + printf("\t Det. %d, Quad.t %d: X = %f, E = %f, LightPMC = %f, LightPMQ = %f\n", + newquad->GetVolume(0),newquad->GetVolume(1),newquad->GetXImpact(), + newquad->GetEnergy(), newquad->GetLightPMC(), newquad->GetLightPMQ()); + */ + delete newquad; +} + //_____________________________________________________________________________ void AliZDC::BuildGeometry() { @@ -103,860 +219,577 @@ void AliZDC::BuildGeometry() // This routine is dummy for the moment // - // TNode *Node, *Top; - // TBRIK *brik; - // const int kColorZDC = kRed; + TNode *node, *top; + TBRIK *brik; + const int kColorZDC = kBlue; // - // Top=gAlice->GetGeometry()->GetNode("alice"); + top=gAlice->GetGeometry()->GetNode("alice"); // 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); - */ + top->cd(); + node = new TNode("ZDC","ZDC","S_ZDC",0,0,600,""); + node->SetLineColor(kColorZDC); + fNodes->Add(node); } -//_____________________________________________________________________________ -Int_t AliZDC::DistancetoPrimitive(Int_t , Int_t ) +//____________________________________________________________________________ +Float_t AliZDC::ZMin(void) const { - // - // Distance from the mouse to the Zero Degree Calorimeter - // Dummy routine - // - return 9999; + // Minimum dimension of the ZDC module in z + return -11600.; } - -//_____________________________________________________________________________ -void AliZDC::SetBeam(Int_t beam, Float_t fx, Float_t fy, Float_t sx, - Float_t sy, Float_t div, Float_t angle, Int_t cross) -{ - // - // Set beam characteristic - // This routine has to be revised as it is disconnected from the - // actual generation in this version of AliRoot - // - // beam : 1 = gaussian beam - // : 2 = uniform beam - // fx : x-coordinate of beam offset - // fy : y-coordinate of beam offset - // sx : sigma-x of the beam (gaussian or uniform) - // sy : sigma-y of the beam (gaussian or uniform) - // div : divergency of the beam (32*10**-6 rad for LHC) - // angle : beam crossing angle (100*10**-6 rad for LHC) - // cross : 1 = horizontal beam crossing - // : 2 = vertical beam crossing - zdc_setbeam(beam,fx,fy,sx,sy,div,angle,cross); +//____________________________________________________________________________ +Float_t AliZDC::ZMax(void) const +{ + // Maximum dimension of the ZDC module in z + return -11750.; } + //_____________________________________________________________________________ -void AliZDC::SetHijing(Int_t hij, Int_t hijf, Int_t hijsp, const char *file) +void AliZDC::MakeBranch(Option_t *opt) { // - // Set the parameter for the HIJING generation - // This routine has to be revised as it is disconnected from the - // actual generation in this version of AliRoot + // Create Tree branches for the ZDC // - // HIJ : 1 = read HIJING event file - // : 2 = " " " " + debug - // HIJF : event number of the first event to be read from file - // HIJSP: 0 = read all particles - // : 1 = remove spectator nucleons - zdc_sethijing(hij,hijf,hijsp, PASSCHARD(file) PASSCHARL(file)); + char branchname[10]; + sprintf(branchname,"%s",GetName()); + + const char *cH = strstr(opt,"H"); + + if(cH && fLoader->TreeH()) + fHits = new TClonesArray("AliZDCHit",1000); + + AliDetector::MakeBranch(opt); } //_____________________________________________________________________________ -void AliZDC::SetVenus(Int_t hiv, Int_t hivf, Int_t hivsp, const char *file) +void AliZDC::Hits2SDigits() { - // - // Set the parameter for the VENUS generation - // This routine has to be revised as it is disconnected from the - // actual generation in this version of AliRoot - // + // Create summable digits from hits + + AliDebug(1,"\n Entering AliZDC::Hits2Digits() "); + + fLoader->LoadHits("read"); + fLoader->LoadSDigits("recreate"); + AliRunLoader* runLoader = fLoader->GetRunLoader(); + AliZDCSDigit sdigit; + AliZDCSDigit* psdigit = &sdigit; - // HIV : 1 = read VENUS event file - // : 2 = " " " " + debug - // HIVF : event number of the first event to be read from file - // HIVSP: 0 = read all particles - // : 1 = remove spectator nucleons - zdc_setvenus(hiv,hivf,hivsp, PASSCHARD(file) PASSCHARL(file)); + // Event loop + for(Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) { + Float_t pmCZN = 0, pmCZP = 0, pmQZN[4], pmQZP[4], pmZEM1 = 0, pmZEM2 = 0; + for(Int_t i = 0; i < 4; i++) pmQZN[i] = pmQZP[i] = 0; + + runLoader->GetEvent(iEvent); + TTree* treeH = fLoader->TreeH(); + Int_t ntracks = (Int_t) treeH->GetEntries(); + ResetHits(); + + // Tracks loop + Int_t sector[2]; + 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] > 4)) { + Error("Hits2SDigits", "sector[0] = %d, sector[1] = %d", + sector[0], sector[1]); + continue; + } + Float_t lightQ = zdcHit->GetLightPMQ(); + Float_t lightC = zdcHit->GetLightPMC(); + + if(sector[0] == 1) { //ZN + pmCZN += lightC; + pmQZN[sector[1]-1] += lightQ; + } else if(sector[0] == 2) { //ZP + pmCZP += lightC; + pmQZP[sector[1]-1] += lightQ; + } else if(sector[0] == 3) { //ZEM + if(sector[1] == 1) pmZEM1 += lightC; + else pmZEM2 += lightQ; + } + }//Hits 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 ZN1 + sector[0] = 1; // Detector = ZN1 + sector[1] = 0; // Common PM ADC + new(psdigit) AliZDCSDigit(sector, pmCZN); + if(pmCZN > 0) treeS->Fill(); + for(Int_t j = 0; j < 4; j++) { + sector[1] = j+1; // Towers PM ADCs + new(psdigit) AliZDCSDigit(sector, pmQZN[j]); + if(pmQZN[j] > 0) treeS->Fill(); + } + + // Create sdigits for ZP1 + sector[0] = 2; // Detector = ZP1 + sector[1] = 0; // Common PM ADC + new(psdigit) AliZDCSDigit(sector, pmCZP); + if(pmCZP > 0) treeS->Fill(); + for(Int_t j = 0; j < 4; j++) { + sector[1] = j+1; // Towers PM ADCs + new(psdigit) AliZDCSDigit(sector, pmQZP[j]); + if(pmQZP[j] > 0) treeS->Fill(); + } + + // Create sdigits for ZEM + sector[0] = 3; + sector[1] = 1; // Detector = ZEM1 + new(psdigit) AliZDCSDigit(sector, pmZEM1); + if(pmZEM1 > 0) treeS->Fill(); + sector[1] = 2; // Detector = ZEM2 + new(psdigit) AliZDCSDigit(sector, pmZEM2); + if(pmZEM2 > 0) treeS->Fill(); + + // write the output tree + fLoader->WriteSDigits("OVERWRITE"); + } + + fLoader->UnloadHits(); + fLoader->UnloadSDigits(); } //_____________________________________________________________________________ -void AliZDC::SetKine(Int_t code, Float_t pmom, Float_t cx, Float_t cy, - Float_t cz, Int_t type, Int_t fermi) +AliDigitizer* AliZDC::CreateDigitizer(AliRunDigitizer* manager) const { - // - // Set the parameter for the event generation - // This routine has to be revised as it is disconnected from the - // actual generation in this version of AliRoot - // + // Create the digitizer for ZDC - // code : GEANT code of the test particle - // pmom : absolute value of particle momentum - // cx,cy,cz : director cosines of the track (if type) - // type : 0 = take director cosines from cx,cy,cz - // : <>0 = pseudorapidity of the test particle - // fermi : 0 = no Fermi motion for the spectator nucleons - // : 1 = Fermi motion for the spectator nucleons - zdc_setkine(code,pmom,cx,cy,cz,type,fermi); + return new AliZDCDigitizer(manager); } - + //_____________________________________________________________________________ -void AliZDC::StepManager() +void AliZDC::Digits2Raw() { + // Convert ZDC digits to raw data + + // Format: 22 interger values -> ZN1 (C+Q1-4), ZP1 (C+Q1-4), ZEM1, 2, ZN (C+Q1-4), ZP2 (C+Q1-4)) + // + 22 interger values for the 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 + // 10 channels x 2 gain chains read from 2nd ADC module + // 12 channels x 2 gain chains read from 3rd ADC module (o.o.t.) + // 10 channels x 2 gain chains read from 4rth ADC module (o.o.t.) // - // Routine called at every step in the Zero Degree Calorimeter - // This is a simple interface to the FORTRAN routine - // A step manager should be written + const int knADCData1=24, knADCData2=20; + UInt_t lADCHeader1; + UInt_t lADCData1[knADCData1]; // - zdc_step(); -} + UInt_t lADCHeader2; + UInt_t lADCData2[knADCData2]; + // + UInt_t lADCHeader3; + UInt_t lADCData3[knADCData1]; + // + UInt_t lADCHeader4; + UInt_t lADCData4[knADCData2]; + // + UInt_t lADCEndBlock; + // 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()); + + // Fill data array + // ADC header + UInt_t lADCHeaderGEO = 0; + UInt_t lADCHeaderCRATE = 0; + UInt_t lADCHeaderCNT1 = knADCData1; + UInt_t lADCHeaderCNT2 = knADCData2; + + lADCHeader1 = lADCHeaderGEO << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT1 << 8 ; + // + lADCHeader2 = lADCHeaderGEO << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT2 << 8 ; + // + lADCHeader3 = lADCHeaderGEO << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT1 << 8 ; + // + lADCHeader4 = lADCHeaderGEO << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 | + lADCHeaderCNT2 << 8 ; + //printf("\t lADCHeader1 = %x, lADCHeader2 = %x\n",lADCHeader1, lADCHeader2); + + // ADC data word + UInt_t lADCDataGEO = lADCHeaderGEO; + UInt_t lADCDataValue1[knADCData1]; + UInt_t lADCDataValue2[knADCData2]; + UInt_t lADCDataValue3[knADCData1]; + UInt_t lADCDataValue4[knADCData2]; + UInt_t lADCDataOvFlw1[knADCData1]; + UInt_t lADCDataOvFlw2[knADCData2]; + UInt_t lADCDataOvFlw3[knADCData1]; + UInt_t lADCDataOvFlw4[knADCData2]; + for(Int_t i=0; i GetEntries(); iDigit++){ + treeD->GetEntry(iDigit); + if(!pdigit) continue; + //digit.Print(""); + + // *** ADC data + Int_t index1=0, index2=0; + // *** ADC1 (ZN1, ZP1, ZEM1,2) o ADC3 (ZN1, ZP1, ZEM1,2 o.o.t.) + if(digit.GetSector(0)==1 || digit.GetSector(0)==2 || digit.GetSector(0)==3){ + if(digit.GetSector(0)==1 || digit.GetSector(0)==2){ + index1 = (digit.GetSector(0)-1) + digit.GetSector(1)*4; // ZN1 or ZP1 + lADCDataChannel = (digit.GetSector(0)-1)*8 + digit.GetSector(1); + } + else if(digit.GetSector(0)==3){ // ZEM 1,2 + index1 = 20 + (digit.GetSector(1)-1); + lADCDataChannel = 5 + (digit.GetSector(1)-1)*8; + } + // + /*printf("\t AliZDC::Digits2raw -> det %d, quad %d, index = %d, ADCch = %d\n", + digit.GetSector(0),digit.GetSector(1),index1,lADCDataChannel);// Ch. debug + */ + // + if(iDigit<22){ + lADCDataValue1[index1] = digit.GetADCValue(0); // High gain ADC ch. + if(lADCDataValue1[index1] > 2047) lADCDataOvFlw1[index1] = 1; + lADCDataValue1[index1+2] = digit.GetADCValue(1); // Low gain ADC ch. + if(lADCDataValue1[index1+2] > 2047) lADCDataOvFlw1[index1+2] = 1; + + lADCData1[index1] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlw1[index1] << 12 | (lADCDataValue1[index1] & 0xfff); + lADCData1[index1+2] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlw1[index1+2] << 12 | (lADCDataValue1[index1+2] & 0xfff); + } + else{ + lADCDataValue3[index1] = digit.GetADCValue(0); // High gain ADC ch. + if(lADCDataValue3[index1] > 2047) lADCDataOvFlw3[index1] = 1; + lADCDataValue3[index1+2] = digit.GetADCValue(1); // Low gain ADC ch. + if(lADCDataValue3[index1+2] > 2047) lADCDataOvFlw3[index1+2] = 1; + + lADCData3[index1] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlw3[index1] << 12 | (lADCDataValue3[index1] & 0xfff); + lADCData3[index1+2] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlw3[index1+2] << 12 | (lADCDataValue3[index1+2] & 0xfff); + } + } + // *** ADC2 (ZN2, ZP2) o ADC4 (ZN2, ZP2 o.o.t.) + else if(digit.GetSector(0)==4 || digit.GetSector(0)==5){ + index2 = (digit.GetSector(0)-4) + digit.GetSector(1)*4; // ZN2 or ZP2 + lADCDataChannel = (digit.GetSector(0)-4)*8 + digit.GetSector(1); + // + /*printf("\t AliZDC::Digits2raw -> det %d, quad %d, index = %d, ADCch = %d\n", + digit.GetSector(0),digit.GetSector(1),index1,lADCDataChannel); // Ch. debug + */ + // + if(iDigit<22){ + lADCDataValue2[index2] = digit.GetADCValue(0); + if(lADCDataValue2[index2] > 2047) lADCDataOvFlw2[index2] = 1; + lADCDataValue2[index2+2] = digit.GetADCValue(1); + if(lADCDataValue2[index2+2] > 2047) lADCDataOvFlw2[index2+2] = 1; + // + lADCData2[index2] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlw2[index2] << 12 | (lADCDataValue2[index2] & 0xfff); + lADCData2[index2+2] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlw2[index2+2] << 12 | (lADCDataValue2[index2+2] & 0xfff); + } + else{ + lADCDataValue4[index2] = digit.GetADCValue(0); + if(lADCDataValue4[index2] > 2047) lADCDataOvFlw4[index2] = 1; + lADCDataValue4[index2+2] = digit.GetADCValue(1); + if(lADCDataValue4[index2+2] > 2047) lADCDataOvFlw4[index2+2] = 1; + // + lADCData4[index2] = lADCDataGEO << 27 | lADCDataChannel << 17 | + lADCDataOvFlw4[index2] << 12 | (lADCDataValue4[index2] & 0xfff); + lADCData4[index2+2] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 | + lADCDataOvFlw4[index2+2] << 12 | (lADCDataValue4[index2+2] & 0xfff); + } + } + if((index1<0) || (index1>23)) { + Error("Digits2Raw", "sector[0] = %d, sector[1] = %d", + digit.GetSector(0), digit.GetSector(1)); + continue; + } + if((index2<0) || (index2>19)) { + Error("Digits2Raw", "sector[0] = %d, sector[1] = %d", + digit.GetSector(0), digit.GetSector(1)); + continue; + } + + + } + /* for(Int_t i=0;i<24;i++) printf("\t ADCData1[%d] = %x\n",i,lADCData1[i]); + for(Int_t i=0;i<20;i++) printf("\t ADCData2[%d] = %x\n",i,lADCData2[i]); + for(Int_t i=0;i<24;i++) printf("\t ADCData3[%d] = %x\n",i,lADCData3[i]); + for(Int_t i=0;i<20;i++) printf("\t ADCData4[%d] = %x\n",i,lADCData4[i]); + */ -ClassImp(AliZDCv1) - + // End of Block + UInt_t lADCEndBlockGEO = lADCHeaderGEO; + UInt_t lADCEndBlockEvCount = gAlice->GetEventNrInRun(); + + lADCEndBlock = lADCEndBlockGEO << 27 | 0x1 << 26 | lADCEndBlockEvCount; + + //printf("\t ADCEndBlock = %d\n",lADCEndBlock); -/////////////////////////////////////////////////////////////////////////////// -// // -// Zero Degree Calorimeter version 1 // -// // -//Begin_Html -/* - -*/ -//End_Html -// // -// // -/////////////////////////////////////////////////////////////////////////////// + + // open the output file + char fileName[30]; + strcpy(fileName,AliDAQ::DdlFileName("ZDC",0)); +#ifndef __DECCXX + ofstream file(fileName, ios::binary); +#else + ofstream file(fileName); +#endif + + // write the DDL data header + AliRawDataHeader 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); + /*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));*/ + header.SetAttribute(0); // valid data + file.write((char*)(&header), sizeof(header)); + + // write the raw data and close the file + file.write((char*) &lADCHeader1, sizeof (lADCHeader1)); + file.write((char*)(lADCData1), sizeof(lADCData1)); + file.write((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file.write((char*) &lADCHeader2, sizeof (lADCHeader2)); + file.write((char*)(lADCData2), sizeof(lADCData2)); + file.write((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file.write((char*) &lADCHeader3, sizeof (lADCHeader3)); + file.write((char*)(lADCData3), sizeof(lADCData3)); + file.write((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file.write((char*) &lADCHeader4, sizeof (lADCHeader4)); + file.write((char*)(lADCData4), sizeof(lADCData4)); + file.write((char*) &lADCEndBlock, sizeof(lADCEndBlock)); + file.close(); + + // unload the digits + fLoader->UnloadDigits(); +} //_____________________________________________________________________________ -AliZDCv1::AliZDCv1() : AliZDC() +Bool_t AliZDC::Raw2SDigits(AliRawReader* rawReader) { - // - // Default constructor for Zero Degree Calorimeter - // + // Convert ZDC raw data to Sdigits + + AliLoader* loader = (gAlice->GetRunLoader())->GetLoader("ZDCLoader"); + if(!loader) { + AliError("no ZDC loader found"); + return kFALSE; + } + +// // Event loop + Int_t iEvent = 0; + while(rawReader->NextEvent()){ + (gAlice->GetRunLoader())->GetEvent(iEvent++); + // Create the output digit tree + TTree* treeS = loader->TreeS(); + if(!treeS){ + loader->MakeTree("S"); + treeS = loader->TreeS(); + } + // + AliZDCSDigit sdigit; + AliZDCSDigit* psdigit = &sdigit; + const Int_t kBufferSize = 4000; + treeS->Branch("ZDC", "AliZDCSDigit", &psdigit, kBufferSize); + // + AliZDCRawStream rawStream(rawReader); + Int_t sector[2], ADCRes, ADCRaw, ADCPedSub, nPheVal; + Int_t jcount = 0; + while(rawStream.Next()){ + if(rawStream.IsADCDataWord()){ + //For the moment only in-time SDigits are foreseen (1st 44 raw values) + if(jcount < 44){ + for(Int_t j=0; j<2; j++) sector[j] = rawStream.GetSector(j); + ADCRaw = rawStream.GetADCValue(); + ADCRes = rawStream.GetADCGain(); + //printf("\t RAw2SDigits raw%d -> RawADC[%d, %d, %d] read\n", + // jcount, sector[0], sector[1], ADCRaw); + // + ADCPedSub = ADCRaw - Pedestal(sector[0], sector[1], ADCRes); + if(ADCPedSub<0) ADCPedSub=0; + nPheVal = ADCch2Phe(sector[0], sector[1], ADCPedSub, ADCRes); + // + //printf("\t \t -> SDigit[%d, %d, %d] created\n", + // sector[0], sector[1], nPheVal); + // + new(psdigit) AliZDCSDigit(sector, (Float_t) nPheVal); + treeS->Fill(); + jcount++; + } + }//IsADCDataWord + }//rawStream.Next + // write the output tree + fLoader->WriteSDigits("OVERWRITE"); + fLoader->UnloadSDigits(); + }//Event loop + + return kTRUE; } - + //_____________________________________________________________________________ -AliZDCv1::AliZDCv1(const char *name, const char *title) - : AliZDC(name,title) +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. // - // Standard constructor for Zero Degree Calorimeter + // Getting calibration object for ZDC set + AliCDBManager *man = AliCDBManager::Instance(); + man->SetDefaultStorage("local://$ALICE_ROOT"); + man->SetRun(0); + AliCDBEntry *entry = man->Get("ZDC/Calib/Data"); + AliZDCCalibData *CalibData = (AliZDCCalibData*) entry->GetObject(); // -} - -//_____________________________________________________________________________ -void AliZDCv1::CreateGeometry() -{ + if(!CalibData){ + printf("\t No calibration object found for ZDC!"); + return -1; + } // - // Create the geometry for the Zero Degree Calorimeter version 1 - // -- Author : E Scomparin + Float_t PedValue; + Float_t meanPed, Pedwidth; + Int_t index=0; + if(Det==1|| Det==2) index = 10*(Det-1)+Quad+5*Res; // ZN1, ZP1 + else if(Det==3) index = 10*(Det-1)+(Quad-1)+Res; // ZEM + else if(Det==4|| Det==5) index = 10*(Det-2)+Quad+5*Res+4; // ZN2, ZP2 // - //Begin_Html - /* - - */ - //End_Html - //Begin_Html - /* - - */ - //End_Html - - // The following variables were illegaly initialized in zdc_init. - // These variables should become data members of this class - // once zdc_init has been converted - //* Initialize COMMON block ZDC_CGEOM - //* - - AliMC* pMC = AliMC::GetMC(); - - const Int_t NZPTX=4; - const Int_t NZPTY=1; - const Int_t NZNTX=2; - const Int_t NZNTY=2; - - Float_t HDZN[3] = {4.0,4.0,50.0}; - Float_t HDZP[3] = {10.0,6.0,75.0}; - // Coordinates of the center of the ZDC front face in the MRS - Float_t ZNPOS[3] = {-0.5,0.,11613.}; - Float_t ZPPOS[3] = {-21.0,0.,11563.}; - Float_t FIZN[3] = {0.,0.01825,50.0}; - Float_t FIZP[3] = {0.,0.01825,75.0}; - Float_t GRZN[3] = {0.025,0.025,50.0}; - Float_t GRZP[3] = {0.040,0.040,75.0}; - Int_t NCEN[3] = {11,11,0}; - Int_t NCEP[3] = {10,10,0}; - - Float_t angle; - Float_t zq, conpar[9], tubpar[3]; - Int_t im1, im2; - Float_t zd1, zd2; - - - Int_t *idtmed = fIdtmed->GetArray()-799; - - // -- Mother of the ZDC - conpar[0] = 0.; - conpar[1] = 360.; - conpar[2] = 2.; - conpar[3] = 1920.; - conpar[4] = 0.; - conpar[5] = 55.; - conpar[6] = 13060.; - conpar[7] = 0.; - conpar[8] = 55.; - pMC->Gsvolu("ZDC ", "PCON", idtmed[891], conpar, 9); - pMC->Gspos("ZDC ", 1, "ALIC", 0., 0., 0., 0, "ONLY"); - // -- FIRST SECTION OF THE BEAM PIPE (from compensator dipole to - // beginning of D1) - - zd1 = 1920.; - - tubpar[0] = 2.3; - tubpar[1] = 2.5; - tubpar[2] = 1961.75; - pMC->Gsvolu("P001", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P001", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - //-- SECOND SECTION OF THE BEAM PIPE (FROM THE END OF D1 TO THE BEGINNING OF - // D2) - - zd1 = 6316.+472.5; - - tubpar[0] = 7.3/2.; - tubpar[1] = 7.7/2.; - tubpar[2] = 90.*0.5; - pMC->Gsvolu("P002", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P002", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 7.3/2.; - tubpar[1] = 7.7/2.; - tubpar[2] = 10.*0.5; - pMC->Gsvolu("P003", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P003", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 3.16/2.; - conpar[1] = 7.3/2.; - conpar[2] = 7.7/2.; - conpar[3] = 9.8/2.; - conpar[4] = 10.0/2.; - pMC->Gsvolu("P004", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P004", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 9.8/2.; - tubpar[1] = 10.0/2; - tubpar[2] = 490./2.; - pMC->Gsvolu("P005", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P005", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 30./2.; - conpar[1] = 9.8/2.; - conpar[2] = 10.0/2.; - conpar[3] = 20.4/2.; - conpar[4] = 20.6/2.; - pMC->Gsvolu("P006", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P006", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 20.4/2.; - tubpar[1] = 20.6/2.; - tubpar[2] = 150./2.; - pMC->Gsvolu("P007", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P007", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 13.6/2.; - conpar[1] = 20.4/2.; - conpar[2] = 20.6/2.; - conpar[3] = 25.2/2.; - conpar[4] = 25.4/2.; - pMC->Gsvolu("P008", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P008", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 25.2/2.; - tubpar[1] = 25.4/2.; - tubpar[2] = 205.8/2.; - pMC->Gsvolu("P009", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P009", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 43.8/2.; - tubpar[1] = 44.0/2.; - tubpar[2] = 500./2.; - pMC->Gsvolu("P010", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P010", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 31.8/2.; - tubpar[1] = 32.0/2.; - tubpar[2] = 757.5/2.; - pMC->Gsvolu("P011", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P011", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 22.7/2.; - conpar[1] = 31.8/2.; - conpar[2] = 32.0/2.; - conpar[3] = 39.8/2.; - conpar[4] = 40.0/2.; - pMC->Gsvolu("P012", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P012", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 39.8/2.; - tubpar[1] = 40.0/2.; - tubpar[2] = 100./2.; - pMC->Gsvolu("P013", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P013", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 39.8/2.; - tubpar[1] = 40.0/2.; - tubpar[2] = 600./2.; - pMC->Gsvolu("P014", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P014", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 28.4/2.; - conpar[1] = 39.8/2.; - conpar[2] = 40.0/2.; - conpar[3] = 49.8/2.; - conpar[4] = 50.0/2.; - pMC->Gsvolu("P015", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P015", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 49.8/2.; - tubpar[1] = 50.0/2.; - tubpar[2] = 100./2.; - pMC->Gsvolu("P016", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P016", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 49.8/2.; - tubpar[1] = 50.0/2.; - tubpar[2] = 600./2.; - pMC->Gsvolu("P017", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P017", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - conpar[0] = 28.4/2.; - conpar[1] = 49.8/2.; - conpar[2] = 50.0/2.; - conpar[3] = 59.8/2.; - conpar[4] = 60.0/2.; - pMC->Gsvolu("P018", "CONE", idtmed[851], conpar, 5); - pMC->Gspos("P018", 1, "ZDC ", 0., 0., conpar[0] + zd1, 0, "ONLY"); - - zd1 += conpar[0] * 2.; - - tubpar[0] = 59.8/2.; - tubpar[1] = 60.0/2.; - tubpar[2] = 50./2.; - pMC->Gsvolu("P019", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P019", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 59.8/2.; - tubpar[1] = 60.0/2.; - tubpar[2] = 800./2.; - pMC->Gsvolu("P020", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P020", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 0.; - tubpar[1] = 60.0/2.; - tubpar[2] = 0.2/2.; - pMC->Gsvolu("P021", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("P021", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - - zd1 += tubpar[2] * 2.; - - tubpar[0] = 0.; - tubpar[1] = 4.4/2.; - tubpar[2] = 0.2/2.; - pMC->Gsvolu("Q021", "TUBE", idtmed[889], tubpar, 3); - tubpar[0] = 0.; - tubpar[1] = 7.0/2.; - tubpar[2] = 0.2/2.; - pMC->Gsvolu("R021", "TUBE", idtmed[889], tubpar, 3); - // -- POSITION Q021 INSIDE P021 - pMC->Gspos("Q021", 1, "P021", -7.7, 0., 0., 0, "ONLY"); - // -- POSITION R020 INSIDE P020 - pMC->Gspos("R021", 1, "P021", 7.7, 0., 0., 0, "ONLY"); - - // -- BEAM PIPES BETWEEN END OF CONICAL PIPE AND BEGINNING OF D2 - tubpar[0] = 4.0/2.; - tubpar[1] = 4.4/2.; - tubpar[2] = 645.*0.5; - pMC->Gsvolu("P022", "TUBE", idtmed[851], tubpar, 3); - tubpar[0] = 7.0/2.; - tubpar[1] = 7.4/2.; - tubpar[2] = 645.*0.5; - pMC->Gsvolu("P023", "TUBE", idtmed[851], tubpar, 3); - - // -- ROTATE PIPES - AliMatrix(im1, 90.-0.071, 0., 90., 90., .071, 180.); - angle = .071*kDegrad; - pMC->Gspos("P022", 1, "ZDC ", TMath::Sin(angle) * 322.5 - 9.7 + - TMath::Sin(angle) * 472.5, 0., tubpar[2] + zd1, im1, "ONLY"); - AliMatrix(im2, 90.+0.071, 0., 90., 90., .071, 0.); - pMC->Gspos("P023", 1, "ZDC ", 9.7 - TMath::Sin(angle) * 322.5, 0., - tubpar[2] + zd1, im2, "ONLY"); - - // -- END OF BEAM PIPE VOLUME DEFINITION. MAGNET DEFINITION FOLLOWS - // (LHC OPTICS 6) - - // -- COMPENSATOR DIPOLE (MCBWA) - // GAP (VACUUM WITH MAGNETIC FIELD) - - tubpar[0] = 0.; - tubpar[1] = 4.5; - tubpar[2] = 190./2.; - pMC->Gsvolu("MCBW", "TUBE", idtmed[890], tubpar, 3); - pMC->Gspos("MCBW", 1, "ZDC ", 0., 0., tubpar[2] + 1920., 0, "ONLY"); - - // -- YOKE (IRON WITHOUT MAGNETIC FIELD) - - tubpar[0] = 4.5; - tubpar[1] = 55.; - tubpar[2] = 190./2.; - pMC->Gsvolu("YMCB", "TUBE", idtmed[851], tubpar, 3); - pMC->Gspos("YMCB", 1, "ZDC ", 0., 0., tubpar[2] + 1920., 0, "ONLY"); - - // -- INNER TRIPLET - - zq = 2300.; - - // -- DEFINE MQXL AND MQX QUADRUPOLE ELEMENT - - // MQXL - // -- GAP (VACUUM WITH MAGNETIC FIELD) - - tubpar[0] = 0.; - tubpar[1] = 3.5; - tubpar[2] = 630./2.; - pMC->Gsvolu("MQXL", "TUBE", idtmed[890], tubpar, 3); - - // -- YOKE - - tubpar[0] = 3.5; - tubpar[1] = 22.; - tubpar[2] = 630./2.; - pMC->Gsvolu("YMQL", "TUBE", idtmed[851], tubpar, 3); - - pMC->Gspos("MQXL", 1, "ZDC ", 0., 0., tubpar[2] + zq, 0, "ONLY"); - pMC->Gspos("YMQL", 1, "ZDC ", 0., 0., tubpar[2] + zq, 0, "ONLY"); - - pMC->Gspos("MQXL", 2, "ZDC ", 0., 0., tubpar[2] + zq + 2430., 0, "ONLY"); - pMC->Gspos("YMQL", 2, "ZDC ", 0., 0., tubpar[2] + zq + 2430., 0, "ONLY"); - - // -- MQX - // -- GAP (VACUUM WITH MAGNETIC FIELD) - - tubpar[0] = 0.; - tubpar[1] = 3.5; - tubpar[2] = 550./2.; - pMC->Gsvolu("MQX ", "TUBE", idtmed[890], tubpar, 3); - - // -- YOKE - - tubpar[0] = 3.5; - tubpar[1] = 22.; - tubpar[2] = 550./2.; - pMC->Gsvolu("YMQ ", "TUBE", idtmed[851], tubpar, 3); - - pMC->Gspos("MQX ", 1, "ZDC ", 0., 0., tubpar[2] + zq + 880., 0, "ONLY"); - pMC->Gspos("YMQ ", 1, "ZDC ", 0., 0., tubpar[2] + zq + 880., 0, "ONLY"); - - pMC->Gspos("MQX ", 2, "ZDC ", 0., 0., tubpar[2] + zq + 1530., 0, "ONLY"); - pMC->Gspos("YMQ ", 2, "ZDC ", 0., 0., tubpar[2] + zq + 1530., 0, "ONLY"); - - // -- SEPARATOR DIPOLE D1 - - zd1 = 5843.5; - - // -- GAP (VACUUM WITH MAGNETIC FIELD) - - tubpar[0] = 0.; - tubpar[1] = 4.5; - tubpar[2] = 945/2.; - pMC->Gsvolu("D1 ", "TUBE", idtmed[890], tubpar, 3); - - // -- YOKE - - tubpar[0] = 0.; - tubpar[1] = 55.; - tubpar[2] = 945/2.; - pMC->Gsvolu("YD1 ", "TUBE", idtmed[851], tubpar, 3); - - pMC->Gspos("YD1 ", 1, "ZDC ", 0., 0., tubpar[2] + zd1, 0, "ONLY"); - pMC->Gspos("D1 ", 1, "YD1 ", 0., 0., 0., 0, "ONLY"); - - // -- DIPOLE D2 - - zd2 = 12113.2; - - // -- GAP (VACUUM WITH MAGNETIC FIELD) - - tubpar[0] = 0.; - tubpar[1] = 4.5; - tubpar[2] = 945./2.; - pMC->Gsvolu("D2 ", "TUBE", idtmed[890], tubpar, 3); - - // -- YOKE - - tubpar[0] = 0.; - tubpar[1] = 55.; - tubpar[2] = 945./2.; - pMC->Gsvolu("YD2 ", "TUBE", idtmed[851], tubpar, 3); - - pMC->Gspos("YD2 ", 1, "ZDC ", 0., 0., tubpar[2] + zd2, 0, "ONLY"); - - pMC->Gspos("D2 ", 1, "YD2 ", -9.7, 0., 0., 0, "ONLY"); - pMC->Gspos("D2 ", 2, "YD2 ", 9.7, 0., 0., 0, "ONLY"); - - // -- END OF MAGNET DEFINITION - - // ----------------- Hadronic calorimeters -------------------- * - - // Neutron calorimeter - - pMC->Gsvolu("ZNEU", "BOX ", idtmed[800], HDZN, 3); // Passive material - pMC->Gsvolu("ZNFI", "TUBE", idtmed[802], FIZN, 3); // Active material - pMC->Gsvolu("ZNGR", "BOX ", idtmed[889], GRZN, 3); // Empty grooves - - // Divide ZNEU in towers - // (for hits purposes) - - pMC->Gsdvn("ZNTX", "ZNEU", NZNTX, 1); // x-tower - pMC->Gsdvn("ZN1 ", "ZNTX", NZNTY, 2); // y-tower - - // Divide ZNEU in minitowers - // (NCEN(1)= NUMBER OF FIBERS PER TOWER ALONG X-AXIS, - // NCEN(2)= NUMBER OF FIBERS PER TOWER ALONG Y-AXIS) - // (one fiber per minitower) - - pMC->Gsdvn("ZNSL", "ZN1 ", NCEN[1], 2); // Slices - pMC->Gsdvn("ZNST", "ZNSL", NCEN[0], 1); // Sticks - - // --- Position the empty grooves in the sticks - pMC->Gspos("ZNGR", 1, "ZNST", 0., 0., 0., 0, "ONLY"); - // --- Position the fibers in the grooves - pMC->Gspos("ZNFI", 1, "ZNGR", 0., 0., 0., 0, "ONLY"); - // --- Position the neutron calorimeter in ZDC - pMC->Gspos("ZNEU", 1, "ZDC ", ZNPOS[0], ZNPOS[1], ZNPOS[2] + HDZN[2], 0, "ONLY"); - - // Proton calorimeter - - pMC->Gsvolu("ZPRO", "BOX ", idtmed[801], HDZP, 3); // Passive material - pMC->Gsvolu("ZPFI", "TUBE", idtmed[802], FIZP, 3); // Active material - pMC->Gsvolu("ZPGR", "BOX ", idtmed[889], GRZP, 3); // Empty grooves - - // Divide ZPRO in towers - // (for hits purposes) - - pMC->Gsdvn("ZPTX", "ZPRO", NZPTX, 1); // x-tower - pMC->Gsdvn("ZP1 ", "ZPTX", NZPTY, 2); // y-tower - - - // Divide ZPRO in minitowers - // (NCEP[0]= NUMBER OF FIBERS ALONG X-AXIS PER MINITOWER, - // NCEP[1]= NUMBER OF FIBERS ALONG Y-AXIS PER MINITOWER) - // (one fiber per minitower) - - pMC->Gsdvn("ZPSL", "ZP1 ", NCEP[1], 2); // Slices - pMC->Gsdvn("ZPST", "ZPSL", NCEP[0], 1); // Sticks + // + meanPed = CalibData->GetMeanPed(index); + Pedwidth = CalibData->GetMeanPedWidth(index); + PedValue = gRandom->Gaus(meanPed,Pedwidth); + // + //printf("\t AliZDC::Pedestal - det(%d, %d) - Ped[%d] = %d\n",Det, Quad, index,(Int_t) PedValue); // Chiara debugging! - // --- Position the empty grooves in the sticks - pMC->Gspos("ZPGR", 1, "ZPST", 0., 0., 0., 0, "ONLY"); - // --- Position the fibers in the grooves - pMC->Gspos("ZPFI", 1, "ZPGR", 0., 0., 0., 0, "ONLY"); - // --- Position the proton calorimeter in ZDC - pMC->Gspos("ZPRO", 1, "ZDC ", ZPPOS[0], ZPPOS[1], ZPPOS[2] + HDZP[2], 0, "ONLY"); + + return (Int_t) PedValue; } - + + //_____________________________________________________________________________ -void AliZDCv1::DrawModule() +Int_t AliZDC::ADCch2Phe(Int_t Det, Int_t Quad, Int_t ADCVal, Int_t Res) const { - // - // Draw a shaded view of the Zero Degree Calorimeter version 1 - // + // Evaluation of the no. of phe produced + Float_t PMGain[6][5]; + Float_t ADCRes[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 + ADCRes[0] = 0.0000008; // ADC Resolution high gain: 200 fC/adcCh + ADCRes[1] = 0.0000064; // ADC Resolution low gain: 25 fC/adcCh + // + Int_t nPhe = (Int_t) (ADCVal * PMGain[Det-1][Quad] * ADCRes[Res]); + // + //printf("\t AliZDC::ADCch2Phe -> det(%d, %d) - ADC %d phe %d\n",Det,Quad,ADCVal,nPhe); - AliMC* pMC = AliMC::GetMC(); - - // Set everything unseen - pMC->Gsatt("*", "seen", -1); - // - // Set ALIC mother transparent - pMC->Gsatt("ALIC","SEEN",0); - // - // Set the volumes visible - pMC->Gsatt("ZDC","SEEN",0); - pMC->Gsatt("P001","SEEN",1); - pMC->Gsatt("P002","SEEN",1); - pMC->Gsatt("P003","SEEN",1); - pMC->Gsatt("P004","SEEN",1); - pMC->Gsatt("P005","SEEN",1); - pMC->Gsatt("P006","SEEN",1); - pMC->Gsatt("P007","SEEN",1); - pMC->Gsatt("P008","SEEN",1); - pMC->Gsatt("P009","SEEN",1); - pMC->Gsatt("P010","SEEN",1); - pMC->Gsatt("P011","SEEN",1); - pMC->Gsatt("P012","SEEN",1); - pMC->Gsatt("P013","SEEN",1); - pMC->Gsatt("P014","SEEN",1); - pMC->Gsatt("P015","SEEN",1); - pMC->Gsatt("P016","SEEN",1); - pMC->Gsatt("P017","SEEN",1); - pMC->Gsatt("P018","SEEN",1); - pMC->Gsatt("P019","SEEN",1); - pMC->Gsatt("P020","SEEN",1); - pMC->Gsatt("P021","SEEN",1); - pMC->Gsatt("Q021","SEEN",1); - pMC->Gsatt("R021","SEEN",1); - pMC->Gsatt("P022","SEEN",1); - pMC->Gsatt("P023","SEEN",1); - pMC->Gsatt("D1 ","SEEN",1); - pMC->Gsatt("YD1 ","SEEN",1); - pMC->Gsatt("D2 ","SEEN",1); - pMC->Gsatt("YD2 ","SEEN",1); - pMC->Gsatt("MCBW","SEEN",1); - pMC->Gsatt("YMCB","SEEN",1); - pMC->Gsatt("MQXL","SEEN",1); - pMC->Gsatt("YMQL","SEEN",1); - pMC->Gsatt("MQX","SEEN",1); - pMC->Gsatt("YMQ","SEEN",1); - pMC->Gsatt("D1","SEEN",1); - pMC->Gsatt("YD1","SEEN",1); - pMC->Gsatt("D2","SEEN",1); - pMC->Gsatt("YD2","SEEN",1); - pMC->Gsatt("ZNEU","SEEN",0); - pMC->Gsatt("ZNFI","SEEN",0); - pMC->Gsatt("ZNGR","SEEN",0); - pMC->Gsatt("ZNTX","SEEN",0); - pMC->Gsatt("ZN1 ","COLO",2); - pMC->Gsatt("ZN1 ","SEEN",1); - pMC->Gsatt("ZNSL","SEEN",0); - pMC->Gsatt("ZNST","SEEN",0); - pMC->Gsatt("ZPRO","SEEN",0); - pMC->Gsatt("ZPFI","SEEN",0); - pMC->Gsatt("ZPGR","SEEN",0); - pMC->Gsatt("ZPTX","SEEN",0); - pMC->Gsatt("ZP1 ","SEEN",1); - pMC->Gsatt("ZPSL","SEEN",0); - pMC->Gsatt("ZPST","SEEN",0); - - // - pMC->Gdopt("hide", "on"); - pMC->Gdopt("shad", "on"); - pMC->Gsatt("*", "fill", 7); - pMC->SetClipBox("."); - pMC->SetClipBox("*", 0, 100, -100, 100, 12000, 16000); - pMC->DefaultRange(); - pMC->Gdraw("alic", 40, 30, 0, 488, 220, .07, .07); - pMC->Gdhead(1111, "Zero Degree Calorimeter Version 1"); - pMC->Gdman(18, 4, "MAN"); + return nPhe; } -//_____________________________________________________________________________ -void AliZDCv1::CreateMaterials() +//______________________________________________________________________ +void AliZDC::SetTreeAddress(){ + + // Set branch address for the Trees. + if(fLoader->TreeH() && (fHits == 0x0)) + fHits = new TClonesArray("AliZDCHit",1000); + + AliDetector::SetTreeAddress(); +} + +//________________________________________________________________ +void AliZDC::CreateCalibData() +{ + // + //if(fCalibData) delete fCalibData; // delete previous version + fCalibData = new AliZDCCalibData(GetName()); +} +//________________________________________________________________ +void AliZDC::WriteCalibData(Int_t option) { // - // Create Materials for the Zero Degree Calorimeter - // - // Origin : E. Scomparin - - AliMC* pMC = AliMC::GetMC(); - - Int_t *idtmed = fIdtmed->GetArray()-799; - - Float_t dens, ubuf[1], wmat[2]; - Int_t isvol_active; - Float_t a[2]; - Int_t i; - Float_t z[2], epsil=0.001, stmin=0.01; - Int_t isvol; - Float_t fieldm = gAlice->Field()->Max(); - Int_t inofld; - Float_t deemax=-1; - Float_t tmaxfd=gAlice->Field()->Max(); - Int_t isxfld = gAlice->Field()->Integ(); - Float_t stemax; - - // --- Store in UBUF r0 for nuclear radius calculation R=r0*A**1/3 - - // --- Tungsten - ubuf[0] = 1.11; - AliMaterial(1, "TUNG", 183.85, 74., 19.3, .35, 10.3, ubuf, 1); - - // --- Brass (CuZn) - dens = 8.48; - a[0] = 63.546; - a[1] = 65.39; - z[0] = 29.; - z[1] = 30.; - wmat[0] = .63; - wmat[1] = .37; - AliMixture(2, "BRASS ", a, z, dens, 2, wmat); - - // --- SiO2 - dens = 2.64; - a[0] = 28.086; - a[1] = 15.9994; - z[0] = 14.; - z[1] = 8.; - wmat[0] = 1.; - wmat[1] = 2.; - AliMixture(3, "SIO2 ", a, z, dens, -2, wmat); - - // --- Lead - ubuf[0] = 1.12; - AliMaterial(4, "LEAD", 207.19, 82., 11.35, .56, 18.5, ubuf, 1); - - // --- Copper - ubuf[0] = 1.1; - AliMaterial(5, "COPP", 63.54, 29., 8.96, 1.4, 0., ubuf, 1); - - // --- Tantalum - ubuf[0] = 1.1; - AliMaterial(6, "TANT", 180.95, 73., 16.65, .4, 11.9, ubuf, 1); - - // Steel still to be added - - // --- Iron - ubuf[0] = 1.1; - AliMaterial(52, "IRON", 55.85, 26., 7.87, 1.76, 0., ubuf, 1); - - // --- Vacuum (no magnetic field) - AliMaterial(90, "VOID", 1e-16, 1e-16, 1e-16, 1e16, 1e16, ubuf,0); - - // --- Vacuum (magnetic field) - AliMaterial(91, "VOIM", 1e-16, 1e-16, 1e-16, 1e16, 1e16, ubuf,0); - - // --- Air non magnetic - AliMaterial(92, "Air $", 14.61, 7.3, .001205, 30420., 67500., ubuf, 0); - - // --- Definition of tracking media: - - // --- Tungsten = 801 ; - // --- Brass = 802 ; - // --- Fibers (SiO2) = 803 ; - // --- Lead = 804 ; - // --- Copper = 805 ; - // --- Tantalum = 806 ; - // --- Steel = 851 ; - // --- Iron = 852 ; - // --- Vacuum (no field) = 890 - // --- Vacuum (with field) = 891 - // --- Air (no field) = 892 - - - // --- Tracking media parameters - epsil = .01; - stemax = 1.; - isvol = 0; - isvol_active = 1; - inofld = 0; - fieldm = 0.; - - AliMedium(1, "ZW", 1, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(2, "ZBRASS", 2, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(3, "ZSIO2", 3, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(4, "ZLEAD", 4, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(5, "ZCOPP", 5, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(6, "ZTANT", 6, isvol_active, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(52, "ZIRON", 52, isvol, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(90, "ZVOID", 90, isvol, inofld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(92, "Air", 92, 0, inofld, fieldm, tmaxfd, stemax,deemax, epsil, stmin); - - fieldm = 45.; - // AliMedium(91, "ZVOIM", 91, isvol, isxfld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - AliMedium(91, "ZVOIM", 91, isvol, isxfld, fieldm, tmaxfd, stemax, deemax, epsil, stmin); - - // Thresholds for showering in the ZDCs - - i = 801; - pMC->Gstpar(idtmed[i-1], "CUTGAM", .01); - pMC->Gstpar(idtmed[i-1], "CUTELE", .01); - pMC->Gstpar(idtmed[i-1], "CUTNEU", .1); - pMC->Gstpar(idtmed[i-1], "CUTHAD", .1); - i = 802; - pMC->Gstpar(idtmed[i-1], "CUTGAM", .01); - pMC->Gstpar(idtmed[i-1], "CUTELE", .01); - pMC->Gstpar(idtmed[i-1], "CUTNEU", .1); - pMC->Gstpar(idtmed[i-1], "CUTHAD", .1); - - // Avoid too detailed showering along the beam line - - i = 852; - pMC->Gstpar(idtmed[i-1], "CUTGAM", .1); - pMC->Gstpar(idtmed[i-1], "CUTELE", .1); - pMC->Gstpar(idtmed[i-1], "CUTNEU", 1.); - pMC->Gstpar(idtmed[i-1], "CUTHAD", 1.); - - // Avoid interaction in fibers (only energy loss allowed) - i = 803; - pMC->Gstpar(idtmed[i-1], "DCAY", 0.); - pMC->Gstpar(idtmed[i-1], "MULS", 0.); - pMC->Gstpar(idtmed[i-1], "PFIS", 0.); - pMC->Gstpar(idtmed[i-1], "MUNU", 0.); - pMC->Gstpar(idtmed[i-1], "LOSS", 1.); - pMC->Gstpar(idtmed[i-1], "PHOT", 0.); - pMC->Gstpar(idtmed[i-1], "COMP", 0.); - pMC->Gstpar(idtmed[i-1], "PAIR", 0.); - pMC->Gstpar(idtmed[i-1], "BREM", 0.); - pMC->Gstpar(idtmed[i-1], "DRAY", 0.); - pMC->Gstpar(idtmed[i-1], "ANNI", 0.); - pMC->Gstpar(idtmed[i-1], "HADR", 0.); + const int kCompressLevel = 9; + char* fnam = GetZDCCalibFName(); + if(!fnam || fnam[0]=='\0') { + fnam = gSystem->ExpandPathName("$(ALICE_ROOT)/data/AliZDCCalib.root"); + Warning("WriteCalibData","No File Name is provided, using default %s",fnam); + } + TFile* cdfile = TFile::Open(fnam,"UPDATE","",kCompressLevel); + + // Writes Calibration Data to current directory. + // User MUST take care of corresponding file opening and ->cd()... !!! + // By default, the object is overwritten. Use 0 option for opposite. + if(option) option = TObject::kOverwrite; + if(fCalibData) fCalibData->Write(0,option); + else if(fCalibData) fCalibData->Write(0,option); + + cdfile->Close(); + delete cdfile; } -ClassImp(AliZDChit) - -//_____________________________________________________________________________ -AliZDChit::AliZDChit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits): - AliHit(shunt, track) +//________________________________________________________________ +void AliZDC::LoadCalibData() { // - // Add a Zero Degree Calorimeter hit - // - Int_t i; - for (i=0;i<4;i++) fVolume[i] = vol[i]; - fX=hits[0]; - fY=hits[1]; - fZ=hits[2]; - fEnergy=hits[3]; + char* fnam = GetZDCCalibFName(); + if(!fnam || fnam[0]=='\0') return; + if(!gAlice->IsFileAccessible(fnam)) { + Error("LoadCalibData","ZDC Calibration Data file is not accessible, %s",fnam); + exit(1); + } + TFile* cdfile = TFile::Open(fnam); + + // Loads Calibration Data from current directory. + // User MUST take care of corresponding file opening and ->cd()...!!! + // + if(fCalibData) delete fCalibData; // delete previous version + TString dtname = "Calib_"; + dtname += GetName(); + fCalibData = (AliZDCCalibData*) gDirectory->Get(dtname.Data()); + if(!fCalibData) { + Error("LoadCalibData","No Calibration data found for %s",GetName()); + exit(1); + } + + cdfile->Close(); + delete cdfile; } +