]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/icepack/iceconvert/IceF2k.cxx
07-jun-2007 GdV OM readout type also updated from the data contents in IceRoot.cxx.
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / IceF2k.cxx
CommitLineData
f67e2651 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 IceF2k
20// Conversion of Amanda F2K data into IceEvent physics event structures.
5481c137 21// This class is derived from AliJob providing a task-based processing
22// structure on an event-by-event basis.
23// The main object in the job environment is an IceEvent* pointer.
24// In case the user has provided sub-tasks, these will be executed
25// on an event-by-event basis after the IceEvent structure has been filled
26// with the F2K data and before the final structures are written out.
1c9018c6 27// Note that the data structures are only written out if an outputfile has
28// been specified via the SetOutputFile memberfunction.
29// In case no outputfile has been specified, this class provides a facility
97a09735 30// to investigate/analyse F2K data using the Ralice/IcePack analysis tools.
0cfe76b5 31// An indication of the active DAQ system is available in the IceEvent structure
32// via a device named "Daq". Here the various daq systems (TWR, Muon, ...)
33// from which the actual hits (ADC, LE, TOT) are composed have been indicated
34// as "signals" of the device itself.
97a09735 35//
36// Note : Sometimes the filtering/reco process which produced the F2K file
37// may have introduced a shift (i.e. offset) in the hit times w.r.t.
38// the actual trigger time. The aim of this is to obtain the hit times
39// centered more or less around zero.
40// In case of real data, this is recorded in the F2K data itself and
41// as such will be taken automatically into account by this IceF2k
42// processor such that all times will be provided again unshifted.
43// In other words, all times will be w.r.t. the actual trigger time
44// as recorded in the trigger data device named "Trigger" in the IceEvent
45// structure.
46// In case of simulated data this shift is not available in the F2K data.
47// The offset denoted in the F2K record is related to the time of the
48// primary interaction to put it well ahead of the detector trigger.
49// This primary interaction time, however, is irrelevant for the
50// reconstruction of the recorded hit patterns.
51// If a user had introduced a shift in producing the MC data,
52// very frequently (but not always) a value of -19000 is used.
53// For the IceF2k processing, the user can manually introduce a
54// time offset in case of MC data via the memberfunction SetMcToffset().
55// This user defined offset value will then be used to correct all
56// the hit times such that they will be provided again unshifted
57// w.r.t. the actual trigger time as recorded in the device named
58// "Trigger" in the IceEvent structure.
59// By default the MC time offset is set to 0 in the constructor
60// of this class.
f67e2651 61//
62// Usage example :
63// ---------------
64//
f5b75967 65// Note : This example creates automatically the ROOT output file, which
66// is the most user friendly way of running the conversion job.
67// In the subdirectory /macros the example macro icef2k.cc provides
68// an example of how to create a ROOT output file yourself and passing
69// this file via a pointer to IceF2k.
70//
f67e2651 71// gSystem->Load("ralice");
72// gSystem->Load("icepack");
73// gSystem->Load("iceconvert");
74//
5481c137 75// IceF2k q("IceF2k","F2K to IcePack data structure conversion");
f67e2651 76//
77// // Limit the number of entries for testing
5481c137 78// q.SetMaxEvents(10);
f67e2651 79//
80// // Print frequency to produce a short summary print every printfreq events
5481c137 81// q.SetPrintFreq(1);
f67e2651 82//
83// // Split level for the output structures
d0120ca2 84// q.SetSplitLevel(0);
f67e2651 85//
86// // Buffer size for the output structures
5481c137 87// q.SetBufferSize(32000);
88//
88b8d522 89// // The F2K input filename(s)
90// q.AddInputFile("run7825.f2k");
f67e2651 91//
5481c137 92// // Output file for the event structures
f5b75967 93// q.SetOutputFile("events.root");
5481c137 94//
95// ///////////////////////////////////////////////////////////////////
96// // Here the user can specify his/her sub-tasks to be executed
97// // on an event-by-event basis after the IceEvent structure
98// // has been filled and before the data is written out.
99// // Sub-tasks (i.e. a user classes derived from TTask) are entered
100// // as follows :
101// //
102// // MyXtalk task1("task1","Cross talk correction");
103// // MyClean task2("task2","Hit cleaning");
104// // q.Add(&task1);
105// // q.Add(&task2);
106// //
107// // The sub-tasks will be executed in the order as they are entered.
108// ///////////////////////////////////////////////////////////////////
109//
110// // Perform the conversion and execute subtasks (if any)
111// // on an event-by-event basis
112// q.ExecuteJob();
f67e2651 113//
114// // Select various objects to be added to the output file
115//
f5b75967 116// TFile* ofile=q.GetOutputFile();
117//
118// if (ofile)
119// {
120// ofile->cd(); // Switch to the output file directory
1c9018c6 121//
f5b75967 122// AliObjMatrix* omdb=q.GetOMdbase();
123// if (omdb) omdb->Write();
f67e2651 124//
f5b75967 125// AliDevice* fitdefs=q.GetFitdefs();
126// if (fitdefs) fitdefs->Write();
f67e2651 127//
f5b75967 128// TDatabasePDG* pdg=q.GetPDG();
129// if (pdg) pdg->Write();
f67e2651 130//
f5b75967 131// // Flush additional objects to the output file.
132// // The output file is not explicitly closed here
133// // to allow interactive investigation of the data tree
134// // when this macro is run in an interactive ROOT/CINT session.
135// ofile->Write();
136// }
f67e2651 137//
138//--- Author: Nick van Eijndhoven 11-mar-2005 Utrecht University
139//- Modified: NvE $Date$ Utrecht University
140///////////////////////////////////////////////////////////////////////////
141
142#include "IceF2k.h"
143#include "Riostream.h"
144
145ClassImp(IceF2k) // Class implementation to enable ROOT I/O
146
5481c137 147IceF2k::IceF2k(const char* name,const char* title) : AliJob(name,title)
f67e2651 148{
149// Default constructor.
d0120ca2 150// By default maxevent=-1, split=0, bsize=32000, printfreq=1.
f67e2651 151
d0120ca2 152 fSplit=0;
5481c137 153 fBsize=32000;
154 fMaxevt=-1;
155 fPrintfreq=1;
88b8d522 156 fInfiles=0;
5481c137 157 fOutfile=0;
f67e2651 158
159 fPdg=0;
160 fOmdb=0;
161 fFitdefs=0;
69884331 162 fTrigdefs=0;
97a09735 163 fToffset=0;
164 fMctoffset=0;
ed6cf482 165 fMctracks=3;
f67e2651 166}
167///////////////////////////////////////////////////////////////////////////
168IceF2k::~IceF2k()
169{
170// Default destructor.
5481c137 171
88b8d522 172 if (fInfiles)
173 {
174 delete fInfiles;
175 fInfiles=0;
176 }
177
f67e2651 178 if (fPdg)
179 {
180 delete fPdg;
181 fPdg=0;
182 }
183
184 if (fOmdb)
185 {
186 delete fOmdb;
187 fOmdb=0;
188 }
189
190 if (fFitdefs)
191 {
192 delete fFitdefs;
193 fFitdefs=0;
194 }
69884331 195
196 if (fTrigdefs)
197 {
198 delete fTrigdefs;
199 fTrigdefs=0;
200 }
f67e2651 201}
202///////////////////////////////////////////////////////////////////////////
5481c137 203void IceF2k::SetMaxEvents(Int_t n)
204{
205// Set the maximum number of events to be processed.
206// n=-1 implies processing of the complete input file, which is the default
207// initialisation in the constructor.
208 fMaxevt=n;
209}
210///////////////////////////////////////////////////////////////////////////
211void IceF2k::SetPrintFreq(Int_t f)
212{
213// Set the printfrequency to produce info every f events.
214// f=1 is the default initialisation in the constructor.
64c21700 215 if (f>=0) fPrintfreq=f;
5481c137 216}
217///////////////////////////////////////////////////////////////////////////
218void IceF2k::SetSplitLevel(Int_t split)
219{
220// Set the split level for the ROOT data file.
d0120ca2 221// split=0 is the default initialisation in the constructor.
5481c137 222 if (split>=0) fSplit=split;
223}
224///////////////////////////////////////////////////////////////////////////
225void IceF2k::SetBufferSize(Int_t bsize)
226{
227// Set the buffer size for the ROOT data file.
228// bsize=32000 is the default initialisation in the constructor.
229 if (bsize>=0) fBsize=bsize;
230}
231///////////////////////////////////////////////////////////////////////////
97a09735 232void IceF2k::SetMcToffset(Float_t toffset)
233{
234// Set a user defined time offset for Monte Carlo data.
235// A very frequently (but not always) used value is -19000.
236// See the introductory docs of this class for further details.
237 fMctoffset=toffset;
238}
239///////////////////////////////////////////////////////////////////////////
ed6cf482 240void IceF2k::SelectMcTracks(Int_t mode)
241{
242// User selection of MC tracks to be stored in the event structure.
243//
244// mode = 0 : No MC tracks are stored
245// 1 : Only muon and muon-neutrino MC tracks are stored
246// 2 : All lepton MC tracks are stored
247// 3 : All MC tracks (incl. brems, pairprod etc...) are stored
248//
249// By default mode=3 is set in the constructor of this class.
250
251 if (mode<0 || mode >3) return;
252 fMctracks=mode;
253}
254///////////////////////////////////////////////////////////////////////////
5481c137 255void IceF2k::SetInputFile(TString name)
256{
257// Set the name of the F2K input file.
88b8d522 258// This function has become obsolete but is kept for backward compatibility.
259// The user is advised to use AddInputFile() instead, which allows processing
260// of multiple F2K input files.
261// This function will reset the list of all F2K input files and put the specified
262// filename at the first position.
263// Additional F2K input files can be specified via AddInputFile().
264
265 if (fInfiles) delete fInfiles;
266
267 fInfiles=new TObjArray();
268 fInfiles->SetOwner();
269
270 TObjString* s=new TObjString();
271 s->SetString(name);
272 fInfiles->Add(s);
273}
274///////////////////////////////////////////////////////////////////////////
275void IceF2k::AddInputFile(TString name)
276{
277// Add the name of this F2K input file to the list to be processed.
278
279 if (!fInfiles)
280 {
281 fInfiles=new TObjArray();
282 fInfiles->SetOwner();
283 }
284
285 TObjString* s=new TObjString();
286 s->SetString(name);
287 fInfiles->Add(s);
5481c137 288}
289///////////////////////////////////////////////////////////////////////////
290void IceF2k::SetOutputFile(TFile* ofile)
291{
292// Set the output file for the ROOT data.
f5b75967 293 if (fOutfile) delete fOutfile;
5481c137 294 fOutfile=ofile;
295}
296///////////////////////////////////////////////////////////////////////////
f5b75967 297void IceF2k::SetOutputFile(TString name)
298{
299// Create the output file for the ROOT data.
300 if (fOutfile) delete fOutfile;
301 fOutfile=new TFile(name.Data(),"RECREATE","F2K data in IceEvent structure");
302}
303///////////////////////////////////////////////////////////////////////////
304TFile* IceF2k::GetOutputFile()
305{
306// Provide pointer to the ROOT output file.
307 return fOutfile;
308}
309///////////////////////////////////////////////////////////////////////////
f67e2651 310TDatabasePDG* IceF2k::GetPDG()
311{
312// Provide pointer to the PDG database
313 return fPdg;
314}
315///////////////////////////////////////////////////////////////////////////
316AliObjMatrix* IceF2k::GetOMdbase()
317{
318// Provide pointer to the OM geometry, calib. etc... database
319 return fOmdb;
320}
321///////////////////////////////////////////////////////////////////////////
322AliDevice* IceF2k::GetFitdefs()
323{
324// Provide pointer to the fit definitions
325 return fFitdefs;
326}
327///////////////////////////////////////////////////////////////////////////
69884331 328AliDevice* IceF2k::GetTrigdefs()
329{
330// Provide pointer to the trigger definitions
331 return fTrigdefs;
332}
333///////////////////////////////////////////////////////////////////////////
5481c137 334void IceF2k::Exec(Option_t* opt)
f67e2651 335{
5481c137 336// Job to loop over the specified number of events and convert the
f67e2651 337// F2K data into the IceEvent structure.
5481c137 338// If maxevents<0 (default) all the entries of the input file
f67e2651 339// will be processed.
340// Every "printfreq" events a short event summary will be printed.
341// The default value is printfreq=1.
5481c137 342// The output will be written on a standard output tree named "T".
343//
344// Notes :
345// -------
346// 1) This class is derived from AliJob, allowing a task based processing.
347// After the conversion of an F2K event into an IceEvent structure,
348// the processing of all available sub-tasks (if any) is invoked.
349// This provides an event-by-event (sub)task processing before the
350// final data structures are written out.
351// 2) The main object in this job environment is an IceEvent* pointer.
352
88b8d522 353 if (!fInfiles)
5481c137 354 {
88b8d522 355 cout << " *IceF2k Exec* No data input file(s) specified." << endl;
5481c137 356 return;
357 }
f67e2651 358
88b8d522 359 Int_t ninfiles=fInfiles->GetEntries();
360 if (!ninfiles)
5481c137 361 {
88b8d522 362 cout << " *IceF2k Exec* No data input file(s) specified." << endl;
5481c137 363 return;
364 }
f67e2651 365
1c9018c6 366 TTree* otree=0;
367 if (fOutfile)
5481c137 368 {
1c9018c6 369 otree=new TTree("T","F2K Data converted to IceEvent structures");
370 otree->SetDirectory(fOutfile);
5481c137 371 }
f67e2651 372
5481c137 373 IceEvent* evt=new IceEvent();
f67e2651 374 evt->SetTrackCopy(1);
375 evt->SetDevCopy(1);
376
377 // Branch in the tree for the event structure
1c9018c6 378 if (otree) otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit);
f67e2651 379
380 // Create the particle database and extend it with some F2000 specific definitions
381 if (!fPdg) fPdg=new TDatabasePDG();
382 Double_t me=fPdg->GetParticle(11)->Mass();
383 fPdg->AddParticle("brems" ,"brems" ,0,1,0,0,"none",10001001,0,0);
384 fPdg->AddParticle("deltae" ,"deltae" ,me,1,0,-3,"Lepton",10001002,0,0);
385 fPdg->AddParticle("pairprod","pairprod",0,1,0,0,"none",10001003,0,0);
386 fPdg->AddParticle("nucl_int","nucl_Int",0,1,0,0,"none",10001004,0,0);
387 fPdg->AddParticle("mu_pair" ,"mu_pair" ,0,1,0,0,"none",10001005,0,0);
388 fPdg->AddParticle("hadrons" ,"hadrons" ,0,1,0,0,"none",10001006,0,0);
389 fPdg->AddParticle("fiberlaser","fiberlaser",0,1,0,0,"none",10002100,0,0);
390 fPdg->AddParticle("n2laser" ,"n2laser" ,0,1,0,0,"none",10002101,0,0);
391 fPdg->AddParticle("yaglaser" ,"yaglaser" ,0,1,0,0,"none",10002201,0,0);
392 fPdg->AddParticle("z_primary","z_primary",0,1,0,0,"none",10003000,0,0);
393 fPdg->AddParticle("a_primary","a_primary",0,1,0,0,"none",10003500,0,0);
394
25eefd00 395 // Storage of the used parameters in the IceF2k device
396 AliSignal params;
397 params.SetNameTitle("IceF2k","IceF2k processor parameters");
398 params.SetSlotName("Toffset",1);
399 params.SetSlotName("Mctoffset",2);
400 params.SetSlotName("Mctracks",3);
401
5481c137 402 // Initialise the job working environment
403 SetMainObject(evt);
1c9018c6 404 if (fOutfile)
405 {
406 AddObject(fOutfile);
407 AddObject(otree);
408 }
5481c137 409
88b8d522 410 TString inputfile;
411
5481c137 412 cout << " ***" << endl;
413 cout << " *** Start processing of job " << GetName() << " ***" << endl;
414 cout << " ***" << endl;
88b8d522 415 for (Int_t i=0; i<ninfiles; i++)
416 {
417 TObjString* sx=(TObjString*)fInfiles->At(i);
418 if (!sx) continue;
419 inputfile=sx->GetString();
420 cout << " F2K input file : " << inputfile.Data() << endl;
421 }
5481c137 422 cout << " Maximum number of events to be processed : " << fMaxevt << endl;
423 cout << " Print frequency : " << fPrintfreq << endl;
1c9018c6 424 if (fOutfile)
425 {
426 cout << " ROOT output file : " << fOutfile->GetName() << endl;
427 cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
428 }
5481c137 429
430 ListEnvironment();
88b8d522 431
0cfe76b5 432 // Set DAQ device info
433 AliDevice daq;
434 daq.SetName("Daq");
435 daq.SetSlotName("Muon",1);
436 daq.SetSignal(1,1);
437
5481c137 438 Int_t nevt=0;
88b8d522 439 for (Int_t ifile=0; ifile<ninfiles; ifile++)
f67e2651 440 {
88b8d522 441 TObjString* sx=(TObjString*)fInfiles->At(ifile);
442 if (!sx) continue;
f67e2651 443
88b8d522 444 inputfile=sx->GetString();
445 if (inputfile=="") continue;
f67e2651 446
88b8d522 447 // Open the input file in the default ascii format (autodetection) for reading
448 fInput=rdmc_mcopen(inputfile.Data(),"r",RDMC_DEFAULT_ASCII_F);
f67e2651 449
88b8d522 450 if (!fInput)
451 {
452 cout << " *IceF2k Exec* No input file found with name : " << inputfile.Data() << endl;
453 continue;
454 }
69884331 455
88b8d522 456 // Initialise the event structure
457 rdmc_init_mevt(&fEvent);
f67e2651 458
88b8d522 459 // Read the file header information
460 rdmc_rarr(fInput,&fHeader);
f67e2651 461
88b8d522 462 // Fill the database with geometry, calib. etc... parameters
463 // for all the devices
464 FillOMdbase();
f67e2651 465
88b8d522 466 // Set the fit definitions according to the F2000 header info
467 SetFitdefs();
5481c137 468
88b8d522 469 // Set the trigger definitions according to the F2000 header info
470 SetTrigdefs();
471
472 while (!rdmc_revt(fInput,&fHeader,&fEvent))
64c21700 473 {
88b8d522 474 if (fMaxevt>-1 && nevt>=fMaxevt) break;
475
476 // Reset the complete Event structure
477 evt->Reset();
478
479 evt->SetRunNumber(fEvent.nrun);
480 evt->SetEventNumber(fEvent.enr);
481 evt->SetMJD(fEvent.mjd,fEvent.secs,fEvent.nsecs);
482
0cfe76b5 483 evt->AddDevice(daq);
484
97a09735 485 // Take trigger offset into account which might have been
486 // introduced during the filtering process.
487 // For simulated data this will be treated separately in PutMcTracks().
488 fToffset=fEvent.t_offset;
489
88b8d522 490 PutTrigger();
491
492 PutMcTracks();
493
494 PutRecoTracks();
f67e2651 495
88b8d522 496 PutHits();
f67e2651 497
25eefd00 498 // Enter the IceF2k processor parameters into the event structure
499 params.SetSignal(fToffset,1);
500 params.SetSignal(fMctoffset,2);
501 params.SetSignal(fMctracks,3);
502 evt->AddDevice(params);
503
88b8d522 504 // Invoke all available sub-tasks (if any)
505 CleanTasks();
506 ExecuteTasks(opt);
507
508 if (fPrintfreq)
509 {
510 if (!(nevt%fPrintfreq)) evt->HeaderData();
511 }
512
513 // Write the complete structure to the output Tree
514 if (otree) otree->Fill();
515
516 // Update event counter
517 nevt++;
518 }
519 if (fMaxevt>-1 && nevt>=fMaxevt) break;
5481c137 520 }
1c9018c6 521
f5b75967 522 // Flush possible memory resident data to the output file
523 if (fOutfile) fOutfile->Write();
524
1c9018c6 525 // Remove the IceEvent object from the environment
526 // and delete it as well
527 if (evt)
528 {
529 RemoveObject(evt);
530 delete evt;
531 }
f67e2651 532}
533///////////////////////////////////////////////////////////////////////////
534void IceF2k::FillOMdbase()
535{
536// Fill the database with geometry, calib. etc... parameters
537// for all the devices.
538
88b8d522 539 if (fHeader.nch<=0)
540 {
541 if (fOmdb)
542 {
543 delete fOmdb;
544 fOmdb=0;
545 }
546 return;
547 }
f67e2651 548
64c21700 549 Int_t adccal=fHeader.is_calib.adc;
550 Int_t tdccal=fHeader.is_calib.tdc;
551 Int_t totcal=fHeader.is_calib.tot;
64c21700 552
553 TF1 fadccal("fadccal","(x-[1])*[0]");
554 TF1 fadcdecal("fadcdecal","(x/[0])+[1]");
216d1d91 555 fadccal.SetParName(0,"BETA-ADC");
556 fadccal.SetParName(1,"PED-ADC");
557 fadcdecal.SetParName(0,"BETA-ADC");
558 fadcdecal.SetParName(1,"PED-ADC");
559
64c21700 560 TF1 ftdccal("ftdccal","(x*[0])-[1]-([0]-1.)*32767.-[2]/sqrt([3])");
561 TF1 ftdcdecal("ftdcdecal","(x+([0]-1.)*32767.+[1]+[2]/sqrt([3]))/[0]");
216d1d91 562 ftdccal.SetParName(0,"BETA-TDC");
563 ftdccal.SetParName(1,"T0");
564 ftdccal.SetParName(2,"ALPHA-TDC");
565 ftdccal.SetParName(3,"ADC-SLEW");
566 ftdcdecal.SetParName(0,"BETA-TDC");
567 ftdcdecal.SetParName(1,"T0");
568 ftdcdecal.SetParName(2,"ALPHA-TDC");
569 ftdcdecal.SetParName(3,"ADC-SLEW");
570
64c21700 571 TF1 ftotcal("ftotcal","x*[0]");
572 TF1 ftotdecal("ftotdecal","x/[0]");
216d1d91 573 ftotcal.SetParName(0,"BETA-TOT");
574 ftotdecal.SetParName(0,"BETA-TOT");
64c21700 575
f67e2651 576 if (fOmdb)
577 {
578 fOmdb->Reset();
579 }
580 else
581 {
582 fOmdb=new AliObjMatrix();
583 fOmdb->SetNameTitle("OMDBASE","The OM geometry, calib. etc... database");
584 fOmdb->SetOwner();
585 }
586
587 IceAOM* dev=0;
588 Double_t pos[3]={0,0,0};
589 for (Int_t i=0; i<fHeader.nch; i++)
590 {
591 dev=new IceAOM();
592 dev->SetUniqueID(i+1);
5ae71069 593 // Slots to hold the various (de)calibration functions
64c21700 594 dev->SetSlotName("ADC",1);
595 dev->SetSlotName("LE",2);
596 dev->SetSlotName("TOT",3);
5ae71069 597 // Slots to hold hardware parameters
64c21700 598 dev->SetSlotName("TYPE",4);
599 dev->SetSlotName("ORIENT",5);
600 dev->SetSlotName("THRESH",6);
601 dev->SetSlotName("SENSIT",7);
aa0a2fa7 602 dev->SetSlotName("READOUT",8); // 0=unknown 1=electrical 2=optical 3=digital
f67e2651 603
604 pos[0]=fHeader.x[i];
605 pos[1]=fHeader.y[i];
606 pos[2]=fHeader.z[i];
607 dev->SetPosition(pos,"car");
64c21700 608
609 fadccal.SetParameter(0,fHeader.cal[i].beta_a);
610 fadccal.SetParameter(1,fHeader.cal[i].ped);
611 fadcdecal.SetParameter(0,fHeader.cal[i].beta_a);
612 if (!fHeader.cal[i].beta_a) fadcdecal.SetParameter(0,1);
613 fadcdecal.SetParameter(1,fHeader.cal[i].ped);
614
615 ftdccal.SetParameter(0,fHeader.cal[i].beta_t);
616 ftdccal.SetParameter(1,fHeader.cal[i].t_0);
617 ftdccal.SetParameter(2,fHeader.cal[i].alpha_t);
618 ftdccal.SetParameter(3,1.e20);
619 ftdcdecal.SetParameter(0,fHeader.cal[i].beta_t);
620 if (!fHeader.cal[i].beta_t) ftdcdecal.SetParameter(0,1);
621 ftdcdecal.SetParameter(1,fHeader.cal[i].t_0);
622 ftdcdecal.SetParameter(2,fHeader.cal[i].alpha_t);
623 ftdcdecal.SetParameter(3,1.e20);
624
625 ftotcal.SetParameter(0,fHeader.cal[i].beta_tot);
626 ftotdecal.SetParameter(0,fHeader.cal[i].beta_tot);
627 if (!fHeader.cal[i].beta_tot) ftotdecal.SetParameter(0,1);
628
629 if (adccal)
630 {
631 dev->SetDecalFunction(&fadcdecal,1);
632 }
633 else
634 {
635 dev->SetCalFunction(&fadccal,1);
636 }
637
638 if (tdccal)
639 {
640 dev->SetDecalFunction(&ftdcdecal,2);
641 }
642 else
643 {
644 dev->SetCalFunction(&ftdccal,2);
645 }
646
647 if (totcal)
648 {
649 dev->SetDecalFunction(&ftotdecal,3);
650 }
651 else
652 {
653 dev->SetCalFunction(&ftotcal,3);
654 }
655
656 dev->SetSignal(fHeader.type[i],4);
657 dev->SetSignal((Float_t)fHeader.costh[i],5);
658 dev->SetSignal(fHeader.thresh[i],6);
659 dev->SetSignal(fHeader.sensit[i],7);
aa0a2fa7 660 dev->SetSignal(0.,8);
64c21700 661
f67e2651 662 fOmdb->EnterObject(i+1,1,dev);
663 }
664}
665///////////////////////////////////////////////////////////////////////////
666void IceF2k::SetFitdefs()
667{
668// Obtain the names of the variables for each fit procedure from the
669// f2000 header. Each different fit procedure is then stored as a separate
69884331 670// "hit" of an AliDevice object and the various fit variables are stored
671// as separate signal slots of the corresponding "hit".
f67e2651 672// Via the GetFitdefs() memberfunction this AliDevice object can be
673// retrieved and stored in the ROOT output file if wanted.
674// The name of the object is FitDefinitions and the stored data can be
675// inspected via the AliDevice::Data() memberfunction and looks as follows :
676//
677// *AliDevice::Data* Id :0 Name : FitDefinitions
678// Position Vector in car coordinates : 0 0 0
679// Err. in car coordinates : 0 0 0
680// The following 8 hits are registered :
681// *AliSignal::Data* Id :0
682// Position Vector in car coordinates : 0 0 0
683// Err. in car coordinates : 0 0 0
684// Owned by device : AliDevice Name : FitDefinitions
69884331 685// Slot : 1 Signal value : 0 name : id
686// Slot : 2 Signal value : 0 name : rchi2
687// Slot : 3 Signal value : 0 name : prob
688// Slot : 4 Signal value : 0 name : sigth
689// Slot : 5 Signal value : 0 name : covmin
690// Slot : 6 Signal value : 0 name : covmax
691// Slot : 7 Signal value : 0 name : cutflag
692// Slot : 8 Signal value : 0 name : chi2
f67e2651 693// *AliSignal::Data* Id :1
694// Position Vector in car coordinates : 0 0 0
695// Err. in car coordinates : 0 0 0
696// Owned by device : AliDevice Name : FitDefinitions
69884331 697// Slot : 1 Signal value : 0 name : id
698// Slot : 2 Signal value : 0 name : rchi2
699// Slot : 3 Signal value : 0 name : prob
f67e2651 700// etc....
701//
702// This memberfunction is based on the original idea/code by Adam Bouchta.
703
88b8d522 704 if (fHeader.n_fit<=0)
705 {
706 if (fFitdefs)
707 {
708 delete fFitdefs;
709 fFitdefs=0;
710 }
711 return;
712 }
f67e2651 713
714 if (fFitdefs)
715 {
716 fFitdefs->Reset(1);
717 }
718 else
719 {
720 fFitdefs=new AliDevice();
721 }
722
723 fFitdefs->SetName("FitDefinitions");
724 fFitdefs->SetHitCopy (1);
725
726 AliSignal s;
727 s.Reset();
728
729 for (Int_t i=0; i<fHeader.n_fit; i++)
730 {
731 s.SetUniqueID(fHeader.def_fit[i].id);
69884331 732 s.SetName(TString(fHeader.def_fit[i].tag));
f67e2651 733
734 for (Int_t j=0; j<fHeader.def_fit[i].nwords; j++)
735 {
736 s.SetSlotName(TString(fHeader.def_fit[i].words[j]),j+1);
69884331 737 s.SetSignal(0,j+1);
f67e2651 738 }
739
740 fFitdefs->AddHit(s);
741 s.Reset(1);
742 }
743}
744///////////////////////////////////////////////////////////////////////////
69884331 745void IceF2k::SetTrigdefs()
746{
747// Obtain the names of the variables for each trigger procedure from the
748// f2000 header. Each different trigger procedure is then stored as a separate
749// "hit" of an AliDevice object and the various trigger variables are stored
750// as separate signal slots of the corresponding "hit".
751// Via the GetFitdefs() memberfunction this AliDevice object can be
752// retrieved and stored in the ROOT output file if wanted.
753// The name of the object is TrigDefinitions and the stored data can be
754// inspected via the AliDevice::Data() memberfunction and looks as follows :
755//
756// *AliDevice::Data* Id : 0 Name : TrigDefinitions
757// Position Vector in car (rad) coordinates : 0 0 0
758// Err. in car (rad) coordinates : 0 0 0
759// The following 9 hits are registered :
760// *AliSignal::Data* Id : 1 Name : main
761// Position Vector in car (rad) coordinates : 0 0 0
762// Err. in car (rad) coordinates : 0 0 0
763// Owned by device : AliDevice Id : 0 Name : TrigDefinitions
764// Slot : 1 Signal value : 0 name : trig_pulse_le
765// Slot : 2 Signal value : 0 name : trig_pulse_tot
766// Slot : 3 Signal value : 0 name : regi_flag
767// *AliSignal::Data* Id : 2 Name : amaa
768// Position Vector in car (rad) coordinates : 0 0 0
769// Err. in car (rad) coordinates : 0 0 0
770// Owned by device : AliDevice Id : 0 Name : TrigDefinitions
771// Slot : 1 Signal value : 0 name : trig_pulse_le
772// Slot : 2 Signal value : 0 name : trig_pulse_tot
773// Slot : 3 Signal value : 0 name : regi_flag
774// *AliSignal::Data* Id : 3 Name : amab10
775// Position Vector in car (rad) coordinates : 0 0 0
776// Err. in car (rad) coordinates : 0 0 0
777// Owned by device : AliDevice Id : 0 Name : TrigDefinitions
778// Slot : 1 Signal value : 0 name : trig_pulse_le
779// Slot : 2 Signal value : 0 name : trig_pulse_tot
780// Slot : 3 Signal value : 0 name : regi_flag
781// etc....
782
88b8d522 783 if (fHeader.n_trigger<=0)
784 {
785 if (fTrigdefs)
786 {
787 delete fTrigdefs;
788 fTrigdefs=0;
789 }
790 return;
791 }
69884331 792
793 if (fTrigdefs)
794 {
795 fTrigdefs->Reset(1);
796 }
797 else
798 {
799 fTrigdefs=new AliDevice();
800 }
801
802 fTrigdefs->SetName("TrigDefinitions");
803 fTrigdefs->SetHitCopy (1);
804
805 AliSignal s;
806 s.Reset();
807
808 for (Int_t i=0; i<fHeader.n_trigger; i++)
809 {
810 s.SetUniqueID(fHeader.def_trig[i].id);
811 s.SetName(TString(fHeader.def_trig[i].tag));
812
813 for (Int_t j=0; j<fHeader.def_trig[i].nwords; j++)
814 {
815 s.SetSlotName(TString(fHeader.def_trig[i].words[j]),j+1);
816 s.SetSignal(0,j+1);
817 }
818
819 fTrigdefs->AddHit(s);
820 s.Reset(1);
821 }
822}
823///////////////////////////////////////////////////////////////////////////
5481c137 824void IceF2k::PutMcTracks()
f67e2651 825{
826// Get the MC tracks from the F2000 file into the IcePack structure.
827// Note : MC tracks are given negative track id's in the event structure.
828// This memberfunction is based on the original code by Adam Bouchta.
829
5481c137 830 IceEvent* evt=(IceEvent*)GetMainObject();
f67e2651 831 if (!evt || fEvent.ntrack<=0) return;
832
97a09735 833 // User defined trigger offset in case of simulated data.
834 // The offset in the F2K file is meant to put the primary interaction
835 // well ahead of the detector trigger.
836 // See the introductory docs of this IceF2k class for further details.
837 fToffset=fMctoffset;
838
ed6cf482 839 if (!fMctracks) return;
840
f67e2651 841 // Loop over all the tracks and add them to the current event
842 AliTrack t;
843 Double_t vec[3];
844 AliPosition r;
845 Ali3Vector p;
846 Int_t tid=0;
847 Int_t idpdg=0;
848 Int_t idf2k=0;
849 for (Int_t i=0; i<fEvent.ntrack; i++)
850 {
851 t.Reset ();
852
853 // Beginpoint of the track
854 vec[0]=fEvent.gen[i].x;
855 vec[1]=fEvent.gen[i].y;
856 vec[2]=fEvent.gen[i].z;
857 r.SetPosition(vec,"car");
858 t.SetBeginPoint(r);
859
860 // Endpoint of the track
861 vec[0]+=fEvent.gen[i].length*fEvent.gen[i].px;
862 vec[1]+=fEvent.gen[i].length*fEvent.gen[i].py;
863 vec[2]+=fEvent.gen[i].length*fEvent.gen[i].pz;
864 r.SetPosition(vec,"car");
865 t.SetEndPoint(r);
866
867 // Momentum in GeV/c
868 vec[0]=fEvent.gen[i].e*fEvent.gen[i].px*1e-3;
869 vec[1]=fEvent.gen[i].e*fEvent.gen[i].py*1e-3;
870 vec[2]=fEvent.gen[i].e*fEvent.gen[i].pz*1e-3;
871 p.SetVector (vec,"car");
872 t.Set3Momentum(p);
873
874 // MC tracks are indicated by negative track id's
875 tid=fEvent.gen[i].tag;
876 t.SetId(-abs(tid));
877
878 idf2k=fEvent.gen[i].id;
879 idpdg=0;
880 if (idf2k>1000)
881 {
882 idpdg=idf2k+10000000;
883 }
884 else if (idf2k <= 48)
885 {
886 idpdg=fPdg->ConvertGeant3ToPdg(idf2k);
887 }
888 else
889 {
890 if (idf2k==201) idpdg=12;
891 if (idf2k==202) idpdg=14;
892 if (idf2k==203) idpdg=16;
893 if (idf2k==204) idpdg=-12;
894 if (idf2k==205) idpdg=-14;
895 if (idf2k==206) idpdg=-16;
896 }
897
ed6cf482 898 // Check for the user selected MC track storage
899 if (fMctracks==1) // Store only muon and muon-neutrino tracks
900 {
901 if (abs(idpdg)!=13 && abs(idpdg)!=14) continue;
902 }
903 else if (fMctracks==2) // Store all lepton tracks
904 {
905 if (abs(idpdg)<11 || abs(idpdg)>16) continue;
906 }
907
f67e2651 908 t.SetParticleCode(idpdg);
909 t.SetName(fPdg->GetParticle(idpdg)->GetName());
910 t.SetTitle("MC track");
911 t.SetMass(fPdg->GetParticle(idpdg)->Mass());
912 t.SetCharge(fPdg->GetParticle(idpdg)->Charge()/3.);
913
914 evt->AddTrack(t);
915 }
916
917 // Create the pointers to each particle's parent particle.
918 Int_t txid=0;
919 Int_t parid=0;
920 for (Int_t itk=1; itk<=evt->GetNtracks (); itk++)
921 {
922 AliTrack* tx=evt->GetTrack(itk);
923
924 if (!tx) continue;
925
926 txid=tx->GetId();
927
928 parid=-1;
929 for (Int_t j=0; j<fEvent.ntrack; j++)
930 {
931 tid=fEvent.gen[j].tag;
932 if (-abs(tid) == txid) parid=fEvent.gen[j].parent;
933 }
934
935 if (parid<0) continue;
936
937 AliTrack* tpar=evt->GetIdTrack(-abs(parid));
938
939 if (!tpar) continue;
940
941 tx->SetParentTrack(tpar);
942 }
943}
944///////////////////////////////////////////////////////////////////////////
5481c137 945void IceF2k::PutRecoTracks()
f67e2651 946{
947// Get the reconstructed tracks from the F2000 file into the IcePack structure.
948// Note : Reco tracks are given positive track id's in the event structure.
949// This memberfunction is based on the original code by Adam Bouchta.
950
5481c137 951 IceEvent* evt=(IceEvent*)GetMainObject();
f67e2651 952 if (!evt || fEvent.nfit<=0) return;
953
954 // Loop over all the tracks and add them to the current event
955 AliTrack t;
956 Double_t vec[3];
957 AliPosition r;
958 Ali3Vector p;
959 Int_t tid=0;
960 Int_t idpdg=0;
961 Int_t idf2k=0;
962 for (Int_t i=0; i<fEvent.nfit; i++)
963 {
964 t.Reset ();
965
966 // Beginpoint of the track
967 vec[0]=fEvent.rec[i].x;
968 vec[1]=fEvent.rec[i].y;
969 vec[2]=fEvent.rec[i].z;
970 r.SetPosition(vec,"car");
971 t.SetBeginPoint(r);
972
973 // Endpoint of the track
974 vec[0]+=fEvent.rec[i].length*fEvent.rec[i].px;
975 vec[1]+=fEvent.rec[i].length*fEvent.rec[i].py;
976 vec[2]+=fEvent.rec[i].length*fEvent.rec[i].pz;
977 r.SetPosition(vec,"car");
978 t.SetEndPoint(r);
979
980 // Momentum in GeV/c
981 if (fEvent.rec[i].e > 0)
982 {
983 vec[0]=fEvent.rec[i].e*fEvent.rec[i].px*1e-3;
984 vec[1]=fEvent.rec[i].e*fEvent.rec[i].py*1e-3;
985 vec[2]=fEvent.rec[i].e*fEvent.rec[i].pz*1e-3;
986 }
987 else // Give the track a nominal momentum of 1 GeV/c
988 {
989 vec[0]=fEvent.rec[i].px;
990 vec[1]=fEvent.rec[i].py;
991 vec[2]=fEvent.rec[i].pz;
992 }
993 p.SetVector (vec,"car");
994 t.Set3Momentum(p);
995
996 // Use the fit number as track id
997 tid=fEvent.rec[i].tag;
998 t.SetId(abs(tid));
999
1000 idf2k=fEvent.rec[i].id;
1001 idpdg=0;
1002 if (idf2k>1000)
1003 {
1004 idpdg=idf2k+10000000;
1005 }
1006 else if (idf2k <= 48)
1007 {
1008 idpdg=fPdg->ConvertGeant3ToPdg(idf2k);
1009 }
1010 else
1011 {
1012 if (idf2k==201) idpdg=12;
1013 if (idf2k==202) idpdg=14;
1014 if (idf2k==203) idpdg=16;
1015 if (idf2k==204) idpdg=-12;
1016 if (idf2k==205) idpdg=-14;
1017 if (idf2k==206) idpdg=-16;
1018 }
1019
1020 t.SetParticleCode(idpdg);
c29371c1 1021 t.SetNameTitle("Sieglinde","RECO track");
f67e2651 1022 t.SetMass(fPdg->GetParticle(idpdg)->Mass());
1023 t.SetCharge(fPdg->GetParticle(idpdg)->Charge()/3.);
1024
1025 // Retrieve the various fit parameters for this track
1026 AliSignal* fitdata=fFitdefs->GetIdHit(i);
1027 for (Int_t jval=0; jval<fEvent.fresult[i].nval; jval++)
1028 {
1029 fitdata->SetSignal(fEvent.fresult[i].val[jval],jval+1);
1030 }
1031
1032 // Store the various fit parameters for this track
1033 t.SetFitDetails(fitdata);
1034
1035 // Store the various reco tracks as track hypotheses.
1036 // A copy of the first reco track is entered as a new track instance
1037 // into the event and all reco tracks (incl. the first one) are
1038 // stored as hypotheses linked to this new reco track.
1039 if (i==0)
1040 {
1041 evt->AddTrack(t);
1042 AliTrack* tx=evt->GetTrack(evt->GetNtracks());
1043 Int_t nrec=evt->GetNtracks(1);
1044 tx->SetId(nrec+1);
1045 }
1046 AliTrack* tx=evt->GetTrack(evt->GetNtracks());
1047 if (tx) tx->AddTrackHypothesis(t);
1048 }
1049}
1050///////////////////////////////////////////////////////////////////////////
5481c137 1051void IceF2k::PutHits()
f67e2651 1052{
1053// Get the hit and waveform info from the F2000 file into the IcePack structure.
1054// This memberfunction is based on the original code by Adam Bouchta.
1055
5481c137 1056 IceEvent* evt=(IceEvent*)GetMainObject();
f67e2651 1057 if (!evt) return;
1058
1059 // Loop over all the hits and add them to the current event
1060 IceAOM om;
1061 AliSignal s;
1062 s.SetSlotName("ADC",1);
1063 s.SetSlotName("LE",2);
1064 s.SetSlotName("TOT",3);
1065 Int_t chan=0;
1066 Int_t maxchan=800;
1067 if (fOmdb) maxchan=fHeader.nch;
1068 IceAOM* omx=0;
1069 AliSignal* sx=0;
1070 Int_t tid=0;
1071 AliTrack* tx=0;
64c21700 1072 Float_t adc=0;
1fba1314 1073 Float_t adcfirst=0; // Adc value of the first hit of an OM
f67e2651 1074 for (Int_t i=0; i<fEvent.nhits; i++)
1075 {
1076 chan=fEvent.h[i].ch+1;
1077 if (chan>maxchan) continue; // Channels 9001, 9002 etc are trigger channels
1078
1079 // Get corresponding device from the current event structure
1080 omx=(IceAOM*)evt->GetIdDevice(chan);
1081 if (!omx)
1082 {
1083 if (fOmdb)
1084 {
1085 omx=(IceAOM*)fOmdb->GetObject(chan,1);
1086 evt->AddDevice(omx);
1087 }
1088 else
1089 {
1090 om.Reset(1);
1091 om.SetUniqueID(chan);
1092 evt->AddDevice(om);
1093 }
1094 omx=(IceAOM*)evt->GetIdDevice(chan);
1095 }
1096
1097 if (!omx) continue;
1098
1fba1314 1099 adc=fEvent.h[i].amp;
1100
1101 // Multiple hits in the same OM with the same ADC value
1102 // are indicated by "*" in the F2K file.
1103 // This corresponds to a value of -2 in the data structure.
1104 if (int(adc) == -2)
1105 {
1106 adc=adcfirst;
1107 }
1108 else
1109 {
1110 adcfirst=adc;
1111 }
f67e2651 1112 s.Reset();
1113 s.SetUniqueID(fEvent.h[i].id);
1fba1314 1114 s.SetSignal(adc,1);
97a09735 1115 s.SetSignal((fEvent.h[i].t-fToffset),2);
f67e2651 1116 s.SetSignal(fEvent.h[i].tot,3);
1117
1118 omx->AddHit(s);
1119
1120 sx=omx->GetHit(omx->GetNhits());
1121 if (!sx) continue;
1122
64c21700 1123 // ADC dependent TDC (de)calibration function for this hit
1124 TF1* fcal=omx->GetCalFunction("LE");
1125 TF1* fdecal=omx->GetDecalFunction("LE");
1126 if (fcal) sx->SetCalFunction(fcal,2);
1127 if (fdecal) sx->SetDecalFunction(fdecal,2);
1128 fcal=sx->GetCalFunction(2);
1129 fdecal=sx->GetDecalFunction(2);
1130 adc=sx->GetSignal(1,-4);
1131 if (adc>0)
1132 {
1133 if (fcal) fcal->SetParameter(3,adc);
1134 if (fdecal) fdecal->SetParameter(3,adc);
1135 }
1136 else
1137 {
a4b77ddf 1138 if (fcal) fcal->SetParameter(3,1.e20);
1139 if (fdecal) fdecal->SetParameter(3,1.e20);
64c21700 1140 }
1141
f67e2651 1142 // Bi-directional link between this hit and the track that caused the ADC value.
1143 // This F2K info is probably only present for MC tracks.
1144 tid=fEvent.h[i].ma;
1145 if (tid > 0)
1146 {
1147 tx=evt->GetIdTrack(tid); // Reco tracks
1148 if (!tx) tx=evt->GetIdTrack(-tid); // MC tracks
d0120ca2 1149 if (tx) sx->AddTrack(*tx);
f67e2651 1150 }
1151 else
1152 {
12c7b122 1153 if (tid == -2) sx->SetNameTitle("N","Noise");
1154 if (tid == -3) sx->SetNameTitle("A","Afterpulse");
f67e2651 1155 }
1156 }
1157
1158 // Loop over all the waveforms and add the histo(s) to the corresponding OM's
1159 TH1F histo;
1160 Int_t nbins=0;
1161 Float_t xlow=0;
1162 Float_t xup=0;
1163 TString hname;
1164 for (Int_t iwf=0; iwf<fEvent.nwf; iwf++)
1165 {
1166 chan=fEvent.wf[iwf].om;
1167 if (chan<=0 || chan>maxchan) continue; // Skip trigger channels
1168
1169 // Get corresponding device from the current event structure
1170 omx=(IceAOM*)evt->GetIdDevice(chan);
1171 if (!omx)
1172 {
1173 if (fOmdb)
1174 {
1175 omx=(IceAOM*)fOmdb->GetObject(chan,1);
1176 evt->AddDevice(omx);
1177 }
1178 else
1179 {
1180 om.Reset(1);
1181 om.SetUniqueID(chan);
1182 evt->AddDevice(om);
1183 }
1184 omx=(IceAOM*)evt->GetIdDevice(chan);
1185 }
1186
1187 if (!omx) continue;
1188
5ae71069 1189 hname="BASELINE-WF";
1190 hname+=omx->GetNwaveforms()+1;
1191 omx->AddNamedSlot(hname);
1192 omx->SetSignal(fEvent.wf[iwf].baseline,hname);
f67e2651 1193
1194 // Fill the waveform histogram
1195 hname="OM";
1196 hname+=chan;
1197 hname+="-WF";
1198 hname+=omx->GetNwaveforms()+1;
1199
1200 histo.Reset();
1201 histo.SetName(hname.Data());
1202 nbins=fEvent.wf[iwf].ndigi;
1203 xlow=fEvent.wf[iwf].t_start;
1204 xup=xlow+float(nbins)*fEvent.wf[iwf].t_bin;
1205 histo.SetBins(nbins,xlow,xup);
1206
1207 for (Int_t jbin=1; jbin<=fEvent.wf[iwf].ndigi; jbin++)
1208 {
5ae71069 1209 histo.SetBinContent(jbin,fEvent.wf[iwf].baseline-fEvent.wf[iwf].digi[jbin-1]);
f67e2651 1210 }
1211
1212 omx->SetWaveform(&histo,omx->GetNwaveforms()+1);
1213 }
1214
1215 // Set bi-directional links between hits and reco track hypotheses.
1216 // Note : Reco tracks are recognised by their positive id.
1217 Int_t hid=0;
1218 TObjArray* rectracks=evt->GetTracks(1);
1219 for (Int_t jtk=0; jtk<rectracks->GetEntries(); jtk++)
1220 {
1221 tx=(AliTrack*)rectracks->At(jtk);
1222 if (!tx) continue;
1223
1224 for (Int_t jhyp=1; jhyp<=tx->GetNhypotheses(); jhyp++)
1225 {
1226 AliTrack* hypx=tx->GetTrackHypothesis(jhyp);
1227 if (!hypx) continue;
1228
1229 // Loop over all combinations of F2K fits and used OM hits
1230 for (Int_t k=0; k<fEvent.nfit_uses; k++)
1231 {
1232 if (fEvent.fit_uses[k].useid != hypx->GetId()) continue;
1233 hid=fEvent.fit_uses[k].hitid;
1234 sx=evt->GetIdHit(hid,"IceAOM");
d0120ca2 1235 if (sx) sx->AddTrack(*hypx);
f67e2651 1236 }
1237 }
1238 }
1239}
1240///////////////////////////////////////////////////////////////////////////
69884331 1241void IceF2k::PutTrigger()
1242{
1243// Get the trigger info from the F2000 file into the IcePack structure.
1244
1245 if (!fTrigdefs) return;
1246
1247 IceEvent* evt=(IceEvent*)GetMainObject();
1248 if (!evt || fEvent.ntrig<=0) return;
1249
1250 AliDevice trig;
1251 trig.SetNameTitle("Trigger","Amanda/IceCube event triggers");
1252 AliSignal s;
1253 TString trigname;
1254 TString slotname;
1255 Int_t id=0;
1256 Int_t nval=0;
1257 for (Int_t i=0; i<fEvent.ntrig; i++)
1258 {
1259 id=fEvent.ptrig[i].id;
1260 nval=fEvent.ptrig[i].nval;
1261 if (!nval) continue;
1262 AliSignal* tdef=fTrigdefs->GetIdHit(id+1);
1263 if (!tdef) continue;
1264 trigname=tdef->GetName();
1265 s.Reset(1);
1266 s.SetName(trigname);
1267 s.SetUniqueID(id+1);
1268 for (Int_t jval=0; jval<fEvent.ptrig[i].nval; jval++)
1269 {
1270 slotname=tdef->GetSlotName(jval+1);
1271 s.SetSlotName(slotname,jval+1);
1272 s.SetSignal(fEvent.ptrig[i].val[jval],jval+1);
1273 }
1274 trig.AddHit(s);
1275 }
1276
1277 // Store the trigger data into the IceEvent structure
1278 evt->AddDevice(trig);
1279}
1280///////////////////////////////////////////////////////////////////////////