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.102 2006/10/27 17:14:27 kharlov
20 * Introduce AliDebug and AliLog (B.Polichtchouk)
22 * Revision 1.101 2006/10/13 06:47:29 kharlov
23 * Simulation of RAW data applies real mapping (B.Polichtchouk)
25 * Revision 1.100 2006/08/11 12:36:26 cvetan
26 * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
28 * Revision 1.99 2006/06/28 11:36:09 cvetan
29 * 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.
31 * Revision 1.98 2006/05/11 11:30:48 cvetan
32 * 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
34 * Revision 1.97 2006/04/22 10:30:17 hristov
35 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
37 * Revision 1.96 2006/04/07 08:41:59 hristov
38 * Follow AliAlignObj framework and remove AliPHOSAlignData (Yu.Kharlov)
40 * Revision 1.95 2006/03/14 19:40:41 kharlov
41 * Remove De-digitizing of raw data and digitizing the raw data fit
43 * Revision 1.94 2006/03/07 18:56:25 kharlov
44 * CDB is passed via environment variable
46 * Revision 1.93 2005/11/22 08:45:11 kharlov
47 * Calibration is read from CDB if any (Boris Polichtchouk)
49 * Revision 1.92 2005/11/03 13:09:19 hristov
50 * Removing meaningless const declarations (linuxicc)
52 * Revision 1.91 2005/07/27 15:08:53 kharlov
53 * Mixture ArCO2 is corrected
55 * Revision 1.90 2005/06/17 07:39:07 hristov
56 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
58 * Revision 1.89 2005/05/28 12:10:07 schutz
59 * Copy constructor is corrected (by T.P.)
63 //_________________________________________________________________________
64 // Base Class for PHOS description:
65 // PHOS consists of a PbWO4 calorimeter (EMCA) and a gazeous charged
66 // particles detector (CPV or PPSD).
67 // The only provided method here is CreateMaterials,
68 // which defines the materials common to all PHOS versions.
70 //*-- Author: Laurent Aphecetche & Yves Schutz (SUBATECH)
71 //////////////////////////////////////////////////////////////////////////////
74 // --- ROOT system ---
78 #include <TVirtualMC.h>
83 // --- Standard library ---
85 // --- AliRoot header files ---
88 #include "AliPHOSGetter.h"
90 #include "AliPHOSDigitizer.h"
91 #include "AliPHOSSDigitizer.h"
92 #include "AliPHOSDigit.h"
93 #include "AliAltroBuffer.h"
94 #include "AliAltroMapping.h"
95 #include "AliPHOSAltroMapping.h"
97 #include "AliCDBManager.h"
98 #include "AliCDBEntry.h"
99 #include "AliCDBStorage.h"
100 #include "AliPHOSCalibData.h"
105 Double_t AliPHOS::fgCapa = 1.; // 1pF
106 Int_t AliPHOS::fgOrder = 2 ;
107 Double_t AliPHOS::fgTimeMax = 2.56E-5 ; // each sample is over 100 ns fTimeMax/fTimeBins
108 Double_t AliPHOS::fgTimePeak = 4.1E-6 ; // 4 micro seconds
109 Double_t AliPHOS::fgTimeTrigger = 100E-9 ; // 100ns, just for a reference
111 Double_t AliPHOS::fgHighCharge = 8.2; // adjusted for a high gain range of 5.12 GeV (10 bits)
112 Double_t AliPHOS::fgHighGain = 6.64;
113 Double_t AliPHOS::fgHighLowGainFactor = 16.; // adjusted for a low gain range of 82 GeV (10 bits)
115 //____________________________________________________________________________
116 AliPHOS:: AliPHOS() : AliDetector()
123 //____________________________________________________________________________
124 AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title)
126 // ctor : title is used to identify the layout
129 //____________________________________________________________________________
134 //____________________________________________________________________________
135 AliDigitizer* AliPHOS::CreateDigitizer(AliRunDigitizer* manager) const
137 return new AliPHOSDigitizer(manager);
140 //____________________________________________________________________________
141 void AliPHOS::CreateMaterials()
143 // Definitions of materials to build PHOS and associated tracking media.
144 // media number in idtmed are 699 to 798.
146 // --- The PbWO4 crystals ---
147 Float_t aX[3] = {207.19, 183.85, 16.0} ;
148 Float_t zX[3] = {82.0, 74.0, 8.0} ;
149 Float_t wX[3] = {1.0, 1.0, 4.0} ;
152 AliMixture(0, "PbWO4$", aX, zX, dX, -3, wX) ;
155 // --- The polysterene scintillator (CH) ---
156 Float_t aP[2] = {12.011, 1.00794} ;
157 Float_t zP[2] = {6.0, 1.0} ;
158 Float_t wP[2] = {1.0, 1.0} ;
161 AliMixture(1, "Polystyrene$", aP, zP, dP, -2, wP) ;
164 AliMaterial(2, "Al$", 26.98, 13., 2.7, 8.9, 999., 0, 0) ;
165 // --- Absorption length is ignored ^
167 // --- Tyvek (CnH2n) ---
168 Float_t aT[2] = {12.011, 1.00794} ;
169 Float_t zT[2] = {6.0, 1.0} ;
170 Float_t wT[2] = {1.0, 2.0} ;
173 AliMixture(3, "Tyvek$", aT, zT, dT, -2, wT) ;
175 // --- Polystyrene foam ---
176 Float_t aF[2] = {12.011, 1.00794} ;
177 Float_t zF[2] = {6.0, 1.0} ;
178 Float_t wF[2] = {1.0, 1.0} ;
181 AliMixture(4, "Foam$", aF, zF, dF, -2, wF) ;
184 Float_t aTIT[3] = {47.88, 26.98, 54.94} ;
185 Float_t zTIT[3] = {22.0, 13.0, 25.0} ;
186 Float_t wTIT[3] = {69.0, 6.0, 1.0} ;
189 AliMixture(5, "Titanium$", aTIT, zTIT, dTIT, -3, wTIT);
192 AliMaterial(6, "Si$", 28.0855, 14., 2.33, 9.36, 42.3, 0, 0) ;
196 // --- Foam thermo insulation ---
197 Float_t aTI[2] = {12.011, 1.00794} ;
198 Float_t zTI[2] = {6.0, 1.0} ;
199 Float_t wTI[2] = {1.0, 1.0} ;
202 AliMixture(7, "Thermo Insul.$", aTI, zTI, dTI, -2, wTI) ;
205 Float_t aTX[4] = {16.0, 28.09, 12.011, 1.00794} ;
206 Float_t zTX[4] = {8.0, 14.0, 6.0, 1.0} ;
207 Float_t wTX[4] = {292.0, 68.0, 462.0, 736.0} ;
210 AliMixture(8, "Textolit$", aTX, zTX, dTX, -4, wTX) ;
213 Float_t aFR[4] = {16.0, 28.09, 12.011, 1.00794} ;
214 Float_t zFR[4] = {8.0, 14.0, 6.0, 1.0} ;
215 Float_t wFR[4] = {292.0, 68.0, 462.0, 736.0} ;
218 AliMixture(9, "FR4$", aFR, zFR, dFR, -4, wFR) ;
220 // --- The Composite Material for micromegas (so far polyetylene) ---
221 Float_t aCM[2] = {12.01, 1.} ;
222 Float_t zCM[2] = {6., 1.} ;
223 Float_t wCM[2] = {1., 2.} ;
224 Float_t dCM = 0.935 ;
226 AliMixture(10, "Compo Mat$", aCM, zCM, dCM, -2, wCM) ;
229 AliMaterial(11, "Cu$", 63.546, 29, 8.96, 1.43, 14.8, 0, 0) ;
231 // --- G10 : Printed Circuit material ---
232 Float_t aG10[4] = { 12., 1., 16., 28.} ;
233 Float_t zG10[4] = { 6., 1., 8., 14.} ;
234 Float_t wG10[4] = { .259, .288, .248, .205} ;
237 AliMixture(12, "G10$", aG10, zG10, dG10, -4, wG10);
240 AliMaterial(13, "Pb$", 207.2, 82, 11.35, 0.56, 0., 0, 0) ;
242 // --- The gas mixture ---
244 Float_t aCO[2] = {12.0, 16.0} ;
245 Float_t zCO[2] = {6.0, 8.0} ;
246 Float_t wCO[2] = {1.0, 2.0} ;
247 Float_t dCO = 0.001977 ;
249 AliMixture(14, "CO2$", aCO, zCO, dCO, -2, wCO);
252 Float_t dAr = 0.001782 ;
253 AliMaterial(15, "Ar$", 39.948, 18.0, dAr, 14.0, 0., 0, 0) ;
255 // Ar+CO2 Mixture (80% / 20%)
256 Float_t arContent = 0.80 ; // Ar-content of the ArCO2-mixture
257 Float_t aArCO[3] = {39.948, 12.0, 16.0} ;
258 Float_t zArCO[3] = {18.0 , 6.0, 8.0} ;
260 wArCO[0] = arContent;
261 wArCO[1] = (1-arContent)*1;
262 wArCO[2] = (1-arContent)*2;
263 Float_t dArCO = arContent*dAr + (1-arContent)*dCO ;
264 AliMixture(16, "ArCO2$", aArCO, zArCO, dArCO, -3, wArCO) ;
266 // --- Stainless steel (let it be pure iron) ---
267 AliMaterial(17, "Steel$", 55.845, 26, 7.87, 1.76, 0., 0, 0) ;
270 // --- Fiberglass ---
271 Float_t aFG[4] = {16.0, 28.09, 12.011, 1.00794} ;
272 Float_t zFG[4] = {8.0, 14.0, 6.0, 1.0} ;
273 Float_t wFG[4] = {292.0, 68.0, 462.0, 736.0} ;
276 AliMixture(18, "Fibergla$", aFG, zFG, dFG, -4, wFG) ;
278 // --- Cables in Air box ---
281 Float_t aCA[4] = { 1.,12.,55.8,63.5 };
282 Float_t zCA[4] = { 1.,6.,26.,29. };
283 Float_t wCA[4] = { .014,.086,.42,.48 };
284 Float_t dCA = 0.8 ; //this density is raw estimation, if you know better - correct
286 AliMixture(19, "Cables $", aCA, zCA, dCA, -4, wCA) ;
290 Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
291 Float_t zAir[4]={6.,7.,8.,18.};
292 Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
293 Float_t dAir = 1.20479E-3;
295 AliMixture(99, "Air$", aAir, zAir, dAir, 4, wAir) ;
297 // DEFINITION OF THE TRACKING MEDIA
299 // for PHOS: idtmed[699->798] equivalent to fIdtmed[0->100]
300 Int_t * idtmed = fIdtmed->GetArray() - 699 ;
301 Int_t isxfld = gAlice->Field()->Integ() ;
302 Float_t sxmgmx = gAlice->Field()->Max() ;
304 // The scintillator of the calorimeter made of PBW04 -> idtmed[699]
305 AliMedium(0, "PHOS Xtal $", 0, 1,
306 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
308 // The scintillator of the CPV made of Polystyrene scintillator -> idtmed[700]
309 AliMedium(1, "CPV scint. $", 1, 1,
310 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
312 // Various Aluminium parts made of Al -> idtmed[701]
313 AliMedium(2, "Al parts $", 2, 0,
314 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
316 // The Tywek which wraps the calorimeter crystals -> idtmed[702]
317 AliMedium(3, "Tyvek wrapper$", 3, 0,
318 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
320 // The Polystyrene foam around the calorimeter module -> idtmed[703]
321 AliMedium(4, "Polyst. foam $", 4, 0,
322 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
324 // The Titanium around the calorimeter crystal -> idtmed[704]
325 AliMedium(5, "Titan. cover $", 5, 0,
326 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.0001, 0.0001, 0, 0) ;
328 // The Silicon of the pin diode to read out the calorimeter crystal -> idtmed[705]
329 AliMedium(6, "Si PIN $", 6, 0,
330 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.01, 0.01, 0, 0) ;
332 // The thermo insulating material of the box which contains the calorimeter module -> idtmed[706]
333 AliMedium(7, "Thermo Insul.$", 7, 0,
334 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
336 // The Textolit which makes up the box which contains the calorimeter module -> idtmed[707]
337 AliMedium(8, "Textolit $", 8, 0,
338 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
340 // FR4: The Plastic which makes up the frame of micromegas -> idtmed[708]
341 AliMedium(9, "FR4 $", 9, 0,
342 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
345 // The Composite Material for micromegas -> idtmed[709]
346 AliMedium(10, "CompoMat $", 10, 0,
347 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
349 // Copper -> idtmed[710]
350 AliMedium(11, "Copper $", 11, 0,
351 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
353 // G10: Printed Circuit material -> idtmed[711]
355 AliMedium(12, "G10 $", 12, 0,
356 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
358 // The Lead -> idtmed[712]
360 AliMedium(13, "Lead $", 13, 0,
361 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
363 // The gas mixture: ArCo2 -> idtmed[715]
365 AliMedium(16, "ArCo2 $", 16, 1,
366 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
368 // Stainless steel -> idtmed[716]
369 AliMedium(17, "Steel $", 17, 0,
370 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
372 // Fibergalss -> idtmed[717]
373 AliMedium(18, "Fiberglass$", 18, 0,
374 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
376 // Cables in air -> idtmed[718]
377 AliMedium(19, "Cables $", 19, 0,
378 isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
380 // Air -> idtmed[798]
381 AliMedium(99, "Air $", 99, 0,
382 isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0, 0, 0) ;
384 // --- Set decent energy thresholds for gamma and electron tracking
386 // Tracking threshold for photons and electrons in the scintillator crystal
387 gMC->Gstpar(idtmed[699], "CUTGAM",0.5E-4) ;
388 gMC->Gstpar(idtmed[699], "CUTELE",1.0E-4) ;
390 // --- Generate explicitly delta rays in the titan cover ---
391 gMC->Gstpar(idtmed[704], "LOSS",3.) ;
392 gMC->Gstpar(idtmed[704], "DRAY",1.) ;
393 // --- and in aluminium parts ---
394 gMC->Gstpar(idtmed[701], "LOSS",3.) ;
395 gMC->Gstpar(idtmed[701], "DRAY",1.) ;
396 // --- and in PIN diode
397 gMC->Gstpar(idtmed[705], "LOSS",3) ;
398 gMC->Gstpar(idtmed[705], "DRAY",1) ;
399 // --- and in the passive convertor
400 gMC->Gstpar(idtmed[712], "LOSS",3) ;
401 gMC->Gstpar(idtmed[712], "DRAY",1) ;
402 // Tracking threshold for photons and electrons in the gas ArC02
403 gMC->Gstpar(idtmed[715], "CUTGAM",1.E-5) ;
404 gMC->Gstpar(idtmed[715], "CUTELE",1.E-5) ;
405 gMC->Gstpar(idtmed[715], "CUTNEU",1.E-5) ;
406 gMC->Gstpar(idtmed[715], "CUTHAD",1.E-5) ;
407 gMC->Gstpar(idtmed[715], "CUTMUO",1.E-5) ;
408 gMC->Gstpar(idtmed[715], "BCUTE",1.E-5) ;
409 gMC->Gstpar(idtmed[715], "BCUTM",1.E-5) ;
410 gMC->Gstpar(idtmed[715], "DCUTE",1.E-5) ;
411 gMC->Gstpar(idtmed[715], "DCUTM",1.E-5) ;
412 gMC->Gstpar(idtmed[715], "PPCUTM",1.E-5) ;
413 gMC->Gstpar(idtmed[715], "LOSS",2.) ;
414 gMC->Gstpar(idtmed[715], "DRAY",0.) ;
415 gMC->Gstpar(idtmed[715], "STRA",2.) ;
419 //____________________________________________________________________________
420 void AliPHOS::Digits2Raw()
422 // convert digits of the current event to raw data
424 AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ;
427 loader->LoadDigits();
428 TClonesArray* digits = loader->Digits() ;
431 AliError(Form("No digits found !"));
436 AliPHOSGeometry* geom = GetGeometry();
438 AliError(Form("No geometry found !"));
442 // some digitization constants
443 // const Int_t kThreshold = 1; // skip digits below this threshold // YVK
444 const Float_t kThreshold = 0.001; // skip digits below 1 MeV
445 const Int_t kAdcThreshold = 1; // Lower ADC threshold to write to raw data
447 AliAltroBuffer* buffer = NULL;
449 Int_t adcValuesLow[fkTimeBins];
450 Int_t adcValuesHigh[fkTimeBins];
460 // loop over digits (assume ordered digits)
461 for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) {
462 AliPHOSDigit* digit = dynamic_cast<AliPHOSDigit *>(digits->At(iDigit)) ;
463 if (digit->GetEnergy() < kThreshold)
466 geom->AbsToRelNumbering(digit->GetId(), relId);
467 Int_t module = relId[0];
471 continue; // ignore digits from CPV
474 Int_t row = relId[2]-1;
475 Int_t col = relId[3]-1;
480 if(0<=row&&row<32 && 0<=col&&col<28) iRCU=0;
483 if(0<=row&&row<32 && 28<=col&&col<56) iRCU=1;
486 if(32<=row&&row<64 && 0<=col&&col<28) iRCU=2;
489 if(32<=row&&row<64 && 28<=col&&col<56) iRCU=3;
492 // PHOS EMCA has 4 DDL per module. Splitting is based on the (row,column) numbers.
493 // PHOS internal convention: 1<module<5.
494 Int_t iDDL = 4 * (module - 1) + iRCU;
497 if (iDDL != prevDDL) {
498 // write real header and close previous file
501 buffer->WriteDataHeader(kFALSE, kFALSE);
505 // open new file and write dummy header
506 TString fileName = AliDAQ::DdlFileName("PHOS",iDDL);
508 TString path = gSystem->Getenv("ALICE_ROOT");
509 path += "/PHOS/mapping/RCU";
513 AliAltroMapping* mapping = new AliPHOSAltroMapping(path.Data());
514 buffer = new AliAltroBuffer(fileName.Data(),mapping);
515 buffer->WriteDataHeader(kTRUE, kFALSE); //Dummy;
520 // out of time range signal (?)
521 if (digit->GetTimeR() > GetRawFormatTimeMax() ) {
522 AliInfo("Signal is out of time range.\n");
523 buffer->FillBuffer((Int_t)digit->GetEnergy());
524 buffer->FillBuffer(GetRawFormatTimeBins() ); // time bin
525 buffer->FillBuffer(3); // bunch length
526 buffer->WriteTrailer(3, relId[3], relId[2], module); // trailer
528 // calculate the time response function
530 Double_t energy = 0 ;
531 Int_t module = relId[0];
532 if ( digit->GetId() <= geom->GetNModules() * geom->GetNCristalsInModule()) {
533 energy=digit->GetEnergy();
534 AliDebug(2,Form("digit energy: %f\n",digit->GetEnergy()));
535 if(energy>eMax) {eMax=energy; modMax=module; colMax=col; rowMax=row;}
538 // energy = digit->GetAmp()*digitizer->GetCPVchannel()+digitizer->GetCPVpedestal();
539 energy = 0; // CPV raw data format is now know yet
541 Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), energy, adcValuesHigh, adcValuesLow) ;
544 buffer->WriteChannel(relId[3]-1, relId[2]-1, 0,
545 GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold);
547 buffer->WriteChannel(relId[3]-1, relId[2]-1, 1,
548 GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold);
553 // write real header and close last file
556 buffer->WriteDataHeader(kFALSE, kFALSE);
560 AliDebug(1,Form("Digit with max. energy: modMax %d colMax %d rowMax %d eMax %f\n",
561 modMax,colMax,rowMax,eMax));
563 loader->UnloadDigits();
566 //____________________________________________________________________________
567 void AliPHOS::Hits2SDigits()
569 // create summable digits
571 AliPHOSSDigitizer phosDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
572 phosDigitizer.SetEventRange(0, -1) ; // do all the events
573 phosDigitizer.ExecuteTask("all") ;
576 //____________________________________________________________________________
577 AliLoader* AliPHOS::MakeLoader(const char* topfoldername)
579 //different behaviour than standard (singleton getter)
580 // --> to be discussed and made eventually coherent
581 fLoader = new AliPHOSLoader(GetName(),topfoldername);
585 //__________________________________________________________________
586 Double_t AliPHOS::RawResponseFunction(Double_t *x, Double_t *par)
588 // Shape of the electronics raw reponse:
589 // It is a semi-gaussian, 2nd order Gamma function of the general form
590 // v(t) = n**n * Q * A**n / C *(t/tp)**n * exp(-n * t/tp) with
591 // tp : peaking time par[0]
592 // n : order of the function
593 // C : integrating capacitor in the preamplifier
594 // A : open loop gain of the preamplifier
595 // Q : the total APD charge to be measured Q = C * energy
598 Double_t xx = x[0] - ( fgTimeTrigger + par[3] ) ;
600 if (xx < 0 || xx > fgTimeMax)
603 Double_t fac = par[0] * TMath::Power(fgOrder, fgOrder) * TMath::Power(par[1], fgOrder) / fgCapa ;
604 signal = fac * par[2] * TMath::Power(xx / fgTimePeak, fgOrder) * TMath::Exp(-fgOrder * (xx / fgTimePeak)) ;
609 //__________________________________________________________________
610 Double_t AliPHOS::RawResponseFunctionMax(Double_t charge, Double_t gain)
612 return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder)
613 / ( fgCapa * TMath::Exp(fgOrder) ) );
617 //__________________________________________________________________
618 Bool_t AliPHOS::RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const
620 // for a start time dtime and an amplitude damp given by digit,
621 // calculates the raw sampled response AliPHOS::RawResponseFunction
622 // Input: dtime - signal start time
623 // damp - signal amplitude (energy)
624 // Output: adcH - array[fkTimeBins] of 10-bit samples for high-gain channel
625 // adcL - array[fkTimeBins] of 10-bit samples for low-gain channel
627 const Int_t kRawSignalOverflow = 0x3FF ;
628 Bool_t lowGain = kFALSE ;
630 TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4);
632 for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) {
633 signalF.SetParameter(0, GetRawFormatHighCharge() ) ;
634 signalF.SetParameter(1, GetRawFormatHighGain() ) ;
635 signalF.SetParameter(2, damp) ;
636 signalF.SetParameter(3, dtime) ;
637 Double_t time = iTime * GetRawFormatTimeMax() / GetRawFormatTimeBins() ;
638 Double_t signal = signalF.Eval(time) ;
639 if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow ){ // larger than 10 bits
640 signal = kRawSignalOverflow ;
643 adcH[iTime] = static_cast<Int_t>(signal + 0.5) ;
644 AliDebug(4,Form("iTime: %d Energy: %f HG signal: %f adcH: %d ",iTime,damp,signal,adcH[iTime]));
646 signalF.SetParameter(0, GetRawFormatLowCharge() ) ;
647 signalF.SetParameter(1, GetRawFormatLowGain() ) ;
648 signal = signalF.Eval(time) ;
649 if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow) // larger than 10 bits
650 signal = kRawSignalOverflow ;
651 adcL[iTime] = static_cast<Int_t>(0.5 + signal ) ;
652 AliDebug(4,Form("..LG: %f adcL: %d\n",signal,adcL[iTime]));
658 //____________________________________________________________________________
659 void AliPHOS::SetTreeAddress()
661 // Links Hits in the Tree to Hits array
664 sprintf(branchname,"%s",GetName());
665 // Branch address for hit tree
666 TTree *treeH = TreeH();
668 branch = treeH->GetBranch(branchname);
671 if (fHits == 0x0) fHits= new TClonesArray("AliPHOSHit",1000);
672 //AliInfo(Form("<%s> Setting Hits Address",GetName()));
673 branch->SetAddress(&fHits);