]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/trains/EventTimeTask.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / trains / EventTimeTask.C
CommitLineData
9aba161a
CHC
1// EventTimeTask.C
2#ifndef __CINT__
3# include <TTree.h>
4# include <TError.h>
67a4bb96 5# include <TChain.h>
9aba161a
CHC
6#else
7class TTree;
8// Force load of libGui
9class TGWindow;
10#endif
11class AliESDEvent;
12
13/**
14 * Data structure to be filled by task - one for each event
15 *
67a4bb96 16 * @ingroup pwglf_forward_eventtime
9aba161a
CHC
17 */
18struct EventTimeData
19{
20 /**
21 * Widths of field in the full timestamp
22 */
23 enum {
24 kBCWidth = 12,
25 kOrbitWidth = 24,
26 kPeriodWidth = 28
27 };
28 /** Full time stamp */
29 ULong64_t fFull;
30 /** LDC creation time - standard time_t */
31 UInt_t fTime;
32 /** Mask of detectors present in the event - FMD is 0x1000 */
33 UInt_t fDetectors;
34 /** Type of event - 7 is physics */
35 UShort_t fType;
67a4bb96
CHC
36 /** GUID */
37 UChar_t fGUID[42];
9aba161a
CHC
38 /**
39 * Create a branch in a tree
40 *
41 * @param tree Tree to create the branch in
42 */
43 void CreateBranch(TTree* tree)
44 {
45 tree->Branch("event", &(this->fFull),
67a4bb96 46 "full/l:time/i:detector:type/s:guid/C");
9aba161a
CHC
47 }
48 /**
49 * Set the address of a branch for reading back objects from the tree
50 *
51 * @param tree Tree to read back from
52 */
53 void ReadBranch(TTree* tree)
54 {
55 tree->SetBranchAddress("event", &(this->fFull));
56 }
57 /**
58 * Utility function to encode the full time stamp from components.
59 *
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)
63 *
64 * @return Encoded full time stamp
65 */
66 static ULong64_t EncodeFull(ULong64_t period,
67 ULong64_t orbit,
68 ULong64_t bc)
69 {
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));
76 return ret;
77 }
78 /**
79 * Fill information from ESD into this data structure.
80 *
81 * @param esd Event
82 * @param dets List of active detectors in this event.
67a4bb96 83 * @param guid Current file GUID
9aba161a 84 */
67a4bb96 85 void Fill(AliESDEvent* esd, UInt_t dets, const TString& guid);
9aba161a
CHC
86};
87
88#ifndef NO_TASK
89# ifndef __CINT__
90# include <AliESDEvent.h>
91# endif
67a4bb96
CHC
92inline void EventTimeData::Fill(AliESDEvent* esd, UInt_t dets,
93 const TString& guid)
9aba161a
CHC
94{
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);
67a4bb96
CHC
102 Int_t i = 0;
103 for (i = 0; i < guid.Length() && i < 42; i++) fGUID[i] = guid[i];
104 for (; i < 42; i++) fGUID[i] = '\0';
105 fGUID[41] = '\0';
9aba161a
CHC
106}
107# else
67a4bb96 108inline void EventTimeData::Fill(AliESDEvent*, UInt_t, const TString&)
9aba161a
CHC
109{
110 Warning("Fill", "Calling empty method - shouldn't happen");
111}
112#endif
113
114#ifndef NO_TASK
115# ifndef __CINT__
116# include <AliAnalysisManager.h>
67a4bb96 117# include <AliVEventHandler.h>
9aba161a
CHC
118# include <AliESDEvent.h>
119# include <TTree.h>
120# include <TH2.h>
121# include <TList.h>
122# include <AliCDBManager.h>
123# include <AliCDBEntry.h>
124# include <AliTriggerConfiguration.h>
125# include <AliTriggerClass.h>
126# include <AliTriggerCluster.h>
127# include <AliDAQ.h>
128# include <TObjArray.h>
129# include <TDirectory.h>
67a4bb96 130# include <TUrl.h>
9aba161a
CHC
131# else
132class AliAnalysisManager;
133class TTree;
134class AliTimeStamp;
135class TList;
136class TH2;
137# endif
138# include <AliAnalysisTaskSE.h>
139# include <vector>
140
141/**
142 * A task to record the unique timestamp of each event.
143 *
144 * @par Input: ESD
145 * @par Output: A tree with a single branch
67a4bb96 146 * @ingroup pwglf_forward_eventtime
9aba161a
CHC
147 */
148class EventTimeTask : public AliAnalysisTaskSE
149{
150public:
151 enum {
152 kListSlot = 1,
153 kTreeSlot = 2
154 };
155 /**
156 * Default CTOR - for I/O only.
157 */
158 EventTimeTask()
159 : AliAnalysisTaskSE(),
160 fTree(0),
161 fHistograms(0),
162 fDetVsType(0)
163 {
164 }
165 /**
166 * User constructor
167 *
168 * @param name Name of task
169 */
170 EventTimeTask(const char* name)
171 : AliAnalysisTaskSE(name),
172 fTree(0),
173 fHistograms(0),
67a4bb96
CHC
174 fDetVsType(0),
175 fGUID("")
9aba161a
CHC
176 {
177 DefineOutput(kListSlot, TList::Class());
178 DefineOutput(kTreeSlot, TTree::Class());
179 fBranchNames = "ESD:AliESDRun.,AliESDHeader.";
180 }
181 /**
182 * Create user output objects.
183 *
184 * Called on each slave at start of job
185 */
186 void UserCreateOutputObjects()
187 {
188 Printf("Creating tree and histogram");
67a4bb96 189 fGUID = "";
9aba161a
CHC
190 fHistograms = new TList();
191 fHistograms->SetOwner();
192 fHistograms->SetName("L");
193
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());
207
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);
216 // savdir->cd();
217
218
219 PostData(kListSlot, fHistograms);
220 PostData(kTreeSlot, fTree);
221 }
222 /**
223 * Analyse a single event
224 *
225 */
226 void UserExec(Option_t*)
227 {
228 static Bool_t first = true;
229 LoadBranches();
230
231 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
232 if (!esd) return;
233 if (!esd->GetHeader()) return;
234
235 if (first) {
236 LoadTriggerConfig(esd->GetRunNumber());
237 first = false;
238 }
239 ULong64_t mask = esd->GetTriggerMask();
240 UInt_t dets = 0;
241 for (UShort_t i = 0; i < fDets.size(); i++) {
242 if ((1 << i) & mask) dets |= fDets[i];
243 }
244 // Printf("Event mask 0x%016llx -> 0x%08x", mask, dets);
67a4bb96 245 fData.Fill(esd, dets, fGUID);
9aba161a
CHC
246 fTree->Fill();
247
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);
252 }
253
254 PostData(kListSlot, fHistograms);
255 PostData(kTreeSlot, fTree);
256 }
67a4bb96
CHC
257 Bool_t UserNotify()
258 {
259 fGUID = "";
260 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
261 AliVEventHandler* inp = mgr->GetInputEventHandler();
262 if (!inp) {
263 Warning("UserNotify", "No input handler");
264 return true;
265 }
266 TTree* tree = inp->GetTree();
267 if (!tree) {
268 Warning("UserNotify", "No input tree");
269 return true;
270 }
271 TFile* file = tree->GetCurrentFile();
272 if (!file) {
273 Warning("UserNotify", "No current file for tree");
274 return true;
275 }
276 const TUrl* url = file->GetEndpointUrl();
277 if (!url) {
278 Warning("UserNotify", "No end point for file");
279 return false;
280 }
281 fGUID = gSystem->BaseName(url->GetFile());
282 Printf("Got GUID=%s from %s", fGUID.Data(), url->GetUrl());
283
284 return true;
285 }
9aba161a
CHC
286 void LoadTriggerConfig(Int_t runNo)
287 {
288 Printf("Loading trigger configuration for run %d", runNo);
289 // --- Connect to CDB --------------------------------------------
290 AliCDBManager* cdb = AliCDBManager::Instance();
291 cdb->SetDefaultStorageFromRun(runNo);
292 cdb->SetRun(runNo);
293
294 // --- Get entry -------------------------------------------------
295 AliCDBEntry* entry = cdb->Get("GRP/CTP/Config");
296 if (!entry || !entry->GetObject()) {
297 Warning("LoadTriggerConfig", "Couldn't get trigger configuration");
298 return;
299 }
300 AliTriggerConfiguration* config =
301 static_cast<AliTriggerConfiguration*>(entry->GetObject());
302
303 // --- Get the classes, and resize cache -------------------------
304 const TObjArray& clss = config->GetClasses();
305 fDets.resize(clss.GetEntries());
306
307 // --- Loop over configurations ----------------------------------
308 TIter next(&clss);
309 AliTriggerClass* cls = 0;
310 while ((cls = static_cast<AliTriggerClass*>(next()))) {
311 Int_t mask = cls->GetMask();
312 AliTriggerCluster* cluster = cls->GetCluster();
313 if (!cluster) {
314 Warning("LoadTriggerConfig",
315 "Failed to get trigger cluster for %s", cls->GetName());
316 continue;
317 }
318 TString names = cluster->GetDetectorsInCluster();
319 if (names.IsNull()) {
320 Warning("LoadTriggerConfig", "No detectors for cluster %s",
321 cls->GetName());
322 continue;
323 }
324 UInt_t dets = AliDAQ::DetectorPattern(names);
325 UInt_t id = UInt_t(TMath::Log2(mask));
326 fDets[id] = dets;
327 Printf("Trigger mask 0x%08x (%3d): 0x%08x (%s)",
328 mask, id, dets, names.Data());
329 }
330 // cdb->Destroy();
331 }
332 /**
333 * Register with manager and connect output containers
334 *
335 * @param mgr Manager
336 */
337 void Connect(AliAnalysisManager* mgr)
338 {
339 mgr->AddTask(this);
340 mgr->ConnectInput(this, 0, mgr->GetCommonInputContainer());
341 AliAnalysisDataContainer* contTree =
342 mgr->CreateContainer("T", TTree::Class(),
343 AliAnalysisManager::kOutputContainer,
344 "time.root");
345 AliAnalysisDataContainer* contList =
346 mgr->CreateContainer("L", TList::Class(),
347 AliAnalysisManager::kOutputContainer,
348 "hist.root");
349 mgr->ConnectOutput(this, kTreeSlot, contTree);
350 mgr->ConnectOutput(this, kListSlot, contList);
351 }
352 /**
353 * Create an instance of this task, and register it and it's
354 * outputs.
355 */
356 static void Create()
357 {
358 EventTimeTask* task = new EventTimeTask("eventTime");
359 task->Connect(AliAnalysisManager::GetAnalysisManager());
360 }
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
67a4bb96 366 TString fGUID;
9aba161a
CHC
367
368 ClassDef(EventTimeTask,3);
369};
370#endif // NO_TASK
371
372#ifndef NO_MAP
373#include <utility>
374#include <map>
375
376typedef std::pair<ULong64_t,ULong64_t> EventTimeMapPair;
377
378/**
379 * A map of event time-stamp to distance to previous event
380 *
67a4bb96 381 * @ingroup pwglf_forward_eventtime
9aba161a
CHC
382 */
383struct EventTimeMap : public TObject
384{
385 /** Map type */
386 typedef std::map<ULong64_t,ULong64_t> Map;
387 /** Key type */
388 typedef Map::key_type Key;
389 /** Mapped value type */
390 typedef Map::mapped_type Value;
391 /** Element type */
392 typedef Map::value_type Pair;
393 /** Iterator type */
394 typedef Map::iterator Iterator;
395 /** Constant iterator type */
396 typedef Map::const_iterator ConstIterator;
397 /**
398 * Constructor
399 */
400 EventTimeMap() : TObject(), fMap() {}
401 /**
402 * Destructor
403 */
404 virtual ~EventTimeMap() {}
405 /**
406 * Get name of this object - always the same
407 *
408 * @return The string "eventTimeMap"
409 */
410 const char* GetName() const { return "eventTimeMap"; }
411 /**
412 * Element access. If the key @a k doesn't already exist, it is
413 * created
414 *
415 * @param k Key
416 *
417 * @return A pair of key and value
418 */
419 Value& operator[](const Key& k)
420 {
421 return fMap[k];
422 }
423 /**
424 * Find the element whos key is @a k
425 *
426 * @param k Key to look for
427 *
428 * @return Iterator pointing to element, or end of container if not found
429 */
430 Iterator Find(const Key& k)
431 {
432 return fMap.find(k);
433 }
434 /**
435 * Find the element whos key is @a k
436 *
437 * @param k Key to look for
438 *
439 * @return Iterator pointing to element, or end of container if not found
440 */
441 ConstIterator Find(const Key& k) const
442 {
443 return fMap.find(k);
444 }
445 /**
446 * Get forward iterator pointing beginning of the container
447 *
448 * @return Iterator to start of container
449 */
450 Iterator Begin()
451 {
452 return fMap.begin();
453 }
454 /**
455 * Get forward iterator pointing beginning of the container
456 *
457 * @return Iterator to start of container
458 */
459 ConstIterator Begin() const
460 {
461 return fMap.begin();
462 }
463 /**
464 * Get forward iterator pointing just beyond the end of the container
465 *
466 * @return Iterator just beyond container
467 */
468 Iterator End()
469 {
470 return fMap.end();
471 }
472 /**
473 * Get forward iterator pointing just beyond the end of the container
474 *
475 * @return Iterator just beyond container
476 */
477 ConstIterator End() const
478 {
479 return fMap.end();
480 }
481 enum {
482 kInvalidTime = 0xFFFFFFFFFFFFFFFF
483 };
484 /**
485 * Get the time difference to previous event from a event with a
486 * given time stamp.
487 *
488 * @param timestamp Time stamp of the event
489 *
490 * @return time difference or kInvalidTime if not found
491 */
492 Value Get(const Key& timestamp) const
493 {
494 ConstIterator i = Find(timestamp);
495 if (i == End()) return kInvalidTime;
496 return i->second;
497 }
498 /**
499 * Set the time to previous event for a given event time stamp
500 *
501 * @param timestamp Event time stamp
502 * @param diff Time to previous event
503 */
504 void Set(const Key& timestamp, const Value& diff)
505 {
506 this->operator[](timestamp) = diff;
507 }
508 ULong64_t Size() const { return fMap.size(); }
509 /** Our embeded map */
510 Map fMap;
511 ClassDef(EventTimeMap,1)
512};
513#endif // NO_MAP
514
515#ifndef NO_SORTER
516# ifndef __CINT__
517# include <TFile.h>
518# include <TArrayL64.h>
519# include <TMath.h>
520# include <TParameter.h>
521# include <TCanvas.h>
522# include <TH1.h>
523# else
524class TFile;
525class TTree;
526class TCanvas;
527# endif
528
529/**
530 * A class to sort the tree and generate our timestamp->dT map.
67a4bb96
CHC
531 *
532 * @ingroup pwglf_forward_eventtime
9aba161a
CHC
533 */
534struct EventTimeSorter
535{
536 TTree* fTree;
537 EventTimeData fData;
538 ULong64_t fMin;
539 ULong64_t fMax;
540
541 /**
542 * Constructor
543 */
544 EventTimeSorter() : fTree(0), fData(), fMin(0xFFFFFFFFFFFFFFFF), fMax(0) {}
545 /**
546 * Progress meter
547 *
548 * @param cur Current entry
549 * @param total Total number of entries
550 */
551 void Progress(Long64_t cur, Long64_t total) const
552 {
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));
557 if (now > old)
558 std::cout << "\rLooping over " << total << " entries: ... "
559 << now << '%' << std::flush;
560 if (now >= 100) std::cout << std::endl;
561 old = now;
562 }
563 /**
564 * Connect a tree
565 *
566 * @param inputName
567 * @param treeName
568 *
569 * @return
570 */
571 Bool_t OpenInput(const char* inputName, const char* treeName)
572 {
573 CloseInput();
574
575 // --- Get input -------------------------------------------------
67a4bb96
CHC
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);
9aba161a
CHC
580 return false;
581 }
67a4bb96 582 fTree = chain;
9aba161a
CHC
583
584 // --- Set branch address ---------------------------------------
585 fData.ReadBranch(fTree);
586
587 return true;
588 }
589 /**
590 * Disconnect tree
591 */
592 void CloseInput()
593 {
594 if (!fTree) return;
595 TFile* file = fTree->GetCurrentFile();
596 if (file) file->Close();
597 fTree = 0;
598 }
599 /**
600 * Run the sorter
601 *
602 * @param inputName Input file name
603 * @param outputName Output file name
604 * @param treeName Tree name
605 *
606 * @return true on success
607 */
608 Bool_t Run(const char* inputName, const char* outputName,
609 const char* treeName="T")
610 {
611 if (!OpenInput(inputName, treeName)) return false;
612
613 // --- Loop over the data ----------------------------------------
614 Long64_t nEnt = fTree->GetEntries();
615 Long64_t n = 0;
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);
622
623 fTree->GetEntry(iEnt);
624
625 if (!(fData.fDetectors & 0x1000))
626 // No FMD read-out
627 continue;
628 if (fData.fType != 7) {
629 // Ignore all but physics events
630 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
631 // continue;
632 }
633
634 // Store values
635 Int_t j = n;
636 values[j] = fData.fFull;
637 dets[j] = fData.fDetectors;
638 types[j] = fData.fType;
639 times[j] = fData.fTime;
640 n++;
641 }
642
643 // --- Now sort all values ---------------------------------------
644 TArrayL64 index(n);
645 TMath::Sort(n, values, index.fArray, false);
646
647 // Maps the unique time to the distance to previous event
648 EventTimeMap eventTimeMap;
649 ULong64_t key = values[index[0]];
650 ULong64_t prev = 0;
651 ULong64_t dt = key-prev;
652 ULong64_t min = 0xFFFFFFFFFFFFFFFF;
653 ULong64_t max = 0;
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];
658 key = values[j];
659 prev = values[k];
660 dt = key - prev;
661 if (dt <= 0) {
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]);
666 // continue;
667 }
668 eventTimeMap[key] = dt;
669 min = TMath::Min(dt, min);
670 max = TMath::Max(dt, max);
671 }
672 std::cout << "Range is [" << min << "," << max << ']' << std::endl;
673
674 TFile* output = TFile::Open(outputName, "RECREATE");
675 if (!output) {
676 Error("Run", "Failed to create output file \"%s\"", outputName);
677 return false;
678 }
679 fMin = min;
680 fMax = max;
681 eventTimeMap.Write();
682 output->Write();
683 output->Close();
684
685 delete [] values;
686
687 CloseInput();
688
689 return true;
690 }
691 Bool_t Test(const char* inputName, const char* outputName,
692 const char* treeName="T")
693 {
694 if (!OpenInput(inputName, treeName)) return false;
695
696 // --- Get our map -----------------------------------------------
697 TFile* output = TFile::Open(outputName, "UPDATE");
698 if (!output) {
699 Error("Test", "Failed to open \"%s\"", outputName);
700 return false;
701 }
702
703 EventTimeMap* eventTimeMap =
704 static_cast<EventTimeMap*>(output->Get("eventTimeMap"));
705 if (!eventTimeMap) {
706 Error("Test", "Failed to get \"%s\" from \"%s\"",
707 "eventTimeMap", outputName);
708 return false;
709 }
710
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);
716 diff->SetStats(0);
717 diff->SetXTitle("#Deltat [ns]");
718 diff->SetFillColor(kRed+1);
719 diff->SetFillStyle(3001);
720 diff->SetDirectory(0);
721
722
723 TH1* ldiff = new TH1D("ldiff", "log(#Deltat) - Events w/FMD",
724 300, 0, 15);
725 ldiff->SetStats(0);
726 ldiff->SetXTitle("log_{10}(#Deltat) [ns]");
727 ldiff->SetFillColor(kGreen+1);
728 ldiff->SetFillStyle(3001);
729 ldiff->SetDirectory(0);
730
731 // --- Loop over the data ----------------------------------------
732 Long64_t nEnt = fTree->GetEntries();
733 Long64_t nZero = 0;
734 Long64_t nMiss = 0;
735 Long64_t nGood = 0;
736 Long64_t nNoFMD = 0;
737 for (Long64_t iEnt = 0; iEnt < /*10*/ nEnt; iEnt++) {
738 Progress(iEnt, nEnt);
739 fTree->GetEntry(iEnt);
740
741 if (!(fData.fDetectors & 0x1000)) {
742 // No FMD read-out
743 nNoFMD++;
744 continue;
745 }
746 if (fData.fType != 7) {
747 // Ignore all but physics events
748 Warning("Run", "Non-PHYSICS event (%d) with FMD in it", fData.fType);
749 // continue;
750 }
751
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);
757 ldiff->Fill(1);
758 nMiss++;
759 continue;
760 }
761 if (dT <= 0) {
762#if 0
763 Warning("Test", "Impossible dt=%llu found for %llu (0x%0x %2d)",
764 dT, value, fData.fDetectors, fData.fType);
765#endif
766 ldiff->Fill(1);
767 nZero++;
768 continue;
769 }
770 nGood++;
771 Double_t dt = 25.*dT;
772 diff->Fill(dt);
773 Double_t logDt = TMath::Log10(dt);
774 ldiff->Fill(logDt);
775 }
776 CloseInput();
777 Printf("missing: %llu, bad: %llu, good: %llu, no FMD: %llu, all: %llu",
778 nMiss,nZero,nGood,nNoFMD,nEnt);
779
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);
787 p->SetLogy();
788 ldiff->DrawCopy();
789
790 p = c->cd(1);
791 p->SetLogy();
792 p->SetLogx();
793 diff->DrawCopy();
794
795 c->Print("dt.png");
796 c->Print("dt.C");
797
798 // --- Write histogram to file -----------------------------------
799 output->cd();
800 diff->Write();
801 output->Write();
802 output->Close();
803
804 return true;
805 }
806};
807#endif // NO_SORTER
808#ifdef __MAKECINT__
809# ifndef NO_MAP
810# pragma link C++ class std::pair<ULong64_t,ULong64_t>+;
811# pragma link C++ class std::map<ULong64_t,ULong64_t>+;
812# endif
813# ifndef NO_TASK
814# pragma link C++ class std::vector<UInt_t>+;
815# endif
816#endif
817
818// EOF
819
820