Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /* $Id$ */
17 :
18 : ///////////////////////////////////////////////////////////////////////////////
19 : // //
20 : // Zero Degree Calorimeter //
21 : // This class contains the basic functions for the ZDCs; //
22 : // functions specific to one particular geometry are //
23 : // contained in the derived classes //
24 : // //
25 : ///////////////////////////////////////////////////////////////////////////////
26 :
27 : // --- ROOT system
28 : #include <TClonesArray.h>
29 : #include <TTree.h>
30 : #include <TFile.h>
31 : #include <TSystem.h>
32 : #include <TRandom.h>
33 : #include <TParticle.h>
34 :
35 : // --- AliRoot header files
36 : #include "AliDetector.h"
37 : #include "AliRawDataHeaderSim.h"
38 : #include "AliRawReader.h"
39 : #include "AliLoader.h"
40 : #include "AliRun.h"
41 : #include "AliMC.h"
42 : #include "AliLog.h"
43 : #include "AliDAQ.h"
44 : #include "AliZDC.h"
45 : #include "AliZDCHit.h"
46 : #include "AliZDCSDigit.h"
47 : #include "AliZDCDigit.h"
48 : #include "AliZDCDigitizer.h"
49 : #include "AliZDCRawStream.h"
50 : #include "AliZDCPedestals.h"
51 : #include "AliZDCEnCalib.h"
52 : #include "AliZDCTowerCalib.h"
53 : #include "AliFstream.h"
54 :
55 :
56 12 : ClassImp(AliZDC)
57 :
58 : //_____________________________________________________________________________
59 : AliZDC::AliZDC() :
60 12 : AliDetector(),
61 12 : fNoShower(0),
62 12 : fPedCalib(0),
63 12 : fEnCalibData(0),
64 12 : fTowCalibData(0),
65 12 : fZDCCalibFName(""),
66 12 : fSpectatorTracked(1),
67 12 : fBeamEnergy(0.),
68 12 : fIspASystem(kFALSE),
69 12 : fIsRELDISgen(kFALSE),
70 12 : fOnlyZEM(kFALSE),
71 12 : fFindMother(kFALSE),
72 12 : fSpectatorParam(1)
73 36 : {
74 : //
75 : // Default constructor for the Zero Degree Calorimeter base class
76 : //
77 :
78 12 : fIshunt = 1;
79 12 : fNhits = 0;
80 12 : fHits = 0;
81 12 : fDigits = 0;
82 12 : fNdigits = 0;
83 :
84 12 : }
85 :
86 : //_____________________________________________________________________________
87 : AliZDC::AliZDC(const char *name, const char *title) :
88 1 : AliDetector(name,title),
89 1 : fNoShower(0),
90 1 : fPedCalib(0),
91 1 : fEnCalibData(0),
92 1 : fTowCalibData(0),
93 1 : fZDCCalibFName(""),
94 1 : fSpectatorTracked(1),
95 1 : fBeamEnergy(0.),
96 1 : fIspASystem(kFALSE),
97 1 : fIsRELDISgen(kFALSE),
98 1 : fOnlyZEM(kFALSE),
99 1 : fFindMother(kFALSE),
100 1 : fSpectatorParam(1)
101 :
102 3 : {
103 : //
104 : // Standard constructor for the Zero Degree Calorimeter base class
105 : //
106 :
107 1 : fIshunt = 1;
108 1 : fNhits = 0;
109 1 : fDigits = 0;
110 1 : fNdigits = 0;
111 :
112 3 : fHits = new TClonesArray("AliZDCHit",1000);
113 1 : gAlice->GetMCApp()->AddHitList(fHits);
114 :
115 2 : SetName("ZDC"); SetTitle("ZDC");
116 :
117 1 : }
118 :
119 : //____________________________________________________________________________
120 : AliZDC::~AliZDC()
121 26 : {
122 : //
123 : // ZDC destructor
124 : //
125 :
126 13 : fIshunt = 0;
127 13 : if(fPedCalib) delete fPedCalib;
128 13 : if(fEnCalibData) delete fEnCalibData;
129 13 : if(fEnCalibData) delete fEnCalibData;
130 :
131 13 : }
132 :
133 : //_____________________________________________________________________________
134 : AliZDC::AliZDC(const AliZDC& ZDC) :
135 0 : AliDetector("ZDC","ZDC"),
136 0 : fNoShower(ZDC.fNoShower),
137 0 : fPedCalib(ZDC.fPedCalib),
138 0 : fEnCalibData(ZDC.fEnCalibData),
139 0 : fTowCalibData(ZDC.fTowCalibData),
140 0 : fZDCCalibFName(ZDC.fZDCCalibFName),
141 0 : fSpectatorTracked(ZDC.fSpectatorTracked),
142 0 : fBeamEnergy(ZDC.fBeamEnergy),
143 0 : fIspASystem(ZDC.fIspASystem),
144 0 : fIsRELDISgen(ZDC.fIsRELDISgen),
145 0 : fOnlyZEM(ZDC.fOnlyZEM),
146 0 : fFindMother(ZDC.fFindMother),
147 0 : fSpectatorParam(ZDC.fSpectatorParam)
148 :
149 0 : {
150 : // copy constructor
151 0 : }
152 :
153 : //_____________________________________________________________________________
154 : AliZDC& AliZDC::operator=(const AliZDC& ZDC)
155 : {
156 : // assignement operator
157 0 : if(this!=&ZDC){
158 0 : fNoShower = ZDC.fNoShower;
159 0 : fPedCalib = ZDC.fPedCalib;
160 0 : fEnCalibData = ZDC.fEnCalibData;
161 0 : fTowCalibData = ZDC.fTowCalibData;
162 0 : fZDCCalibFName = ZDC.fZDCCalibFName;
163 0 : fBeamEnergy = ZDC.fBeamEnergy;
164 0 : fIspASystem = ZDC.fIspASystem;
165 0 : fIsRELDISgen = ZDC.fIsRELDISgen;
166 0 : fOnlyZEM = ZDC.fOnlyZEM;
167 0 : fFindMother = ZDC.fFindMother;
168 0 : } return *this;
169 : }
170 :
171 : //_____________________________________________________________________________
172 : void AliZDC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
173 : {
174 : //
175 : // Add a ZDC hit to the hit list.
176 :
177 : static Float_t trackTime=0., trackEta=0., primKinEn=0., xImpact=0., yImpact=0., sFlag=0.;
178 : static Int_t pcPDGcode=0, motPDGcode=0;
179 :
180 : AliZDCHit *curprimquad;
181 17792 : AliZDCHit newquad(fIshunt, track, vol, hits);
182 8896 : TClonesArray &lhits = *fHits;
183 :
184 8896 : if(fNhits==0){
185 : // First hit -> setting flag for primary or secondary particle
186 8 : TParticle * p = gAlice->GetMCApp()->Particle(track);
187 8 : Int_t imo = p->GetFirstMother();
188 : //
189 8 : if(track != imo){
190 8 : newquad.SetSFlag(1.); // SECONDARY particle entering the ZDC
191 8 : }
192 0 : else if(track == imo){
193 0 : newquad.SetSFlag(0.); // PRIMARY particle entering the ZDC
194 0 : }
195 : //
196 8 : sFlag = newquad.GetSFlag();
197 8 : primKinEn = newquad.GetPrimKinEn();
198 8 : xImpact = newquad.GetXImpact();
199 8 : yImpact = newquad.GetYImpact();
200 8 : pcPDGcode = newquad.GetPDGCode();
201 8 : motPDGcode = newquad.GetMotherPDGCode();
202 8 : trackTime = newquad.GetTrackTOF();
203 8 : trackEta = newquad.GetTrackEta();
204 : //
205 : //newquad->Print("");
206 8 : }
207 : else{
208 : // -> setting flag for primary or secondary particle
209 8888 : TParticle * p = gAlice->GetMCApp()->Particle(track);
210 8888 : Int_t imo = p->GetFirstMother();
211 : //
212 : Float_t sFlag = -1;
213 8888 : if(track != imo){
214 8888 : newquad.SetSFlag(1.); // SECONDARY particle entering the ZDC
215 8888 : }
216 0 : else if(track == imo){
217 0 : newquad.SetSFlag(0.); // PRIMARY particle entering the ZDC
218 0 : }
219 : //
220 8888 : newquad.SetPrimKinEn(primKinEn);
221 8888 : newquad.SetXImpact(xImpact);
222 8888 : newquad.SetYImpact(yImpact);
223 8888 : newquad.SetPDGCode(pcPDGcode);
224 8888 : newquad.SetMotherPDGCode(motPDGcode);
225 8888 : newquad.SetTrackTOF(trackTime);
226 8888 : newquad.SetTrackEta(trackEta);
227 : }
228 :
229 : Int_t j;
230 26919 : for(j=0; j<fNhits; j++){
231 : // If hits are equal (same track, same volume), sum them.
232 26895 : curprimquad = (AliZDCHit*) lhits[j];
233 17922 : if(*curprimquad == newquad){
234 26652 : *curprimquad = *curprimquad+newquad;
235 : // Ch. debug
236 : //printf("\n\t Summing hits **************** \n");
237 : //curprimquad->Print("");
238 : //
239 8884 : return;
240 : }
241 : }
242 : //printf( "PDG from hits[10] = %f\n", hits[10]);
243 :
244 : //Otherwise create a new hit
245 36 : new(lhits[fNhits]) AliZDCHit(newquad);
246 : // Ch. debug
247 : //printf("\n\t New ZDC hit added! fNhits = %d\n", fNhits);
248 : //newquad->Print("");
249 : //
250 12 : fNhits++;
251 :
252 8908 : }
253 :
254 : //____________________________________________________________________________
255 : Float_t AliZDC::ZMin(void) const
256 : {
257 : // Minimum dimension of the ZDC module in z
258 0 : return -11600.;
259 : }
260 :
261 : //____________________________________________________________________________
262 : Float_t AliZDC::ZMax(void) const
263 : {
264 : // Maximum dimension of the ZDC module in z
265 0 : return 11750.;
266 : }
267 :
268 :
269 : //_____________________________________________________________________________
270 : void AliZDC::MakeBranch(Option_t *opt)
271 : {
272 : //
273 : // Create Tree branches for the ZDC
274 : //
275 :
276 8 : char branchname[10];
277 4 : snprintf(branchname, 10, "%s", GetName());
278 :
279 4 : const char *cH = strstr(opt,"H");
280 :
281 8 : if(cH && fLoader->TreeH()) {
282 4 : if (fHits) {
283 4 : fHits->Clear();
284 4 : fNhits = 0;
285 4 : }
286 : else {
287 0 : fHits = new TClonesArray("AliZDCHit",1000);
288 0 : if (gAlice && gAlice->GetMCApp())
289 0 : gAlice->GetMCApp()->AddHitList(fHits);
290 : }
291 : }
292 :
293 4 : AliDetector::MakeBranch(opt);
294 4 : }
295 :
296 : //_____________________________________________________________________________
297 : void AliZDC::Hits2SDigits()
298 : {
299 : // Create summable digits from hits
300 :
301 4 : AliDebug(1,"\n AliZDC::Hits2SDigits() ");
302 :
303 1 : fLoader->LoadHits("read");
304 1 : fLoader->LoadSDigits("recreate");
305 1 : AliRunLoader* runLoader = fLoader->GetRunLoader();
306 1 : AliZDCSDigit sdigit;
307 1 : AliZDCSDigit* psdigit = &sdigit;
308 :
309 : // Event loop
310 15 : for(Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
311 4 : Float_t pmZNC[5], pmZPC[5], pmZNA[5], pmZPA[5], pmZEM1=0., pmZEM2=0.;
312 48 : for(Int_t i=0; i<5; i++) pmZNC[i] = pmZPC[i] = pmZNA[i] = pmZPA[i] = 0;
313 :
314 4 : runLoader->GetEvent(iEvent);
315 4 : TTree* treeH = fLoader->TreeH();
316 8 : Int_t ntracks = (Int_t) treeH->GetEntries();
317 4 : ResetHits();
318 :
319 : // Tracks loop
320 4 : Int_t sector[2]; Float_t trackTime = 0.;
321 232 : for(Int_t itrack = 0; itrack < ntracks; itrack++) {
322 112 : treeH->GetEntry(itrack);
323 360 : for(AliZDCHit* zdcHit = (AliZDCHit*)FirstHit(-1); zdcHit;
324 24 : zdcHit = (AliZDCHit*)NextHit()) {
325 :
326 24 : sector[0] = zdcHit->GetVolume(0);
327 24 : sector[1] = zdcHit->GetVolume(1);
328 24 : if((sector[1] < 1) || (sector[1]>5)) {
329 0 : Error("Hits2SDigits", "sector[0] = %d, sector[1] = %d", sector[0], sector[1]);
330 : continue;
331 : }
332 12 : Float_t lightQ = zdcHit->GetLightPMQ();
333 12 : Float_t lightC = zdcHit->GetLightPMC();
334 12 : trackTime = zdcHit->GetTrackTOF();
335 : // Signals from ZEM are delayed to arrive in time with ZDC signals
336 24 : if(sector[0] == 3) trackTime += 320;
337 : // Ch. debug
338 : //printf("\t det %d vol %d trackTOF %f lightQ %1.0f lightC %1.0f\n",
339 : // sector[0], sector[1], trackTime, lightQ, lightC);
340 :
341 12 : if(sector[0] == 1) { //ZNC
342 0 : pmZNC[0] += lightC;
343 0 : pmZNC[sector[1]] += lightQ;
344 0 : }
345 12 : else if(sector[0] == 2) { //ZPC
346 0 : pmZPC[0] += lightC;
347 0 : pmZPC[sector[1]] += lightQ;
348 0 : }
349 12 : else if(sector[0] == 3) { //ZEM
350 19 : if(sector[1] == 1) pmZEM1 += lightC;
351 5 : else pmZEM2 += lightQ;
352 : }
353 12 : if(sector[0] == 4) { //ZNA
354 0 : pmZNA[0] += lightC;
355 0 : pmZNA[sector[1]] += lightQ;
356 0 : }
357 12 : else if(sector[0] == 5) { //ZPA
358 0 : pmZPA[0] += lightC;
359 0 : pmZPA[sector[1]] += lightQ;
360 0 : }
361 12 : }//Hits loop
362 : }//Tracks loop
363 :
364 : // create the output tree
365 4 : fLoader->MakeTree("S");
366 4 : TTree* treeS = fLoader->TreeS();
367 : const Int_t kBufferSize = 4000;
368 8 : treeS->Branch(GetName(), "AliZDCSDigit", &psdigit, kBufferSize);
369 :
370 : // Create sdigits for ZNC
371 4 : sector[0] = 1; // Detector = ZNC
372 48 : for(Int_t j = 0; j < 5; j++) {
373 20 : sector[1] = j;
374 20 : if(pmZNC[j]>0){
375 0 : new(psdigit) AliZDCSDigit(sector, pmZNC[j], trackTime);
376 0 : treeS->Fill();
377 : // Ch. debug
378 : //printf("\t SDigit created: det %d quad %d pmZNC[%d] %1.0f trackTOF %f\n",
379 : // sector[0], sector[1], j, pmZNC[j], trackTime);
380 : }
381 : }
382 :
383 : // Create sdigits for ZPC
384 4 : sector[0] = 2; // Detector = ZPC
385 48 : for(Int_t j = 0; j < 5; j++) {
386 20 : sector[1] = j; // Towers PM ADCs
387 20 : if(pmZPC[j]>0){
388 0 : new(psdigit) AliZDCSDigit(sector, pmZPC[j], trackTime);
389 0 : treeS->Fill();
390 : // Ch. debug
391 : //printf("\t SDigit created: det %d quad %d pmZPC[%d] %1.0f trackTOF %f\n",
392 : // sector[0], sector[1], j, pmZPC[j], trackTime);
393 : }
394 : }
395 :
396 : // Create sdigits for ZEM
397 4 : sector[0] = 3;
398 4 : sector[1] = 1; // Detector = ZEM1
399 4 : if(pmZEM1>0){
400 4 : new(psdigit) AliZDCSDigit(sector, pmZEM1, trackTime);
401 2 : treeS->Fill();
402 : // Ch. debug
403 : //printf("\t SDigit created: det %d quad %d pmZEM1 %1.0f trackTOF %f\n",
404 : // sector[0], sector[1], pmZEM1, trackTime);
405 : }
406 4 : sector[1] = 2; // Detector = ZEM2
407 4 : if(pmZEM2>0){
408 0 : new(psdigit) AliZDCSDigit(sector, pmZEM2, trackTime);
409 0 : treeS->Fill();
410 : // Ch. debug
411 : //printf("\t SDigit created: det %d quad %d pmZEM2 %1.0f trackTOF %f\n",
412 : // sector[0], sector[1], pmZEM2, trackTime);
413 : }
414 :
415 : // Create sdigits for ZNA
416 4 : sector[0] = 4; // Detector = ZNA
417 48 : for(Int_t j = 0; j < 5; j++) {
418 20 : sector[1] = j; // Towers PM ADCs
419 20 : if(pmZNA[j]>0){
420 0 : new(psdigit) AliZDCSDigit(sector, pmZNA[j], trackTime);
421 0 : treeS->Fill();
422 : // Ch. debug
423 : //printf("\t SDigit created: det %d quad %d pmZNA[%d] %1.0f trackTOF %f\n",
424 : // sector[0], sector[1], j, pmZNA[j], trackTime);
425 : }
426 : }
427 :
428 : // Create sdigits for ZPA
429 4 : sector[0] = 5; // Detector = ZPA
430 4 : sector[1] = 0; // Common PM ADC
431 48 : for(Int_t j = 0; j < 5; j++) {
432 20 : sector[1] = j; // Towers PM ADCs
433 20 : if(pmZPA[j]>0){
434 0 : new(psdigit) AliZDCSDigit(sector, pmZPA[j], trackTime);
435 0 : treeS->Fill();
436 : // Ch. debug
437 : //printf("\t SDigit created: det %d quad %d pmZPA[%d] %1.0f trackTOF %f\n",
438 : // sector[0], sector[1], j, pmZPA[j], trackTime);
439 : }
440 : }
441 :
442 : // write the output tree
443 4 : fLoader->WriteSDigits("OVERWRITE");
444 4 : }
445 :
446 1 : fLoader->UnloadHits();
447 1 : fLoader->UnloadSDigits();
448 1 : }
449 :
450 : //_____________________________________________________________________________
451 : AliDigitizer* AliZDC::CreateDigitizer(AliDigitizationInput* digInput) const{
452 : // Create the digitizer for ZDC
453 2 : AliZDCDigitizer *zdcDigitizer = new AliZDCDigitizer(digInput);
454 1 : if(fSpectatorParam!=1) zdcDigitizer->SetSpectatorParam(fSpectatorParam);
455 1 : if(fSpectatorTracked==0) zdcDigitizer->SetSpectators2Track();
456 1 : if(fBeamEnergy>0.01) zdcDigitizer->SetBeamEnergy(fBeamEnergy);
457 1 : if(fIspASystem==kTRUE) zdcDigitizer->SetpAsystem();
458 1 : if(fIsRELDISgen==kTRUE) zdcDigitizer->SetRELDISGenerator();
459 : //if(fIspASystem==kTRUE) printf("\n **** ZDC digitizer initialized for p-A collisions\n\n");
460 1 : return zdcDigitizer;
461 0 : }
462 :
463 : //_____________________________________________________________________________
464 : void AliZDC::Digits2Raw()
465 : {
466 : // Convert ZDC digits to raw data
467 :
468 : // 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
469 : // + 24 int values for the corresponding out of time channels
470 : // For the CAEN module V965 we have an Header, the Data Words and an End Of Block
471 : // 12 channels x 2 gain chains read from 1st ADC module
472 : // 12 channels x 2 gain chains read from 2nd ADC module
473 : // 12 channels x 2 gain chains read from 3rd ADC module (o.o.t.)
474 : // 12 channels x 2 gain chains read from 4rth ADC module (o.o.t.)
475 : //
476 : const int knADCData1=12, knADCData2=12;
477 : const int knADCData3=12, knADCData4=12;
478 : //
479 8 : UInt_t lADCHeader1;
480 4 : UInt_t lADCHeader2;
481 4 : UInt_t lADCHeader3;
482 4 : UInt_t lADCHeader4;
483 : //
484 4 : UInt_t lADCData1[2*knADCData1];
485 4 : UInt_t lADCData2[2*knADCData2];
486 4 : UInt_t lADCData3[2*knADCData3];
487 4 : UInt_t lADCData4[2*knADCData4];
488 : //
489 4 : UInt_t lADCEndBlock;
490 :
491 : // load the digits
492 4 : fLoader->LoadDigits("read");
493 4 : AliZDCDigit digit;
494 4 : AliZDCDigit* pdigit = &digit;
495 4 : TTree* treeD = fLoader->TreeD();
496 4 : if(!treeD) return;
497 4 : treeD->SetBranchAddress("ZDC", &pdigit);
498 : //printf("\t AliZDC::Digits2Raw -> TreeD has %d entries\n",(Int_t) treeD->GetEntries());
499 :
500 : // Reading channel map
501 : //printf("\n\t Reading ADC mapping from OCDB\n");
502 4 : AliZDCChMap * chMap = GetChMap();
503 : const int nCh = knADCData1+knADCData2+knADCData3+knADCData4;
504 4 : Int_t mapADC[nCh][4];
505 392 : for(Int_t i=0; i<nCh; i++){
506 192 : mapADC[i][0] = chMap->GetADCModule(i);
507 192 : mapADC[i][1] = chMap->GetADCChannel(i);
508 192 : mapADC[i][2] = chMap->GetDetector(i);
509 192 : mapADC[i][3] = chMap->GetSector(i);
510 : // Ch. debug
511 : //printf(" mapADC[%d] = (%d %d %d %d)\n", i,
512 : // mapADC[i][0],mapADC[i][1],mapADC[i][2],mapADC[i][3]);
513 : }
514 :
515 : // *** Fill data array
516 : // ** ADC header
517 : UInt_t lADCHeaderGEO1 = 0;
518 : UInt_t lADCHeaderGEO2 = 1;
519 : UInt_t lADCHeaderGEO3 = 2;
520 : UInt_t lADCHeaderGEO4 = 3;
521 : UInt_t lADCHeaderCRATE = 0;
522 : UInt_t lADCHeaderCNT1 = knADCData1;
523 : UInt_t lADCHeaderCNT2 = knADCData2;
524 : UInt_t lADCHeaderCNT3 = knADCData3;
525 : UInt_t lADCHeaderCNT4 = knADCData4;
526 :
527 4 : lADCHeader1 = lADCHeaderGEO1 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 |
528 : lADCHeaderCNT1 << 8 ;
529 4 : lADCHeader2 = lADCHeaderGEO2 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 |
530 : lADCHeaderCNT2 << 8 ;
531 4 : lADCHeader3 = lADCHeaderGEO3 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 |
532 : lADCHeaderCNT3 << 8 ;
533 4 : lADCHeader4 = lADCHeaderGEO4 << 27 | 0x1 << 25 | lADCHeaderCRATE << 16 |
534 : lADCHeaderCNT4 << 8 ;
535 :
536 : // ** ADC data word
537 : UInt_t lADCDataGEO = 0;
538 : //
539 4 : UInt_t lADCDataValue1[2*knADCData1];
540 4 : UInt_t lADCDataValue2[2*knADCData2];
541 4 : UInt_t lADCDataValue3[2*knADCData3];
542 4 : UInt_t lADCDataValue4[2*knADCData4];
543 : //
544 : UInt_t lADCDataOvFlwHG = 0;
545 : UInt_t lADCDataOvFlwLG = 0;
546 : //
547 200 : for(Int_t i=0; i<2*knADCData1 ; i++) lADCDataValue1[i] = 0;
548 200 : for(Int_t i=0; i<2*knADCData2 ; i++) lADCDataValue2[i] = 0;
549 200 : for(Int_t i=0; i<2*knADCData3 ; i++) lADCDataValue3[i] = 0;
550 200 : for(Int_t i=0; i<2*knADCData4 ; i++) lADCDataValue4[i] = 0;
551 : //
552 : UInt_t lADCDataChannel = 0;
553 :
554 : Int_t indADC0=0, indADC1=0, indADC2=0, indADC3=0;
555 :
556 : // loop over digits
557 592 : for(Int_t iDigit=0; iDigit<(Int_t) (treeD->GetEntries()); iDigit++){
558 192 : treeD->GetEntry(iDigit);
559 192 : if(!pdigit) continue;
560 : //digit.Print("");
561 :
562 : // *** ADC data
563 : // Scan of the map to assign the correct ADC module-channel
564 9604 : for(Int_t k=0; k<nCh; k++){
565 9592 : if(iDigit<knADCData1+knADCData2){
566 6296 : if(digit.GetSector(0)==mapADC[k][2] && digit.GetSector(1)==mapADC[k][3]){
567 96 : lADCDataGEO = (UInt_t) mapADC[k][0];
568 96 : lADCDataChannel = (UInt_t) mapADC[k][1];
569 96 : break;
570 : }
571 : }
572 : else{
573 4420 : if(digit.GetSector(0)==mapADC[k][2] && digit.GetSector(1)==mapADC[k][3]){
574 192 : lADCDataGEO = (UInt_t) mapADC[k][0];
575 192 : lADCDataChannel = (UInt_t) mapADC[k][1];
576 284 : if(k>knADCData1+knADCData2) break;
577 : }
578 : }
579 : }
580 : // Ch. debug
581 : //printf("iDigit %d det %d sec %d -> lADCDataGEO %d lADCDataChannel %d\n",
582 : // iDigit,digit.GetSector(0),digit.GetSector(1),lADCDataGEO,lADCDataChannel);
583 :
584 192 : if(lADCDataGEO==0){
585 48 : if(indADC0>=knADCData1){
586 0 : AliWarning(Form(" Problem with digit index %d for ADC0\n", indADC0));
587 0 : return;
588 : }
589 48 : Int_t indLG = indADC0+knADCData1;
590 : // High gain ADC ch.
591 48 : if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1;
592 48 : lADCDataValue1[indADC0] = digit.GetADCValue(0);
593 144 : lADCData1[indADC0] = lADCDataGEO << 27 | lADCDataChannel << 17 |
594 96 : lADCDataOvFlwHG << 12 | (lADCDataValue1[indADC0] & 0xfff);
595 : // Low gain ADC ch.
596 48 : if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1;
597 48 : lADCDataValue1[indLG] = digit.GetADCValue(1);
598 144 : lADCData1[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 |
599 96 : lADCDataOvFlwLG << 12 | (lADCDataValue1[indLG] & 0xfff);
600 : // Ch. debug
601 : //printf(" lADCDataGEO %d ADCdataHG[%d] %d ADCdataLG[%d] %d\n",
602 : // lADCDataGEO,indADC0,lADCDataValue1[indADC0],indLG,lADCDataValue1[indLG]);
603 :
604 48 : indADC0++;
605 48 : }
606 144 : else if(lADCDataGEO==1){
607 48 : if(indADC1>=knADCData2){
608 0 : AliWarning(Form(" Problem with digit index %d for ADC1\n", indADC1));
609 0 : return;
610 : }
611 48 : Int_t indLG = indADC1+knADCData2;
612 : // High gain ADC ch.
613 48 : if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1;
614 48 : lADCDataValue2[indADC1] = digit.GetADCValue(0);
615 144 : lADCData2[indADC1] = lADCDataGEO << 27 | lADCDataChannel << 17 |
616 96 : lADCDataOvFlwHG << 12 | (lADCDataValue2[indADC1] & 0xfff);
617 : // Low gain ADC ch.
618 48 : if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1;
619 48 : lADCDataValue2[indLG] = digit.GetADCValue(1);
620 144 : lADCData2[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 |
621 96 : lADCDataOvFlwLG << 12 | (lADCDataValue2[indLG] & 0xfff);
622 : // Ch. debug
623 : //printf(" lADCDataGEO %d ADCdataHG[%d] %d ADCdataLG[%d] %d\n",
624 : // lADCDataGEO,indADC1,lADCDataValue2[indADC1],indLG,lADCDataValue2[indLG]);
625 :
626 48 : indADC1++;
627 48 : }
628 96 : else if(lADCDataGEO==2){
629 48 : if(indADC2>=knADCData3){
630 0 : AliWarning(Form(" Problem with digit index %d for ADC2\n", indADC2));
631 0 : return;
632 : }
633 48 : Int_t indLG = indADC2+knADCData3;
634 : // High gain ADC ch.
635 48 : if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1;
636 48 : lADCDataValue3[indADC1] = digit.GetADCValue(0);
637 144 : lADCData3[indADC1] = lADCDataGEO << 27 | lADCDataChannel << 17 |
638 96 : lADCDataOvFlwHG << 12 | (lADCDataValue3[indADC2] & 0xfff);
639 : // Low gain ADC ch.
640 48 : if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1;
641 48 : lADCDataValue3[indLG] = digit.GetADCValue(1);
642 144 : lADCData3[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 |
643 96 : lADCDataOvFlwLG << 12 | (lADCDataValue3[indLG] & 0xfff);
644 : // Ch. debug
645 : //printf(" lADCDataGEO %d ADCdataHG[%d] %d ADCdataLG[%d] %d\n",
646 : // lADCDataGEO,indADC2,lADCDataValue3[indADC2],indLG,lADCDataValue3[indLG]);
647 :
648 48 : indADC2++;
649 48 : }
650 48 : else if(lADCDataGEO==3){
651 48 : if(indADC3>=knADCData4){
652 0 : AliWarning(Form(" Problem with digit index %d for ADC2\n", indADC3));
653 0 : return;
654 : }
655 48 : Int_t indLG = indADC3+knADCData4;
656 : // High gain ADC ch.
657 48 : if(digit.GetADCValue(0) > 2047) lADCDataOvFlwHG = 1;
658 48 : lADCDataValue4[indADC3] = digit.GetADCValue(0);
659 144 : lADCData4[indADC3] = lADCDataGEO << 27 | lADCDataChannel << 17 |
660 96 : lADCDataOvFlwHG << 12 | (lADCDataValue4[indADC3] & 0xfff);
661 : // Low gain ADC ch.
662 48 : if(digit.GetADCValue(1) > 2047) lADCDataOvFlwLG = 1;
663 48 : lADCDataValue4[indLG] = digit.GetADCValue(1);
664 144 : lADCData4[indLG] = lADCDataGEO << 27 | lADCDataChannel << 17 | 0x1 << 16 |
665 96 : lADCDataOvFlwLG << 12 | (lADCDataValue4[indLG] & 0xfff);
666 : // Ch. debug
667 : //printf(" lADCDataGEO %d ADCdataHG[%d] %d ADCdataLG[%d] %d\n",
668 : // lADCDataGEO,indADC3,lADCDataValue4[indADC3],indLG,lADCDataValue4[indLG]);
669 :
670 48 : indADC3++;
671 48 : }
672 :
673 : }
674 : //
675 : /*for(Int_t i=0;i<2*knADCData1;i++) printf("\t ADCData1[%d] = %x\n",i,lADCData1[i]);
676 : for(Int_t i=0;i<2*knADCData2;i++) printf("\t ADCData2[%d] = %x\n",i,lADCData2[i]);
677 : for(Int_t i=0;i<2*knADCData3;i++) printf("\t ADCData3[%d] = %x\n",i,lADCData3[i]);
678 : for(Int_t i=0;i<2*knADCData4;i++) printf("\t ADCData4[%d] = %x\n",i,lADCData4[i]);*/
679 :
680 : // End of Block
681 : UInt_t lADCEndBlockGEO = 0;
682 : // Event counter in ADC EOB -> getting no. of events in run from AliRunLoader
683 : // get run loader
684 4 : AliRunLoader* runLoader = fLoader->GetRunLoader();
685 4 : UInt_t lADCEndBlockEvCount = runLoader->GetEventNumber();
686 : //
687 4 : lADCEndBlock = lADCEndBlockGEO << 27 | 0x1 << 26 | lADCEndBlockEvCount;
688 : //printf("\t AliZDC::Digits2Raw -> ADCEndBlock = %d\n",lADCEndBlock);
689 :
690 : // open the output file
691 4 : TString fileName;
692 8 : fileName.Form("%s",AliDAQ::DdlFileName("ZDC",0));
693 :
694 12 : AliFstream* file = new AliFstream(fileName.Data());
695 :
696 : // write the DDL data header
697 4 : AliRawDataHeaderSim header;
698 4 : header.fSize = sizeof(header) +
699 : sizeof(lADCHeader1) + sizeof(lADCData1) + sizeof(lADCEndBlock) +
700 : sizeof(lADCHeader2) + sizeof(lADCData2) + sizeof(lADCEndBlock) +
701 : sizeof(lADCHeader3) + sizeof(lADCData3) + sizeof(lADCEndBlock) +
702 : sizeof(lADCHeader4) + sizeof(lADCData4) + sizeof(lADCEndBlock);
703 : //
704 : /*printf("sizeof header = %d, ADCHeader1 = %d, ADCData1 = %d, ADCEndBlock = %d\n",
705 : sizeof(header),sizeof(lADCHeader1),sizeof(lADCData1),sizeof(lADCEndBlock));
706 : printf("sizeof header = %d, ADCHeader2 = %d, ADCData2 = %d, ADCEndBlock = %d\n",
707 : sizeof(header),sizeof(lADCHeader2),sizeof(lADCData2),sizeof(lADCEndBlock));
708 : printf("sizeof header = %d, ADCHeader3 = %d, ADCData3 = %d, ADCEndBlock = %d\n",
709 : sizeof(header),sizeof(lADCHeader1),sizeof(lADCData1),sizeof(lADCEndBlock));
710 : printf("sizeof header = %d, ADCHeader4 = %d, ADCData4 = %d, ADCEndBlock = %d\n",
711 : sizeof(header),sizeof(lADCHeader2),sizeof(lADCData2),sizeof(lADCEndBlock));*/
712 :
713 4 : header.SetAttribute(0); // valid data
714 4 : file->WriteBuffer((char*)(&header), sizeof(header));
715 : // write the raw data and close the file
716 4 : file->WriteBuffer((char*) &lADCHeader1, sizeof (lADCHeader1));
717 4 : file->WriteBuffer((char*) &lADCData1, sizeof(lADCData1));
718 4 : file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock));
719 4 : file->WriteBuffer((char*) &lADCHeader2, sizeof (lADCHeader2));
720 4 : file->WriteBuffer((char*) (lADCData2), sizeof(lADCData2));
721 4 : file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock));
722 4 : file->WriteBuffer((char*) &lADCHeader3, sizeof (lADCHeader3));
723 4 : file->WriteBuffer((char*) (lADCData3), sizeof(lADCData3));
724 4 : file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock));
725 4 : file->WriteBuffer((char*) &lADCHeader4, sizeof (lADCHeader4));
726 4 : file->WriteBuffer((char*) (lADCData4), sizeof(lADCData4));
727 4 : file->WriteBuffer((char*) &lADCEndBlock, sizeof(lADCEndBlock));
728 8 : delete file;
729 :
730 : // unload the digits
731 4 : fLoader->UnloadDigits();
732 12 : }
733 :
734 : //_____________________________________________________________________________
735 : Bool_t AliZDC::Raw2SDigits(AliRawReader* rawReader)
736 : {
737 : // Convert ZDC raw data to Sdigits
738 : const int kNch = 48;
739 0 : AliLoader* loader = (AliRunLoader::Instance())->GetLoader("ZDCLoader");
740 0 : if(!loader) {
741 0 : AliError("no ZDC loader found");
742 0 : return kFALSE;
743 : }
744 :
745 : // Create the output digit tree
746 0 : TTree* treeS = loader->TreeS();
747 0 : if(!treeS){
748 0 : loader->MakeTree("S");
749 0 : treeS = loader->TreeS();
750 0 : }
751 : //
752 0 : AliZDCSDigit sdigit;
753 0 : AliZDCSDigit* psdigit = &sdigit;
754 : const Int_t kBufferSize = 4000;
755 0 : treeS->Branch("ZDC", "AliZDCSDigit", &psdigit, kBufferSize);
756 : //
757 0 : AliZDCRawStream rawStream(rawReader);
758 0 : Int_t sector[2], resADC, rawADC, corrADC, nPheVal;
759 : Int_t jcount = 0;
760 0 : while(rawStream.Next()){
761 0 : if(rawStream.IsADCDataWord()){
762 : //For the moment only in-time SDigits are foreseen (1st 48 raw values)
763 0 : if(jcount < kNch){
764 0 : for(Int_t j=0; j<2; j++) sector[j] = rawStream.GetSector(j);
765 0 : rawADC = rawStream.GetADCValue();
766 0 : resADC = rawStream.GetADCGain();
767 : //printf("\t RAw2SDigits raw%d -> RawADC[%d, %d, %d] read\n",
768 : // jcount, sector[0], sector[1], rawADC);
769 : //
770 0 : corrADC = rawADC - Pedestal(sector[0], sector[1], resADC);
771 0 : if(corrADC<0) corrADC=0;
772 0 : nPheVal = ADCch2Phe(sector[0], sector[1], corrADC, resADC);
773 : //
774 : //printf("\t \t -> SDigit[%d, %d, %d] created\n",
775 : // sector[0], sector[1], nPheVal);
776 : //
777 0 : new(psdigit) AliZDCSDigit(sector, (Float_t) nPheVal, 0.);
778 0 : treeS->Fill();
779 0 : jcount++;
780 0 : }
781 : }//IsADCDataWord
782 : }//rawStream.Next
783 : // write the output tree
784 0 : fLoader->WriteSDigits("OVERWRITE");
785 0 : fLoader->UnloadSDigits();
786 :
787 : return kTRUE;
788 0 : }
789 :
790 : //_____________________________________________________________________________
791 : Int_t AliZDC::Pedestal(Int_t Det, Int_t Quad, Int_t Res) const
792 : {
793 : // Returns a pedestal for detector det, PM quad, channel with res.
794 : //
795 : // Getting calibration object for ZDC set
796 : Float_t pedValue = 0.;
797 0 : AliCDBManager *man = AliCDBManager::Instance();
798 0 : AliCDBEntry *entry = man->Get("ZDC/Calib/Pedestals");
799 : AliZDCPedestals *calibPed = 0x0;
800 0 : if(!entry) AliFatal("No calibration data loaded!");
801 : else{
802 0 : calibPed = (AliZDCPedestals*) entry->GetObject();
803 : //
804 0 : if(!calibPed){
805 0 : printf("\t No calibration object found for ZDC!");
806 0 : return -1;
807 : }
808 : //
809 : Int_t index=0, kNch=24;
810 0 : if(Quad!=5){
811 0 : if(Det==1) index = Quad+kNch*Res; // ZN1
812 0 : else if(Det==2) index = Quad+5+kNch*Res; // ZP1
813 0 : else if(Det==3) index = Quad+9+kNch*Res; // ZEM
814 0 : else if(Det==4) index = Quad+12+kNch*Res; // ZN2
815 0 : else if(Det==5) index = Quad+17+kNch*Res; // ZP2
816 : }
817 0 : else index = (Det-1)/3+22+kNch*Res; // Reference PMs
818 : //
819 : //
820 0 : Float_t meanPed = calibPed->GetMeanPed(index);
821 0 : Float_t pedWidth = calibPed->GetMeanPedWidth(index);
822 0 : pedValue = gRandom->Gaus(meanPed,pedWidth);
823 : //
824 : //printf("\t AliZDC::Pedestal - det(%d, %d) - Ped[%d] = %d\n",Det, Quad, index,(Int_t) pedValue); // Chiara debugging!
825 : }
826 :
827 0 : return (Int_t) pedValue;
828 0 : }
829 :
830 :
831 : //_____________________________________________________________________________
832 : Int_t AliZDC::ADCch2Phe(Int_t Det, Int_t Quad, Int_t ADCVal, Int_t Res) const
833 : {
834 : // Evaluation of the no. of phe produced
835 0 : Float_t pmGain[6][5];
836 0 : Float_t resADC[2];
837 0 : for(Int_t j = 0; j < 5; j++){
838 0 : pmGain[0][j] = 50000.;
839 0 : pmGain[1][j] = 100000.;
840 0 : pmGain[2][j] = 100000.;
841 0 : pmGain[3][j] = 50000.;
842 0 : pmGain[4][j] = 100000.;
843 0 : pmGain[5][j] = 100000.;
844 : }
845 : // ADC Caen V965
846 0 : resADC[0] = 0.0000008; // ADC Resolution high gain: 200 fC/adcCh
847 0 : resADC[1] = 0.0000064; // ADC Resolution low gain: 25 fC/adcCh
848 : //
849 0 : Int_t nPhe = (Int_t) (ADCVal / (pmGain[Det-1][Quad] * resADC[Res]));
850 : //
851 : //printf("\t AliZDC::ADCch2Phe -> det(%d, %d) - ADC %d phe %d\n",Det,Quad,ADCVal,nPhe);
852 :
853 0 : return nPhe;
854 0 : }
855 :
856 : //______________________________________________________________________
857 : void AliZDC::SetTreeAddress(){
858 :
859 : // Set branch address for the Trees.
860 340 : if(fLoader->TreeH() && (fHits == 0x0))
861 4 : fHits = new TClonesArray("AliZDCHit",1000);
862 :
863 155 : AliDetector::SetTreeAddress();
864 155 : }
865 :
866 : //_____________________________________________________________________________
867 : AliZDCChMap* AliZDC::GetChMap() const
868 : {
869 :
870 : // Getting calibration object for ZDC
871 : AliZDCChMap *calibdata = 0x0;
872 12 : AliCDBEntry *entry = AliCDBManager::Instance()->Get("ZDC/Calib/ChMap");
873 4 : if(!entry) AliFatal("No calibration data loaded!");
874 : else{
875 12 : calibdata = dynamic_cast<AliZDCChMap*> (entry->GetObject());
876 4 : if(!calibdata) AliFatal("Wrong calibration object in calibration file!");
877 : }
878 4 : return calibdata;
879 0 : }
|