]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOS.cxx
removing duplicated code (Christian)
[u/mrichter/AliRoot.git] / PHOS / AliPHOS.cxx
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 /* $Id$ */
16 /* History of cvs commits:
17  *
18  * $Log$
19  * Revision 1.100  2006/08/11 12:36:26  cvetan
20  * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
21  *
22  * Revision 1.99  2006/06/28 11:36:09  cvetan
23  * 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.
24  *
25  * Revision 1.98  2006/05/11 11:30:48  cvetan
26  * 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
27  *
28  * Revision 1.97  2006/04/22 10:30:17  hristov
29  * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
30  *
31  * Revision 1.96  2006/04/07 08:41:59  hristov
32  * Follow AliAlignObj framework and remove AliPHOSAlignData (Yu.Kharlov)
33  *
34  * Revision 1.95  2006/03/14 19:40:41  kharlov
35  * Remove De-digitizing of raw data and digitizing the raw data fit
36  *
37  * Revision 1.94  2006/03/07 18:56:25  kharlov
38  * CDB is passed via environment variable
39  *
40  * Revision 1.93  2005/11/22 08:45:11  kharlov
41  * Calibration is read from CDB if any (Boris Polichtchouk)
42  *
43  * Revision 1.92  2005/11/03 13:09:19  hristov
44  * Removing meaningless const declarations (linuxicc)
45  *
46  * Revision 1.91  2005/07/27 15:08:53  kharlov
47  * Mixture ArCO2 is corrected
48  *
49  * Revision 1.90  2005/06/17 07:39:07  hristov
50  * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
51  *
52  * Revision 1.89  2005/05/28 12:10:07  schutz
53  * Copy constructor is corrected (by T.P.)
54  *
55  */
56
57 //_________________________________________________________________________
58 // Base Class for PHOS description:
59 //   PHOS consists of a PbWO4 calorimeter (EMCA) and a gazeous charged 
60 //    particles detector (CPV or PPSD).
61 //   The only provided method here is CreateMaterials, 
62 //    which defines the materials common to all PHOS versions.   
63 // 
64 //*-- Author: Laurent Aphecetche & Yves Schutz (SUBATECH) 
65 //////////////////////////////////////////////////////////////////////////////
66
67
68 // --- ROOT system ---
69 class TFile;
70 #include <TFolder.h> 
71 #include <TTree.h>
72 #include <TVirtualMC.h> 
73 #include <TH1F.h> 
74 #include <TF1.h> 
75 #include <TRandom.h> 
76
77 // --- Standard library ---
78
79 // --- AliRoot header files ---
80 #include "AliMagF.h"
81 #include "AliPHOS.h"
82 #include "AliPHOSGetter.h"
83 #include "AliRun.h"
84 #include "AliPHOSDigitizer.h"
85 #include "AliPHOSSDigitizer.h"
86 #include "AliPHOSDigit.h"
87 #include "AliAltroBuffer.h"
88 #include "AliAltroMapping.h"
89 #include "AliPHOSAltroMapping.h"
90 #include "AliLog.h"
91 #include "AliCDBManager.h"
92 #include "AliCDBEntry.h"
93 #include "AliCDBStorage.h"
94 #include "AliPHOSCalibData.h"
95 #include "AliDAQ.h"
96
97 ClassImp(AliPHOS)
98
99 Double_t AliPHOS::fgCapa        = 1.;        // 1pF 
100 Int_t    AliPHOS::fgOrder       = 2 ;
101 Double_t AliPHOS::fgTimeMax     = 2.56E-5 ;  // each sample is over 100 ns fTimeMax/fTimeBins
102 Double_t AliPHOS::fgTimePeak    = 4.1E-6 ;   // 4 micro seconds
103 Double_t AliPHOS::fgTimeTrigger = 100E-9 ;      // 100ns, just for a reference
104
105 Double_t AliPHOS::fgHighCharge  = 8.2;       // adjusted for a high gain range of 5.12 GeV (10 bits)
106 Double_t AliPHOS::fgHighGain    = 6.64;
107 Double_t AliPHOS::fgHighLowGainFactor = 16.; // adjusted for a low gain range of 82 GeV (10 bits) 
108
109 //____________________________________________________________________________
110   AliPHOS:: AliPHOS() : AliDetector()
111 {
112   // Default ctor
113   fName   = "PHOS" ;
114
115 }
116
117 //____________________________________________________________________________
118 AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title)
119 {
120   //   ctor : title is used to identify the layout
121 }
122
123 //____________________________________________________________________________
124 AliPHOS::~AliPHOS() 
125 {  
126 }
127
128 //____________________________________________________________________________
129 void AliPHOS::Copy(TObject &obj)const
130 {
131   // copy method to be used by the cpy ctor
132   TObject::Copy(obj);
133 }
134
135 //____________________________________________________________________________
136 AliDigitizer* AliPHOS::CreateDigitizer(AliRunDigitizer* manager) const
137 {
138   return new AliPHOSDigitizer(manager);
139 }
140
141 //____________________________________________________________________________
142 void AliPHOS::CreateMaterials()
143 {
144   // Definitions of materials to build PHOS and associated tracking media.
145   // media number in idtmed are 699 to 798.
146
147   // --- The PbWO4 crystals ---
148   Float_t aX[3] = {207.19, 183.85, 16.0} ;
149   Float_t zX[3] = {82.0, 74.0, 8.0} ;
150   Float_t wX[3] = {1.0, 1.0, 4.0} ;
151   Float_t dX = 8.28 ;
152
153   AliMixture(0, "PbWO4$", aX, zX, dX, -3, wX) ;
154
155
156   // --- The polysterene scintillator (CH) ---
157   Float_t aP[2] = {12.011, 1.00794} ;
158   Float_t zP[2] = {6.0, 1.0} ;
159   Float_t wP[2] = {1.0, 1.0} ;
160   Float_t dP = 1.032 ;
161
162   AliMixture(1, "Polystyrene$", aP, zP, dP, -2, wP) ;
163
164   // --- Aluminium ---
165   AliMaterial(2, "Al$", 26.98, 13., 2.7, 8.9, 999., 0, 0) ;
166   // ---         Absorption length is ignored ^
167
168  // --- Tyvek (CnH2n) ---
169   Float_t aT[2] = {12.011, 1.00794} ;
170   Float_t zT[2] = {6.0, 1.0} ;
171   Float_t wT[2] = {1.0, 2.0} ;
172   Float_t dT = 0.331 ;
173
174   AliMixture(3, "Tyvek$", aT, zT, dT, -2, wT) ;
175
176   // --- Polystyrene foam ---
177   Float_t aF[2] = {12.011, 1.00794} ;
178   Float_t zF[2] = {6.0, 1.0} ;
179   Float_t wF[2] = {1.0, 1.0} ;
180   Float_t dF = 0.12 ;
181
182   AliMixture(4, "Foam$", aF, zF, dF, -2, wF) ;
183
184  // --- Titanium ---
185   Float_t aTIT[3] = {47.88, 26.98, 54.94} ;
186   Float_t zTIT[3] = {22.0, 13.0, 25.0} ;
187   Float_t wTIT[3] = {69.0, 6.0, 1.0} ;
188   Float_t dTIT = 4.5 ;
189
190   AliMixture(5, "Titanium$", aTIT, zTIT, dTIT, -3, wTIT);
191
192  // --- Silicon ---
193   AliMaterial(6, "Si$", 28.0855, 14., 2.33, 9.36, 42.3, 0, 0) ;
194
195
196
197   // --- Foam thermo insulation ---
198   Float_t aTI[2] = {12.011, 1.00794} ;
199   Float_t zTI[2] = {6.0, 1.0} ;
200   Float_t wTI[2] = {1.0, 1.0} ;
201   Float_t dTI = 0.04 ;
202
203   AliMixture(7, "Thermo Insul.$", aTI, zTI, dTI, -2, wTI) ;
204
205   // --- Textolith ---
206   Float_t aTX[4] = {16.0, 28.09, 12.011, 1.00794} ;
207   Float_t zTX[4] = {8.0, 14.0, 6.0, 1.0} ;
208   Float_t wTX[4] = {292.0, 68.0, 462.0, 736.0} ;
209   Float_t dTX    = 1.75 ;
210
211   AliMixture(8, "Textolit$", aTX, zTX, dTX, -4, wTX) ;
212
213   //--- FR4  ---
214   Float_t aFR[4] = {16.0, 28.09, 12.011, 1.00794} ;
215   Float_t zFR[4] = {8.0, 14.0, 6.0, 1.0} ;
216   Float_t wFR[4] = {292.0, 68.0, 462.0, 736.0} ;
217   Float_t dFR = 1.8 ; 
218
219   AliMixture(9, "FR4$", aFR, zFR, dFR, -4, wFR) ;
220
221   // --- The Composite Material for  micromegas (so far polyetylene) ---                                       
222   Float_t aCM[2] = {12.01, 1.} ; 
223   Float_t zCM[2] = {6., 1.} ; 
224   Float_t wCM[2] = {1., 2.} ; 
225   Float_t dCM = 0.935 ; 
226
227   AliMixture(10, "Compo Mat$", aCM, zCM, dCM, -2, wCM) ;
228
229   // --- Copper ---                                                                    
230   AliMaterial(11, "Cu$", 63.546, 29, 8.96, 1.43, 14.8, 0, 0) ;
231  
232   // --- G10 : Printed Circuit material ---                                                  
233   Float_t aG10[4] = { 12., 1., 16., 28.} ;
234   Float_t zG10[4] = { 6., 1., 8., 14.} ;
235   Float_t wG10[4] = { .259, .288, .248, .205} ;
236   Float_t dG10  = 1.7 ;
237   
238   AliMixture(12, "G10$", aG10, zG10, dG10, -4, wG10);
239
240   // --- Lead ---                                                                     
241   AliMaterial(13, "Pb$", 207.2, 82, 11.35, 0.56, 0., 0, 0) ;
242
243  // --- The gas mixture ---                                                                
244  // Co2
245   Float_t aCO[2] = {12.0, 16.0} ; 
246   Float_t zCO[2] = {6.0, 8.0} ; 
247   Float_t wCO[2] = {1.0, 2.0} ; 
248   Float_t dCO = 0.001977 ; 
249
250   AliMixture(14, "CO2$", aCO, zCO, dCO, -2, wCO);
251
252  // Ar
253   Float_t dAr = 0.001782 ; 
254   AliMaterial(15, "Ar$", 39.948, 18.0, dAr, 14.0, 0., 0, 0) ;   
255  
256   // Ar+CO2 Mixture (80% / 20%)
257   Float_t arContent = 0.80 ;  // Ar-content of the ArCO2-mixture
258   Float_t aArCO[3]  = {39.948, 12.0, 16.0} ;
259   Float_t zArCO[3]  = {18.0  ,  6.0,  8.0} ;
260   Float_t wArCO[3];
261   wArCO[0] = arContent;
262   wArCO[1] = (1-arContent)*1;
263   wArCO[2] = (1-arContent)*2;
264   Float_t dArCO = arContent*dAr + (1-arContent)*dCO ;
265   AliMixture(16, "ArCO2$", aArCO, zArCO, dArCO,  -3, wArCO) ;
266
267   // --- Stainless steel (let it be pure iron) ---
268   AliMaterial(17, "Steel$", 55.845, 26, 7.87, 1.76, 0., 0, 0) ;
269
270
271   // --- Fiberglass ---
272   Float_t aFG[4] = {16.0, 28.09, 12.011, 1.00794} ;
273   Float_t zFG[4] = {8.0, 14.0, 6.0, 1.0} ;
274   Float_t wFG[4] = {292.0, 68.0, 462.0, 736.0} ;
275   Float_t dFG    = 1.9 ;
276
277   AliMixture(18, "Fibergla$", aFG, zFG, dFG, -4, wFG) ;
278
279   // --- Cables in Air box  ---
280   // SERVICES
281
282   Float_t aCA[4] = { 1.,12.,55.8,63.5 };
283   Float_t zCA[4] = { 1.,6.,26.,29. }; 
284   Float_t wCA[4] = { .014,.086,.42,.48 };
285   Float_t dCA    = 0.8 ;  //this density is raw estimation, if you know better - correct
286
287   AliMixture(19, "Cables  $", aCA, zCA, dCA, -4, wCA) ;
288
289
290   // --- Air ---
291   Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
292   Float_t zAir[4]={6.,7.,8.,18.};
293   Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
294   Float_t dAir = 1.20479E-3;
295  
296   AliMixture(99, "Air$", aAir, zAir, dAir, 4, wAir) ;
297
298   // DEFINITION OF THE TRACKING MEDIA
299
300   // for PHOS: idtmed[699->798] equivalent to fIdtmed[0->100]
301   Int_t * idtmed = fIdtmed->GetArray() - 699 ; 
302   Int_t   isxfld = gAlice->Field()->Integ() ;
303   Float_t sxmgmx = gAlice->Field()->Max() ;
304
305   // The scintillator of the calorimeter made of PBW04                              -> idtmed[699]
306   AliMedium(0, "PHOS Xtal    $", 0, 1,
307             isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
308
309   // The scintillator of the CPV made of Polystyrene scintillator                   -> idtmed[700]
310   AliMedium(1, "CPV scint.   $", 1, 1,
311             isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
312
313   // Various Aluminium parts made of Al                                             -> idtmed[701]
314   AliMedium(2, "Al parts     $", 2, 0,
315              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
316
317   // The Tywek which wraps the calorimeter crystals                                 -> idtmed[702]
318   AliMedium(3, "Tyvek wrapper$", 3, 0,
319              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.001, 0.001, 0, 0) ;
320
321   // The Polystyrene foam around the calorimeter module                             -> idtmed[703]
322   AliMedium(4, "Polyst. foam $", 4, 0,
323              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
324
325   // The Titanium around the calorimeter crystal                                    -> idtmed[704]
326   AliMedium(5, "Titan. cover $", 5, 0,
327              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.0001, 0.0001, 0, 0) ;
328
329   // The Silicon of the pin diode to read out the calorimeter crystal               -> idtmed[705] 
330  AliMedium(6, "Si PIN       $", 6, 0,
331              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.01, 0.01, 0, 0) ;
332
333  // The thermo insulating material of the box which contains the calorimeter module -> idtmed[706]
334   AliMedium(7, "Thermo Insul.$", 7, 0,
335              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
336
337   // The Textolit which makes up the box which contains the calorimeter module      -> idtmed[707]
338   AliMedium(8, "Textolit     $", 8, 0,
339              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
340
341   // FR4: The Plastic which makes up the frame of micromegas                        -> idtmed[708]
342   AliMedium(9, "FR4 $", 9, 0,
343              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ; 
344
345
346   // The Composite Material for  micromegas                                         -> idtmed[709]
347   AliMedium(10, "CompoMat   $", 10, 0,
348              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
349
350   // Copper                                                                         -> idtmed[710]
351   AliMedium(11, "Copper     $", 11, 0,
352              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
353
354   // G10: Printed Circuit material                                                  -> idtmed[711]
355  
356   AliMedium(12, "G10        $", 12, 0,
357              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
358
359   // The Lead                                                                       -> idtmed[712]
360  
361   AliMedium(13, "Lead      $", 13, 0,
362              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
363
364   // The gas mixture: ArCo2                                                         -> idtmed[715]
365  
366   AliMedium(16, "ArCo2      $", 16, 1,
367              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
368  
369   // Stainless steel                                                                -> idtmed[716]
370   AliMedium(17, "Steel     $", 17, 0,
371              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.0001, 0, 0) ;
372
373   // Fibergalss                                                                     -> idtmed[717]
374   AliMedium(18, "Fiberglass$", 18, 0,
375              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
376
377   // Cables in air                                                                  -> idtmed[718]
378   AliMedium(19, "Cables    $", 19, 0,
379              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
380
381   // Air                                                                            -> idtmed[798] 
382   AliMedium(99, "Air          $", 99, 0,
383              isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0, 0, 0) ;
384
385   // --- Set decent energy thresholds for gamma and electron tracking
386
387   // Tracking threshold for photons and electrons in the scintillator crystal 
388   gMC->Gstpar(idtmed[699], "CUTGAM",0.5E-4) ; 
389   gMC->Gstpar(idtmed[699], "CUTELE",1.0E-4) ;
390  
391   // --- Generate explicitly delta rays in the titan cover ---
392   gMC->Gstpar(idtmed[704], "LOSS",3.) ;
393   gMC->Gstpar(idtmed[704], "DRAY",1.) ;
394   // --- and in aluminium parts ---
395   gMC->Gstpar(idtmed[701], "LOSS",3.) ;
396   gMC->Gstpar(idtmed[701], "DRAY",1.) ;
397   // --- and in PIN diode
398   gMC->Gstpar(idtmed[705], "LOSS",3) ;
399   gMC->Gstpar(idtmed[705], "DRAY",1) ;
400   // --- and in the passive convertor
401   gMC->Gstpar(idtmed[712], "LOSS",3) ;
402   gMC->Gstpar(idtmed[712], "DRAY",1) ;
403   // Tracking threshold for photons and electrons in the gas ArC02 
404   gMC->Gstpar(idtmed[715], "CUTGAM",1.E-5) ; 
405   gMC->Gstpar(idtmed[715], "CUTELE",1.E-5) ;
406   gMC->Gstpar(idtmed[715], "CUTNEU",1.E-5) ;
407   gMC->Gstpar(idtmed[715], "CUTHAD",1.E-5) ;
408   gMC->Gstpar(idtmed[715], "CUTMUO",1.E-5) ;
409   gMC->Gstpar(idtmed[715], "BCUTE",1.E-5) ;
410   gMC->Gstpar(idtmed[715], "BCUTM",1.E-5) ;
411   gMC->Gstpar(idtmed[715], "DCUTE",1.E-5) ;
412   gMC->Gstpar(idtmed[715], "DCUTM",1.E-5) ;
413   gMC->Gstpar(idtmed[715], "PPCUTM",1.E-5) ;
414   gMC->Gstpar(idtmed[715], "LOSS",2.) ;
415   gMC->Gstpar(idtmed[715], "DRAY",0.) ;
416   gMC->Gstpar(idtmed[715], "STRA",2.) ;
417
418 }
419
420 //____________________________________________________________________________
421 void AliPHOS::Digits2Raw()
422 {
423 // convert digits of the current event to raw data
424   
425   AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ; 
426
427   // get the digits
428   loader->LoadDigits();
429   TClonesArray* digits = loader->Digits() ;
430
431   if (!digits) {
432     AliError(Form("No digits found !"));
433     return;
434   }
435
436   // get the geometry
437   AliPHOSGeometry* geom = GetGeometry();
438   if (!geom) {
439     AliError(Form("No geometry found !"));
440     return;
441   }
442
443   // some digitization constants
444 //   const Int_t    kThreshold = 1; // skip digits below this threshold // YVK
445   const Float_t    kThreshold = 0.001; // skip digits below 1 MeV
446   const Int_t      kAdcThreshold = 1;  // Lower ADC threshold to write to raw data
447
448   AliAltroBuffer* buffer = NULL;
449   Int_t prevDDL = -1;
450   Int_t adcValuesLow[fkTimeBins];
451   Int_t adcValuesHigh[fkTimeBins];
452
453   // loop over digits (assume ordered digits)
454   for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) {
455     AliPHOSDigit* digit = dynamic_cast<AliPHOSDigit *>(digits->At(iDigit)) ;
456     if (digit->GetEnergy() < kThreshold) 
457       continue;
458     Int_t relId[4];
459     geom->AbsToRelNumbering(digit->GetId(), relId);
460     Int_t module = relId[0];
461  
462    // Begin FIXME 
463     if (relId[1] != 0) 
464       continue;    // ignore digits from CPV
465    // End FIXME 
466
467     Int_t row = relId[2]-1;
468     Int_t col = relId[3]-1;
469
470     Int_t iRCU = -111;
471
472     //RCU0
473     if(0<=row&&row<32 && 0<=col&&col<28) iRCU=0;
474
475     //RCU1
476     if(0<=row&&row<32 && 28<=col&&col<56) iRCU=1;
477
478     //RCU2
479     if(32<=row&&row<64 && 0<=col&&col<28) iRCU=2;
480
481     //RCU3
482     if(32<=row&&row<64 && 28<=col&&col<56) iRCU=3;
483
484
485     // PHOS EMCA has 4 DDL per module. Splitting is based on the (row,column) numbers.
486     // PHOS internal convention: 1<module<5.
487     Int_t iDDL = 4 * (module - 1) + iRCU;
488
489     // new DDL
490     if (iDDL != prevDDL) {
491       // write real header and close previous file
492       if (buffer) {
493         buffer->Flush();
494         buffer->WriteDataHeader(kFALSE, kFALSE);
495         delete buffer;
496       }
497
498       // open new file and write dummy header
499       TString fileName = AliDAQ::DdlFileName("PHOS",iDDL);
500
501       TString path = gSystem->Getenv("ALICE_ROOT");
502       path += "/PHOS/mapping/RCU";
503       path += iRCU;
504       path += ".data";
505
506       AliAltroMapping* mapping = new AliPHOSAltroMapping(path.Data());
507       buffer = new AliAltroBuffer(fileName.Data(),mapping);
508       buffer->WriteDataHeader(kTRUE, kFALSE);  //Dummy;
509
510       prevDDL = iDDL;
511     }
512
513     // out of time range signal (?)
514     if (digit->GetTimeR() > GetRawFormatTimeMax() ) {
515       printf("Signal is out of time range.\n");
516       buffer->FillBuffer((Int_t)digit->GetEnergy());
517       buffer->FillBuffer(GetRawFormatTimeBins() );  // time bin
518       buffer->FillBuffer(3);          // bunch length      
519       buffer->WriteTrailer(3, relId[3], relId[2], module);  // trailer
520       
521     // calculate the time response function
522     } else {
523       Double_t energy = 0 ;
524       Int_t   module = relId[0];
525       if ( digit->GetId() <= geom->GetNModules() *  geom->GetNCristalsInModule()) {
526         energy=digit->GetEnergy();
527       }
528       else {
529 //      energy = digit->GetAmp()*digitizer->GetCPVchannel()+digitizer->GetCPVpedestal();
530         energy = 0; // CPV raw data format is now know yet
531       }        
532       Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), energy, adcValuesHigh, adcValuesLow) ; 
533       
534       if (lowgain) 
535         buffer->WriteChannel(relId[3]-1, relId[2]-1, 0, 
536                              GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold);
537       else 
538         buffer->WriteChannel(relId[3]-1, relId[2]-1, 1, 
539                              GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold);
540       
541     }
542   }
543   
544   // write real header and close last file
545   if (buffer) {
546     buffer->Flush();
547     buffer->WriteDataHeader(kFALSE, kFALSE);
548     delete buffer;
549   }
550   
551   loader->UnloadDigits();
552 }
553
554 //____________________________________________________________________________
555 void AliPHOS::Hits2SDigits()  
556
557 // create summable digits
558
559   AliPHOSSDigitizer phosDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
560   phosDigitizer.SetEventRange(0, -1) ; // do all the events
561   phosDigitizer.ExecuteTask("all") ; 
562 }
563
564 //____________________________________________________________________________
565 AliLoader* AliPHOS::MakeLoader(const char* topfoldername)
566 {
567 //different behaviour than standard (singleton getter)
568 // --> to be discussed and made eventually coherent
569  fLoader = new AliPHOSLoader(GetName(),topfoldername);
570  return fLoader;
571 }
572
573 //__________________________________________________________________
574 Double_t AliPHOS::RawResponseFunction(Double_t *x, Double_t *par) 
575 {
576   // Shape of the electronics raw reponse:
577   // It is a semi-gaussian, 2nd order Gamma function of the general form
578   // v(t) = n**n * Q * A**n / C *(t/tp)**n * exp(-n * t/tp) with 
579   // tp : peaking time par[0]
580   // n  : order of the function
581   // C  : integrating capacitor in the preamplifier
582   // A  : open loop gain of the preamplifier
583   // Q  : the total APD charge to be measured Q = C * energy
584   
585   Double_t signal ;
586   Double_t xx = x[0] - ( fgTimeTrigger + par[3] ) ; 
587
588   if (xx < 0 || xx > fgTimeMax) 
589     signal = 0. ;  
590   else { 
591     Double_t fac = par[0] * TMath::Power(fgOrder, fgOrder) * TMath::Power(par[1], fgOrder) / fgCapa ; 
592     signal = fac * par[2] * TMath::Power(xx / fgTimePeak, fgOrder) * TMath::Exp(-fgOrder * (xx / fgTimePeak)) ; 
593   }
594   return signal ;  
595 }
596
597 //__________________________________________________________________
598 Double_t AliPHOS::RawResponseFunctionMax(Double_t charge, Double_t gain) 
599 {
600   return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder) 
601      / ( fgCapa * TMath::Exp(fgOrder) ) );  
602
603 }
604
605 //__________________________________________________________________
606 Bool_t AliPHOS::RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const 
607 {
608   // for a start time dtime and an amplitude damp given by digit, 
609   // calculates the raw sampled response AliPHOS::RawResponseFunction
610   // Input: dtime - signal start time
611   //        damp  - signal amplitude (energy)
612   // Output: adcH - array[fkTimeBins] of 10-bit samples for high-gain channel
613   //         adcL - array[fkTimeBins] of 10-bit samples for low-gain channel
614
615   const Int_t kRawSignalOverflow = 0x3FF ; 
616   Bool_t lowGain = kFALSE ; 
617
618   TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4);
619
620   for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) {
621     signalF.SetParameter(0, GetRawFormatHighCharge() ) ; 
622     signalF.SetParameter(1, GetRawFormatHighGain() ) ; 
623     signalF.SetParameter(2, damp) ; 
624     signalF.SetParameter(3, dtime) ; 
625     Double_t time = iTime * GetRawFormatTimeMax() / GetRawFormatTimeBins() ;
626     Double_t signal = signalF.Eval(time) ;     
627     if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow ){  // larger than 10 bits 
628       signal = kRawSignalOverflow ;
629       lowGain = kTRUE ; 
630     }
631     adcH[iTime] =  static_cast<Int_t>(signal + 0.5) ;
632
633     signalF.SetParameter(0, GetRawFormatLowCharge() ) ;     
634     signalF.SetParameter(1, GetRawFormatLowGain() ) ; 
635     signal = signalF.Eval(time) ;  
636     if ( static_cast<Int_t>(signal+0.5) > kRawSignalOverflow)  // larger than 10 bits 
637       signal = kRawSignalOverflow ;
638     adcL[iTime] = static_cast<Int_t>(0.5 + signal ) ; 
639
640   }
641   return lowGain ; 
642 }
643
644 //____________________________________________________________________________
645 void AliPHOS::SetTreeAddress()
646
647   // Links Hits in the Tree to Hits array
648   TBranch *branch;
649   char branchname[20];
650   sprintf(branchname,"%s",GetName());
651   // Branch address for hit tree
652     TTree *treeH = TreeH();
653   if (treeH) {
654     branch = treeH->GetBranch(branchname);
655     if (branch) 
656      { 
657        if (fHits == 0x0) fHits= new TClonesArray("AliPHOSHit",1000);
658        //AliInfo(Form("<%s> Setting Hits Address",GetName()));
659        branch->SetAddress(&fHits);
660      }
661   }
662 }
663