1 /*******************************************************************************
2 * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
4 * Author: The IceCube RALICE-based Offline 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.
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 *******************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
20 // Conversion of Amanda (ascii) calibration data into a AliObjMatrix objects
21 // containing the complete OM position, calibration, Xtalk etc... database.
22 // Via specification of the various input files, various AliObjMatrix objects
23 // are created and (optionally) stored in a single output file.
24 // The names of the AliObjMatrix objects indicate the type of database they
27 // The name "MuDaq-OMDBASE" indicates the database info for MuDaq data,
28 // whereas TWRDaq calibration data is in the object named "TWRDaq-OMDBASE".
29 // Note that a MuDaq Amacalib ascii input file has always to be provided,
30 // since the geometry data for all the other databases is obtained from there.
31 // In addition a PDG particle database, extended with some specific Amanda
32 // entries, is provided as well.
33 // This class is derived from AliJob providing task-based processing.
34 // Note that the data structures are only written out if an outputfile has
35 // been specified via the SetOutputFile memberfunction.
36 // In case no outputfile has been specified, this class provides a facility
37 // to investigate/use the dbase data directly in subsequent (sub)tasks.
39 // The OM database information in the AliObjMatrix has the following structure :
41 // (j,1) : Pointer to OM with identifier "j"
42 // (j,k+1) : Pointer to a TF1* being the probability function for Xtalk
43 // with OM "j" as transmitter and OM "k" as receiver.
45 // The latter is only available for MuDaq databases.
47 // The geometry information is directly available from the OM pointer
48 // in the form of its position and data words like "ORIENT" for orientation etc...
49 // Just use the OM memberfunction Data() to obtain a full overview.
51 // Note : Position coordinates are indicated in meters and times are in nanoseconds,
52 // in accordance with the convention used previously for Amanda.
54 // From the OM pointer also the various (de)calibration functions for
55 // ADC, LE and TOT can be obtained as TF1* pointers.
56 // The actual values of the calibration constants are stored as parameters
57 // of these (de)calibration functions and can be investigated via the
58 // usual TF1::Print() or TF1::GetParameter() facilities.
59 // The last two parameters of the Xtalk probability function have no effect
60 // on the evaluated probability value. However, these two parameters provide
61 // the minimum and maximum allowed LE differences between the transmitter
62 // and receiver hits, respectively (as can be seen from the parameter names).
64 // The (de)calibration of signals and/or determination of the Xtalk probability
65 // can be performed via the standard TF1::Eval(x) functionality, where "x"
66 // represents the input argument of the function (e.g. an uncalibrated ADC value).
68 // In general the database is not directly accessed by the user in performing
69 // physics analysis, since all the necessary information is contained in the
70 // event data itself and available via the GetSignal() memberfunction of the hits.
71 // However, specific tasks like e.g. calibration, Xtalk correction,
72 // bad module removal, noise hit removal etc... might need explicit database access.
73 // So, at the end of the example below some functionality is indicated for clarity.
74 // The user may use exactly the same procedures to obtain explicit access to the calibration
75 // functions etc... from the various OMs and/or hits within the actual event data which he/she
78 // The PDG particle database is a standard ROOT TDatabasePDG object
79 // with the following extensions :
89 // fiberlaser 10002100
98 // gSystem->Load("ralice");
99 // gSystem->Load("icepack");
100 // gSystem->Load("iceconvert");
102 // IceCal2Root q("IceCal2Root","Amacalib to IcePack data structure conversion");
104 // // The MuDaq Amacalib input filename
105 // q.SetAmacalibFile("amacalib_amanda2_2005.txt");
107 // // The TWRDaq input filename with the newly determined TWR T0 and ADC calibs.
108 // q.SetTWRDaqFile("twr-cal-2005.txt");
110 // // Output file for the event structures
111 // q.SetOutputFile("cal2005.root");
113 // ///////////////////////////////////////////////////////////////////
114 // // Here the user can specify his/her sub-tasks to be executed
115 // // after the database structures have been filled and before the
116 // // data is written out.
117 // // Sub-tasks (i.e. a user classes derived from TTask) are entered
120 // // MyTask1 task1("task1","Some modifications to specific OMs");
121 // // MyTask2 task2("task2","Removal of specific OMs");
122 // // MyTask3 task3("task3","Add private objects to the output file");
127 // // The sub-tasks will be executed in the order as they are entered.
128 // ///////////////////////////////////////////////////////////////////
130 // // Perform the conversion and execute subtasks (if any)
133 // // Outline of dbase usage for (de)calibration and Xtalk
135 // AliObjMatrix* omdb=q.GetOMdbase("MuDaq");
136 // IceAOM* om=(IceAOM*)omdb->GetObject(9,1); // Pointer to OM 9
137 // om->Data(); // Overview of generic module parameters
138 // TF1* fcal=0; // Calibration function
139 // TF1* fdecal=0; // De-calibration function
140 // fcal=om->GetCalFunction("ADC");
141 // Float_t adc=248; // Uncalibrated ADC
142 // Float_t cadc=0; // Calibrated ADC
143 // if (fcal) cadc=fcal->Eval(adc);
144 // fcal=om->GetCalFunction("TOT");
145 // Float_t tot=1538; // Uncalibrated TOT
146 // Float_t ctot=0; // Calibrated TOT
147 // if (fcal) ctot=fcal->Eval(tot);
148 // fdecal=om->GetDecalFunction("LE");
149 // Float_t le=21697; // Uncalibrated LE
150 // Float_t cle=0; // Calibrated LE
151 // if (fcal) cle=fcal->Eval(le);
153 // // Xtalk probability between (trans) OM 90 and (rec) OM 113
154 // // for a transmitter signal of uncalibrated amplitude "adc".
155 // TF1* fxtalkp=(TF1*)omdb->GetObject(90,113+1);
158 // if (fxtalkp) prob=fxtalkp->Eval(adc);
160 //--- Author: Nick van Eijndhoven 09-aug-2005 Utrecht University
161 //- Modified: NvE $Date$ Utrecht University
162 ///////////////////////////////////////////////////////////////////////////
164 #include "IceCal2Root.h"
165 #include "Rstrstream.h"
167 ClassImp(IceCal2Root) // Class implementation to enable ROOT I/O
169 IceCal2Root::IceCal2Root(const char* name,const char* title) : AliJob(name,title)
171 // Default constructor.
181 ///////////////////////////////////////////////////////////////////////////
182 IceCal2Root::~IceCal2Root()
184 // Default destructor.
204 ///////////////////////////////////////////////////////////////////////////
205 void IceCal2Root::SetAmacalibFile(TString name)
207 // Set the name of the Amacalib MuDaq input file.
208 fAmacalFileName=name;
210 ///////////////////////////////////////////////////////////////////////////
211 void IceCal2Root::SetTWRDaqFile(TString name)
213 // Set the name of the TWRDaq calibration input file.
214 fTWRDaqFileName=name;
216 ///////////////////////////////////////////////////////////////////////////
217 void IceCal2Root::SetOutputFile(TString name)
219 // Set the name of the ROOT output file.
222 ///////////////////////////////////////////////////////////////////////////
223 TDatabasePDG* IceCal2Root::GetPDG()
225 // Provide pointer to the PDG database
228 ///////////////////////////////////////////////////////////////////////////
229 AliObjMatrix* IceCal2Root::GetOMdbase(TString name)
231 // Provide pointer to the requested OM geometry, calib. etc... database.
232 // Options for the "name" specification are : MuDaq, TWRDaq.
233 // For backward compatibility the default is name="MuDaq".
235 if (name=="MuDaq") return fMuDaqdb;
236 if (name=="TWRDaq") return fTWRDaqdb;
239 ///////////////////////////////////////////////////////////////////////////
240 void IceCal2Root::Exec(Option_t* opt)
242 // Job to convert the (ascii) database info into the IcePack structure.
246 // 1) This class is derived from AliJob, allowing a task based processing.
247 // After conversion of the (ascii) dbase data into the IcePack structure,
248 // the processing of all available sub-tasks (if any) is invoked.
249 // This provides a facility to investigate/use the dbase data in
250 // subsequent (sub)tasks processing before the final data structures
253 // 2) Creation of a TFolder via the argument of the ExecuteJob statement
254 // makes all created database objects accessible to subsequent tasks
255 // via the TFolder::FindObject facility.
262 if (fRootFileName != "")
264 fOutfile=new TFile(fRootFileName.Data(),"RECREATE","Calibration data in IcePack structure");
267 // Create the particle database and extend it with some F2000 specific definitions
268 if (fPdg) delete fPdg;
269 fPdg=new TDatabasePDG();
270 fPdg->SetNameTitle("PDG-DBASE","The extended PDG particle database");
271 Double_t me=fPdg->GetParticle(11)->Mass();
272 fPdg->AddParticle("brems" ,"brems" ,0,1,0,0,"none",10001001,0,0);
273 fPdg->AddParticle("deltae" ,"deltae" ,me,1,0,-3,"Lepton",10001002,0,0);
274 fPdg->AddParticle("pairprod","pairprod",0,1,0,0,"none",10001003,0,0);
275 fPdg->AddParticle("nucl_int","nucl_Int",0,1,0,0,"none",10001004,0,0);
276 fPdg->AddParticle("mu_pair" ,"mu_pair" ,0,1,0,0,"none",10001005,0,0);
277 fPdg->AddParticle("hadrons" ,"hadrons" ,0,1,0,0,"none",10001006,0,0);
278 fPdg->AddParticle("fiberlaser","fiberlaser",0,1,0,0,"none",10002100,0,0);
279 fPdg->AddParticle("n2laser" ,"n2laser" ,0,1,0,0,"none",10002101,0,0);
280 fPdg->AddParticle("yaglaser" ,"yaglaser" ,0,1,0,0,"none",10002201,0,0);
281 fPdg->AddParticle("z_primary","z_primary",0,1,0,0,"none",10003000,0,0);
282 fPdg->AddParticle("a_primary","a_primary",0,1,0,0,"none",10003500,0,0);
284 // Initialise the job working environment
286 if (fOutfile) AddObject(fOutfile);
288 cout << " ***" << endl;
289 cout << " *** Start processing of job " << GetName() << " ***" << endl;
290 cout << " ***" << endl;
291 cout << " Amacalib MuDaq input file : " << fAmacalFileName.Data() << endl;
292 cout << " TWRDaq input file : " << fTWRDaqFileName.Data() << endl;
293 if (fOutfile) cout << " ROOT output file : " << fOutfile->GetName() << endl;
296 if (fMuDaqdb) AddObject(fMuDaqdb);
299 if (fTWRDaqdb) AddObject(fTWRDaqdb);
303 // Invoke all available sub-tasks (if any)
307 // Write the datastructures to the output file
311 if (fMuDaqdb) fMuDaqdb->Write();
312 if (fTWRDaqdb) fTWRDaqdb->Write();
313 if (fPdg) fPdg->Write();
316 // Flush remaining memory resident data to the output file
317 if (fOutfile) fOutfile->Write();
319 ///////////////////////////////////////////////////////////////////////////
320 void IceCal2Root::GetMuDaqData()
322 // Obtain all the MuDaq geometry, calibration and Xtalk data.
324 if (fAmacalFileName=="")
326 cout << " *IceCal2Root GetMuDaqData* No amacalib input file specified." << endl;
331 fInput.open(fAmacalFileName.Data());
335 cout << " *IceCal2Root GetMuDaqData* Bad input file : " << fAmacalFileName.Data() << endl;
339 // The MuDaq OM database object
346 fMuDaqdb=new AliObjMatrix();
347 fMuDaqdb->SetNameTitle("MuDaq-OMDBASE","The MuDaq OM geometry, calib. etc... database");
348 fMuDaqdb->SetOwner();
351 // Prescription of the various (de)calibration functions
352 TF1 fadccal("fadccal","(x-[1])*[0]");
353 TF1 fadcdecal("fadcdecal","(x/[0])+[1]");
354 fadccal.SetParName(0,"BETA-ADC");
355 fadccal.SetParName(1,"PED-ADC");
356 fadcdecal.SetParName(0,"BETA-ADC");
357 fadcdecal.SetParName(1,"PED-ADC");
359 TF1 ftdccal("ftdccal","(x*[0])-[1]-([0]-1.)*32767.-[2]/sqrt([3])");
360 TF1 ftdcdecal("ftdcdecal","(x+([0]-1.)*32767.+[1]+[2]/sqrt([3]))/[0]");
361 ftdccal.SetParName(0,"BETA-TDC");
362 ftdccal.SetParName(1,"T0");
363 ftdccal.SetParName(2,"ALPHA-TDC");
364 ftdccal.SetParName(3,"ADC-SLEW");
365 ftdcdecal.SetParName(0,"BETA-TDC");
366 ftdcdecal.SetParName(1,"T0");
367 ftdcdecal.SetParName(2,"ALPHA-TDC");
368 ftdcdecal.SetParName(3,"ADC-SLEW");
370 TF1 ftotcal("ftotcal","x*[0]");
371 TF1 ftotdecal("ftotdecal","x/[0]");
372 ftotcal.SetParName(0,"BETA-TOT");
373 ftotdecal.SetParName(0,"BETA-TOT");
375 // The cross talk probability function
376 TF1 fxtalkp("fxtalkp","(1.+[2]-[2]+[3]-[3])/(1.+exp(([0]-x)/[1]))");
377 fxtalkp.SetParName(0,"C");
378 fxtalkp.SetParName(1,"B");
379 fxtalkp.SetParName(2,"dLE-min");
380 fxtalkp.SetParName(3,"dLE-max");
382 // The basic OM contents
385 // Slots to hold the various (de)calibration functions
386 om.AddNamedSlot("ADC");
387 om.AddNamedSlot("LE");
388 om.AddNamedSlot("TOT");
389 // Slots with hardware parameters
390 om.AddNamedSlot("TYPE");
391 om.AddNamedSlot("ORIENT");
392 /// om.AddNamedSlot("THRESH");
393 /// om.AddNamedSlot("SENSIT");
394 /// om.AddNamedSlot("READOUT"); // 0=unknown 1=electrical 2=optical 3=digital
396 fInput.seekg(0); // Position at beginning of file
397 fInput >> dec; // Make sure all integers starting with 0 are taken in decimal format
400 Int_t jmod,type,serial,string,ix,iy,iz,ori;
402 /// Float_t thresh=0;
403 /// Float_t sensit=1;
404 /// Float_t readout=0;
405 Double_t pos[3]={0,0,0};
406 Float_t ped,beta,alpha;
410 Float_t c,b,dlemin,dlemax;
416 if (s == "P") // Read the Geom data
418 fInput >> jmod >> type >> serial >> string >> ix >> iy >> iz >> ori;
419 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
423 omx->SetUniqueID(jmod);
424 fMuDaqdb->EnterObject(jmod,1,omx);
426 pos[0]=double(ix)/1000.;
427 pos[1]=double(iy)/1000.;
428 pos[2]=double(iz)/1000.;
429 omx->SetPosition(pos,"car");
431 if (ori==2) costh=-1;
432 omx->SetSignal(type,"TYPE");
433 omx->SetSignal(costh,"ORIENT");
434 /// omx->SetSignal(thresh,"THRESH");
435 /// omx->SetSignal(sensit,"SENSIT");
436 /// omx->SetSignal(readout,"READOUT");
438 else if (s == "T") // Read the Time calibration constants
440 fInput >> jmod >> ped >> beta >> alpha >> pol;
441 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
445 omx->SetUniqueID(jmod);
446 fMuDaqdb->EnterObject(jmod,1,omx);
449 omx->SetCalFunction(&ftdccal,"LE");
450 omx->SetDecalFunction(&ftdcdecal,"LE");
451 omx->SetCalFunction(&ftotcal,"TOT");
452 omx->SetDecalFunction(&ftotdecal,"TOT");
454 // Flag time slots of bad OMs as dead and don't provide time (de)calib functions
455 if (ped<-1e5 || beta<=0 || alpha<0)
459 omx->SetCalFunction(0,"LE");
460 omx->SetDecalFunction(0,"LE");
461 omx->SetCalFunction(0,"TOT");
462 omx->SetDecalFunction(0,"TOT");
465 fcal=omx->GetCalFunction("LE");
466 fdecal=omx->GetDecalFunction("LE");
469 fcal->SetParameter(0,beta);
470 fcal->SetParameter(1,ped);
471 fcal->SetParameter(2,alpha);
472 fcal->SetParameter(3,1.e20);
476 fdecal->SetParameter(0,beta);
477 if (!beta) fdecal->SetParameter(0,1);
478 fdecal->SetParameter(1,ped);
479 fdecal->SetParameter(2,alpha);
480 fdecal->SetParameter(3,1.e20);
483 fcal=omx->GetCalFunction("TOT");
484 fdecal=omx->GetDecalFunction("TOT");
487 fcal->SetParameter(0,beta);
491 fdecal->SetParameter(0,beta);
494 else if (s == "A") // Read the Amplitude calibration constants
496 fInput >> jmod >> ped >> beta >> totped >> pol;
497 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
501 omx->SetUniqueID(jmod);
502 fMuDaqdb->EnterObject(jmod,1,omx);
505 omx->SetCalFunction(&fadccal,"ADC");
506 omx->SetDecalFunction(&fadcdecal,"ADC");
508 // Flag amplitude slots of bad OMs as dead and don't provide amplitude (de)calib functions
509 if (ped<-1e5 || beta<=0)
512 omx->SetCalFunction(0,"ADC");
513 omx->SetDecalFunction(0,"ADC");
518 omx->SetCalFunction(0,"TOT");
519 omx->SetDecalFunction(0,"TOT");
522 fcal=omx->GetCalFunction("ADC");
523 fdecal=omx->GetDecalFunction("ADC");
526 fcal->SetParameter(0,beta);
527 fcal->SetParameter(1,ped);
531 fdecal->SetParameter(0,beta);
532 if (!beta) fdecal->SetParameter(0,1);
533 fdecal->SetParameter(1,ped);
536 else if (s == "K") // Read the cross talk probability constants
538 fInput >> jtrans >> jrec >> c >> b >> dlemin >> dlemax;
539 omx=(IceAOM*)fMuDaqdb->GetObject(jtrans,1);
543 omx->SetUniqueID(jtrans);
544 fMuDaqdb->EnterObject(jtrans,1,omx);
547 TF1* fx=new TF1(fxtalkp);
548 fx->SetParameter(0,c);
551 fx->SetParameter(1,b);
555 fx->SetParameter(1,1);
557 fx->SetParameter(2,dlemin);
558 fx->SetParameter(3,dlemax);
559 fMuDaqdb->EnterObject(jtrans,jrec+1,fx);
561 else // Skip this line
563 fInput.ignore(99999,'\n');
569 ///////////////////////////////////////////////////////////////////////////
570 void IceCal2Root::GetTWRDaqData()
572 // Obtain all the TWRDaq geometry and calibration data.
574 if (fTWRDaqFileName=="")
576 cout << " *IceCal2Root GetTWRDaqData* No TWRDaq calibration data will be produced." << endl;
581 fInput.open(fTWRDaqFileName.Data());
585 cout << " *IceCal2Root GetTWRDaqData* Bad input file : " << fTWRDaqFileName.Data() << endl;
589 // The geometry info will be obtained from the MuDaq OM database
592 cout << " *IceCal2Root GetTWRDaqData* MuDaq OM geometry database is missing." << endl;
596 // The TWRDaq OM database object
603 fTWRDaqdb=new AliObjMatrix();
604 fTWRDaqdb->SetNameTitle("TWRDaq-OMDBASE","The TWRDaq OM geometry, calib. etc... database");
605 fTWRDaqdb->SetOwner();
608 // Prescription of the various (de)calibration functions
609 TF1 fadccal("fadccal","x*(5./4096.)/(50.*[0])");
610 TF1 fadcdecal("fadcdecal","x*(50.*[0])/(5./4096.)");
611 fadccal.SetParName(0,"nC/PE");
612 fadcdecal.SetParName(0,"nC/PE");
614 TF1 ftdccal("ftdccal","x-[0]");
615 TF1 ftdcdecal("ftdcdecal","x+[0]");
616 ftdccal.SetParName(0,"T0");
617 ftdcdecal.SetParName(0,"T0");
619 TF1 ftotcal("ftotcal","x*[0]");
620 TF1 ftotdecal("ftotdecal","x/[0]");
621 ftotcal.SetParName(0,"TOT-FACT");
622 ftotdecal.SetParName(0,"TOT-FACT");
624 fInput.seekg(0); // Position at beginning of file
625 fInput >> dec; // Make sure all integers starting with 0 are taken in decimal format
633 while (fInput >> jmod >> t0 >> ncpe)
635 // Copy the Geom data from the MuDaq OM database
636 IceAOM* omg=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
639 omx=new IceAOM(*omg);
641 // Reset all previous "dead" flags
642 omx->SetAlive("ADC");
644 omx->SetAlive("TOT");
646 // Enter the TWRDaq (de)calibration functions
647 omx->SetCalFunction(&fadccal,"ADC");
648 omx->SetDecalFunction(&fadcdecal,"ADC");
649 omx->SetCalFunction(&ftdccal,"LE");
650 omx->SetDecalFunction(&ftdcdecal,"LE");
651 omx->SetCalFunction(&ftotcal,"TOT");
652 omx->SetDecalFunction(&ftotdecal,"TOT");
654 // Flag slots of bad OMs as dead and don't provide time (de)calib functions
658 omx->SetCalFunction(0,"ADC");
659 omx->SetDecalFunction(0,"ADC");
665 omx->SetCalFunction(0,"LE");
666 omx->SetDecalFunction(0,"LE");
667 omx->SetCalFunction(0,"TOT");
668 omx->SetDecalFunction(0,"TOT");
671 // Set the TWRDaq (de)calibration function parameters for the good OMs
672 fcal=omx->GetCalFunction("ADC");
673 fdecal=omx->GetDecalFunction("ADC");
676 fcal->SetParameter(0,ncpe);
680 fdecal->SetParameter(0,ncpe);
683 fcal=omx->GetCalFunction("LE");
684 fdecal=omx->GetDecalFunction("LE");
687 fcal->SetParameter(0,t0);
691 fdecal->SetParameter(0,t0);
694 fcal=omx->GetCalFunction("TOT");
695 fdecal=omx->GetDecalFunction("TOT");
698 fcal->SetParameter(0,1);
702 fdecal->SetParameter(0,1);
705 fTWRDaqdb->EnterObject(jmod,1,omx);
707 } // End of reading loop
711 ///////////////////////////////////////////////////////////////////////////