2ea0699fe562443d8bbead5fda1226a755d6240f
[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.104  2006/11/23 13:40:44  hristov
20  * Common class for raw data reading and ALTRO mappiing for PHOS and EMCAL (Gustavo, Cvetan)
21  *
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
24  *
25  * Revision 1.102  2006/10/27 17:14:27  kharlov
26  * Introduce AliDebug and AliLog (B.Polichtchouk)
27  *
28  * Revision 1.101  2006/10/13 06:47:29  kharlov
29  * Simulation of RAW data applies real mapping (B.Polichtchouk)
30  *
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)
33  *
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.
36  *
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
39  *
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)
42  *
43  * Revision 1.96  2006/04/07 08:41:59  hristov
44  * Follow AliAlignObj framework and remove AliPHOSAlignData (Yu.Kharlov)
45  *
46  * Revision 1.95  2006/03/14 19:40:41  kharlov
47  * Remove De-digitizing of raw data and digitizing the raw data fit
48  *
49  * Revision 1.94  2006/03/07 18:56:25  kharlov
50  * CDB is passed via environment variable
51  *
52  * Revision 1.93  2005/11/22 08:45:11  kharlov
53  * Calibration is read from CDB if any (Boris Polichtchouk)
54  *
55  * Revision 1.92  2005/11/03 13:09:19  hristov
56  * Removing meaningless const declarations (linuxicc)
57  *
58  * Revision 1.91  2005/07/27 15:08:53  kharlov
59  * Mixture ArCO2 is corrected
60  *
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
63  *
64  * Revision 1.89  2005/05/28 12:10:07  schutz
65  * Copy constructor is corrected (by T.P.)
66  *
67  */
68
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.   
75 // 
76 //*-- Author: Laurent Aphecetche & Yves Schutz (SUBATECH) 
77 //////////////////////////////////////////////////////////////////////////////
78
79
80 // --- ROOT system ---
81 class TFile;
82 #include <TFolder.h> 
83 #include <TTree.h>
84 #include <TVirtualMC.h> 
85 #include <TH1F.h> 
86 #include <TF1.h> 
87 #include <TRandom.h> 
88
89 // --- Standard library ---
90
91 // --- AliRoot header files ---
92 #include "AliMagF.h"
93 #include "AliPHOS.h"
94 #include "AliPHOSGetter.h"
95 #include "AliRun.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"
102 #include "AliLog.h"
103 #include "AliCDBManager.h"
104 #include "AliCDBEntry.h"
105 #include "AliCDBStorage.h"
106 #include "AliPHOSCalibData.h"
107 #include "AliDAQ.h"
108
109 ClassImp(AliPHOS)
110
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
116
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) 
120
121 //____________________________________________________________________________
122   AliPHOS:: AliPHOS() : AliDetector()
123 {
124   // Default ctor
125   fName   = "PHOS" ;
126
127 }
128
129 //____________________________________________________________________________
130 AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title)
131 {
132   //   ctor : title is used to identify the layout
133 }
134
135 //____________________________________________________________________________
136 AliPHOS::~AliPHOS() 
137 {  
138 }
139
140 //____________________________________________________________________________
141 AliDigitizer* AliPHOS::CreateDigitizer(AliRunDigitizer* manager) const
142 {
143   return new AliPHOSDigitizer(manager);
144 }
145
146 //____________________________________________________________________________
147 void AliPHOS::CreateMaterials()
148 {
149   // Definitions of materials to build PHOS and associated tracking media.
150   // media number in idtmed are 699 to 798.
151
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} ;
156   Float_t dX = 8.28 ;
157
158   AliMixture(0, "PbWO4$", aX, zX, dX, -3, wX) ;
159
160
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} ;
165   Float_t dP = 1.032 ;
166
167   AliMixture(1, "Polystyrene$", aP, zP, dP, -2, wP) ;
168
169   // --- Aluminium ---
170   AliMaterial(2, "Al$", 26.98, 13., 2.7, 8.9, 999., 0, 0) ;
171   // ---         Absorption length is ignored ^
172
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} ;
177   Float_t dT = 0.331 ;
178
179   AliMixture(3, "Tyvek$", aT, zT, dT, -2, wT) ;
180
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} ;
185   Float_t dF = 0.12 ;
186
187   AliMixture(4, "Foam$", aF, zF, dF, -2, wF) ;
188
189  // --- Titanium ---
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} ;
193   Float_t dTIT = 4.5 ;
194
195   AliMixture(5, "Titanium$", aTIT, zTIT, dTIT, -3, wTIT);
196
197  // --- Silicon ---
198   AliMaterial(6, "Si$", 28.0855, 14., 2.33, 9.36, 42.3, 0, 0) ;
199
200
201
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} ;
206   Float_t dTI = 0.04 ;
207
208   AliMixture(7, "Thermo Insul.$", aTI, zTI, dTI, -2, wTI) ;
209
210   // --- Textolith ---
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} ;
214   Float_t dTX    = 1.75 ;
215
216   AliMixture(8, "Textolit$", aTX, zTX, dTX, -4, wTX) ;
217
218   //--- FR4  ---
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} ;
222   Float_t dFR = 1.8 ; 
223
224   AliMixture(9, "FR4$", aFR, zFR, dFR, -4, wFR) ;
225
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 ; 
231
232   AliMixture(10, "Compo Mat$", aCM, zCM, dCM, -2, wCM) ;
233
234   // --- Copper ---                                                                    
235   AliMaterial(11, "Cu$", 63.546, 29, 8.96, 1.43, 14.8, 0, 0) ;
236  
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} ;
241   Float_t dG10  = 1.7 ;
242   
243   AliMixture(12, "G10$", aG10, zG10, dG10, -4, wG10);
244
245   // --- Lead ---                                                                     
246   AliMaterial(13, "Pb$", 207.2, 82, 11.35, 0.56, 0., 0, 0) ;
247
248  // --- The gas mixture ---                                                                
249  // Co2
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 ; 
254
255   AliMixture(14, "CO2$", aCO, zCO, dCO, -2, wCO);
256
257  // Ar
258   Float_t dAr = 0.001782 ; 
259   AliMaterial(15, "Ar$", 39.948, 18.0, dAr, 14.0, 0., 0, 0) ;   
260  
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} ;
265   Float_t wArCO[3];
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) ;
271
272   // --- Stainless steel (let it be pure iron) ---
273   AliMaterial(17, "Steel$", 55.845, 26, 7.87, 1.76, 0., 0, 0) ;
274
275
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} ;
280   Float_t dFG    = 1.9 ;
281
282   AliMixture(18, "Fibergla$", aFG, zFG, dFG, -4, wFG) ;
283
284   // --- Cables in Air box  ---
285   // SERVICES
286
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
291
292   AliMixture(19, "Cables  $", aCA, zCA, dCA, -4, wCA) ;
293
294
295   // --- Air ---
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;
300  
301   AliMixture(99, "Air$", aAir, zAir, dAir, 4, wAir) ;
302
303   // DEFINITION OF THE TRACKING MEDIA
304
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() ;
309
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) ;
313
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) ;
317
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) ;
321
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) ;
325
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) ;
329
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) ;
333
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) ;
337
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) ;
341
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) ;
345
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) ; 
349
350
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) ;
354
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) ;
358
359   // G10: Printed Circuit material                                                  -> idtmed[711]
360  
361   AliMedium(12, "G10        $", 12, 0,
362              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
363
364   // The Lead                                                                       -> idtmed[712]
365  
366   AliMedium(13, "Lead      $", 13, 0,
367              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.1, 0, 0) ;
368
369   // The gas mixture: ArCo2                                                         -> idtmed[715]
370  
371   AliMedium(16, "ArCo2      $", 16, 1,
372              isxfld, sxmgmx, 10.0, 0.1, 0.1, 0.1, 0.01, 0, 0) ;
373  
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) ;
377
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) ;
381
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) ;
385
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) ;
389
390   // --- Set decent energy thresholds for gamma and electron tracking
391
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) ;
395  
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.) ;
422
423 }
424
425 //____________________________________________________________________________
426 void AliPHOS::Digits2Raw()
427 {
428 // convert digits of the current event to raw data
429   
430   AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ; 
431
432   // get the digits
433   loader->LoadDigits();
434   TClonesArray* digits = loader->Digits() ;
435
436   if (!digits) {
437     AliError(Form("No digits found !"));
438     return;
439   }
440
441   // get the geometry
442   AliPHOSGeometry* geom = GetGeometry();
443   if (!geom) {
444     AliError(Form("No geometry found !"));
445     return;
446   }
447
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
452
453   AliAltroBuffer* buffer = NULL;
454   Int_t prevDDL = -1;
455   Int_t adcValuesLow[fkTimeBins];
456   Int_t adcValuesHigh[fkTimeBins];
457
458
459   //!!!!for debug!!!
460   Int_t modMax=-111;
461   Int_t colMax=-111;
462   Int_t rowMax=-111;
463   Float_t eMax=-333;
464   //!!!for debug!!!
465
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) 
470       continue;
471     Int_t relId[4];
472     geom->AbsToRelNumbering(digit->GetId(), relId);
473     Int_t module = relId[0];
474  
475    // Begin FIXME 
476     if (relId[1] != 0) 
477       continue;    // ignore digits from CPV
478    // End FIXME 
479
480     Int_t row = relId[2]-1;
481     Int_t col = relId[3]-1;
482
483     Int_t iRCU = -111;
484
485     //RCU0
486     if(0<=row&&row<32 && 0<=col&&col<28) iRCU=0;
487
488     //RCU1
489     if(0<=row&&row<32 && 28<=col&&col<56) iRCU=1;
490
491     //RCU2
492     if(32<=row&&row<64 && 0<=col&&col<28) iRCU=2;
493
494     //RCU3
495     if(32<=row&&row<64 && 28<=col&&col<56) iRCU=3;
496
497
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;
501
502     // new DDL
503     if (iDDL != prevDDL) {
504       // write real header and close previous file
505       if (buffer) {
506         buffer->Flush();
507         buffer->WriteDataHeader(kFALSE, kFALSE);
508         delete buffer;
509       }
510
511       // open new file and write dummy header
512       TString fileName = AliDAQ::DdlFileName("PHOS",iDDL);
513
514       TString path = gSystem->Getenv("ALICE_ROOT");
515       path += "/PHOS/mapping/RCU";
516       path += iRCU;
517       path += ".data";
518
519       AliAltroMapping* mapping = new AliCaloAltroMapping(path.Data());
520       buffer = new AliAltroBuffer(fileName.Data(),mapping);
521       buffer->WriteDataHeader(kTRUE, kFALSE);  //Dummy;
522
523       prevDDL = iDDL;
524     }
525
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
533       
534     // calculate the time response function
535     } else {
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;}
542       }
543       else {
544         energy = 0; // CPV raw data format is now know yet
545       }        
546       Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), energy, adcValuesHigh, adcValuesLow) ; 
547       
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);
552       
553     }
554   }
555   
556   // write real header and close last file
557   if (buffer) {
558     buffer->Flush();
559     buffer->WriteDataHeader(kFALSE, kFALSE);
560     delete buffer;
561   }
562   
563   AliDebug(1,Form("Digit with max. energy:  modMax %d colMax %d rowMax %d  eMax %f\n",
564          modMax,colMax,rowMax,eMax));
565
566   loader->UnloadDigits();
567 }
568
569 //____________________________________________________________________________
570 void AliPHOS::Hits2SDigits()  
571
572 // create summable digits
573
574   AliPHOSSDigitizer phosDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
575   phosDigitizer.SetEventRange(0, -1) ; // do all the events
576   phosDigitizer.ExecuteTask("all") ; 
577 }
578
579 //____________________________________________________________________________
580 AliLoader* AliPHOS::MakeLoader(const char* topfoldername)
581 {
582 //different behaviour than standard (singleton getter)
583 // --> to be discussed and made eventually coherent
584  fLoader = new AliPHOSLoader(GetName(),topfoldername);
585  return fLoader;
586 }
587
588 //__________________________________________________________________
589 Double_t AliPHOS::RawResponseFunction(Double_t *x, Double_t *par) 
590 {
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
599   
600   Double_t signal ;
601   Double_t xx = x[0] - ( fgTimeTrigger + par[3] ) ; 
602
603   if (xx < 0 || xx > fgTimeMax) 
604     signal = 0. ;  
605   else { 
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)) ; 
608   }
609   return signal ;  
610 }
611
612 //__________________________________________________________________
613 Double_t AliPHOS::RawResponseFunctionMax(Double_t charge, Double_t gain) 
614 {
615   return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder) 
616      / ( fgCapa * TMath::Exp(fgOrder) ) );  
617
618 }
619
620 //__________________________________________________________________
621 Bool_t AliPHOS::RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const 
622 {
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
629
630   const Int_t kRawSignalOverflow = 0x3FF ; 
631   Bool_t lowGain = kFALSE ; 
632
633   TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4);
634
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 ;
644       lowGain = kTRUE ; 
645     }
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]));
648
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]));
656
657   }
658   return lowGain ; 
659 }
660
661 //____________________________________________________________________________
662 void AliPHOS::SetTreeAddress()
663
664   // Links Hits in the Tree to Hits array
665   TBranch *branch;
666   char branchname[20];
667   sprintf(branchname,"%s",GetName());
668   // Branch address for hit tree
669     TTree *treeH = TreeH();
670   if (treeH) {
671     branch = treeH->GetBranch(branchname);
672     if (branch) 
673      { 
674        if (fHits == 0x0) fHits= new TClonesArray("AliPHOSHit",1000);
675        //AliInfo(Form("<%s> Setting Hits Address",GetName()));
676        branch->SetAddress(&fHits);
677      }
678   }
679 }
680