8 // Force load of libGui
14 * Data structure to be filled by task - one for each event
16 * @ingroup pwglf_forward_eventtime
21 * Widths of field in the full timestamp
28 /** Full time stamp */
30 /** LDC creation time - standard time_t */
32 /** Mask of detectors present in the event - FMD is 0x1000 */
34 /** Type of event - 7 is physics */
39 * Create a branch in a tree
41 * @param tree Tree to create the branch in
43 void CreateBranch(TTree* tree)
45 tree->Branch("event", &(this->fFull),
46 "full/l:time/i:detector:type/s:guid/C");
49 * Set the address of a branch for reading back objects from the tree
51 * @param tree Tree to read back from
53 void ReadBranch(TTree* tree)
55 tree->SetBranchAddress("event", &(this->fFull));
58 * Utility function to encode the full time stamp from components.
60 * @param period Period counter (overflow of orbit counter)
61 * @param orbit Orbit counter (period of 88us)
62 * @param bc Bunch crossing number (period of 25ns)
64 * @return Encoded full time stamp
66 static ULong64_t EncodeFull(ULong64_t period,
70 const ULong64_t bcMask = (1 << kBCWidth) - 1;
71 const ULong64_t orbitMask = (1 << kOrbitWidth) - 1;
72 const ULong64_t periodMask = (1 << kPeriodWidth) - 1;
73 ULong64_t ret = ((bc & bcMask) |
74 (orbit & orbitMask) << kBCWidth |
75 (period & periodMask) << (kBCWidth+kOrbitWidth));
79 * Fill information from ESD into this data structure.
82 * @param dets List of active detectors in this event.
83 * @param guid Current file GUID
85 void Fill(AliESDEvent* esd, UInt_t dets, const TString& guid);
90 # include <AliESDEvent.h>
92 inline void EventTimeData::Fill(AliESDEvent* esd, UInt_t dets,
95 ULong64_t period = esd->GetPeriodNumber();
96 ULong64_t orbit = esd->GetOrbitNumber();
97 ULong64_t bc = esd->GetBunchCrossNumber();
98 fType = esd->GetEventType();
99 fTime = esd->GetTimeStamp();//LDC time
100 fDetectors = dets; // esd->GetDAQDetectorPattern();
101 fFull = EncodeFull(period, orbit, bc);
103 for (i = 0; i < guid.Length() && i < 42; i++) fGUID[i] = guid[i];
104 for (; i < 42; i++) fGUID[i] = '\0';
108 inline void EventTimeData::Fill(AliESDEvent*, UInt_t, const TString&)
110 Warning("Fill", "Calling empty method - shouldn't happen");
116 # include <AliAnalysisManager.h>
117 # include <AliVEventHandler.h>
118 # include <AliESDEvent.h>
122 # include <AliCDBManager.h>
123 # include <AliCDBEntry.h>
124 # include <AliTriggerConfiguration.h>
125 # include <AliTriggerClass.h>
126 # include <AliTriggerCluster.h>
128 # include <TObjArray.h>
129 # include <TDirectory.h>
132 class AliAnalysisManager;
138 # include <AliAnalysisTaskSE.h>
142 * A task to record the unique timestamp of each event.
145 * @par Output: A tree with a single branch
146 * @ingroup pwglf_forward_eventtime
148 class EventTimeTask : public AliAnalysisTaskSE
156 * Default CTOR - for I/O only.
159 : AliAnalysisTaskSE(),
168 * @param name Name of task
170 EventTimeTask(const char* name)
171 : AliAnalysisTaskSE(name),
177 DefineOutput(kListSlot, TList::Class());
178 DefineOutput(kTreeSlot, TTree::Class());
179 fBranchNames = "ESD:AliESDRun.,AliESDHeader.";
182 * Create user output objects.
184 * Called on each slave at start of job
186 void UserCreateOutputObjects()
188 Printf("Creating tree and histogram");
190 fHistograms = new TList();
191 fHistograms->SetOwner();
192 fHistograms->SetName("L");
194 fDetVsType = new TH2D("detVsType", "Detector vs type",
195 16, -.5, 15.5, 31, -.5, 30.5);
196 fDetVsType->SetXTitle("Type");
197 fDetVsType->SetYTitle("Detector");
198 fDetVsType->SetDirectory(0);
199 fHistograms->Add(fDetVsType);
200 Printf("Histogram (%d,%f,%f)x(%d,%f,%f)",
201 fDetVsType->GetXaxis()->GetNbins(),
202 fDetVsType->GetXaxis()->GetXmin(),
203 fDetVsType->GetXaxis()->GetXmax(),
204 fDetVsType->GetYaxis()->GetNbins(),
205 fDetVsType->GetYaxis()->GetXmin(),
206 fDetVsType->GetYaxis()->GetXmax());
208 // TDirectory* savdir = gDirectory;
209 // Printf("Opening file at slot %d", kTreeSlot);
210 // OpenFile(kTreeSlot);
211 Printf("Make tree and disassociate from file");
212 fTree = new TTree("T", "T");
213 fTree->SetDirectory(0);
214 Printf("Create branch");
215 fData.CreateBranch(fTree);
219 PostData(kListSlot, fHistograms);
220 PostData(kTreeSlot, fTree);
223 * Analyse a single event
226 void UserExec(Option_t*)
228 static Bool_t first = true;
231 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
233 if (!esd->GetHeader()) return;
236 LoadTriggerConfig(esd->GetRunNumber());
239 ULong64_t mask = esd->GetTriggerMask();
241 for (UShort_t i = 0; i < fDets.size(); i++) {
242 if ((1 << i) & mask) dets |= fDets[i];
244 // Printf("Event mask 0x%016llx -> 0x%08x", mask, dets);
245 fData.Fill(esd, dets, fGUID);
248 UInt_t type = esd->GetEventType();
249 UInt_t detectors = dets;
250 for (UInt_t i = 0; i < 31; i++) {
251 if ((1 << i) & detectors) fDetVsType->Fill(type, i);
254 PostData(kListSlot, fHistograms);
255 PostData(kTreeSlot, fTree);
260 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
261 AliVEventHandler* inp = mgr->GetInputEventHandler();
263 Warning("UserNotify", "No input handler");
266 TTree* tree = inp->GetTree();
268 Warning("UserNotify", "No input tree");
271 TFile* file = tree->GetCurrentFile();
273 Warning("UserNotify", "No current file for tree");
276 const TUrl* url = file->GetEndpointUrl();
278 Warning("UserNotify", "No end point for file");
281 fGUID = gSystem->BaseName(url->GetFile());
282 Printf("Got GUID=%s from %s", fGUID.Data(), url->GetUrl());
286 void LoadTriggerConfig(Int_t runNo)
288 Printf("Loading trigger configuration for run %d", runNo);
289 // --- Connect to CDB --------------------------------------------
290 AliCDBManager* cdb = AliCDBManager::Instance();
291 cdb->SetDefaultStorageFromRun(runNo);
294 // --- Get entry -------------------------------------------------
295 AliCDBEntry* entry = cdb->Get("GRP/CTP/Config");
296 if (!entry || !entry->GetObject()) {
297 Warning("LoadTriggerConfig", "Couldn't get trigger configuration");
300 AliTriggerConfiguration* config =
301 static_cast<AliTriggerConfiguration*>(entry->GetObject());
303 // --- Get the classes, and resize cache -------------------------
304 const TObjArray& clss = config->GetClasses();
305 fDets.resize(clss.GetEntries());
307 // --- Loop over configurations ----------------------------------
309 AliTriggerClass* cls = 0;
310 while ((cls = static_cast<AliTriggerClass*>(next()))) {
311 Int_t mask = cls->GetMask();
312 AliTriggerCluster* cluster = cls->GetCluster();
314 Warning("LoadTriggerConfig",
315 "Failed to get trigger cluster for %s", cls->GetName());
318 TString names = cluster->GetDetectorsInCluster();
319 if (names.IsNull()) {
320 Warning("LoadTriggerConfig", "No detectors for cluster %s",
324 UInt_t dets = AliDAQ::DetectorPattern(names);
325 UInt_t id = UInt_t(TMath::Log2(mask));
327 Printf("Trigger mask 0x%08x (%3d): 0x%08x (%s)",
328 mask, id, dets, names.Data());
333 * Register with manager and connect output containers
337 void Connect(AliAnalysisManager* mgr)
340 mgr->ConnectInput(this, 0, mgr->GetCommonInputContainer());
341 AliAnalysisDataContainer* contTree =
342 mgr->CreateContainer("T", TTree::Class(),
343 AliAnalysisManager::kOutputContainer,
345 AliAnalysisDataContainer* contList =
346 mgr->CreateContainer("L", TList::Class(),
347 AliAnalysisManager::kOutputContainer,
349 mgr->ConnectOutput(this, kTreeSlot, contTree);
350 mgr->ConnectOutput(this, kListSlot, contList);
353 * Create an instance of this task, and register it and it's
358 EventTimeTask* task = new EventTimeTask("eventTime");
359 task->Connect(AliAnalysisManager::GetAnalysisManager());
361 TTree* fTree; // Our tree
362 EventTimeData fData; // Our data
363 TList* fHistograms; // List
364 TH2D* fDetVsType; // Histogram
365 std::vector<UInt_t> fDets; // Per-trigger-bit detector mask
368 ClassDef(EventTimeTask,3);
376 typedef std::pair<ULong64_t,ULong64_t> EventTimeMapPair;
379 * A map of event time-stamp to distance to previous event
381 * @ingroup pwglf_forward_eventtime
383 struct EventTimeMap : public TObject
386 typedef std::map<ULong64_t,ULong64_t> Map;
388 typedef Map::key_type Key;
389 /** Mapped value type */
390 typedef Map::mapped_type Value;
392 typedef Map::value_type Pair;
394 typedef Map::iterator Iterator;
395 /** Constant iterator type */
396 typedef Map::const_iterator ConstIterator;
400 EventTimeMap() : TObject(), fMap() {}
404 virtual ~EventTimeMap() {}
406 * Get name of this object - always the same
408 * @return The string "eventTimeMap"
410 const char* GetName() const { return "eventTimeMap"; }
412 * Element access. If the key @a k doesn't already exist, it is
417 * @return A pair of key and value
419 Value& operator[](const Key& k)
424 * Find the element whos key is @a k
426 * @param k Key to look for
428 * @return Iterator pointing to element, or end of container if not found
430 Iterator Find(const Key& k)
435 * Find the element whos key is @a k
437 * @param k Key to look for
439 * @return Iterator pointing to element, or end of container if not found
441 ConstIterator Find(const Key& k) const
446 * Get forward iterator pointing beginning of the container
448 * @return Iterator to start of container
455 * Get forward iterator pointing beginning of the container
457 * @return Iterator to start of container
459 ConstIterator Begin() const
464 * Get forward iterator pointing just beyond the end of the container
466 * @return Iterator just beyond container
473 * Get forward iterator pointing just beyond the end of the container
475 * @return Iterator just beyond container
477 ConstIterator End() const
482 kInvalidTime = 0xFFFFFFFFFFFFFFFF
485 * Get the time difference to previous event from a event with a
488 * @param timestamp Time stamp of the event
490 * @return time difference or kInvalidTime if not found
492 Value Get(const Key& timestamp) const
494 ConstIterator i = Find(timestamp);
495 if (i == End()) return kInvalidTime;
499 * Set the time to previous event for a given event time stamp
501 * @param timestamp Event time stamp
502 * @param diff Time to previous event
504 void Set(const Key& timestamp, const Value& diff)
506 this->operator[](timestamp) = diff;
508 ULong64_t Size() const { return fMap.size(); }
509 /** Our embeded map */
511 ClassDef(EventTimeMap,1)
518 # include <TArrayL64.h>
520 # include <TParameter.h>
521 # include <TCanvas.h>
530 * A class to sort the tree and generate our timestamp->dT map.
532 * @ingroup pwglf_forward_eventtime
534 struct EventTimeSorter
544 EventTimeSorter() : fTree(0), fData(), fMin(0xFFFFFFFFFFFFFFFF), fMax(0) {}
548 * @param cur Current entry
549 * @param total Total number of entries
551 void Progress(Long64_t cur, Long64_t total) const
553 static UShort_t old = 0;
554 if (cur == 0) old = 0;
555 UShort_t now = UShort_t(100 * (cur + 1 == total ? 1 :
556 Double_t(cur)/total));
558 std::cout << "\rLooping over " << total << " entries: ... "
559 << now << '%' << std::flush;
560 if (now >= 100) std::cout << std::endl;
571 Bool_t OpenInput(const char* inputName, const char* treeName)
575 // --- Get input -------------------------------------------------
576 TChain* chain = new TChain(treeName);
577 chain->Add(inputName);
578 if (chain->GetListOfFiles()->GetEntries() < 1) {
579 Error("Run", "Failed to add \"%s\" to chain", inputName);
584 // --- Set branch address ---------------------------------------
585 fData.ReadBranch(fTree);
595 TFile* file = fTree->GetCurrentFile();
596 if (file) file->Close();
602 * @param inputName Input file name
603 * @param outputName Output file name
604 * @param treeName Tree name
606 * @return true on success
608 Bool_t Run(const char* inputName, const char* outputName,
609 const char* treeName="T")
611 if (!OpenInput(inputName, treeName)) return false;
613 // --- Loop over the data ----------------------------------------
614 Long64_t nEnt = fTree->GetEntries();
616 ULong64_t* values = new ULong64_t[nEnt];
617 UInt_t* dets = new UInt_t[nEnt];
618 UShort_t* types = new UShort_t[nEnt];
619 UInt_t* times = new UInt_t[nEnt];
620 for (Long64_t iEnt = 0; iEnt < nEnt; iEnt++) {
621 Progress(iEnt, nEnt);
623 fTree->GetEntry(iEnt);
625 if (!(fData.fDetectors & 0x1000))
628 if (fData.fType != 7) {
629 // Ignore all but physics events
630 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
636 values[j] = fData.fFull;
637 dets[j] = fData.fDetectors;
638 types[j] = fData.fType;
639 times[j] = fData.fTime;
643 // --- Now sort all values ---------------------------------------
645 TMath::Sort(n, values, index.fArray, false);
647 // Maps the unique time to the distance to previous event
648 EventTimeMap eventTimeMap;
649 ULong64_t key = values[index[0]];
651 ULong64_t dt = key-prev;
652 ULong64_t min = 0xFFFFFFFFFFFFFFFF;
654 eventTimeMap[key] = dt;
655 for (Long64_t i = 1; i < n; i++) {
656 Long64_t j = index[i];
657 Long64_t k = index[i-1];
662 Printf("0x%016llx==0x%016llx -> dt=%10llu [%10lld %10lld] "
663 "(det: 0x%08x 0x%08x type: 0x%04x 0x%04x time: %08d %08d)",
664 key, prev, dt, j, k, dets[j], dets[k],
665 types[j], types[k], times[j], times[k]);
668 eventTimeMap[key] = dt;
669 min = TMath::Min(dt, min);
670 max = TMath::Max(dt, max);
672 std::cout << "Range is [" << min << "," << max << ']' << std::endl;
674 TFile* output = TFile::Open(outputName, "RECREATE");
676 Error("Run", "Failed to create output file \"%s\"", outputName);
681 eventTimeMap.Write();
691 Bool_t Test(const char* inputName, const char* outputName,
692 const char* treeName="T")
694 if (!OpenInput(inputName, treeName)) return false;
696 // --- Get our map -----------------------------------------------
697 TFile* output = TFile::Open(outputName, "UPDATE");
699 Error("Test", "Failed to open \"%s\"", outputName);
703 EventTimeMap* eventTimeMap =
704 static_cast<EventTimeMap*>(output->Get("eventTimeMap"));
706 Error("Test", "Failed to get \"%s\" from \"%s\"",
707 "eventTimeMap", outputName);
711 // --- Histograms --------------------------------------------------
712 ULong64_t mmin = TMath::Min(25*fMin, 900000ULL);
713 ULong64_t mmax = TMath::Min(25*fMax, 110000000ULL);
714 TH1* diff = new TH1D("diff", "Time-to-last-event (10#mus bins w/FMD)",
715 (mmax-mmin)/10000, mmin, mmax);
717 diff->SetXTitle("#Deltat [ns]");
718 diff->SetFillColor(kRed+1);
719 diff->SetFillStyle(3001);
720 diff->SetDirectory(0);
723 TH1* ldiff = new TH1D("ldiff", "log(#Deltat) - Events w/FMD",
726 ldiff->SetXTitle("log_{10}(#Deltat) [ns]");
727 ldiff->SetFillColor(kGreen+1);
728 ldiff->SetFillStyle(3001);
729 ldiff->SetDirectory(0);
731 // --- Loop over the data ----------------------------------------
732 Long64_t nEnt = fTree->GetEntries();
737 for (Long64_t iEnt = 0; iEnt < /*10*/ nEnt; iEnt++) {
738 Progress(iEnt, nEnt);
739 fTree->GetEntry(iEnt);
741 if (!(fData.fDetectors & 0x1000)) {
746 if (fData.fType != 7) {
747 // Ignore all but physics events
748 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
752 // Look-up the timestamp
753 ULong64_t value = fData.fFull;
754 ULong64_t dT = eventTimeMap->Get(value);
755 if (dT == EventTimeMap::kInvalidTime) {
756 Warning("Test", "Value %llu not found", value);
763 Warning("Test", "Impossible dt=%llu found for %llu (0x%0x %2d)",
764 dT, value, fData.fDetectors, fData.fType);
771 Double_t dt = 25.*dT;
773 Double_t logDt = TMath::Log10(dt);
777 Printf("missing: %llu, bad: %llu, good: %llu, no FMD: %llu, all: %llu",
778 nMiss,nZero,nGood,nNoFMD,nEnt);
780 // --- Draw results ----------------------------------------------
781 TCanvas* c = new TCanvas("c", "C");
782 c->SetTopMargin(0.01);
783 c->SetRightMargin(0.01);
784 c->Divide(2,1); // ,0,0);
785 TVirtualPad* p = c->cd(2);
786 // p->SetRightMargin(0.10);
798 // --- Write histogram to file -----------------------------------
810 # pragma link C++ class std::pair<ULong64_t,ULong64_t>+;
811 # pragma link C++ class std::map<ULong64_t,ULong64_t>+;
814 # pragma link C++ class std::vector<UInt_t>+;