]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/icepack/iceconvert/IceCal2Root.cxx
04-oct-2007 NvE New memberfunctions GetLevel and GetOMId introduced in class IceGOM
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / IceCal2Root.cxx
1 /*******************************************************************************
2  * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
3  *
4  * Author: The IceCube RALICE-based Offline 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.
12  * The authors make no claims about the suitability of this software for
13  * any purpose. It is provided "as is" without express or implied warranty.
14  *******************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class IceCal2Root
20 // Conversion of Amanda (ascii) calibration data into a AliObjMatrix objects
21 // containing the complete OM position, calibration, Xtalk etc... database.
22 //
23 // This facility will become obsolete soon and is only kept for
24 // backward compatibility and testing purposes.
25 // Please use the more recent IceDB2Root facility instead.
26 //
27 // Via specification of the various input files, various AliObjMatrix objects
28 // are created and (optionally) stored in a single output file.
29 // The names of the AliObjMatrix objects indicate the type of database they
30 // contain.
31 // For example :
32 // The name "MuDaq-OMDBASE" indicates the database info for MuDaq data,
33 // whereas TWRDaq calibration data is in the object named "TWRDaq-OMDBASE".
34 // Note that a MuDaq Amacalib ascii input file has always to be provided,
35 // since the geometry data for all the other databases is obtained from there.   
36 // In addition a PDG particle database, extended with some specific Amanda
37 // entries, is provided as well.
38 // This class is derived from AliJob providing task-based processing.
39 // Note that the data structures are only written out if an outputfile has
40 // been specified via the SetOutputFile memberfunction.
41 // In case no outputfile has been specified, this class provides a facility
42 // to investigate/use the dbase data directly in subsequent (sub)tasks.
43 //
44 // The OM database information in the AliObjMatrix has the following structure :
45 //
46 // (j,1)    : Pointer to OM with identifier "j"
47 // (j,k+1)  : Pointer to a TF1* being the probability function for Xtalk
48 //            with OM "j" as transmitter and OM "k" as receiver.
49 //
50 // The latter is only available for MuDaq databases.
51 //
52 // The geometry information is directly available from the OM pointer
53 // in the form of its position and data words like "ORIENT" for orientation etc...
54 // Just use the OM memberfunction Data() to obtain a full overview. 
55 //
56 // Note : Position coordinates are indicated in meters and times are in nanoseconds,
57 //        in accordance with the convention used previously for Amanda.
58 //
59 // From the OM pointer also the various (de)calibration functions for
60 // ADC, LE and TOT can be obtained as TF1* pointers.
61 // The actual values of the calibration constants are stored as parameters
62 // of these (de)calibration functions and can be investigated via the
63 // usual TF1::Print() or TF1::GetParameter() facilities.
64 // The last two parameters of the Xtalk probability function have no effect
65 // on the evaluated probability value. However, these two parameters provide
66 // the minimum and maximum allowed LE differences between the transmitter
67 // and receiver hits, respectively (as can be seen from the parameter names).
68 //
69 // The (de)calibration of signals and/or determination of the Xtalk probability
70 // can be performed via the standard TF1::Eval(x) functionality, where "x"
71 // represents the input argument of the function (e.g. an uncalibrated ADC value).
72 //
73 // In general the database is not directly accessed by the user in performing
74 // physics analysis, since all the necessary information is contained in the
75 // event data itself and available via the GetSignal() memberfunction of the hits.
76 // However, specific tasks like e.g. calibration, Xtalk correction,
77 // bad module removal, noise hit removal etc... might need explicit database access.
78 // So, at the end of the example below some functionality is indicated for clarity.
79 // The user may use exactly the same procedures to obtain explicit access to the calibration
80 // functions etc... from the various OMs and/or hits within the actual event data which he/she
81 // is analysing.
82 //
83 // The PDG particle database is a standard ROOT TDatabasePDG object
84 // with the following extensions :
85 //
86 // Name        PDG code
87 // ----        --------
88 // brems       10001001
89 // deltae      10001002
90 // pairprod    10001003
91 // nucl_int    10001004
92 // mu_pair     10001005
93 // hadrons     10001006
94 // fiberlaser  10002100
95 // n2laser     10002101
96 // yaglaser    10002201
97 // z_primary   10003000
98 // a_primary   10003500
99 // 
100 // Usage example :
101 // ---------------
102 //
103 // gSystem->Load("ralice");
104 // gSystem->Load("icepack");
105 // gSystem->Load("iceconvert");
106 //
107 // IceCal2Root q("IceCal2Root","Amacalib to IcePack data structure conversion");
108 //
109 // // The MuDaq Amacalib input filename
110 // q.SetAmacalibFile("amacalib_amanda2_2005.txt");
111 //
112 // // The TWRDaq input filename with the newly determined TWR T0 and ADC calibs.
113 // q.SetTWRDaqFile("twr-cal-2005.txt");
114 //
115 // // Output file for the event structures
116 // q.SetOutputFile("cal2005.root");
117 //
118 // ///////////////////////////////////////////////////////////////////
119 // // Here the user can specify his/her sub-tasks to be executed
120 // // after the database structures have been filled and before the
121 // // data is written out.
122 // // Sub-tasks (i.e. a user classes derived from TTask) are entered
123 // // as follows :
124 // //
125 // //    MyTask1 task1("task1","Some modifications to specific OMs");
126 // //    MyTask2 task2("task2","Removal of specific OMs");
127 // //    MyTask3 task3("task3","Add private objects to the output file");
128 // //    q.Add(&task1);
129 // //    q.Add(&task2);
130 // //    q.Add(&task3);
131 // //
132 // // The sub-tasks will be executed in the order as they are entered.
133 // ///////////////////////////////////////////////////////////////////
134 //
135 // // Perform the conversion and execute subtasks (if any)
136 // q.ExecuteJob();
137 //
138 // // Outline of dbase usage for (de)calibration and Xtalk
139 //
140 // AliObjMatrix* omdb=q.GetOMdbase("MuDaq");
141 // IceAOM* om=(IceAOM*)omdb->GetObject(9,1); // Pointer to OM 9
142 // om->Data(); // Overview of generic module parameters
143 // TF1* fcal=0;   // Calibration function
144 // TF1* fdecal=0; // De-calibration function
145 // fcal=om->GetCalFunction("ADC");
146 // Float_t adc=248; // Uncalibrated ADC
147 // Float_t cadc=0;  // Calibrated ADC
148 // if (fcal) cadc=fcal->Eval(adc);
149 // fcal=om->GetCalFunction("TOT");
150 // Float_t tot=1538; // Uncalibrated TOT
151 // Float_t ctot=0;   // Calibrated TOT
152 // if (fcal) ctot=fcal->Eval(tot);
153 // fdecal=om->GetDecalFunction("LE");
154 // Float_t le=21697; // Uncalibrated LE
155 // Float_t cle=0;    // Calibrated LE
156 // if (fcal) cle=fcal->Eval(le);
157 //
158 // // Xtalk probability between (trans) OM 90 and (rec) OM 113
159 // // for a transmitter signal of uncalibrated amplitude "adc".
160 // TF1* fxtalkp=(TF1*)omdb->GetObject(90,113+1);
161 // Float_t prob=0;
162 // adc=378;
163 // if (fxtalkp) prob=fxtalkp->Eval(adc);
164 //
165 //--- Author: Nick van Eijndhoven 09-aug-2005 Utrecht University
166 //- Modified: NvE $Date$ Utrecht University
167 ///////////////////////////////////////////////////////////////////////////
168  
169 #include "IceCal2Root.h"
170 #include "Rstrstream.h"
171
172 ClassImp(IceCal2Root) // Class implementation to enable ROOT I/O
173
174 IceCal2Root::IceCal2Root(const char* name,const char* title) : AliJob(name,title)
175 {
176 // Default constructor.
177  fAmacalFileName="";
178  fTWRDaqFileName="";
179  fRootFileName="";
180  fOutfile=0;
181
182  fPdg=0;
183  fMuDaqdb=0;
184  fTWRDaqdb=0;
185 }
186 ///////////////////////////////////////////////////////////////////////////
187 IceCal2Root::~IceCal2Root()
188 {
189 // Default destructor.
190
191  if (fPdg)
192  {
193   delete fPdg;
194   fPdg=0;
195  }
196
197  if (fMuDaqdb)
198  {
199   delete fMuDaqdb;
200   fMuDaqdb=0;
201  }
202
203  if (fTWRDaqdb)
204  {
205   delete fTWRDaqdb;
206   fTWRDaqdb=0;
207  }
208 }
209 ///////////////////////////////////////////////////////////////////////////
210 void IceCal2Root::SetAmacalibFile(TString name)
211 {
212 // Set the name of the Amacalib MuDaq input file.
213  fAmacalFileName=name;
214 }
215 ///////////////////////////////////////////////////////////////////////////
216 void IceCal2Root::SetTWRDaqFile(TString name)
217 {
218 // Set the name of the TWRDaq calibration input file.
219  fTWRDaqFileName=name;
220 }
221 ///////////////////////////////////////////////////////////////////////////
222 void IceCal2Root::SetOutputFile(TString name)
223 {
224 // Set the name of the ROOT output file.
225  fRootFileName=name;
226 }
227 ///////////////////////////////////////////////////////////////////////////
228 TDatabasePDG* IceCal2Root::GetPDG()
229 {
230 // Provide pointer to the PDG database
231  return fPdg;
232 }
233 ///////////////////////////////////////////////////////////////////////////
234 AliObjMatrix* IceCal2Root::GetOMdbase(TString name)
235 {
236 // Provide pointer to the requested OM geometry, calib. etc... database.
237 // Options for the "name" specification are : MuDaq, TWRDaq.
238 // For backward compatibility the default is name="MuDaq".
239
240  if (name=="MuDaq") return fMuDaqdb;
241  if (name=="TWRDaq") return fTWRDaqdb;
242  return 0;
243 }
244 ///////////////////////////////////////////////////////////////////////////
245 void IceCal2Root::Exec(Option_t* opt)
246 {
247 // Job to convert the (ascii) database info into the IcePack structure.
248 //
249 // Notes :
250 // -------
251 // 1) This class is derived from AliJob, allowing a task based processing.
252 //    After conversion of the (ascii) dbase data into the IcePack structure,
253 //    the processing of all available sub-tasks (if any) is invoked.
254 //    This provides a facility to investigate/use the dbase data in
255 //    subsequent (sub)tasks processing before the final data structures
256 //    are written out.
257 //
258 // 2) Creation of a TFolder via the argument of the ExecuteJob statement
259 //    makes all created database objects accessible to subsequent tasks
260 //    via the TFolder::FindObject facility.
261
262  if (fOutfile)
263  {
264   delete fOutfile;
265   fOutfile=0;
266  }
267  if (fRootFileName != "")
268  {
269   fOutfile=new TFile(fRootFileName.Data(),"RECREATE","Calibration data in IcePack structure");
270  }
271
272  // Create the particle database and extend it with some F2000 specific definitions
273  if (fPdg) delete fPdg;
274  fPdg=new TDatabasePDG();
275  fPdg->SetNameTitle("PDG-DBASE","The extended PDG particle database");
276  Double_t me=fPdg->GetParticle(11)->Mass();
277  fPdg->AddParticle("brems"   ,"brems"   ,0,1,0,0,"none",10001001,0,0);
278  fPdg->AddParticle("deltae"  ,"deltae"  ,me,1,0,-3,"Lepton",10001002,0,0);
279  fPdg->AddParticle("pairprod","pairprod",0,1,0,0,"none",10001003,0,0);
280  fPdg->AddParticle("nucl_int","nucl_Int",0,1,0,0,"none",10001004,0,0);
281  fPdg->AddParticle("mu_pair" ,"mu_pair" ,0,1,0,0,"none",10001005,0,0);
282  fPdg->AddParticle("hadrons" ,"hadrons" ,0,1,0,0,"none",10001006,0,0);
283  fPdg->AddParticle("fiberlaser","fiberlaser",0,1,0,0,"none",10002100,0,0);
284  fPdg->AddParticle("n2laser"   ,"n2laser"   ,0,1,0,0,"none",10002101,0,0);
285  fPdg->AddParticle("yaglaser"  ,"yaglaser"  ,0,1,0,0,"none",10002201,0,0);
286  fPdg->AddParticle("z_primary","z_primary",0,1,0,0,"none",10003000,0,0);
287  fPdg->AddParticle("a_primary","a_primary",0,1,0,0,"none",10003500,0,0);
288
289  // Initialise the job working environment
290  AddObject(fPdg);
291  if (fOutfile) AddObject(fOutfile);
292
293  cout << " ***" << endl;
294  cout << " *** Start processing of job " << GetName() << " ***" << endl;
295  cout << " ***" << endl;
296  cout << " Amacalib MuDaq input file : " << fAmacalFileName.Data() << endl;
297  cout << " TWRDaq input file : " << fTWRDaqFileName.Data() << endl;
298  if (fOutfile) cout << " ROOT output file : " << fOutfile->GetName() << endl;
299
300  GetMuDaqData();
301  if (fMuDaqdb) AddObject(fMuDaqdb);
302
303  GetTWRDaqData();
304  if (fTWRDaqdb) AddObject(fTWRDaqdb);
305
306  ListEnvironment();
307
308  // Invoke all available sub-tasks (if any)
309  CleanTasks();
310  ExecuteTasks(opt);
311
312  // Write the datastructures to the output file
313  if (fOutfile)
314  {
315   fOutfile->cd();
316   if (fMuDaqdb) fMuDaqdb->Write();
317   if (fTWRDaqdb) fTWRDaqdb->Write();
318   if (fPdg) fPdg->Write();
319  }
320
321  // Flush remaining memory resident data to the output file
322  if (fOutfile) fOutfile->Write();
323 }
324 ///////////////////////////////////////////////////////////////////////////
325 void IceCal2Root::GetMuDaqData()
326 {
327 // Obtain all the MuDaq geometry, calibration and Xtalk data.
328
329  if (fAmacalFileName=="")
330  {
331   cout << " *IceCal2Root GetMuDaqData* No amacalib input file specified." << endl;
332   return;
333  }
334
335  fInput.clear();
336  fInput.open(fAmacalFileName.Data());
337
338  if (!fInput.good())
339  {
340   cout << " *IceCal2Root GetMuDaqData* Bad input file : " << fAmacalFileName.Data() << endl;
341   return;
342  }
343
344  // The MuDaq OM database object
345  if (fMuDaqdb)
346  {
347   fMuDaqdb->Reset();
348  }
349  else
350  {
351   fMuDaqdb=new AliObjMatrix();
352   fMuDaqdb->SetNameTitle("MuDaq-OMDBASE","The MuDaq OM geometry, calib. etc... database");
353   fMuDaqdb->SetOwner();
354  }
355
356  // Prescription of the various (de)calibration functions
357  TF1 fadccal("fadccal","(x-[1])*[0]");
358  TF1 fadcdecal("fadcdecal","(x/[0])+[1]");
359  fadccal.SetParName(0,"BETA-ADC");
360  fadccal.SetParName(1,"PED-ADC");
361  fadcdecal.SetParName(0,"BETA-ADC");
362  fadcdecal.SetParName(1,"PED-ADC");
363
364  TF1 ftdccal("ftdccal","(x*[0])-[1]-([0]-1.)*32767.-[2]/sqrt([3])");
365  TF1 ftdcdecal("ftdcdecal","(x+([0]-1.)*32767.+[1]+[2]/sqrt([3]))/[0]");
366  ftdccal.SetParName(0,"BETA-TDC");
367  ftdccal.SetParName(1,"T0");
368  ftdccal.SetParName(2,"ALPHA-TDC");
369  ftdccal.SetParName(3,"ADC-SLEW");
370  ftdcdecal.SetParName(0,"BETA-TDC");
371  ftdcdecal.SetParName(1,"T0");
372  ftdcdecal.SetParName(2,"ALPHA-TDC");
373  ftdcdecal.SetParName(3,"ADC-SLEW");
374
375  TF1 ftotcal("ftotcal","x*[0]");
376  TF1 ftotdecal("ftotdecal","x/[0]");
377  ftotcal.SetParName(0,"BETA-TOT");
378  ftotdecal.SetParName(0,"BETA-TOT");
379
380  // The cross talk probability function
381  TF1 fxtalkp("fxtalkp","(1.+[2]-[2]+[3]-[3])/(1.+exp(([0]-x)/[1]))");
382  fxtalkp.SetParName(0,"C");
383  fxtalkp.SetParName(1,"B");
384  fxtalkp.SetParName(2,"dLE-min");
385  fxtalkp.SetParName(3,"dLE-max");
386
387  // The basic OM contents
388  IceAOM om;
389
390  // Slots to hold the various (de)calibration functions
391  om.AddNamedSlot("ADC");
392  om.AddNamedSlot("LE");
393  om.AddNamedSlot("TOT");
394  // Slots with hardware parameters
395  om.AddNamedSlot("TYPE");
396  om.AddNamedSlot("ORIENT");
397 /// om.AddNamedSlot("THRESH");
398 /// om.AddNamedSlot("SENSIT");
399 /// om.AddNamedSlot("READOUT"); // 0=unknown 1=electrical 2=optical 3=digital
400
401  fInput.seekg(0); // Position at beginning of file
402  fInput >> dec;   // Make sure all integers starting with 0 are taken in decimal format
403
404  TString s;
405  Int_t jmod,type,serial,string,ix,iy,iz,ori;
406  Float_t costh=0;
407 /// Float_t thresh=0;
408 /// Float_t sensit=1;
409 /// Float_t readout=0;
410  Double_t pos[3]={0,0,0};
411  Float_t ped,beta,alpha;
412  Int_t pol;
413  Float_t totped;
414  Int_t jtrans,jrec;
415  Float_t c,b,dlemin,dlemax;
416  IceAOM* omx=0;
417  TF1* fcal=0;
418  TF1* fdecal=0;
419  while (fInput >> s)
420  {
421   if (s == "P") // Read the Geom data
422   {
423    fInput >> jmod >> type >> serial >> string >> ix >> iy >> iz >> ori;
424    omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
425    if (!omx)
426    {
427     omx=new IceAOM(om);
428     omx->SetUniqueID(jmod);
429     fMuDaqdb->EnterObject(jmod,1,omx);
430    }
431    pos[0]=double(ix)/1000.;
432    pos[1]=double(iy)/1000.;
433    pos[2]=double(iz)/1000.;
434    omx->SetPosition(pos,"car");
435    costh=1;
436    if (ori==2) costh=-1;
437    omx->SetSignal(type,"TYPE");
438    omx->SetSignal(costh,"ORIENT");
439 ///   omx->SetSignal(thresh,"THRESH");
440 ///   omx->SetSignal(sensit,"SENSIT");
441 ///   omx->SetSignal(readout,"READOUT");
442   }
443   else if (s == "T") // Read the Time calibration constants
444   {
445    fInput >> jmod >> ped >> beta >> alpha >> pol;
446    omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
447    if (!omx)
448    {
449     omx=new IceAOM(om);
450     omx->SetUniqueID(jmod);
451     fMuDaqdb->EnterObject(jmod,1,omx);
452    }
453
454    omx->SetCalFunction(&ftdccal,"LE");
455    omx->SetDecalFunction(&ftdcdecal,"LE");
456    omx->SetCalFunction(&ftotcal,"TOT");
457    omx->SetDecalFunction(&ftotdecal,"TOT");
458
459    // Flag time slots of bad OMs as dead and don't provide time (de)calib functions
460    if (ped<-1e5 || beta<=0 || alpha<0)
461    {
462     omx->SetDead("LE");
463     omx->SetDead("TOT");
464     omx->SetCalFunction(0,"LE");
465     omx->SetDecalFunction(0,"LE");
466     omx->SetCalFunction(0,"TOT");
467     omx->SetDecalFunction(0,"TOT");
468    }
469
470    fcal=omx->GetCalFunction("LE");
471    fdecal=omx->GetDecalFunction("LE");
472    if (fcal)
473    {
474     fcal->SetParameter(0,beta);
475     fcal->SetParameter(1,ped);
476     fcal->SetParameter(2,alpha);
477     fcal->SetParameter(3,1.e20);
478    }
479    if (fdecal)
480    {
481     fdecal->SetParameter(0,beta);
482     if (!beta) fdecal->SetParameter(0,1);
483     fdecal->SetParameter(1,ped);
484     fdecal->SetParameter(2,alpha);
485     fdecal->SetParameter(3,1.e20);
486    }
487
488    fcal=omx->GetCalFunction("TOT");
489    fdecal=omx->GetDecalFunction("TOT");
490    if (fcal)
491    {
492     fcal->SetParameter(0,beta);
493    }
494    if (fdecal)
495    {
496     fdecal->SetParameter(0,beta);
497    }
498   }
499   else if (s == "A") // Read the Amplitude calibration constants
500   {
501    fInput >> jmod >> ped >> beta >> totped >> pol;
502    omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
503    if (!omx)
504    {
505     omx=new IceAOM(om);
506     omx->SetUniqueID(jmod);
507     fMuDaqdb->EnterObject(jmod,1,omx);
508    }
509
510    omx->SetCalFunction(&fadccal,"ADC");
511    omx->SetDecalFunction(&fadcdecal,"ADC");
512
513    // Flag amplitude slots of bad OMs as dead and don't provide amplitude (de)calib functions
514    if (ped<-1e5 || beta<=0)
515    {
516     omx->SetDead("ADC");
517     omx->SetCalFunction(0,"ADC");
518     omx->SetDecalFunction(0,"ADC");
519    }
520    if (totped<-1e5)
521    {
522     omx->SetDead("TOT");
523     omx->SetCalFunction(0,"TOT");
524     omx->SetDecalFunction(0,"TOT");
525    }
526
527    fcal=omx->GetCalFunction("ADC");
528    fdecal=omx->GetDecalFunction("ADC");
529    if (fcal)
530    {
531     fcal->SetParameter(0,beta);
532     fcal->SetParameter(1,ped);
533    }
534    if (fdecal)
535    {
536     fdecal->SetParameter(0,beta);
537     if (!beta) fdecal->SetParameter(0,1);
538     fdecal->SetParameter(1,ped);
539    }
540   }
541   else if (s == "K") // Read the cross talk probability constants
542   {
543    fInput >> jtrans >> jrec >> c >> b >> dlemin >> dlemax;
544    omx=(IceAOM*)fMuDaqdb->GetObject(jtrans,1);
545    if (!omx)
546    {
547     omx=new IceAOM(om);
548     omx->SetUniqueID(jtrans);
549     fMuDaqdb->EnterObject(jtrans,1,omx);
550    }
551
552    TF1* fx=new TF1(fxtalkp);
553    fx->SetParameter(0,c);
554    if (b)
555    {
556     fx->SetParameter(1,b);
557    }
558    else
559    {
560     fx->SetParameter(1,1);
561    }
562    fx->SetParameter(2,dlemin);
563    fx->SetParameter(3,dlemax);
564    fMuDaqdb->EnterObject(jtrans,jrec+1,fx);
565   }
566   else // Skip this line
567   {
568    fInput.ignore(99999,'\n');
569   } 
570  }
571
572  fInput.close();
573 }
574 ///////////////////////////////////////////////////////////////////////////
575 void IceCal2Root::GetTWRDaqData()
576 {
577 // Obtain all the TWRDaq geometry and calibration data.
578
579  if (fTWRDaqFileName=="")
580  {
581   cout << " *IceCal2Root GetTWRDaqData* No TWRDaq calibration data will be produced." << endl;
582   return;
583  }
584
585  fInput.clear();
586  fInput.open(fTWRDaqFileName.Data());
587
588  if (!fInput.good())
589  {
590   cout << " *IceCal2Root GetTWRDaqData* Bad input file : " << fTWRDaqFileName.Data() << endl;
591   return;
592  }
593
594  // The geometry info will be obtained from the MuDaq OM database
595  if (!fMuDaqdb)
596  {
597   cout << " *IceCal2Root GetTWRDaqData* MuDaq OM geometry database is missing." << endl;
598   return;
599  }
600
601  // The TWRDaq OM database object
602  if (fTWRDaqdb)
603  {
604   fTWRDaqdb->Reset();
605  }
606  else
607  {
608   fTWRDaqdb=new AliObjMatrix();
609   fTWRDaqdb->SetNameTitle("TWRDaq-OMDBASE","The TWRDaq OM geometry, calib. etc... database");
610   fTWRDaqdb->SetOwner();
611  }
612
613  // Prescription of the various (de)calibration functions
614  TF1 fadccal("fadccal","x*(5./4096.)/(50.*[0])");
615  TF1 fadcdecal("fadcdecal","x*(50.*[0])/(5./4096.)");
616  fadccal.SetParName(0,"nC/PE");
617  fadcdecal.SetParName(0,"nC/PE");
618
619  TF1 ftdccal("ftdccal","x-[0]");
620  TF1 ftdcdecal("ftdcdecal","x+[0]");
621  ftdccal.SetParName(0,"T0");
622  ftdcdecal.SetParName(0,"T0");
623
624  TF1 ftotcal("ftotcal","x*[0]");
625  TF1 ftotdecal("ftotdecal","x/[0]");
626  ftotcal.SetParName(0,"TOT-FACT");
627  ftotdecal.SetParName(0,"TOT-FACT");
628
629  fInput.seekg(0); // Position at beginning of file
630  fInput >> dec;   // Make sure all integers starting with 0 are taken in decimal format
631
632  Int_t jmod;
633  Float_t t0;
634  Float_t ncpe;
635  IceAOM* omx=0;
636  TF1* fcal=0;
637  TF1* fdecal=0;
638  while (fInput >> jmod >> t0 >> ncpe)
639  {
640   // Copy the Geom data from the MuDaq OM database
641   IceAOM* omg=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
642   if (!omg) continue;
643
644   omx=new IceAOM(*omg);
645
646   // Reset all previous "dead" flags
647   omx->SetAlive("ADC");
648   omx->SetAlive("LE");
649   omx->SetAlive("TOT");
650
651   // Enter the TWRDaq (de)calibration functions
652   omx->SetCalFunction(&fadccal,"ADC");
653   omx->SetDecalFunction(&fadcdecal,"ADC");
654   omx->SetCalFunction(&ftdccal,"LE");
655   omx->SetDecalFunction(&ftdcdecal,"LE");
656   omx->SetCalFunction(&ftotcal,"TOT");
657   omx->SetDecalFunction(&ftotdecal,"TOT");
658
659   // Flag slots of bad OMs as dead and don't provide time (de)calib functions
660   if (ncpe<=0)
661   {
662    omx->SetDead("ADC");
663    omx->SetCalFunction(0,"ADC");
664    omx->SetDecalFunction(0,"ADC");
665   }
666   if (t0<-999)
667   {
668    omx->SetDead("LE");
669    omx->SetDead("TOT");
670    omx->SetCalFunction(0,"LE");
671    omx->SetDecalFunction(0,"LE");
672    omx->SetCalFunction(0,"TOT");
673    omx->SetDecalFunction(0,"TOT");
674   }
675
676   // Set the TWRDaq (de)calibration function parameters for the good OMs
677   fcal=omx->GetCalFunction("ADC");
678   fdecal=omx->GetDecalFunction("ADC");
679   if (fcal)
680   {
681    fcal->SetParameter(0,ncpe);
682   }
683   if (fdecal)
684   {
685    fdecal->SetParameter(0,ncpe);
686   }
687
688   fcal=omx->GetCalFunction("LE");
689   fdecal=omx->GetDecalFunction("LE");
690   if (fcal)
691   {
692    fcal->SetParameter(0,t0);
693   }
694   if (fdecal)
695   {
696    fdecal->SetParameter(0,t0);
697   }
698
699   fcal=omx->GetCalFunction("TOT");
700   fdecal=omx->GetDecalFunction("TOT");
701   if (fcal)
702   {
703    fcal->SetParameter(0,1);
704   }
705   if (fdecal)
706   {
707    fdecal->SetParameter(0,1);
708   }
709
710   fTWRDaqdb->EnterObject(jmod,1,omx);
711
712  } // End of reading loop
713
714  fInput.close();
715 }
716 ///////////////////////////////////////////////////////////////////////////