1 /**************************************************************************
2 * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line 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. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /** @file AliFMDInput.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:42:40 2006
19 @brief FMD utility classes for reading FMD data
21 //___________________________________________________________________
23 // The classes defined here, are utility classes for reading in data
24 // for the FMD. They are put in a seperate library to not polute the
25 // normal libraries. The classes are intended to be used as base
26 // classes for customized class that do some sort of analysis on the
27 // various types of data produced by the FMD.
29 // Latest changes by Christian Holm Christensen
31 #include "AliFMDInput.h" // ALIFMDHIT_H
32 #include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
33 #include "AliLoader.h" // ALILOADER_H
34 #include "AliRunLoader.h" // ALIRUNLOADER_H
35 #include "AliRun.h" // ALIRUN_H
36 #include "AliStack.h" // ALISTACK_H
37 #include "AliRawReaderFile.h" // ALIRAWREADERFILE_H
38 #include "AliFMD.h" // ALIFMD_H
39 #include "AliFMDHit.h" // ALIFMDHIT_H
40 #include "AliFMDDigit.h" // ALIFMDDigit_H
41 #include "AliFMDSDigit.h" // ALIFMDDigit_H
42 #include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
43 #include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
45 #include <AliESDFMD.h>
46 #include <AliCDBManager.h>
47 #include <AliCDBEntry.h>
48 #include <AliAlignObjAngles.h>
49 #include <TTree.h> // ROOT_TTree
50 #include <TChain.h> // ROOT_TChain
51 #include <TParticle.h> // ROOT_TParticle
52 #include <TString.h> // ROOT_TString
53 #include <TDatabasePDG.h> // ROOT_TDatabasePDG
54 #include <TMath.h> // ROOT_TMath
55 #include <TGeoManager.h> // ROOT_TGeoManager
56 #include <TSystemDirectory.h> // ROOT_TSystemDirectory
57 #include <Riostream.h> // ROOT_Riostream
58 #include <TFile.h> // ROOT_TFile
59 #include <TStreamerInfo.h>
60 //____________________________________________________________________
63 ; // This is here to keep Emacs for indenting the next line
67 //____________________________________________________________________
68 AliFMDInput::AliFMDInput()
95 // Constructor of an FMD input object. Specify what data to read in
96 // using the AddLoad member function. Sub-classes should at a
97 // minimum overload the member function Event. A full job can be
98 // executed using the member function Run.
103 //____________________________________________________________________
104 AliFMDInput::AliFMDInput(const char* gAliceFile)
105 : fGAliceFile(gAliceFile),
131 // Constructor of an FMD input object. Specify what data to read in
132 // using the AddLoad member function. Sub-classes should at a
133 // minimum overload the member function Event. A full job can be
134 // executed using the member function Run.
137 //____________________________________________________________________
139 AliFMDInput::NEvents() const
141 // Get number of events
142 if (fTreeE) return fTreeE->GetEntries();
146 //____________________________________________________________________
150 // Initialize the object. Get the needed loaders, and such.
152 // Check if we have been initialized
154 AliWarning("Already initialized");
157 if (fGAliceFile.IsNull()) fGAliceFile = "galice.root";
159 fLoader = AliRunLoader::Open(fGAliceFile.Data(), "Alice", "read");
161 AliError(Form("Coulnd't read the file %s", fGAliceFile.Data()));
166 if (fLoader->LoadgAlice()) return kFALSE;
167 fRun = fLoader->GetAliRun();
170 fFMD = static_cast<AliFMD*>(fRun->GetDetector("FMD"));
172 AliError("Failed to get detector FMD from loader");
176 // Get the FMD loader
177 fFMDLoader = fLoader->GetLoader("FMDLoader");
179 AliError("Failed to get detector FMD loader from loader");
182 if (fLoader->LoadHeader()) {
183 AliError("Failed to get event header information from loader");
186 fTreeE = fLoader->TreeE();
188 // Optionally, get the ESD files
189 if (TESTBIT(fTreeMask, kESD)) {
190 fChainE = new TChain("esdTree");
191 TSystemDirectory dir(".",".");
192 TList* files = dir.GetListOfFiles();
193 TSystemFile* file = 0;
195 AliError("No files");
200 while ((file = static_cast<TSystemFile*>(next()))) {
201 TString fname(file->GetName());
202 if (fname.Contains("AliESDs")) fChainE->AddFile(fname.Data());
204 fChainE->SetBranchAddress("ESD", &fMainESD);
207 if (TESTBIT(fTreeMask, kRaw)) {
208 AliInfo("Getting FMD raw data digits");
209 fArrayA = new TClonesArray("AliFMDDigit");
210 fReader = new AliRawReaderFile(-1);
213 // Optionally, get the geometry
214 if (TESTBIT(fTreeMask, kGeometry)) {
215 TString fname(fRun->GetGeometryFileName());
216 if (fname.IsNull()) {
217 Warning("Init", "No file name for the geometry from AliRun");
218 fname = gSystem->DirName(fGAliceFile);
219 fname.Append("/geometry.root");
221 fGeoManager = TGeoManager::Import(fname.Data());
223 Fatal("Init", "No geometry manager found");
226 AliCDBManager* cdb = AliCDBManager::Instance();
227 AliCDBEntry* align = cdb->Get("FMD/Align/Data");
229 AliInfo("Got alignment data from CDB");
230 TClonesArray* array = dynamic_cast<TClonesArray*>(align->GetObject());
232 AliWarning("Invalid align data from CDB");
235 Int_t nAlign = array->GetEntries();
236 for (Int_t i = 0; i < nAlign; i++) {
237 AliAlignObjAngles* a = static_cast<AliAlignObjAngles*>(array->At(i));
238 if (!a->ApplyToGeometry()) {
239 AliWarning(Form("Failed to apply alignment to %s",
252 //____________________________________________________________________
254 AliFMDInput::Begin(Int_t event)
256 // Called at the begining of each event. Per default, it gets the
257 // data trees and gets pointers to the output arrays. Users can
258 // overload this, but should call this member function in the
259 // overloaded member function of the derived class.
261 // Check if we have been initialized
263 AliError("Not initialized");
267 if (fLoader->GetEvent(event)) return kFALSE;
268 AliInfo(Form("Now in event %d/%d", event, NEvents()));
270 // Possibly load global kinematics information
271 if (TESTBIT(fTreeMask, kKinematics) || TESTBIT(fTreeMask, kTracks)) {
272 AliInfo("Getting kinematics");
273 if (fLoader->LoadKinematics()) return kFALSE;
274 fStack = fLoader->Stack();
276 // Possibly load FMD Hit information
277 if (TESTBIT(fTreeMask, kHits) || TESTBIT(fTreeMask, kTracks)) {
278 AliInfo("Getting FMD hits");
279 if (fFMDLoader->LoadHits()) return kFALSE;
280 fTreeH = fFMDLoader->TreeH();
281 if (!fArrayH) fArrayH = fFMD->Hits();
283 // Possibly load FMD Digit information
284 if (TESTBIT(fTreeMask, kDigits)) {
285 AliInfo("Getting FMD digits");
286 if (fFMDLoader->LoadDigits()) return kFALSE;
287 fTreeD = fFMDLoader->TreeD();
289 if (!fArrayD) fArrayD = fFMD->Digits();
293 AliWarning(Form("Failed to load FMD Digits"));
296 // Possibly load FMD Sdigit information
297 if (TESTBIT(fTreeMask, kSDigits)) {
298 AliInfo("Getting FMD summable digits");
299 if (fFMDLoader->LoadSDigits()) return kFALSE;
300 fTreeS = fFMDLoader->TreeS();
301 if (!fArrayS) fArrayS = fFMD->SDigits();
303 // Possibly load FMD RecPoints information
304 if (TESTBIT(fTreeMask, kRecPoints)) {
305 AliInfo("Getting FMD reconstructed points");
306 if (fFMDLoader->LoadRecPoints()) return kFALSE;
307 fTreeR = fFMDLoader->TreeR();
308 if (!fArrayR) fArrayR = new TClonesArray("AliFMDRecPoint");
309 fTreeR->SetBranchAddress("FMD", &fArrayR);
310 } // Possibly load FMD ESD information
311 if (TESTBIT(fTreeMask, kESD)) {
312 AliInfo("Getting FMD event summary data");
313 Int_t read = fChainE->GetEntry(event);
314 if (read <= 0) return kFALSE;
315 fESD = fMainESD->GetFMDData();
316 if (!fESD) return kFALSE;
317 TFile* f = fChainE->GetFile();
319 TObject* o = f->GetStreamerInfoList()->FindObject("AliFMDMap");
321 TStreamerInfo* info = static_cast<TStreamerInfo*>(o);
322 std::cout << "AliFMDMap class version read is "
323 << info->GetClassVersion() << std::endl;
326 // fESD->CheckNeedUShort(fChainE->GetFile());
328 // Possibly load FMD Digit information
329 if (TESTBIT(fTreeMask, kRaw)) {
330 AliInfo("Getting FMD raw data digits");
331 if (!fReader->NextEvent()) return kFALSE;
332 AliFMDRawReader r(fReader, 0);
341 //____________________________________________________________________
345 // Process one event. The default implementation one or more of
347 // - ProcessHits if the hits are loaded.
348 // - ProcessDigits if the digits are loaded.
349 // - ProcessSDigits if the sumbable digits are loaded.
350 // - ProcessRecPoints if the reconstructed points are loaded.
351 // - ProcessESD if the event summary data is loaded
353 if (TESTBIT(fTreeMask, kHits))
354 if (!ProcessHits()) return kFALSE;
355 if (TESTBIT(fTreeMask, kTracks))
356 if (!ProcessTracks()) return kFALSE;
357 if (TESTBIT(fTreeMask, kDigits))
358 if (!ProcessDigits()) return kFALSE;
359 if (TESTBIT(fTreeMask, kSDigits))
360 if (!ProcessSDigits()) return kFALSE;
361 if (TESTBIT(fTreeMask, kRaw))
362 if (!ProcessRawDigits()) return kFALSE;
363 if (TESTBIT(fTreeMask, kRecPoints))
364 if (!ProcessRecPoints()) return kFALSE;
365 if (TESTBIT(fTreeMask, kESD))
366 if (!ProcessESDs()) return kFALSE;
371 //____________________________________________________________________
373 AliFMDInput::ProcessHits()
375 // Read the hit tree, and pass each hit to the member function
378 AliError("No hit tree defined");
381 Int_t nTracks = fTreeH->GetEntries();
382 for (Int_t i = 0; i < nTracks; i++) {
383 Int_t hitRead = fTreeH->GetEntry(i);
384 if (hitRead <= 0) continue;
386 AliError("No hit array defined");
389 Int_t nHit = fArrayH->GetEntries();
390 if (nHit <= 0) continue;
391 for (Int_t j = 0; j < nHit; j++) {
392 AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
394 TParticle* track = 0;
395 if (TESTBIT(fTreeMask, kKinematics) && fStack) {
396 Int_t trackno = hit->Track();
397 track = fStack->Particle(trackno);
399 if (!ProcessHit(hit, track)) return kFALSE;
405 //____________________________________________________________________
407 AliFMDInput::ProcessTracks()
409 // Read the hit tree, and pass each hit to the member function
412 AliError("No track tree defined");
416 AliError("No hit tree defined");
419 Int_t nTracks = fTreeH->GetEntries();
420 for (Int_t i = 0; i < nTracks; i++) {
421 TParticle* track = fStack->Particle(i);
422 if (!track) continue;
423 Int_t hitRead = fTreeH->GetEntry(i);
424 if (hitRead <= 0) continue;
426 AliError("No hit array defined");
429 Int_t nHit = fArrayH->GetEntries();
430 if (nHit <= 0) continue;
432 for (Int_t j = 0; j < nHit; j++) {
433 AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
435 if (!ProcessTrack(i, track, hit)) return kFALSE;
437 // if (!ProcessTrack(i, track, fArrayH)) return kFALSE;
442 //____________________________________________________________________
444 AliFMDInput::ProcessDigits()
446 // Read the digit tree, and pass each digit to the member function
448 Int_t nEv = fTreeD->GetEntries();
449 for (Int_t i = 0; i < nEv; i++) {
450 Int_t digitRead = fTreeD->GetEntry(i);
451 if (digitRead <= 0) continue;
452 Int_t nDigit = fArrayD->GetEntries();
453 if (nDigit <= 0) continue;
454 for (Int_t j = 0; j < nDigit; j++) {
455 AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayD->At(j));
456 if (!digit) continue;
457 if (!ProcessDigit(digit)) return kFALSE;
463 //____________________________________________________________________
465 AliFMDInput::ProcessSDigits()
467 // Read the summable digit tree, and pass each sumable digit to the
468 // member function ProcessSdigit.
469 Int_t nEv = fTreeD->GetEntries();
470 for (Int_t i = 0; i < nEv; i++) {
471 Int_t sdigitRead = fTreeS->GetEntry(i);
472 if (sdigitRead <= 0) continue;
473 Int_t nSdigit = fArrayS->GetEntries();
474 if (nSdigit <= 0) continue;
475 for (Int_t j = 0; j < nSdigit; j++) {
476 AliFMDSDigit* sdigit = static_cast<AliFMDSDigit*>(fArrayS->At(j));
477 if (!sdigit) continue;
478 if (!ProcessSDigit(sdigit)) return kFALSE;
484 //____________________________________________________________________
486 AliFMDInput::ProcessRawDigits()
488 // Read the digit tree, and pass each digit to the member function
490 Int_t nDigit = fArrayA->GetEntries();
491 if (nDigit <= 0) return kTRUE;
492 for (Int_t j = 0; j < nDigit; j++) {
493 AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayA->At(j));
494 if (!digit) continue;
495 if (!ProcessRawDigit(digit)) return kFALSE;
500 //____________________________________________________________________
502 AliFMDInput::ProcessRecPoints()
504 // Read the reconstrcted points tree, and pass each reconstruction
505 // object (AliFMDRecPoint) to either ProcessRecPoint.
506 Int_t nEv = fTreeR->GetEntries();
507 for (Int_t i = 0; i < nEv; i++) {
508 Int_t recRead = fTreeR->GetEntry(i);
509 if (recRead <= 0) continue;
510 Int_t nRecPoint = fArrayR->GetEntries();
511 for (Int_t j = 0; j < nRecPoint; j++) {
512 AliFMDRecPoint* recPoint = static_cast<AliFMDRecPoint*>(fArrayR->At(j));
513 if (!recPoint) continue;
514 if (!ProcessRecPoint(recPoint)) return kFALSE;
520 //____________________________________________________________________
522 AliFMDInput::ProcessESDs()
524 // Process event summary data
525 if (!fESD) return kFALSE;
526 for (UShort_t det = 1; det <= 3; det++) {
527 Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
528 for (Char_t* rng = rings; *rng != '\0'; rng++) {
529 UShort_t nsec = (*rng == 'I' ? 20 : 40);
530 UShort_t nstr = (*rng == 'I' ? 512 : 256);
531 for (UShort_t sec = 0; sec < nsec; sec++) {
532 for (UShort_t str = 0; str < nstr; str++) {
533 Float_t eta = fESD->Eta(det,*rng,sec,str);
534 Float_t mult = fESD->Multiplicity(det,*rng,sec,str);
535 if (!fESD->IsAngleCorrected())
536 mult *= TMath::Abs(TMath::Cos(2.*TMath::ATan(TMath::Exp(-eta))));
537 if (!ProcessESD(det, *rng, sec, str, eta, mult)) continue;
545 //____________________________________________________________________
549 // Called at the end of each event. Per default, it unloads the
550 // data trees and resets the pointers to the output arrays. Users
551 // can overload this, but should call this member function in the
552 // overloaded member function of the derived class.
554 // Check if we have been initialized
556 AliError("Not initialized");
559 // Possibly unload global kinematics information
560 if (TESTBIT(fTreeMask, kKinematics) || TESTBIT(fTreeMask, kTracks)) {
561 fLoader->UnloadKinematics();
565 // Possibly unload FMD Hit information
566 if (TESTBIT(fTreeMask, kHits) || TESTBIT(fTreeMask, kTracks)) {
567 fFMDLoader->UnloadHits();
570 // Possibly unload FMD Digit information
571 if (TESTBIT(fTreeMask, kDigits)) {
572 fFMDLoader->UnloadDigits();
575 // Possibly unload FMD Sdigit information
576 if (TESTBIT(fTreeMask, kSDigits)) {
577 fFMDLoader->UnloadSDigits();
580 // Possibly unload FMD RecPoints information
581 if (TESTBIT(fTreeMask, kRecPoints)) {
582 fFMDLoader->UnloadRecPoints();
585 AliInfo("Now out event");
589 //____________________________________________________________________
593 // Run over all events and files references in galice.root
596 if (!(retval = Init())) return retval;
598 Int_t nEvents = NEvents();
599 for (Int_t event = 0; event < nEvents; event++) {
600 if (!(retval = Begin(event))) break;
601 if (!(retval = Event())) break;
602 if (!(retval = End())) break;
604 if (!retval) return retval;
610 //____________________________________________________________________