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.
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.
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
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.
44 // The OM database information in the AliObjMatrix has the following structure :
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.
50 // The latter is only available for MuDaq databases.
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.
56 // Note : Position coordinates are indicated in meters and times are in nanoseconds,
57 // in accordance with the convention used previously for Amanda.
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).
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).
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
83 // The PDG particle database is a standard ROOT TDatabasePDG object
84 // with the following extensions :
94 // fiberlaser 10002100
103 // gSystem->Load("ralice");
104 // gSystem->Load("icepack");
105 // gSystem->Load("iceconvert");
107 // IceCal2Root q("IceCal2Root","Amacalib to IcePack data structure conversion");
109 // // The MuDaq Amacalib input filename
110 // q.SetAmacalibFile("amacalib_amanda2_2005.txt");
112 // // The TWRDaq input filename with the newly determined TWR T0 and ADC calibs.
113 // q.SetTWRDaqFile("twr-cal-2005.txt");
115 // // Output file for the event structures
116 // q.SetOutputFile("cal2005.root");
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
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");
132 // // The sub-tasks will be executed in the order as they are entered.
133 // ///////////////////////////////////////////////////////////////////
135 // // Perform the conversion and execute subtasks (if any)
138 // // Outline of dbase usage for (de)calibration and Xtalk
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);
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);
163 // if (fxtalkp) prob=fxtalkp->Eval(adc);
165 //--- Author: Nick van Eijndhoven 09-aug-2005 Utrecht University
166 //- Modified: NvE $Date$ Utrecht University
167 ///////////////////////////////////////////////////////////////////////////
169 #include "IceCal2Root.h"
170 #include "Rstrstream.h"
172 ClassImp(IceCal2Root) // Class implementation to enable ROOT I/O
174 IceCal2Root::IceCal2Root(const char* name,const char* title) : AliJob(name,title)
176 // Default constructor.
186 ///////////////////////////////////////////////////////////////////////////
187 IceCal2Root::~IceCal2Root()
189 // Default destructor.
209 ///////////////////////////////////////////////////////////////////////////
210 void IceCal2Root::SetAmacalibFile(TString name)
212 // Set the name of the Amacalib MuDaq input file.
213 fAmacalFileName=name;
215 ///////////////////////////////////////////////////////////////////////////
216 void IceCal2Root::SetTWRDaqFile(TString name)
218 // Set the name of the TWRDaq calibration input file.
219 fTWRDaqFileName=name;
221 ///////////////////////////////////////////////////////////////////////////
222 void IceCal2Root::SetOutputFile(TString name)
224 // Set the name of the ROOT output file.
227 ///////////////////////////////////////////////////////////////////////////
228 TDatabasePDG* IceCal2Root::GetPDG()
230 // Provide pointer to the PDG database
233 ///////////////////////////////////////////////////////////////////////////
234 AliObjMatrix* IceCal2Root::GetOMdbase(TString name)
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".
240 if (name=="MuDaq") return fMuDaqdb;
241 if (name=="TWRDaq") return fTWRDaqdb;
244 ///////////////////////////////////////////////////////////////////////////
245 void IceCal2Root::Exec(Option_t* opt)
247 // Job to convert the (ascii) database info into the IcePack structure.
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
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.
267 if (fRootFileName != "")
269 fOutfile=new TFile(fRootFileName.Data(),"RECREATE","Calibration data in IcePack structure");
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);
289 // Initialise the job working environment
291 if (fOutfile) AddObject(fOutfile);
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;
301 if (fMuDaqdb) AddObject(fMuDaqdb);
304 if (fTWRDaqdb) AddObject(fTWRDaqdb);
308 // Invoke all available sub-tasks (if any)
312 // Write the datastructures to the output file
316 if (fMuDaqdb) fMuDaqdb->Write();
317 if (fTWRDaqdb) fTWRDaqdb->Write();
318 if (fPdg) fPdg->Write();
321 // Flush remaining memory resident data to the output file
322 if (fOutfile) fOutfile->Write();
324 ///////////////////////////////////////////////////////////////////////////
325 void IceCal2Root::GetMuDaqData()
327 // Obtain all the MuDaq geometry, calibration and Xtalk data.
329 if (fAmacalFileName=="")
331 cout << " *IceCal2Root GetMuDaqData* No amacalib input file specified." << endl;
336 fInput.open(fAmacalFileName.Data());
340 cout << " *IceCal2Root GetMuDaqData* Bad input file : " << fAmacalFileName.Data() << endl;
344 // The MuDaq OM database object
351 fMuDaqdb=new AliObjMatrix();
352 fMuDaqdb->SetNameTitle("MuDaq-OMDBASE","The MuDaq OM geometry, calib. etc... database");
353 fMuDaqdb->SetOwner();
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");
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");
375 TF1 ftotcal("ftotcal","x*[0]");
376 TF1 ftotdecal("ftotdecal","x/[0]");
377 ftotcal.SetParName(0,"BETA-TOT");
378 ftotdecal.SetParName(0,"BETA-TOT");
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");
387 // The basic OM contents
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
401 fInput.seekg(0); // Position at beginning of file
402 fInput >> dec; // Make sure all integers starting with 0 are taken in decimal format
405 Int_t jmod,type,serial,string,ix,iy,iz,ori;
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;
415 Float_t c,b,dlemin,dlemax;
421 if (s == "P") // Read the Geom data
423 fInput >> jmod >> type >> serial >> string >> ix >> iy >> iz >> ori;
424 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
428 omx->SetUniqueID(jmod);
429 fMuDaqdb->EnterObject(jmod,1,omx);
431 pos[0]=double(ix)/1000.;
432 pos[1]=double(iy)/1000.;
433 pos[2]=double(iz)/1000.;
434 omx->SetPosition(pos,"car");
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");
443 else if (s == "T") // Read the Time calibration constants
445 fInput >> jmod >> ped >> beta >> alpha >> pol;
446 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
450 omx->SetUniqueID(jmod);
451 fMuDaqdb->EnterObject(jmod,1,omx);
454 omx->SetCalFunction(&ftdccal,"LE");
455 omx->SetDecalFunction(&ftdcdecal,"LE");
456 omx->SetCalFunction(&ftotcal,"TOT");
457 omx->SetDecalFunction(&ftotdecal,"TOT");
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)
464 omx->SetCalFunction(0,"LE");
465 omx->SetDecalFunction(0,"LE");
466 omx->SetCalFunction(0,"TOT");
467 omx->SetDecalFunction(0,"TOT");
470 fcal=omx->GetCalFunction("LE");
471 fdecal=omx->GetDecalFunction("LE");
474 fcal->SetParameter(0,beta);
475 fcal->SetParameter(1,ped);
476 fcal->SetParameter(2,alpha);
477 fcal->SetParameter(3,1.e20);
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);
488 fcal=omx->GetCalFunction("TOT");
489 fdecal=omx->GetDecalFunction("TOT");
492 fcal->SetParameter(0,beta);
496 fdecal->SetParameter(0,beta);
499 else if (s == "A") // Read the Amplitude calibration constants
501 fInput >> jmod >> ped >> beta >> totped >> pol;
502 omx=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
506 omx->SetUniqueID(jmod);
507 fMuDaqdb->EnterObject(jmod,1,omx);
510 omx->SetCalFunction(&fadccal,"ADC");
511 omx->SetDecalFunction(&fadcdecal,"ADC");
513 // Flag amplitude slots of bad OMs as dead and don't provide amplitude (de)calib functions
514 if (ped<-1e5 || beta<=0)
517 omx->SetCalFunction(0,"ADC");
518 omx->SetDecalFunction(0,"ADC");
523 omx->SetCalFunction(0,"TOT");
524 omx->SetDecalFunction(0,"TOT");
527 fcal=omx->GetCalFunction("ADC");
528 fdecal=omx->GetDecalFunction("ADC");
531 fcal->SetParameter(0,beta);
532 fcal->SetParameter(1,ped);
536 fdecal->SetParameter(0,beta);
537 if (!beta) fdecal->SetParameter(0,1);
538 fdecal->SetParameter(1,ped);
541 else if (s == "K") // Read the cross talk probability constants
543 fInput >> jtrans >> jrec >> c >> b >> dlemin >> dlemax;
544 omx=(IceAOM*)fMuDaqdb->GetObject(jtrans,1);
548 omx->SetUniqueID(jtrans);
549 fMuDaqdb->EnterObject(jtrans,1,omx);
552 TF1* fx=new TF1(fxtalkp);
553 fx->SetParameter(0,c);
556 fx->SetParameter(1,b);
560 fx->SetParameter(1,1);
562 fx->SetParameter(2,dlemin);
563 fx->SetParameter(3,dlemax);
564 fMuDaqdb->EnterObject(jtrans,jrec+1,fx);
566 else // Skip this line
568 fInput.ignore(99999,'\n');
574 ///////////////////////////////////////////////////////////////////////////
575 void IceCal2Root::GetTWRDaqData()
577 // Obtain all the TWRDaq geometry and calibration data.
579 if (fTWRDaqFileName=="")
581 cout << " *IceCal2Root GetTWRDaqData* No TWRDaq calibration data will be produced." << endl;
586 fInput.open(fTWRDaqFileName.Data());
590 cout << " *IceCal2Root GetTWRDaqData* Bad input file : " << fTWRDaqFileName.Data() << endl;
594 // The geometry info will be obtained from the MuDaq OM database
597 cout << " *IceCal2Root GetTWRDaqData* MuDaq OM geometry database is missing." << endl;
601 // The TWRDaq OM database object
608 fTWRDaqdb=new AliObjMatrix();
609 fTWRDaqdb->SetNameTitle("TWRDaq-OMDBASE","The TWRDaq OM geometry, calib. etc... database");
610 fTWRDaqdb->SetOwner();
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");
619 TF1 ftdccal("ftdccal","x-[0]");
620 TF1 ftdcdecal("ftdcdecal","x+[0]");
621 ftdccal.SetParName(0,"T0");
622 ftdcdecal.SetParName(0,"T0");
624 TF1 ftotcal("ftotcal","x*[0]");
625 TF1 ftotdecal("ftotdecal","x/[0]");
626 ftotcal.SetParName(0,"TOT-FACT");
627 ftotdecal.SetParName(0,"TOT-FACT");
629 fInput.seekg(0); // Position at beginning of file
630 fInput >> dec; // Make sure all integers starting with 0 are taken in decimal format
638 while (fInput >> jmod >> t0 >> ncpe)
640 // Copy the Geom data from the MuDaq OM database
641 IceAOM* omg=(IceAOM*)fMuDaqdb->GetObject(jmod,1);
644 omx=new IceAOM(*omg);
646 // Reset all previous "dead" flags
647 omx->SetAlive("ADC");
649 omx->SetAlive("TOT");
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");
659 // Flag slots of bad OMs as dead and don't provide time (de)calib functions
663 omx->SetCalFunction(0,"ADC");
664 omx->SetDecalFunction(0,"ADC");
670 omx->SetCalFunction(0,"LE");
671 omx->SetDecalFunction(0,"LE");
672 omx->SetCalFunction(0,"TOT");
673 omx->SetDecalFunction(0,"TOT");
676 // Set the TWRDaq (de)calibration function parameters for the good OMs
677 fcal=omx->GetCalFunction("ADC");
678 fdecal=omx->GetDecalFunction("ADC");
681 fcal->SetParameter(0,ncpe);
685 fdecal->SetParameter(0,ncpe);
688 fcal=omx->GetCalFunction("LE");
689 fdecal=omx->GetDecalFunction("LE");
692 fcal->SetParameter(0,t0);
696 fdecal->SetParameter(0,t0);
699 fcal=omx->GetCalFunction("TOT");
700 fdecal=omx->GetDecalFunction("TOT");
703 fcal->SetParameter(0,1);
707 fdecal->SetParameter(0,1);
710 fTWRDaqdb->EnterObject(jmod,1,omx);
712 } // End of reading loop
716 ///////////////////////////////////////////////////////////////////////////