7 // Force load of libGui
13 * Data structure to be filled by task - one for each event
19 * Widths of field in the full timestamp
26 /** Full time stamp */
28 /** LDC creation time - standard time_t */
30 /** Mask of detectors present in the event - FMD is 0x1000 */
32 /** Type of event - 7 is physics */
35 * Create a branch in a tree
37 * @param tree Tree to create the branch in
39 void CreateBranch(TTree* tree)
41 tree->Branch("event", &(this->fFull),
42 "full/l:time/i:detector:type/s");
45 * Set the address of a branch for reading back objects from the tree
47 * @param tree Tree to read back from
49 void ReadBranch(TTree* tree)
51 tree->SetBranchAddress("event", &(this->fFull));
54 * Utility function to encode the full time stamp from components.
56 * @param period Period counter (overflow of orbit counter)
57 * @param orbit Orbit counter (period of 88us)
58 * @param bc Bunch crossing number (period of 25ns)
60 * @return Encoded full time stamp
62 static ULong64_t EncodeFull(ULong64_t period,
66 const ULong64_t bcMask = (1 << kBCWidth) - 1;
67 const ULong64_t orbitMask = (1 << kOrbitWidth) - 1;
68 const ULong64_t periodMask = (1 << kPeriodWidth) - 1;
69 ULong64_t ret = ((bc & bcMask) |
70 (orbit & orbitMask) << kBCWidth |
71 (period & periodMask) << (kBCWidth+kOrbitWidth));
75 * Fill information from ESD into this data structure.
78 * @param dets List of active detectors in this event.
80 void Fill(AliESDEvent* esd, UInt_t dets);
85 # include <AliESDEvent.h>
87 inline void EventTimeData::Fill(AliESDEvent* esd, UInt_t dets)
89 ULong64_t period = esd->GetPeriodNumber();
90 ULong64_t orbit = esd->GetOrbitNumber();
91 ULong64_t bc = esd->GetBunchCrossNumber();
92 fType = esd->GetEventType();
93 fTime = esd->GetTimeStamp();//LDC time
94 fDetectors = dets; // esd->GetDAQDetectorPattern();
95 fFull = EncodeFull(period, orbit, bc);
98 inline void EventTimeData::Fill(AliESDEvent*, UInt_t)
100 Warning("Fill", "Calling empty method - shouldn't happen");
106 # include <AliAnalysisManager.h>
107 # include <AliESDEvent.h>
111 # include <AliCDBManager.h>
112 # include <AliCDBEntry.h>
113 # include <AliTriggerConfiguration.h>
114 # include <AliTriggerClass.h>
115 # include <AliTriggerCluster.h>
117 # include <TObjArray.h>
118 # include <TDirectory.h>
120 class AliAnalysisManager;
126 # include <AliAnalysisTaskSE.h>
130 * A task to record the unique timestamp of each event.
133 * @par Output: A tree with a single branch
135 class EventTimeTask : public AliAnalysisTaskSE
143 * Default CTOR - for I/O only.
146 : AliAnalysisTaskSE(),
155 * @param name Name of task
157 EventTimeTask(const char* name)
158 : AliAnalysisTaskSE(name),
163 DefineOutput(kListSlot, TList::Class());
164 DefineOutput(kTreeSlot, TTree::Class());
165 fBranchNames = "ESD:AliESDRun.,AliESDHeader.";
168 * Create user output objects.
170 * Called on each slave at start of job
172 void UserCreateOutputObjects()
174 Printf("Creating tree and histogram");
175 fHistograms = new TList();
176 fHistograms->SetOwner();
177 fHistograms->SetName("L");
179 fDetVsType = new TH2D("detVsType", "Detector vs type",
180 16, -.5, 15.5, 31, -.5, 30.5);
181 fDetVsType->SetXTitle("Type");
182 fDetVsType->SetYTitle("Detector");
183 fDetVsType->SetDirectory(0);
184 fHistograms->Add(fDetVsType);
185 Printf("Histogram (%d,%f,%f)x(%d,%f,%f)",
186 fDetVsType->GetXaxis()->GetNbins(),
187 fDetVsType->GetXaxis()->GetXmin(),
188 fDetVsType->GetXaxis()->GetXmax(),
189 fDetVsType->GetYaxis()->GetNbins(),
190 fDetVsType->GetYaxis()->GetXmin(),
191 fDetVsType->GetYaxis()->GetXmax());
193 // TDirectory* savdir = gDirectory;
194 // Printf("Opening file at slot %d", kTreeSlot);
195 // OpenFile(kTreeSlot);
196 Printf("Make tree and disassociate from file");
197 fTree = new TTree("T", "T");
198 fTree->SetDirectory(0);
199 Printf("Create branch");
200 fData.CreateBranch(fTree);
204 PostData(kListSlot, fHistograms);
205 PostData(kTreeSlot, fTree);
208 * Analyse a single event
211 void UserExec(Option_t*)
213 static Bool_t first = true;
216 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
218 if (!esd->GetHeader()) return;
221 LoadTriggerConfig(esd->GetRunNumber());
224 ULong64_t mask = esd->GetTriggerMask();
226 for (UShort_t i = 0; i < fDets.size(); i++) {
227 if ((1 << i) & mask) dets |= fDets[i];
229 // Printf("Event mask 0x%016llx -> 0x%08x", mask, dets);
230 fData.Fill(esd, dets);
233 UInt_t type = esd->GetEventType();
234 UInt_t detectors = dets;
235 for (UInt_t i = 0; i < 31; i++) {
236 if ((1 << i) & detectors) fDetVsType->Fill(type, i);
239 PostData(kListSlot, fHistograms);
240 PostData(kTreeSlot, fTree);
242 void LoadTriggerConfig(Int_t runNo)
244 Printf("Loading trigger configuration for run %d", runNo);
245 // --- Connect to CDB --------------------------------------------
246 AliCDBManager* cdb = AliCDBManager::Instance();
247 cdb->SetDefaultStorageFromRun(runNo);
250 // --- Get entry -------------------------------------------------
251 AliCDBEntry* entry = cdb->Get("GRP/CTP/Config");
252 if (!entry || !entry->GetObject()) {
253 Warning("LoadTriggerConfig", "Couldn't get trigger configuration");
256 AliTriggerConfiguration* config =
257 static_cast<AliTriggerConfiguration*>(entry->GetObject());
259 // --- Get the classes, and resize cache -------------------------
260 const TObjArray& clss = config->GetClasses();
261 fDets.resize(clss.GetEntries());
263 // --- Loop over configurations ----------------------------------
265 AliTriggerClass* cls = 0;
266 while ((cls = static_cast<AliTriggerClass*>(next()))) {
267 Int_t mask = cls->GetMask();
268 AliTriggerCluster* cluster = cls->GetCluster();
270 Warning("LoadTriggerConfig",
271 "Failed to get trigger cluster for %s", cls->GetName());
274 TString names = cluster->GetDetectorsInCluster();
275 if (names.IsNull()) {
276 Warning("LoadTriggerConfig", "No detectors for cluster %s",
280 UInt_t dets = AliDAQ::DetectorPattern(names);
281 UInt_t id = UInt_t(TMath::Log2(mask));
283 Printf("Trigger mask 0x%08x (%3d): 0x%08x (%s)",
284 mask, id, dets, names.Data());
289 * Register with manager and connect output containers
293 void Connect(AliAnalysisManager* mgr)
296 mgr->ConnectInput(this, 0, mgr->GetCommonInputContainer());
297 AliAnalysisDataContainer* contTree =
298 mgr->CreateContainer("T", TTree::Class(),
299 AliAnalysisManager::kOutputContainer,
301 AliAnalysisDataContainer* contList =
302 mgr->CreateContainer("L", TList::Class(),
303 AliAnalysisManager::kOutputContainer,
305 mgr->ConnectOutput(this, kTreeSlot, contTree);
306 mgr->ConnectOutput(this, kListSlot, contList);
309 * Create an instance of this task, and register it and it's
314 EventTimeTask* task = new EventTimeTask("eventTime");
315 task->Connect(AliAnalysisManager::GetAnalysisManager());
317 TTree* fTree; // Our tree
318 EventTimeData fData; // Our data
319 TList* fHistograms; // List
320 TH2D* fDetVsType; // Histogram
321 std::vector<UInt_t> fDets; // Per-trigger-bit detector mask
323 ClassDef(EventTimeTask,3);
331 typedef std::pair<ULong64_t,ULong64_t> EventTimeMapPair;
334 * A map of event time-stamp to distance to previous event
337 struct EventTimeMap : public TObject
340 typedef std::map<ULong64_t,ULong64_t> Map;
342 typedef Map::key_type Key;
343 /** Mapped value type */
344 typedef Map::mapped_type Value;
346 typedef Map::value_type Pair;
348 typedef Map::iterator Iterator;
349 /** Constant iterator type */
350 typedef Map::const_iterator ConstIterator;
354 EventTimeMap() : TObject(), fMap() {}
358 virtual ~EventTimeMap() {}
360 * Get name of this object - always the same
362 * @return The string "eventTimeMap"
364 const char* GetName() const { return "eventTimeMap"; }
366 * Element access. If the key @a k doesn't already exist, it is
371 * @return A pair of key and value
373 Value& operator[](const Key& k)
378 * Find the element whos key is @a k
380 * @param k Key to look for
382 * @return Iterator pointing to element, or end of container if not found
384 Iterator Find(const Key& k)
389 * Find the element whos key is @a k
391 * @param k Key to look for
393 * @return Iterator pointing to element, or end of container if not found
395 ConstIterator Find(const Key& k) const
400 * Get forward iterator pointing beginning of the container
402 * @return Iterator to start of container
409 * Get forward iterator pointing beginning of the container
411 * @return Iterator to start of container
413 ConstIterator Begin() const
418 * Get forward iterator pointing just beyond the end of the container
420 * @return Iterator just beyond container
427 * Get forward iterator pointing just beyond the end of the container
429 * @return Iterator just beyond container
431 ConstIterator End() const
436 kInvalidTime = 0xFFFFFFFFFFFFFFFF
439 * Get the time difference to previous event from a event with a
442 * @param timestamp Time stamp of the event
444 * @return time difference or kInvalidTime if not found
446 Value Get(const Key& timestamp) const
448 ConstIterator i = Find(timestamp);
449 if (i == End()) return kInvalidTime;
453 * Set the time to previous event for a given event time stamp
455 * @param timestamp Event time stamp
456 * @param diff Time to previous event
458 void Set(const Key& timestamp, const Value& diff)
460 this->operator[](timestamp) = diff;
462 ULong64_t Size() const { return fMap.size(); }
463 /** Our embeded map */
465 ClassDef(EventTimeMap,1)
472 # include <TArrayL64.h>
474 # include <TParameter.h>
475 # include <TCanvas.h>
484 * A class to sort the tree and generate our timestamp->dT map.
486 struct EventTimeSorter
496 EventTimeSorter() : fTree(0), fData(), fMin(0xFFFFFFFFFFFFFFFF), fMax(0) {}
500 * @param cur Current entry
501 * @param total Total number of entries
503 void Progress(Long64_t cur, Long64_t total) const
505 static UShort_t old = 0;
506 if (cur == 0) old = 0;
507 UShort_t now = UShort_t(100 * (cur + 1 == total ? 1 :
508 Double_t(cur)/total));
510 std::cout << "\rLooping over " << total << " entries: ... "
511 << now << '%' << std::flush;
512 if (now >= 100) std::cout << std::endl;
523 Bool_t OpenInput(const char* inputName, const char* treeName)
527 // --- Get input -------------------------------------------------
528 TFile* input = TFile::Open(inputName, "READ");
530 Error("Run", "Failed to open \"%s\"", inputName);
534 fTree = static_cast<TTree*>(input->Get(treeName));
536 Error("Run", "Couldn't get tree \"%s\" from \"%s\"", treeName,inputName);
540 // --- Set branch address ---------------------------------------
541 fData.ReadBranch(fTree);
551 TFile* file = fTree->GetCurrentFile();
552 if (file) file->Close();
558 * @param inputName Input file name
559 * @param outputName Output file name
560 * @param treeName Tree name
562 * @return true on success
564 Bool_t Run(const char* inputName, const char* outputName,
565 const char* treeName="T")
567 if (!OpenInput(inputName, treeName)) return false;
569 // --- Loop over the data ----------------------------------------
570 Long64_t nEnt = fTree->GetEntries();
572 ULong64_t* values = new ULong64_t[nEnt];
573 UInt_t* dets = new UInt_t[nEnt];
574 UShort_t* types = new UShort_t[nEnt];
575 UInt_t* times = new UInt_t[nEnt];
576 for (Long64_t iEnt = 0; iEnt < nEnt; iEnt++) {
577 Progress(iEnt, nEnt);
579 fTree->GetEntry(iEnt);
581 if (!(fData.fDetectors & 0x1000))
584 if (fData.fType != 7) {
585 // Ignore all but physics events
586 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
592 values[j] = fData.fFull;
593 dets[j] = fData.fDetectors;
594 types[j] = fData.fType;
595 times[j] = fData.fTime;
599 // --- Now sort all values ---------------------------------------
601 TMath::Sort(n, values, index.fArray, false);
603 // Maps the unique time to the distance to previous event
604 EventTimeMap eventTimeMap;
605 ULong64_t key = values[index[0]];
607 ULong64_t dt = key-prev;
608 ULong64_t min = 0xFFFFFFFFFFFFFFFF;
610 eventTimeMap[key] = dt;
611 for (Long64_t i = 1; i < n; i++) {
612 Long64_t j = index[i];
613 Long64_t k = index[i-1];
618 Printf("0x%016llx==0x%016llx -> dt=%10llu [%10lld %10lld] "
619 "(det: 0x%08x 0x%08x type: 0x%04x 0x%04x time: %08d %08d)",
620 key, prev, dt, j, k, dets[j], dets[k],
621 types[j], types[k], times[j], times[k]);
624 eventTimeMap[key] = dt;
625 min = TMath::Min(dt, min);
626 max = TMath::Max(dt, max);
628 std::cout << "Range is [" << min << "," << max << ']' << std::endl;
630 TFile* output = TFile::Open(outputName, "RECREATE");
632 Error("Run", "Failed to create output file \"%s\"", outputName);
637 eventTimeMap.Write();
647 Bool_t Test(const char* inputName, const char* outputName,
648 const char* treeName="T")
650 if (!OpenInput(inputName, treeName)) return false;
652 // --- Get our map -----------------------------------------------
653 TFile* output = TFile::Open(outputName, "UPDATE");
655 Error("Test", "Failed to open \"%s\"", outputName);
659 EventTimeMap* eventTimeMap =
660 static_cast<EventTimeMap*>(output->Get("eventTimeMap"));
662 Error("Test", "Failed to get \"%s\" from \"%s\"",
663 "eventTimeMap", outputName);
667 // --- Histograms --------------------------------------------------
668 ULong64_t mmin = TMath::Min(25*fMin, 900000ULL);
669 ULong64_t mmax = TMath::Min(25*fMax, 110000000ULL);
670 TH1* diff = new TH1D("diff", "Time-to-last-event (10#mus bins w/FMD)",
671 (mmax-mmin)/10000, mmin, mmax);
673 diff->SetXTitle("#Deltat [ns]");
674 diff->SetFillColor(kRed+1);
675 diff->SetFillStyle(3001);
676 diff->SetDirectory(0);
679 TH1* ldiff = new TH1D("ldiff", "log(#Deltat) - Events w/FMD",
682 ldiff->SetXTitle("log_{10}(#Deltat) [ns]");
683 ldiff->SetFillColor(kGreen+1);
684 ldiff->SetFillStyle(3001);
685 ldiff->SetDirectory(0);
687 // --- Loop over the data ----------------------------------------
688 Long64_t nEnt = fTree->GetEntries();
693 for (Long64_t iEnt = 0; iEnt < /*10*/ nEnt; iEnt++) {
694 Progress(iEnt, nEnt);
695 fTree->GetEntry(iEnt);
697 if (!(fData.fDetectors & 0x1000)) {
702 if (fData.fType != 7) {
703 // Ignore all but physics events
704 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
708 // Look-up the timestamp
709 ULong64_t value = fData.fFull;
710 ULong64_t dT = eventTimeMap->Get(value);
711 if (dT == EventTimeMap::kInvalidTime) {
712 Warning("Test", "Value %llu not found", value);
719 Warning("Test", "Impossible dt=%llu found for %llu (0x%0x %2d)",
720 dT, value, fData.fDetectors, fData.fType);
727 Double_t dt = 25.*dT;
729 Double_t logDt = TMath::Log10(dt);
733 Printf("missing: %llu, bad: %llu, good: %llu, no FMD: %llu, all: %llu",
734 nMiss,nZero,nGood,nNoFMD,nEnt);
736 // --- Draw results ----------------------------------------------
737 TCanvas* c = new TCanvas("c", "C");
738 c->SetTopMargin(0.01);
739 c->SetRightMargin(0.01);
740 c->Divide(2,1); // ,0,0);
741 TVirtualPad* p = c->cd(2);
742 // p->SetRightMargin(0.10);
754 // --- Write histogram to file -----------------------------------
766 # pragma link C++ class std::pair<ULong64_t,ULong64_t>+;
767 # pragma link C++ class std::map<ULong64_t,ULong64_t>+;
770 # pragma link C++ class std::vector<UInt_t>+;