6 #include <FairLogger.h>
7 #include <FairRootFileSink.h>
8 #include <FairRootManager.h>
9 #include <FairRunAna.h>
14 #include <TClonesArray.h>
17 #include <TMathBase.h>
20 #include "HTTimestamp.h"
28 if (evtTree !=
nullptr) {
29 LOG(error) <<
"HiRAEVT Tree was already set! Add more trees using the "
30 <<
"function AddInputTree.";
34 evtTree = std::make_unique<TChain>(treeName);
42 if (evtTree ==
nullptr) {
43 LOG(fatal) <<
"HiRAEVT TChain was not initialized using the "
44 <<
"function SetInputTree.";
48 return (evtTree->Add(fileName, -1) == 1);
53 auto *run =
dynamic_cast<AtRunAna *
>(FairRunAna::Instance());
55 LOG(fatal) <<
"Run must be of type AtRunAna or a derived type!";
58 FairRootManager *ioMan = FairRootManager::Instance();
59 if (ioMan ==
nullptr) {
60 LOG(fatal) <<
"Cannot find RootManager!";
64 fInputEventArray =
dynamic_cast<TClonesArray *
>(ioMan->GetObject(fInputBranchName));
65 if (fInputEventArray ==
nullptr) {
66 LOG(fatal) <<
"Cannot find AtRawEvent array in branch " << fInputBranchName <<
"!";
71 if (evtTree ==
nullptr) {
72 LOG(fatal) <<
"HiRAEVT tree was never initialized!";
75 std::cout <<
"EVT address: " << evtTree.get() << std::endl;
76 evtTree->SetBranchAddress(fEvtTimestampName, &fEvtTS);
79 fEvtOutputFile =
new TFile(fEvtOutputFileName,
"RECREATE");
80 if (fEvtOutputFile->IsZombie()) {
81 LOG(fatal) <<
"Failed to open output file: " << fEvtOutputFileName;
85 fEvtOutputTree = evtTree->CloneTree(0);
86 LOG(info) <<
"Initialized output EVT tree in " << fEvtOutputFileName;
91 void AtLinkDAQTask::DoFirstEvent()
94 fEvtTimestamp = fEvtTS->GetTimestamp();
97 LOG(info) <<
"Initial timestamps: " << fTpcTimestamp.at(fTpcTimestampIndex) <<
" " << fEvtTimestamp;
99 AtRunAna::Instance()->MarkFill(
false);
106 for (
int i = 0; i < numTimestamps; ++i) {
107 fGrDataRatio.emplace_back();
108 fGrDataAbs.emplace_back();
112 bool AtLinkDAQTask::UpdateTimestamps()
114 if (evtTree->GetEntry(fEvtTreeIndex) <= 0)
119 fOldEvtTimestamp = fEvtTimestamp;
120 fOldTpcTimestamp = fTpcTimestamp;
121 fEvtTimestamp = fEvtTS->GetTimestamp();
123 if (fTpcTimestamp.size() < fTpcTimestampIndex)
129 void AtLinkDAQTask::ResetFlags()
131 auto *run =
dynamic_cast<AtRunAna *
>(FairRunAna::Instance());
132 kFillEvt = run->GetMarkFill();
133 kCorruptedTimestamp =
false;
139 Int_t AtLinkDAQTask::CheckMatch()
141 if (kCorruptedTimestamp) {
144 Double_t diff =
static_cast<double>(fEvtTimestamp) -
static_cast<double>(fTpcTimestamp[fTpcTimestampIndex]);
145 diff -= fDifferenceOffset;
147 if (TMath::Abs(diff) < fCorruptedSearchRadius)
150 LOG(info) <<
"TPC Timestamp: " << fTpcTimestamp.at(fTpcTimestampIndex) << std::endl
151 <<
"EVT Timestamp: " << fEvtTimestamp << std::endl
152 <<
"diff: " << diff << std::endl;
156 fIntervalEvt = fEvtTimestamp - fOldEvtTimestamp;
157 fIntervalTpc = fTpcTimestamp.at(fTpcTimestampIndex) - fOldTpcTimestamp.at(fTpcTimestampIndex);
160 double scaledInterval = GetScaledInterval(fIntervalEvt, fIntervalTpc);
162 if (scaledInterval < fSearchRadius)
165 LOG(info) <<
"TPC Timestamp: " << fTpcTimestamp.at(fTpcTimestampIndex) << std::endl
166 <<
"EVT Timestamp: " << fEvtTimestamp << std::endl
167 <<
"TPC Interval: " << fIntervalTpc << std::endl
168 <<
"EVT Interval: " << fIntervalEvt << std::endl
169 <<
"Scaled Interval: " << scaledInterval << std::endl;
171 if (fIntervalTpc > fIntervalEvt * fSearchMean)
183 if (fInputEventArray->GetEntriesFast() == 0)
185 fEvent =
dynamic_cast<AtBaseEvent *
>(fInputEventArray->At(0));
193 if (!UpdateTimestamps()) {
194 LOG(warn) <<
"Failed to update timestamps. Skipping event";
195 AtRunAna::Instance()->MarkFill(
false);
202 ULong64_t upperInt = fTpcTimestamp.at(fTpcTimestampIndex) & 0xFFFFFFFF00000000;
203 kCorruptedTimestamp = (upperInt == 0xFFFFFFFF00000000);
204 if (kCorruptedTimestamp) {
205 LOG(warn) <<
"Corrupted timestamp " << std::hex << fTpcTimestamp.at(fTpcTimestampIndex) <<
" correcting to "
206 << (fTpcTimestamp.at(fTpcTimestampIndex) & 0x00000000FFFFFFFF) <<
" EVT: " << fEvtTimestamp << std::dec;
208 fTpcTimestamp.at(fTpcTimestampIndex) &= 0x00000000FFFFFFFF;
214 if (fEvtTimestamp < fOldEvtTimestamp ||
215 fTpcTimestamp.at(fTpcTimestampIndex) < fOldTpcTimestamp.at(fTpcTimestampIndex)) {
216 LOG(warn) <<
"Timestamp was reset between EVT event " << fEvtTreeIndex - 2 <<
" and " << fEvtTreeIndex - 1
217 <<
" reseting old timestamps and "
219 LOG(warn) <<
"EVT TS old: " << fOldEvtTimestamp <<
" EVT TS new: " << fEvtTimestamp;
220 LOG(warn) <<
"TPC TS old: " << fOldTpcTimestamp.at(fTpcTimestampIndex)
221 <<
" TPC TS new: " << fTpcTimestamp.at(fTpcTimestampIndex);
222 AtRunAna::Instance()->MarkFill(
false);
230 auto match = CheckMatch();
234 if (fDifferenceOffset == 0)
235 fDifferenceOffset = (double)fEvtTimestamp - (
double)fTpcTimestamp[fTpcTimestampIndex];
241 LOG(warn) <<
"Extra event, match number: " << match;
244 LOG(info) <<
"Extra EVT event found, searching for matching event";
248 auto currentIndex = fEvtTreeIndex;
249 auto maxIndex = currentIndex + 3;
251 if (maxIndex > evtTree->GetEntries())
252 maxIndex = evtTree->GetEntries();
255 while (currentIndex < maxIndex) {
257 evtTree->GetEntry(currentIndex++);
258 fEvtTimestamp = fEvtTS->GetTimestamp();
261 if (CheckMatch() == 0) {
262 LOG(info) <<
"Found match!" << std::endl;
263 fEvtTreeIndex = currentIndex;
269 LOG(error) <<
"Did not find match in next three events" << std::endl;
270 AtRunAna::Instance()->MarkFill(
false);
277 LOG(info) <<
"Extra TPC event found, searching for matching event!";
279 AtRunAna::Instance()->MarkFill(
false);
287 void AtLinkDAQTask::Fill()
294 double evtInterval = fEvtTimestamp - fOldEvtTimestamp;
295 for (
int i = 0; i < fGrDataRatio.size(); ++i) {
297 double intDiff = evtInterval;
299 if (i < fTpcTimestamp.size() && i < fOldTpcTimestamp.size())
300 intDiff -=
static_cast<double>(fTpcTimestamp.at(i) - fOldTpcTimestamp.at(i));
302 fGrDataAbs.at(i).push_back(intDiff);
304 intDiff /= evtInterval;
305 fGrDataRatio.at(i).push_back(intDiff);
307 fEvtOutputTree->Fill();
312 auto run =
dynamic_cast<AtRunAna *
>(FairRunAna::Instance());
313 auto outFile =
dynamic_cast<FairRootFileSink *
>(run->GetSink());
315 LOG(info) <<
"Adding TTree " << fEvtOutputTree->GetName() <<
" as friend to output tree "
316 << outFile->GetOutTree()->GetName();
317 outFile->GetOutTree()->AddFriend(fEvtOutputTree);
320 LOG(info) <<
"Writing graph and tree";
323 for (
int index = 0; index < fGrDataRatio.size(); ++index) {
324 fEvtOutputFile->cd();
325 auto gr = std::make_unique<TGraph>(fGrDataRatio[index].size());
326 auto gr2 = std::make_unique<TGraph>(fGrDataAbs[index].size());
327 gr->SetTitle(TString::Format(
"Relative intercal difference. TS_%d", index));
328 gr2->SetTitle(TString::Format(
"Abs interval difference. TS_%d", index));
330 for (
int i = 0; i < fGrDataRatio[index].size(); ++i) {
331 gr->SetPoint(i, i, fGrDataRatio[index].at(i));
332 gr2->SetPoint(i, i, fGrDataAbs[index].at(i));
334 gr->Write(TString::Format(
"Ratio_%d", index));
335 gr2->Write(TString::Format(
"Abs_%d", index));
338 fEvtOutputFile->cd();
339 fEvtOutputTree->Write();
340 fEvtOutputFile->Close();
343 Double_t AtLinkDAQTask::GetScaledInterval(ULong64_t intervalEvt, ULong64_t fIntercalTPC)
346 return TMath::Abs(
static_cast<double>(fIntercalTPC) /
static_cast<double>(intervalEvt)) / fSearchMean;
347 return TMath::Abs(
static_cast<double>(intervalEvt) -
static_cast<double>(fIntercalTPC)) / fSearchMean;