1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /* History of cvs commits:
19 * Revision 1.104 2006/11/23 13:40:44 hristov
20 * Common class for raw data reading and ALTRO mappiing for PHOS and EMCAL (Gustavo, Cvetan)
22 * Revision 1.103 2006/11/14 17:11:15 hristov
23 * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
25 * Revision 1.102 2006/10/27 17:14:27 kharlov
26 * Introduce AliDebug and AliLog (B.Polichtchouk)
28 * Revision 1.101 2006/10/13 06:47:29 kharlov
29 * Simulation of RAW data applies real mapping (B.Polichtchouk)
31 * Revision 1.100 2006/08/11 12:36:26 cvetan
32 * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
34 * Revision 1.99 2006/06/28 11:36:09 cvetan
35 * New detector numbering scheme (common for DAQ/HLT/Offline). All the subdetectors shall use the AliDAQ class for the sim and rec of the raw data. The AliDAQ and raw reader classes now provide all the necessary interfaces to write and select the detector specific raw-data payload. Look into the AliDAQ.h and AliRawReader.h for more details.
37 * Revision 1.98 2006/05/11 11:30:48 cvetan
38 * Major changes in AliAltroBuffer. Now it can be used only for writing of raw data. All the corresponding read method are removed. It is based now on AliFstream in order to avoid endianess problems. The altro raw data is written always with little endian
40 * Revision 1.97 2006/04/22 10:30:17 hristov
41 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
43 * Revision 1.96 2006/04/07 08:41:59 hristov
44 * Follow AliAlignObj framework and remove AliPHOSAlignData (Yu.Kharlov)
46 * Revision 1.95 2006/03/14 19:40:41 kharlov
47 * Remove De-digitizing of raw data and digitizing the raw data fit
49 * Revision 1.94 2006/03/07 18:56:25 kharlov
50 * CDB is passed via environment variable
52 * Revision 1.93 2005/11/22 08:45:11 kharlov
53 * Calibration is read from CDB if any (Boris Polichtchouk)
55 * Revision 1.92 2005/11/03 13:09:19 hristov
56 * Removing meaningless const declarations (linuxicc)
58 * Revision 1.91 2005/07/27 15:08:53 kharlov
59 * Mixture ArCO2 is corrected
61 * Revision 1.90 2005/06/17 07:39:07 hristov
62 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
64 * Revision 1.89 2005/05/28 12:10:07 schutz
65 * Copy constructor is corrected (by T.P.)
69 //_________________________________________________________________________
70 // Base Class for PHOS description:
71 // PHOS consists of a PbWO4 calorimeter (EMCA) and a gazeous charged
72 // particles detector (CPV or PPSD).
73 // The only provided method here is CreateMaterials,
74 // which defines the materials common to all PHOS versions.
76 //*-- Author: Laurent Aphecetche & Yves Schutz (SUBATECH)
77 //////////////////////////////////////////////////////////////////////////////
80 // --- ROOT system ---
84 #include <TVirtualMC.h>
89 // --- Standard library ---
91 // --- AliRoot header files ---
94 #include "AliPHOSGetter.h"
96 #include "AliPHOSDigitizer.h"
97 #include "AliPHOSSDigitizer.h"
98 #include "AliPHOSDigit.h"
99 #include "AliAltroBuffer.h"
100 #include "AliAltroMapping.h"
101 #include "AliCaloAltroMapping.h"
103 #include "AliCDBManager.h"
104 #include "AliCDBEntry.h"
105 #include "AliCDBStorage.h"
106 #include "AliPHOSCalibData.h"
111 Double_t AliPHOS::fgCapa = 1.; // 1pF
112 Int_t AliPHOS::fgOrder = 2 ;
113 Double_t AliPHOS::fgTimeMax = 2.56E-5 ; // each sample is over 100 ns fTimeMax/fTimeBins
114 Double_t AliPHOS::fgTimePeak = 4.1E-6 ; // 4 micro seconds
115 Double_t AliPHOS::fgTimeTrigger = 100E-9 ; // 100ns, just for a reference
117 Double_t AliPHOS::fgHighCharge = 8.2; // adjusted for a high gain range of 5.12 GeV (10 bits)
118 Double_t AliPHOS::fgHighGain = 6.64;
119 Double_t AliPHOS::fgHighLowGainFactor = 16.; // adjusted for a low gain range of 82 GeV (10 bits)
121 //____________________________________________________________________________
122 AliPHOS:: AliPHOS() : AliDetector()
129 //____________________________________________________________________________
130 AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title)
132 // ctor : title is used to identify the layout
135 //____________________________________________________________________________
140 //____________________________________________________________________________
141 AliDigitizer* AliPHOS::CreateDigitizer(AliRunDigitizer* manager) const
143 return new AliPHOSDigitizer(manager);
146 //____________________________________________________________________________
147 void AliPHOS::CreateMaterials()
149 // Definitions of materials to build PHOS and associated tracking media.
150 // media number in idtmed are 699 to 798.
152 // --- The PbWO4 crystals ---
153 Float_t aX[3] = {207.19, 183.85, 16.0} ;
154 Float_t zX[3] = {82.0, 74.0, 8.0} ;
155 Float_t wX[3] = {1.0, 1.0, 4.0} ;
158 AliMixture(0, "PbWO4$", aX, zX, dX, -3, wX) ;
161 // --- The polysterene scintillator (CH) ---
162 Float_t aP[2] = {12.011, 1.00794} ;
163 Float_t zP[2] = {6.0, 1.0} ;
164 Float_t wP[2] = {1.0, 1.0} ;
167 AliMixture(1, "Polystyrene$", aP, zP, dP, -2, wP) ;
170 AliMaterial(2, "Al$", 26.98, 13., 2.7, 8.9, 999., 0, 0) ;
171 // --- Absorption length is ignored ^
173 // --- Tyvek (CnH2n) ---
174 Float_t aT[2] = {12.011, 1.00794} ;
175 Float_t zT[2] = {6.0, 1.0} ;
176 Float_t wT[2] = {1.0, 2.0} ;
179 AliMixture(3, "Tyvek$", aT, zT, dT, -2, wT) ;
181 // --- Polystyrene foam ---
182 Float_t aF[2] = {12.011, 1.00794} ;
183 Float_t zF[2] = {6.0, 1.0} ;
184 Float_t wF[2] = {1.0, 1.0} ;
187 AliMixture(4, "Foam$", aF, zF, dF, -2, wF) ;
190 Float_t aTIT[3] = {47.88, 26.98, 54.94} ;
191 Float_t zTIT[3] = {22.0, 13.0, 25.0} ;
192 Float_t wTIT[3] = {69.0, 6.0, 1.0} ;
195 AliMixture(5, "Titanium$", aTIT, zTIT, dTIT, -3, wTIT);
198 AliMaterial(6, "Si$", 28.0855, 14., 2.33, 9.36, 42.3, 0, 0) ;
202 // --- Foam thermo insulation ---
203 Float_t aTI[2] = {12.011, 1.00794} ;
204 Float_t zTI[2] = {6.0, 1.0} ;
205 Float_t wTI[2] = {1.0, 1.0} ;
208 AliMixture(7, "Thermo Insul.$", aTI, zTI, dTI, -2, wTI) ;
211 Float_t aTX[4] = {16.0, 28.09, 12.011, 1.00794} ;
212 Float_t zTX[4] = {8.0, 14.0, 6.0, 1.0} ;
213 Float_t wTX[4] = {292.0, 68.0, 462.0, 736.0} ;
216 AliMixture(8, "Textolit$", aTX, zTX, dTX, -4, wTX) ;
219 Float_t aFR[4] = {16.0, 28.09, 12.011, 1.00794} ;
220 Float_t zFR[4] = {8.0, 14.0, 6.0, 1.0} ;
221 Float_t wFR[4] = {292.0, 68.0, 462.0, 736.0} ;
224 AliMixture(9, "FR4$", aFR, zFR, dFR, -4, wFR) ;
226 // --- The Composite Material for micromegas (so far polyetylene) ---
227 Float_t aCM[2] = {12.01, 1.} ;
228 Float_t zCM[2] = {6., 1.} ;
229 Float_t wCM[2] = {1., 2.} ;
230 Float_t dCM = 0.935 ;
232 AliMixture(10, "Compo Mat$", aCM, zCM, dCM, -2, wCM) ;
235 AliMaterial(11, "Cu$", 63.546, 29, 8.96, 1.43, 14.8, 0, 0) ;
237 // --- G10 : Printed Circuit material ---
238 Float_t aG10[4] = { 12., 1., 16., 28.} ;
239 Float_t zG10[4] = { 6., 1., 8., 14.} ;
240 Float_t wG10[4] = { .259, .288, .248, .205} ;
243 AliMixture(12, "G10$", aG10, zG10, dG10, -4, wG10);
246 AliMaterial(13, "Pb$", 207.2, 82, 11.35, 0.56, 0., 0, 0) ;
248 // --- The gas mixture ---
250 Float_t aCO[2] = {12.0, 16.0} ;
251 Float_t zCO[2] = {6.0, 8.0} ;
252 Float_t wCO[2] = {1.0, 2.0} ;
253 Float_t dCO = 0.001977 ;
255 AliMixture(14, "CO2$", aCO, zCO, dCO, -2, wCO);
258 Float_t dAr = 0.001782 ;
259 AliMaterial(15, "Ar$", 39.948, 18.0, dAr, 14.0, 0., 0, 0) ;
261 // Ar+CO2 Mixture (80% / 20%)
262 Float_t arContent = 0.80 ; // Ar-content of the ArCO2-mixture
263 Float_t aArCO[3] = {39.948, 12.0, 16.0} ;
264 Float_t zArCO[3] = {18.0 , 6.0, 8.0} ;
266 wArCO[0] = arContent;
267 wArCO[1] = (1-arContent)*1;
268 wArCO[2] = (1-arContent)*2;
269 Float_t dArCO = arContent*dAr + (1-arContent)*dCO ;
270 AliMixture(16, "ArCO2$", aArCO, zArCO, dArCO, -3, wArCO) ;
272 // --- Stainless steel (let it be pure iron) ---
273 AliMaterial(17, "Steel$", 55.845, 26, 7.87, 1.76, 0., 0, 0) ;
276 // --- Fiberglass ---
277 Float_t aFG[4] = {16.0, 28.09, 12.011, 1.00794} ;
278 Float_t zFG[4] = {8.0, 14.0, 6.0, 1.0} ;
279 Float_t wFG[4] = {292.0, 68.0, 462.0, 736.0} ;
282 AliMixture(18, "Fibergla$", aFG, zFG, dFG, -4, wFG) ;
284 // --- Cables in Air box ---
287 Float_t aCA[4] = { 1.,12.,55.8,63.5 };
288 Float_t zCA[4] = { 1.,6.,26.,29. };
289 Float_t wCA[4] = { .014,.086,.42,.48 };
290 Float_t dCA = 0.8 ; //this density is raw estimation, if you know better - correct
292 AliMixture(19, "Cables $", aCA, zCA, dCA, -4, wCA) ;
296 Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
297 Float_t zAir[4]={6.,7.,8.,18.};
298 Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
299 Float_t dAir = 1.20479E-3;
301 AliMixture(99, "Air$", aAir, zAir, dAir, 4, wAir) ;
303 // DEFINITION OF THE TRACKING MEDIA
305 // for PHOS: idtmed[699->798] equivalent to fIdtmed[0->100]
306 Int_t * idtmed = fIdtmed->GetArray() - 699 ;
307 Int_t isxfld = gAlice->Field()->Integ() ;
308 Float_t sxmgmx = gAlice->Field()->Max() ;
310 // The scintillator of the calorimeter made of PBW04 -> idtmed[699]
311 AliMedium(0, "PHOS Xtal $", 0, 1,
312 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
314 // The scintillator of the CPV made of Polystyrene scintillator -> idtmed[700]
315 AliMedium(1, "CPV scint. $", 1, 1,
316 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
318 // Various Aluminium parts made of Al -> idtmed[701]
319 AliMedium(2, "Al parts $", 2, 0,
320 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
322 // The Tywek which wraps the calorimeter crystals -> idtmed[702]
323 AliMedium(3, "Tyvek wrapper$", 3, 0,
324 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
326 // The Polystyrene foam around the calorimeter module -> idtmed[703]
327 AliMedium(4, "Polyst. foam $", 4, 0,
328 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
330 // The Titanium around the calorimeter crystal -> idtmed[704]
331 AliMedium(5, "Titan. cover $", 5, 0,
332 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.0001, 0.0001, 0, 0) ;
334 // The Silicon of the pin diode to read out the calorimeter crystal -> idtmed[705]
335 AliMedium(6, "Si PIN $", 6, 0,
336 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.01, 0.01, 0, 0) ;
338 // The thermo insulating material of the box which contains the calorimeter module -> idtmed[706]
339 AliMedium(7, "Thermo Insul.$", 7, 0,
340 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
342 // The Textolit which makes up the box which contains the calorimeter module -> idtmed[707]
343 AliMedium(8, "Textolit $", 8, 0,
344 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
346 // FR4: The Plastic which makes up the frame of micromegas -> idtmed[708]
347 AliMedium(9, "FR4 $", 9, 0,
348 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
351 // The Composite Material for micromegas -> idtmed[709]
352 AliMedium(10, "CompoMat $", 10, 0,
353 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
355 // Copper -> idtmed[710]
356 AliMedium(11, "Copper $", 11, 0,
357 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
359 // G10: Printed Circuit material -> idtmed[711]
361 AliMedium(12, "G10 $", 12, 0,
362 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
364 // The Lead -> idtmed[712]
366 AliMedium(13, "Lead $", 13, 0,
367 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
369 // The gas mixture: ArCo2 -> idtmed[715]
371 AliMedium(16, "ArCo2 $", 16, 1,
372 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
374 // Stainless steel -> idtmed[716]
375 AliMedium(17, "Steel $", 17, 0,
376 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
378 // Fibergalss -> idtmed[717]
379 AliMedium(18, "Fiberglass$", 18, 0,
380 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
382 // Cables in air -> idtmed[718]
383 AliMedium(19, "Cables $", 19, 0,
384 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
386 // Air -> idtmed[798]
387 AliMedium(99, "Air $", 99, 0,
388 isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0, 0, 0) ;
390 // --- Set decent energy thresholds for gamma and electron tracking
392 // Tracking threshold for photons and electrons in the scintillator crystal
393 gMC->Gstpar(idtmed[699], "CUTGAM",0.5E-4) ;
394 gMC->Gstpar(idtmed[699], "CUTELE",1.0E-4) ;
396 // --- Generate explicitly delta rays in the titan cover ---
397 gMC->Gstpar(idtmed[704], "LOSS",3.) ;
398 gMC->Gstpar(idtmed[704], "DRAY",1.) ;
399 // --- and in aluminium parts ---
400 gMC->Gstpar(idtmed[701], "LOSS",3.) ;
401 gMC->Gstpar(idtmed[701], "DRAY",1.) ;
402 // --- and in PIN diode
403 gMC->Gstpar(idtmed[705], "LOSS",3) ;
404 gMC->Gstpar(idtmed[705], "DRAY",1) ;
405 // --- and in the passive convertor
406 gMC->Gstpar(idtmed[712], "LOSS",3) ;
407 gMC->Gstpar(idtmed[712], "DRAY",1) ;
408 // Tracking threshold for photons and electrons in the gas ArC02
409 gMC->Gstpar(idtmed[715], "CUTGAM",1.E-5) ;
410 gMC->Gstpar(idtmed[715], "CUTELE",1.E-5) ;
411 gMC->Gstpar(idtmed[715], "CUTNEU",1.E-5) ;
412 gMC->Gstpar(idtmed[715], "CUTHAD",1.E-5) ;
413 gMC->Gstpar(idtmed[715], "CUTMUO",1.E-5) ;
414 gMC->Gstpar(idtmed[715], "BCUTE",1.E-5) ;
415 gMC->Gstpar(idtmed[715], "BCUTM",1.E-5) ;
416 gMC->Gstpar(idtmed[715], "DCUTE",1.E-5) ;
417 gMC->Gstpar(idtmed[715], "DCUTM",1.E-5) ;
418 gMC->Gstpar(idtmed[715], "PPCUTM",1.E-5) ;
419 gMC->Gstpar(idtmed[715], "LOSS",2.) ;
420 gMC->Gstpar(idtmed[715], "DRAY",0.) ;
421 gMC->Gstpar(idtmed[715], "STRA",2.) ;
425 //____________________________________________________________________________
426 void AliPHOS::Digits2Raw()
428 // convert digits of the current event to raw data
430 AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ;
433 loader->LoadDigits();
434 TClonesArray* digits = loader->Digits() ;
437 AliError(Form("No digits found !"));
442 AliPHOSGeometry* geom = GetGeometry();
444 AliError(Form("No geometry found !"));
448 // some digitization constants
449 // const Int_t kThreshold = 1; // skip digits below this threshold // YVK
450 const Float_t kThreshold = 0.001; // skip digits below 1 MeV
451 const Int_t kAdcThreshold = 1; // Lower ADC threshold to write to raw data
453 AliAltroBuffer* buffer = NULL;
455 Int_t adcValuesLow[fkTimeBins];
456 Int_t adcValuesHigh[fkTimeBins];
466 // loop over digits (assume ordered digits)
467 for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) {
468 AliPHOSDigit* digit = dynamic_cast<AliPHOSDigit *>(digits->At(iDigit)) ;
469 if (digit->GetEnergy() < kThreshold)
472 geom->AbsToRelNumbering(digit->GetId(), relId);
473 Int_t module = relId[0];
477 continue; // ignore digits from CPV
480 Int_t row = relId[2]-1;
481 Int_t col = relId[3]-1;
486 if(0<=row&&row<32 && 0<=col&&col<28) iRCU=0;
489 if(0<=row&&row<32 && 28<=col&&col<56) iRCU=1;
492 if(32<=row&&row<64 && 0<=col&&col<28) iRCU=2;
495 if(32<=row&&row<64 && 28<=col&&col<56) iRCU=3;
498 // PHOS EMCA has 4 DDL per module. Splitting is based on the (row,column) numbers.
499 // PHOS internal convention: 1<module<5.
500 Int_t iDDL = 4 * (module - 1) + iRCU;
503 if (iDDL != prevDDL) {
504 // write real header and close previous file
507 buffer->WriteDataHeader(kFALSE, kFALSE);
511 // open new file and write dummy header
512 TString fileName = AliDAQ::DdlFileName("PHOS",iDDL);
514 TString path = gSystem->Getenv("ALICE_ROOT");
515 path += "/PHOS/mapping/RCU";
519 AliAltroMapping* mapping = new AliCaloAltroMapping(path.Data());
520 buffer = new AliAltroBuffer(fileName.Data(),mapping);
521 buffer->WriteDataHeader(kTRUE, kFALSE); //Dummy;
526 // out of time range signal (?)
527 if (digit->GetTimeR() > GetRawFormatTimeMax() ) {
528 AliInfo("Signal is out of time range.\n");
529 buffer->FillBuffer((Int_t)digit->GetEnergy());
530 buffer->FillBuffer(GetRawFormatTimeBins() ); // time bin
531 buffer->FillBuffer(3); // bunch length
532 buffer->WriteTrailer(3, relId[3], relId[2], module); // trailer
534 // calculate the time response function
536 Double_t energy = 0 ;
537 Int_t module = relId[0];
538 if ( digit->GetId() <= geom->GetNModules() * geom->GetNCristalsInModule()) {
539 energy=digit->GetEnergy();
540 AliDebug(2,Form("digit energy: %f\n",digit->GetEnergy()));
541 if(energy>eMax) {eMax=energy; modMax=module; colMax=col; rowMax=row;}
544 energy = 0; // CPV raw data format is now know yet
546 Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), energy, adcValuesHigh, adcValuesLow) ;
548 buffer->WriteChannel(relId[3]-1, relId[2]-1, 0,
549 GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold);
550 buffer->WriteChannel(relId[3]-1, relId[2]-1, 1,
551 GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold);
556 // write real header and close last file
559 buffer->WriteDataHeader(kFALSE, kFALSE);
563 AliDebug(1,Form("Digit with max. energy: modMax %d colMax %d rowMax %d eMax %f\n",
564 modMax,colMax,rowMax,eMax));
566 loader->UnloadDigits();
569 //____________________________________________________________________________
570 void AliPHOS::Hits2SDigits()
572 // create summable digits
574 AliPHOSSDigitizer phosDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
575 phosDigitizer.SetEventRange(0, -1) ; // do all the events
576 phosDigitizer.ExecuteTask("all") ;
579 //____________________________________________________________________________
580 AliLoader* AliPHOS::MakeLoader(const char* topfoldername)
582 //different behaviour than standard (singleton getter)
583 // --> to be discussed and made eventually coherent
584 fLoader = new AliPHOSLoader(GetName(),topfoldername);
588 //__________________________________________________________________
589 Double_t AliPHOS::RawResponseFunction(Double_t *x, Double_t *par)
591 // Shape of the electronics raw reponse:
592 // It is a semi-gaussian, 2nd order Gamma function of the general form
593 // v(t) = n**n * Q * A**n / C *(t/tp)**n * exp(-n * t/tp) with
594 // tp : peaking time par[0]
595 // n : order of the function
596 // C : integrating capacitor in the preamplifier
597 // A : open loop gain of the preamplifier
598 // Q : the total APD charge to be measured Q = C * energy
601 Double_t xx = x[0] - ( fgTimeTrigger + par[3] ) ;
603 if (xx < 0 || xx > fgTimeMax)
606 Double_t fac = par[0] * TMath::Power(fgOrder, fgOrder) * TMath::Power(par[1], fgOrder) / fgCapa ;
607 signal = fac * par[2] * TMath::Power(xx / fgTimePeak, fgOrder) * TMath::Exp(-fgOrder * (xx / fgTimePeak)) ;
612 //__________________________________________________________________
613 Double_t AliPHOS::RawResponseFunctionMax(Double_t charge, Double_t gain)
615 return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder)
616 / ( fgCapa * TMath::Exp(fgOrder) ) );
620 //__________________________________________________________________
621 Bool_t AliPHOS::RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const
623 // for a start time dtime and an amplitude damp given by digit,
624 // calculates the raw sampled response AliPHOS::RawResponseFunction
625 // Input: dtime - signal start time
626 // damp - signal amplitude (energy)
627 // Output: adcH - array[fkTimeBins] of 10-bit samples for high-gain channel
628 // adcL - array[fkTimeBins] of 10-bit samples for low-gain channel
630 const Int_t kRawSignalOverflow = 0x3FF ;
631 Bool_t lowGain = kFALSE ;
633 TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4);
635 for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) {
636 signalF.SetParameter(0, GetRawFormatHighCharge() ) ;
637 signalF.SetParameter(1, GetRawFormatHighGain() ) ;
638 signalF.SetParameter(2, damp) ;
639 signalF.SetParameter(3, dtime) ;
640 Double_t time = iTime * GetRawFormatTimeMax() / GetRawFormatTimeBins() ;
641 Double_t signal = signalF.Eval(time) ;
642 if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow ){ // larger than 10 bits
643 signal = kRawSignalOverflow ;
646 adcH[iTime] = static_cast<Int_t>(signal + 0.5) ;
647 AliDebug(4,Form("iTime: %d Energy: %f HG signal: %f adcH: %d ",iTime,damp,signal,adcH[iTime]));
649 signalF.SetParameter(0, GetRawFormatLowCharge() ) ;
650 signalF.SetParameter(1, GetRawFormatLowGain() ) ;
651 signal = signalF.Eval(time) ;
652 if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow) // larger than 10 bits
653 signal = kRawSignalOverflow ;
654 adcL[iTime] = static_cast<Int_t>(0.5 + signal ) ;
655 AliDebug(4,Form("..LG: %f adcL: %d\n",signal,adcL[iTime]));
661 //____________________________________________________________________________
662 void AliPHOS::SetTreeAddress()
664 // Links Hits in the Tree to Hits array
667 sprintf(branchname,"%s",GetName());
668 // Branch address for hit tree
669 TTree *treeH = TreeH();
671 branch = treeH->GetBranch(branchname);
674 if (fHits == 0x0) fHits= new TClonesArray("AliPHOSHit",1000);
675 //AliInfo(Form("<%s> Setting Hits Address",GetName()));
676 branch->SetAddress(&fHits);