2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
4 /**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
10 #include "AliEveEventManager.h"
11 #include "AliEveEventSelector.h"
12 #include "AliEveMacroExecutor.h"
13 #include <TEveManager.h>
14 #include <TEveViewer.h>
16 #include <AliRunLoader.h>
18 #include <AliESDRun.h>
19 #include <AliESDEvent.h>
20 #include <AliESDfriend.h>
21 #include <AliAODEvent.h>
24 #include <AliRawEventHeaderBase.h>
25 #include <AliRawReaderRoot.h>
26 #include <AliRawReaderFile.h>
27 #include <AliRawReaderDate.h>
29 #include <AliCDBManager.h>
30 #include <AliCDBStorage.h>
31 #include <AliCDBEntry.h>
32 #include <AliGRPObject.h>
33 #include <AliHeader.h>
34 #include <AliGeomManager.h>
38 #include <TGeoManager.h>
39 #include <TGeoGlobalMagField.h>
41 #include <TTimeStamp.h>
45 //==============================================================================
46 //==============================================================================
48 //==============================================================================
50 //______________________________________________________________________________
52 // Provides interface for loading and navigating standard AliRoot data
53 // (AliRunLoader), ESD, AOD and RAW.
55 // ESDfriend is attached automatically, if the file is found.
57 // AODfriends are not attached automatically as there are several
58 // possible files involved. To have a specific AODfriend attached, call
60 // AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
61 // before initializing the event-manager.
63 // Also provides interface to magnetic-field and geometry. Mostly
64 // intended as wrappers over standard AliRoot functionality for
65 // convenient use from visualizateion macros.
67 // There can be a single main event-manger, it is stored in private
68 // data member fgMaster and can be accessed via static member function
71 // For event overlaying and embedding one can instantiate additional
72 // event-managers via static method AddDependentManager(const TString& path).
73 // This interface is under development.
75 ClassImp(AliEveEventManager)
77 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
78 Bool_t AliEveEventManager::fgAssertESD = kFALSE;
79 Bool_t AliEveEventManager::fgAssertAOD = kFALSE;
80 Bool_t AliEveEventManager::fgAssertRaw = kFALSE;
82 TString AliEveEventManager::fgESDFileName("AliESDs.root");
83 TString AliEveEventManager::fgAODFileName("AliAOD.root");
84 TString AliEveEventManager::fgRawFileName("raw.root");
85 TString AliEveEventManager::fgCdbUri("local://$ALICE_ROOT/OCDB");
87 TList* AliEveEventManager::fgAODfriends = 0;
89 AliGRPObject* AliEveEventManager::fgGRPData = 0;
90 AliMagF* AliEveEventManager::fgMagField = 0;
91 Bool_t AliEveEventManager::fgUniformField = kFALSE;
93 AliEveEventManager* AliEveEventManager::fgMaster = 0;
94 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
96 void AliEveEventManager::InitInternals()
98 // Initialize internal members.
100 static const TEveException kEH("AliEveEventManager::InitInternals ");
104 throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
114 fAutoLoadTimer = new TTimer;
115 fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
117 fExecutor = new AliEveMacroExecutor;
119 fTransients = new TEveElementList("Transients", "Transient per-event elements.");
120 fTransients->IncDenyDestroy();
121 gEve->AddToListTree(fTransients, kFALSE);
123 fTransientLists = new TEveElementList("Transient Lists", "Containers of transient elements.");
124 fTransientLists->IncDenyDestroy();
125 gEve->AddToListTree(fTransientLists, kFALSE);
127 fPEventSelector = new AliEveEventSelector(this);
130 AliEveEventManager::AliEveEventManager(const TString& name) :
131 TEveEventManager(name),
133 fPath ( ), fEventId (-1),
135 fESDFile (0), fESDTree (0), fESD (0),
136 fESDfriend (0), fESDfriendExists(kFALSE),
137 fAODFile (0), fAODTree (0), fAOD (0),
139 fAutoLoad (kFALSE), fAutoLoadTime (5.), fAutoLoadTimer(0),
140 fIsOpen (kFALSE), fHasEvent (kFALSE), fExternalCtrl (kFALSE),
141 fExecutor (0), fTransients(0), fTransientLists(0),
144 fAutoLoadTimerRunning(kFALSE)
146 // Default constructor.
151 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
152 TEveEventManager(name, path),
154 fPath (path), fEventId(-1),
156 fESDFile (0), fESDTree (0), fESD (0),
157 fESDfriend (0), fESDfriendExists(kFALSE),
158 fAODFile (0), fAODTree (0), fAOD (0),
160 fAutoLoad (kFALSE), fAutoLoadTime (5), fAutoLoadTimer(0),
161 fIsOpen (kFALSE), fHasEvent (kFALSE), fExternalCtrl (kFALSE),
162 fExecutor (0), fTransients(0), fTransientLists(0),
165 fAutoLoadTimerRunning(kFALSE)
167 // Constructor with event-directory URL and event-id.
178 AliEveEventManager::~AliEveEventManager()
189 fTransients->DecDenyDestroy();
190 fTransients->Destroy();
192 fTransientLists->DecDenyDestroy();
193 fTransientLists->Destroy();
196 /******************************************************************************/
198 void AliEveEventManager::SetESDFileName(const TString& esd)
200 // Set file-name for opening ESD, default "AliESDs.root".
202 if ( ! esd.IsNull()) fgESDFileName = esd;
205 void AliEveEventManager::SetAODFileName(const TString& aod)
207 // Set file-name for opening AOD, default "AliAOD.root".
209 if ( ! aod.IsNull()) fgAODFileName = aod;
212 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
214 // Add new AOD friend file-name to be attached when opening AOD.
215 // This should include '.root', as in 'AliAOD.VertexingHF.root'.
217 if (fgAODfriends == 0)
219 fgAODfriends = new TList;
220 fgAODfriends->SetOwner(kTRUE);
222 if (fgAODfriends->FindObject(friendFileName) == 0)
224 fgAODfriends->Add(new TObjString(friendFileName));
228 void AliEveEventManager::SetRawFileName(const TString& raw)
230 // Set file-name for opening of raw-data, default "raw.root"
231 if ( ! raw.IsNull()) fgRawFileName = raw;
234 void AliEveEventManager::SetCdbUri(const TString& cdb)
236 // Set path to CDB, default "local://$ALICE_ROOT/OCDB".
238 if ( ! cdb.IsNull()) fgCdbUri = cdb;
241 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
242 Bool_t assertAod, Bool_t assertRaw)
244 // Set global flags that detrmine which parts of the event-data must
245 // be present when the event is opened.
247 fgAssertRunLoader = assertRunloader;
248 fgAssertESD = assertEsd;
249 fgAssertAOD = assertAod;
250 fgAssertRaw = assertRaw;
253 /******************************************************************************/
255 void AliEveEventManager::Open()
257 // Open event-data from URL specified in fPath.
258 // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
259 // Warning is reported if run-loader or ESD is not found.
260 // Global data-members fgAssertRunLoader and fgAssertESD can be set
261 // to throw exceptions instead.
263 static const TEveException kEH("AliEveEventManager::Open ");
267 throw (kEH + "Event-loop is under external control.");
271 throw (kEH + "Event-files already opened.");
274 gSystem->ExpandPathName(fPath);
275 // The following magick is required for ESDfriends to be loaded properly
276 // from non-current directory.
277 if (fPath.IsNull() || fPath == ".")
279 fPath = gSystem->WorkingDirectory();
281 else if ( ! fPath.BeginsWith("file:/"))
283 TUrl url(fPath, kTRUE);
284 TString protocol(url.GetProtocol());
285 if (protocol == "file" && fPath[0] != '/')
286 fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
291 // Open ESD and ESDfriends
293 TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
294 if ((fESDFile = TFile::Open(esdPath)))
296 fESD = new AliESDEvent();
297 fESDTree = (TTree*) fESDFile->Get("esdTree");
300 // Check if ESDfriends exists and attach the branch.
301 // We use TFile::Open() instead of gSystem->AccessPathName
302 // as it seems to work better when attachine alieve to a
303 // running reconstruction process with auto-save on.
304 // There was also a problem with TTree::Refresh() - it didn't
305 // save the friend branch on a separate file, fixed in 5.22.2 -
306 // so we might want to try the old way again soon.
307 TString p(Form("%s/AliESDfriends.root", fPath.Data()));
308 TFile *esdFriendFile = TFile::Open(p);
311 if (!esdFriendFile->IsZombie())
313 esdFriendFile->Close();
314 fESDfriendExists = kTRUE;
315 fESDTree->SetBranchStatus ("ESDfriend*", 1);
317 delete esdFriendFile;
320 fESD->ReadFromTree(fESDTree);
321 if (fESDfriendExists)
323 fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
324 Info(kEH, "found and attached ESD friend.");
328 Warning(kEH, "ESDfriend not found.");
331 if (fESDTree->GetEntry(0) <= 0)
333 delete fESDFile; fESDFile = 0;
334 delete fESD; fESD = 0;
335 Warning(kEH, "failed getting the first entry from esdTree.");
340 runNo = fESD->GetESDRun()->GetRunNumber();
345 delete fESDFile; fESDFile = 0;
346 delete fESD; fESD = 0;
347 Warning(kEH, "failed getting the esdTree.");
350 else // esd not readable
352 Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
358 throw (kEH + "ESD not initialized. Its precence was requested.");
360 Warning(kEH, "ESD not initialized.");
364 // Open AOD and registered friends
366 TString aodPath(Form("%s/%s", fPath.Data(), fgAODFileName.Data()));
367 if ((fAODFile = TFile::Open(aodPath)))
369 fAOD = new AliAODEvent();
370 fAODTree = (TTree*) fAODFile->Get("aodTree");
373 // Check if AODfriends exist and attach them.
374 TIter friends(fgAODfriends);
376 while ((name = (TObjString*) friends()) != 0)
378 TString p(Form("%s/%s", fPath.Data(), name->GetName()));
379 if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
381 fAODTree->AddFriend("aodTree", name->GetName());
385 fAOD->ReadFromTree(fAODTree);
387 if (fAODTree->GetEntry(0) <= 0)
389 delete fAODFile; fAODFile = 0;
390 delete fAOD; fAOD = 0;
391 Warning(kEH, "failed getting the first entry from addTree.");
396 runNo = fAOD->GetRunNumber();
401 delete fAODFile; fAODFile = 0;
402 delete fAOD; fAOD = 0;
403 Warning(kEH, "failed getting the aodTree.");
406 else // aod not readable
408 Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
414 throw (kEH + "AOD not initialized. Its precence was requested.");
416 Warning(kEH, "AOD not initialized.");
420 // Open RunLoader from galice.root
422 TString gaPath(Form("%s/galice.root", fPath.Data()));
423 // If i use open directly, we get fatal.
424 // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
425 if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
427 fRunLoader = AliRunLoader::Open(gaPath, GetName());
430 TString alicePath = fPath + "/";
431 fRunLoader->SetDirName(alicePath);
433 if (fRunLoader->LoadgAlice() != 0)
434 Warning(kEH, "failed loading gAlice via run-loader.");
436 if (fRunLoader->LoadHeader() == 0)
439 runNo = fRunLoader->GetHeader()->GetRun();
443 Warning(kEH, "failed loading run-loader's header.");
448 else // run-loader open failed
450 Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
453 else // galice not readable
455 Warning(kEH, "can not read '%s'.", gaPath.Data());
459 if (fgAssertRunLoader)
460 throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
462 Warning(kEH, "Bootstraping of run-loader failed.");
465 // Open raw-data file
467 TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
468 // If i use open directly, raw-reader reports an error but i have
469 // no way to detect it.
470 // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
471 AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
472 if (fgAssertRaw == kFALSE)
474 AliLog::SetGlobalLogLevel(AliLog::kFatal);
476 if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
478 fRawReader = AliRawReader::Create(rawPath);
482 fRawReader = AliRawReader::Create(fgRawFileName);
484 if (fgAssertRaw == kFALSE)
486 AliLog::SetGlobalLogLevel(oldLogLevel);
493 throw (kEH + "raw-data not initialized. Its precence was requested.");
495 Warning(kEH, "raw-data not initialized.");
503 fRawReader->NextEvent();
504 runNo = fRawReader->GetRunNumber();
505 Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
506 fRawReader->RewindEvents();
508 throw (kEH + "unknown run number.");
512 // Initialize OCDB ... only in master event-manager
514 if (this == fgMaster)
516 AliCDBManager* cdb = AliCDBManager::Instance();
517 if (cdb->IsDefaultStorageSet() == kTRUE)
519 Warning(kEH, "CDB already set - using the old storage:\n '%s'",
520 cdb->GetDefaultStorage()->GetURI().Data());
524 cdb->SetDefaultStorage(fgCdbUri);
525 if (cdb->IsDefaultStorageSet() == kFALSE)
526 throw (kEH + "CDB initialization failed.");
534 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
536 // Set an event from an external source.
537 // The method is used in the online visualisation.
538 // AOD is not supported.
540 static const TEveException kEH("AliEveEventManager::SetEvent ");
544 Warning(kEH, "Event-files were open. Closing and switching to external control.");
548 fRunLoader = runLoader;
549 fRawReader = rawReader;
556 fExternalCtrl = kTRUE;
558 SetTitle("Online event in memory");
559 SetName ("Online Event");
562 AfterNewEventLoaded();
564 if (fAutoLoad) StartAutoLoadTimer();
567 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
569 // Returns maximum available event id.
570 // If under external control or event is not opened -1 is returned.
571 // If raw-data is the only data-source this can not be known
572 // and 10,000,000 is returned.
573 // If neither data-source is initialised an exception is thrown.
574 // If refresh_esd is true and ESD is the primary event-data source
575 // its header is re-read from disk.
577 static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
579 if (fExternalCtrl || fIsOpen == kFALSE)
586 // Refresh crashes with root-5.21.1-alice.
587 // Fixed by Philippe 5.8.2008 r25053, can be reactivated
588 // when we move to a newer root.
590 // fESDTree->Refresh();
591 return fESDTree->GetEntries() - 1;
595 return fAODTree->GetEntries() - 1;
599 return fRunLoader->GetNumberOfEvents() - 1;
603 Int_t n = fRawReader->GetNumberOfEvents() - 1;
604 return n > -1 ? n : 10000000;
608 throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
612 void AliEveEventManager::GotoEvent(Int_t event)
614 // Load data for specified event.
615 // If event is out of range an exception is thrown and old state
617 // After successful loading of event, the virtual function
618 // AfterNewEventLoaded() is called. This executes commands that
619 // were registered via TEveEventManager::AddNewEventCommand().
621 // If event is negative, it is subtracted from the number of
622 // available events, thus passing -1 will load the last event.
623 // This is not supported when raw-data is the only data-source
624 // as the number of events is not known.
626 static const TEveException kEH("AliEveEventManager::GotoEvent ");
628 if (fAutoLoadTimerRunning)
630 throw (kEH + "Event auto-load timer is running.");
634 throw (kEH + "Event-loop is under external control.");
638 throw (kEH + "Event-files not opened.");
646 // Refresh crashes with root-5.21.1-alice.
647 // Fixed by Philippe 5.8.2008 r25053, can be reactivated
648 // when we move to a newer root.
649 // fESDTree->Refresh();
650 maxEvent = fESDTree->GetEntries() - 1;
652 event = fESDTree->GetEntries() + event;
656 maxEvent = fAODTree->GetEntries() - 1;
658 event = fAODTree->GetEntries() + event;
662 maxEvent = fRunLoader->GetNumberOfEvents() - 1;
664 event = fRunLoader->GetNumberOfEvents() + event;
668 maxEvent = fRawReader->GetNumberOfEvents() - 1;
673 Error(kEH, "current raw-data source does not support direct event access.");
676 Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
681 event = fRawReader->GetNumberOfEvents() + event;
686 throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
688 if (event < 0 || event > maxEvent)
690 throw (kEH + Form("event %d not present, available range [%d, %d].",
691 event, 0, maxEvent));
694 TEveManager::TRedrawDisabler rd(gEve);
695 gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
697 // !!! MT this is somewhat brutal; at least optionally, one could be
698 // a bit gentler, checking for objs owning their external refs and having
699 // additinal parents.
700 gEve->GetViewers()->DeleteAnnotations();
701 fTransients->DestroyElements();
702 for (TEveElement::List_i i = fTransientLists->BeginChildren();
703 i != fTransientLists->EndChildren(); ++i)
705 (*i)->DestroyElements();
710 if (fESDTree->GetEntry(event) <= 0)
711 throw (kEH + "failed getting required event from ESD.");
713 if (fESDfriendExists)
714 fESD->SetESDfriend(fESDfriend);
718 if (fAODTree->GetEntry(event) <= 0)
719 throw (kEH + "failed getting required event from AOD.");
723 if (fRunLoader->GetEvent(event) != 0)
724 throw (kEH + "failed getting required event.");
729 // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
730 if (fRawReader->GotoEvent(event) == kFALSE)
732 // Use fallback method - iteration with NextEvent().
733 Int_t rawEv = fEventId;
736 fRawReader->RewindEvents();
740 while (rawEv < event)
742 if ( ! fRawReader->NextEvent())
744 fRawReader->RewindEvents();
746 throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
750 Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
756 if (this == fgMaster)
758 SetName(Form("Event %d", fEventId));
762 AfterNewEventLoaded();
765 void AliEveEventManager::NextEvent()
768 // Does magick needed for online display when under external event control.
770 static const TEveException kEH("AliEveEventManager::NextEvent ");
772 if (fAutoLoadTimerRunning)
774 throw (kEH + "Event auto-load timer is running.");
779 // !!! This should really go somewhere else. It is done in GotoEvent(),
780 // so here we should do it in SetEvent().
788 if (fPEventSelector->FindNext(nextevent))
790 GotoEvent(nextevent);
793 // GotoEvent(fEventId + 1);
797 void AliEveEventManager::PrevEvent()
799 // Loads previous event.
801 static const TEveException kEH("AliEveEventManager::PrevEvent ");
803 if (fAutoLoadTimerRunning)
805 throw (kEH + "Event auto-load timer is running.");
809 throw (kEH + "Event-loop is under external control.");
812 if (fPEventSelector->FindPrev(nextevent))
814 GotoEvent(nextevent);
817 // GotoEvent(fEventId - 1);
820 void AliEveEventManager::Close()
822 // Close the event data-files and delete ESD, ESDfriend, run-loader
825 static const TEveException kEH("AliEveEventManager::Close ");
829 throw (kEH + "Event-files not opened.");
832 if (fAutoLoadTimerRunning)
836 delete fESD; fESD = 0;
837 delete fESDfriend; fESDfriend = 0;
838 fESDfriendExists = kFALSE;
840 delete fESDTree; fESDTree = 0;
841 delete fESDFile; fESDFile = 0;
845 delete fAOD; fAOD = 0;
847 delete fAODTree; fAODTree = 0;
848 delete fAODFile; fAODFile = 0;
852 delete fRunLoader; fRunLoader = 0;
856 delete fRawReader; fRawReader = 0;
865 //------------------------------------------------------------------------------
866 // Static convenience functions, mainly used from macros.
867 //------------------------------------------------------------------------------
869 Bool_t AliEveEventManager::HasRunLoader()
871 // Check if AliRunLoader is initialized.
873 return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
876 Bool_t AliEveEventManager::HasESD()
878 // Check if AliESDEvent is initialized.
880 return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
883 Bool_t AliEveEventManager::HasESDfriend()
885 // Check if AliESDfriend is initialized.
887 return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
890 Bool_t AliEveEventManager::HasAOD()
892 // Check if AliESDEvent is initialized.
894 return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
897 Bool_t AliEveEventManager::HasRawReader()
899 // Check if raw-reader is initialized.
901 return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
904 AliRunLoader* AliEveEventManager::AssertRunLoader()
906 // Make sure AliRunLoader is initialized and return it.
907 // Throws exception in case run-loader is not available.
908 // Static utility for macros.
910 static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
912 if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
913 throw (kEH + "ALICE event not ready.");
914 if (fgCurrent->fRunLoader == 0)
915 throw (kEH + "AliRunLoader not initialised.");
916 return fgCurrent->fRunLoader;
919 AliESDEvent* AliEveEventManager::AssertESD()
921 // Make sure AliESDEvent is initialized and return it.
922 // Throws exception in case ESD is not available.
923 // Static utility for macros.
925 static const TEveException kEH("AliEveEventManager::AssertESD ");
927 if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
928 throw (kEH + "ALICE event not ready.");
929 if (fgCurrent->fESD == 0)
930 throw (kEH + "AliESD not initialised.");
931 return fgCurrent->fESD;
934 AliESDfriend* AliEveEventManager::AssertESDfriend()
936 // Make sure AliESDfriend is initialized and return it.
937 // Throws exception in case ESDfriend-loader is not available.
938 // Static utility for macros.
940 static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
942 if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
943 throw (kEH + "ALICE event not ready.");
944 if (fgCurrent->fESDfriend == 0)
945 throw (kEH + "AliESDfriend not initialised.");
946 return fgCurrent->fESDfriend;
949 AliAODEvent* AliEveEventManager::AssertAOD()
951 // Make sure AliAODEvent is initialized and return it.
952 // Throws exception in case AOD is not available.
953 // Static utility for macros.
955 static const TEveException kEH("AliEveEventManager::AssertAOD ");
957 if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
958 throw (kEH + "ALICE event not ready.");
959 if (fgCurrent->fAOD == 0)
960 throw (kEH + "AliAOD not initialised.");
961 return fgCurrent->fAOD;
964 AliRawReader* AliEveEventManager::AssertRawReader()
966 // Make sure raw-reader is initialized and return it.
968 static const TEveException kEH("AliEveEventManager::AssertRawReader ");
970 if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
971 throw (kEH + "ALICE event not ready.");
972 if (fgCurrent->fRawReader == 0)
973 throw (kEH + "RawReader not ready.");
975 return fgCurrent->fRawReader;
978 //==============================================================================
980 AliMagF* AliEveEventManager::AssertMagField()
982 // Make sure AliMagF is initialized and returns it.
983 // Throws exception in case magnetic field is not available.
984 // Static utility for macros.
986 static const TEveException kEH("AliEveEventManager::AssertMagField ");
996 if (TGeoGlobalMagField::Instance())
998 fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
1000 throw kEH + "Global field set, but it is not AliMagF.";
1004 throw kEH + "Could not initialize magnetic field.";
1010 TGeoManager* AliEveEventManager::AssertGeometry()
1012 // Make sure AliGeomManager is initialized and returns the
1013 // corresponding TGeoManger.
1014 // gGeoManager is set to the return value.
1015 // Throws exception if geometry can not be loaded or if it is not
1016 // available and the TGeoManager is locked.
1017 // Static utility for macros.
1019 static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1021 if (AliGeomManager::GetGeometry() == 0)
1023 if (TGeoManager::IsLocked())
1024 throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1027 AliGeomManager::LoadGeometry();
1028 if ( ! AliGeomManager::GetGeometry())
1030 throw (kEH + "can not load geometry.");
1032 if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1034 ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1035 // throw (kEH + "could not apply align objs.");
1037 AliGeomManager::GetGeometry()->DefaultColors();
1040 gGeoManager = AliGeomManager::GetGeometry();
1044 //------------------------------------------------------------------------------
1046 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1048 // Create and attach a dependent event-manager.
1049 // It is not added into eve list tree.
1051 static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1054 throw(kEH + "Master event-manager must be instantiated first.");
1056 if (fgMaster->fSubManagers == 0)
1058 fgMaster->fSubManagers = new TList;
1059 fgMaster->fSubManagers->SetOwner(kTRUE);
1062 AliEveEventManager* new_mgr = 0;
1066 new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1067 fgMaster->fSubManagers->Add(new_mgr);
1069 catch (TEveException& exc)
1071 ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1073 fgCurrent = fgMaster;
1078 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1080 // Get a dependant manager by name.
1081 // This will not change the current manager, use helper class
1082 // AliEveEventManager::CurrentChanger for that.
1084 static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1087 throw(kEH + "Master event-manager must be instantiated first.");
1089 if (fgMaster->fSubManagers == 0)
1092 return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1095 AliEveEventManager* AliEveEventManager::GetMaster()
1097 // Get master event-manager.
1102 AliEveEventManager* AliEveEventManager::GetCurrent()
1104 // Get current event-manager.
1109 void AliEveEventManager::RegisterTransient(TEveElement* element)
1111 GetCurrent()->fTransients->AddElement(element);
1114 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1116 GetCurrent()->fTransientLists->AddElement(element);
1119 //------------------------------------------------------------------------------
1120 // Autoloading of events
1121 //------------------------------------------------------------------------------
1123 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1125 // Set the auto-load time in seconds
1127 fAutoLoadTime = time;
1130 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1132 // Set the automatic event loading mode
1134 static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1136 if (fAutoLoad == autoLoad)
1138 Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1142 fAutoLoad = autoLoad;
1145 StartAutoLoadTimer();
1149 StopAutoLoadTimer();
1153 void AliEveEventManager::StartAutoLoadTimer()
1155 // Start the auto-load timer.
1157 fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1158 fAutoLoadTimer->Reset();
1159 fAutoLoadTimer->TurnOn();
1160 fAutoLoadTimerRunning = kTRUE;
1163 void AliEveEventManager::StopAutoLoadTimer()
1165 // Stop the auto-load timer.
1167 fAutoLoadTimerRunning = kFALSE;
1168 fAutoLoadTimer->TurnOff();
1171 void AliEveEventManager::AutoLoadNextEvent()
1173 // Called from auto-load timer, so it has to be public.
1174 // Do NOT call it directly.
1176 static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1178 if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1180 Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1184 StopAutoLoadTimer();
1186 if (fAutoLoad && !fExternalCtrl)
1187 StartAutoLoadTimer();
1190 //------------------------------------------------------------------------------
1191 // Post event-loading functions
1192 //------------------------------------------------------------------------------
1194 void AliEveEventManager::AfterNewEventLoaded()
1196 // Execute registered macros and commands.
1197 // At the end emit NewEventLoaded signal.
1199 // Virtual from TEveEventManager.
1201 static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1204 fExecutor->ExecMacros();
1206 TEveEventManager::AfterNewEventLoaded();
1210 if (this == fgMaster && fSubManagers != 0)
1212 TIter next(fSubManagers);
1213 while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1215 gEve->SetCurrentEvent(fgCurrent);
1218 fgCurrent->GotoEvent(fEventId);
1220 catch (TEveException& exc)
1222 // !!! Should somehow tag / disable / remove it?
1223 Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1224 fEventId, fgCurrent->GetName(), exc.Data());
1227 fgCurrent = fgMaster;
1228 gEve->SetCurrentEvent(fgMaster);
1232 void AliEveEventManager::NewEventLoaded()
1234 // Emit NewEventLoaded signal.
1236 Emit("NewEventLoaded()");
1240 //------------------------------------------------------------------------------
1241 // Event info dumpers
1242 //------------------------------------------------------------------------------
1244 TString AliEveEventManager::GetEventInfoHorizontal() const
1246 // Dumps the event-header contents in vertical formatting.
1248 TString rawInfo, esdInfo;
1252 rawInfo = "No raw-data event info is available!\n";
1256 const UInt_t* attr = fRawReader->GetAttributes();
1257 TTimeStamp ts(fRawReader->GetTimestamp());
1258 rawInfo.Form("RAW event info: Run#: %d Event type: %d (%s) Period: %x Orbit: %x BC: %x\n"
1259 "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x Timestamp: %s\n",
1260 fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1261 fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1262 fRawReader->GetClassMask(),
1263 *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1264 attr[0],attr[1],attr[2], ts.AsString("s"));
1269 esdInfo = "No ESD event info is available!";
1273 TString acttrclasses = fESD->GetESDRun()->GetActiveTriggerClasses();
1274 TString firedtrclasses = fESD->GetFiredTriggerClasses();
1275 TTimeStamp ts(fESD->GetTimeStamp());
1276 esdInfo.Form("ESD event info: Run#: %d Event type: %d (%s) Period: %x Orbit: %x BC: %x\n"
1277 "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d Timestamp: %s, MagField: %.2e",
1278 fESD->GetRunNumber(),
1279 fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1280 fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1281 acttrclasses.Data(),
1282 fESD->GetTriggerMask(),firedtrclasses.Data(),
1283 fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1286 return rawInfo + esdInfo;
1289 TString AliEveEventManager::GetEventInfoVertical() const
1291 // Dumps the event-header contents in vertical formatting.
1293 TString rawInfo, esdInfo;
1297 rawInfo = "No raw-data event info is available!\n";
1301 const UInt_t* attr = fRawReader->GetAttributes();
1302 rawInfo.Form("Raw-data event info:\nRun#: %d\nEvent type: %d (%s)\nPeriod: %x\nOrbit: %x BC: %x\nTrigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x\nTimestamp: %x\n",
1303 fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1304 fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1305 fRawReader->GetClassMask(),
1306 *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1307 attr[0],attr[1],attr[2],
1308 fRawReader->GetTimestamp());
1313 esdInfo = "No ESD event info is available!\n";
1317 TString acttrclasses = fESD->GetESDRun()->GetActiveTriggerClasses();
1318 TString firedtrclasses = fESD->GetFiredTriggerClasses();
1319 esdInfo.Form("ESD event info:\nRun#: %d\nActive trigger classes: %s\nEvent type: %d (%s)\nPeriod: %x\nOrbit: %x BC: %x\nTrigger: %llx (%s)\nEvent# in file:%d\nTimestamp: %x\n",
1320 fESD->GetRunNumber(),
1321 acttrclasses.Data(),
1322 fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1323 fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1324 fESD->GetTriggerMask(),firedtrclasses.Data(),
1325 fESD->GetEventNumberInFile(),
1326 fESD->GetTimeStamp());
1329 return rawInfo + "\n" + esdInfo;
1333 //==============================================================================
1334 // Reading of GRP and MagneticField.
1335 // This is a reap-off from reconstruction ... should really be a common
1336 // code to do this somewhere in STEER.
1337 //==============================================================================
1339 Bool_t AliEveEventManager::InitGRP()
1341 //------------------------------------
1342 // Initialization of the GRP entry
1343 //------------------------------------
1345 static const TEveException kEH("AliEveEventManager::InitGRP ");
1347 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1351 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
1355 ::Info(kEH, "Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1356 fgGRPData = new AliGRPObject();
1357 fgGRPData->ReadValuesFromMap(m);
1361 ::Info(kEH, "Found an AliGRPObject in GRP/GRP/Data, reading it");
1362 fgGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
1366 AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1371 ::Error(kEH, "No GRP entry found in OCDB!");
1375 TString lhcState = fgGRPData->GetLHCState();
1376 if (lhcState==AliGRPObject::GetInvalidString())
1378 ::Error(kEH, "GRP/GRP/Data entry: missing value for the LHC state ! Using UNKNOWN");
1379 lhcState = "UNKNOWN";
1382 TString beamType = fgGRPData->GetBeamType();
1383 if (beamType==AliGRPObject::GetInvalidString())
1385 ::Error(kEH, "GRP/GRP/Data entry: missing value for the beam type ! Using UNKNOWN");
1386 beamType = "UNKNOWN";
1389 Float_t beamEnergy = fgGRPData->GetBeamEnergy();
1390 if (beamEnergy==AliGRPObject::GetInvalidFloat())
1392 ::Error(kEH, "GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
1395 beamEnergy /= 120E3; // energy is provided in MeV*120
1397 TString runType = fgGRPData->GetRunType();
1398 if (runType==AliGRPObject::GetInvalidString())
1400 ::Error(kEH, "GRP/GRP/Data entry: missing value for the run type ! Using UNKNOWN");
1401 runType = "UNKNOWN";
1404 Int_t activeDetectors = fgGRPData->GetDetectorMask();
1405 if (activeDetectors==AliGRPObject::GetInvalidUInt())
1407 ::Error(kEH, "GRP/GRP/Data entry: missing value for the detector mask ! Using 1074790399");
1408 activeDetectors = 1074790399;
1412 // Might become useful.
1414 fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1415 printf("AliRunInfo - %s %s %f %s %d\n", lhcState.Data(), beamType.Data(), beamEnergy, runType.Data(), activeDetectors);
1419 // Process the list of active detectors
1420 if (activeDetectors) {
1421 UInt_t detMask = activeDetectors;
1422 fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1423 fRunTracking = MatchDetectorList(fRunTracking,detMask);
1424 fFillESD = MatchDetectorList(fFillESD,detMask);
1425 fQADetectors = MatchDetectorList(fQADetectors,detMask);
1426 fLoadCDB.Form("%s %s %s %s",
1427 fRunLocalReconstruction.Data(),
1428 fRunTracking.Data(),
1430 fQADetectors.Data());
1431 fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1432 if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1)) {
1433 // switch off the vertexer
1434 ::Info(kEH, "SPD is not in the list of active detectors. Vertexer switched off.");
1435 fRunVertexFinder = kFALSE;
1437 if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1438 // switch off the reading of CTP raw-data payload
1439 if (fFillTriggerESD) {
1440 ::Info(kEH, "CTP is not in the list of active detectors. CTP data reading switched off.");
1441 fFillTriggerESD = kFALSE;
1446 ::Info(kEH, "===================================================================================");
1447 ::Info(kEH, "Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data());
1448 ::Info(kEH, "Running tracking for detectors: %s",fRunTracking.Data());
1449 ::Info(kEH, "Filling ESD for detectors: %s",fFillESD.Data());
1450 ::Info(kEH, "Quality assurance is active for detectors: %s",fQADetectors.Data());
1451 ::Info(kEH, "CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data());
1452 ::Info(kEH, "===================================================================================");
1455 //*** Dealing with the magnetic field map
1456 if (TGeoGlobalMagField::Instance()->IsLocked())
1458 ::Info(kEH, "Running with externally locked B field!");
1462 // Construct the field map out of the information retrieved from GRP.
1464 Float_t l3Current = fgGRPData->GetL3Current((AliGRPObject::Stats)0);
1465 if (l3Current == AliGRPObject::GetInvalidFloat())
1466 throw kEH + "GRPData entry: missing value for the L3 current!";
1468 Char_t l3Polarity = fgGRPData->GetL3Polarity();
1469 if (l3Polarity == AliGRPObject::GetInvalidChar())
1470 throw kEH + "GRPData entry: missing value for the L3 polarity!";
1472 Float_t diCurrent = fgGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1473 if (diCurrent == AliGRPObject::GetInvalidFloat())
1474 throw kEH + "GRPData entry: missing value for the dipole current!";
1476 Char_t diPolarity = fgGRPData->GetDipolePolarity();
1477 if (diPolarity == AliGRPObject::GetInvalidChar())
1478 throw kEH + "GRPData entry: missing value for the dipole polarity!";
1480 if (!SetFieldMap(l3Current, diCurrent, l3Polarity ? -1:1, diPolarity ? -1:1))
1481 throw kEH + "Failed to create B field map!";
1483 ::Info(kEH, "Running with the B field constructed from GRP.");
1486 //*** Get the diamond profiles from OCDB
1487 // Eventually useful.
1490 entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1492 fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());
1494 ::Error(kEH, "No SPD diamond profile found in OCDB!");
1497 entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1499 fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());
1501 ::Error(kEH, "No diamond profile found in OCDB!");
1504 entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1506 fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());
1508 ::Error(kEH, "No TPC diamond profile found in OCDB!");
1515 Bool_t AliEveEventManager::SetFieldMap(Float_t l3Cur, Float_t diCur,
1516 Float_t l3Pol, Float_t diPol,
1518 const Char_t *beamtype,
1521 //------------------------------------------------
1522 // The magnetic field map, defined externally...
1523 // L3 current 30000 A -> 0.5 T
1524 // L3 current 12000 A -> 0.2 T
1525 // dipole current 6000 A
1526 // The polarities must be the same
1527 //------------------------------------------------
1529 static const TEveException kEH("AliEveEventManager::SetFieldMap ");
1531 const Float_t l3NominalCurrent1 = 30000.0; // (A)
1532 const Float_t l3NominalCurrent2 = 12000.0; // (A)
1533 const Float_t diNominalCurrent = 6000.0; // (A)
1535 const Float_t tolerance = 0.03; // relative current tolerance
1536 const Float_t zero = 77.0; // "zero" current (A)
1538 TString s = (l3Pol < 0) ? "L3: -" : "L3: +";
1540 AliMagF::BMap_t map = AliMagF::k5kG;
1544 l3Cur = TMath::Abs(l3Cur);
1545 if (TMath::Abs(l3Cur-l3NominalCurrent1)/l3NominalCurrent1 < tolerance)
1547 fcL3 = l3Cur/l3NominalCurrent1;
1548 map = AliMagF::k5kG;
1551 else if (TMath::Abs(l3Cur-l3NominalCurrent2)/l3NominalCurrent2 < tolerance)
1553 fcL3 = l3Cur/l3NominalCurrent2;
1554 map = AliMagF::k2kG;
1557 else if (l3Cur <= zero)
1560 map = AliMagF::k5kGUniform;
1562 fgUniformField = kTRUE; // track with the uniform (zero) B field
1566 ::Error(kEH, "Wrong L3 current (%f A)!", l3Cur);
1570 diCur = TMath::Abs(diCur);
1571 if (TMath::Abs(diCur-diNominalCurrent)/diNominalCurrent < tolerance)
1573 // 3% current tolerance...
1574 fcDip = diCur/diNominalCurrent;
1577 else if (diCur <= zero)
1578 { // some small current..
1584 ::Error(kEH, "Wrong dipole current (%f A)!", diCur);
1588 if (l3Pol != diPol && (map==AliMagF::k5kG || map==AliMagF::k2kG) && fcDip != 0)
1590 ::Error(kEH, "L3 and Dipole polarities must be the same");
1594 if (l3Pol<0) fcL3 = -fcL3;
1595 if (diPol<0) fcDip = -fcDip;
1597 AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
1598 TString btypestr = beamtype;
1601 TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
1602 TPRegexp ionBeam ("(lead|pb|ion|a)\\s*-?\\s*\\1");
1604 if (btypestr.Contains(ionBeam))
1605 btype = AliMagF::kBeamTypeAA;
1606 else if (btypestr.Contains(protonBeam))
1607 btype = AliMagF::kBeamTypepp;
1609 ::Info(kEH, "Cannot determine the beam type from %s, assume no LHC magnet field",
1612 AliMagF* fld = new AliMagF("MagneticFieldMap", s.Data(), 2, fcL3, fcDip, 10., map, path,
1614 TGeoGlobalMagField::Instance()->SetField(fld);
1615 TGeoGlobalMagField::Instance()->Lock();