REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
Loading...
Searching...
No Matches
TRestEventTimeSelectionProcess.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
115
116#include "TRestEventTimeSelectionProcess.h"
117
118using namespace std;
119
121
126
132 SetSectionName(this->ClassName());
133 fEvent = nullptr;
134 fFileWithTimes = "";
135 fIsActiveTime = true;
136 fDelimiter = ',';
137 fStartEndTimes.clear();
138 fTimeOffsetInSeconds = 0;
139 fTimeStartMarginInSeconds = 0;
140 fTimeEndMarginInSeconds = 0;
141 fUseRunStartAndEndTimes = true;
143 fNEventsSelected = 0;
144 fTotalTimeInSeconds = 0;
145}
146
152 // Read the file with the time ranges
153 if (!fFileWithTimes.empty()) {
154 fStartEndTimes = ReadFileWithTimes(fFileWithTimes, fDelimiter);
155 }
156 if (fUseRunStartAndEndTimes) {
157 TRestRun* run = GetRunInfo();
158 if (run) {
159 auto startTimeStamp = run->GetStartTimestamp();
160 auto endTimeStamp = run->GetEndTimestamp();
161 ApplyStartRunTime(startTimeStamp);
162 ApplyEndRunTime(endTimeStamp);
163 } else {
164 RESTWarning << "No run information available to get TRestRun start and end times." << RESTendl;
165 }
166 }
167 fTotalTimeInSeconds = CalculateTotalTimeInSeconds();
169 fNEventsSelected = 0;
170}
171
172std::vector<Interval> TRestEventTimeSelectionProcess::ReadFileWithTimes(std::string fileWithTimes,
173 Char_t delimiter) {
174 std::vector<Interval> startEndTimes;
175 string line;
176 ifstream file(fileWithTimes);
177 if (file.is_open()) {
178 while (getline(file, line)) {
179 if (line[0] == '#') { // understand as comment
180 continue;
181 }
182 std::istringstream lineStream(line);
183 std::string startDate, endDate;
184 if (std::getline(lineStream, startDate, delimiter) &&
185 std::getline(lineStream, endDate, delimiter)) {
186 // check if the time format is correct. TODO: use better way to check
187 // (StringToTimeStamp usually returns a negative big number if not)
188 if (StringToTimeStamp(startDate) < 0 || StringToTimeStamp(endDate) < 0) {
189 continue;
190 }
191 TTimeStamp sts = StringToTimeStamp(startDate);
192 TTimeStamp ets = StringToTimeStamp(endDate);
193 startEndTimes.emplace_back(sts, ets);
194 }
195 }
196 file.close();
197 }
198
199 // sort by start time and then by end time (lexicographically)
200 std::sort(startEndTimes.begin(), startEndTimes.end());
201
202 return startEndTimes;
203}
204
211 Double_t totalTime = 0;
212 for (auto se : fStartEndTimes) {
213 TTimeStamp startTime = se.first;
214 TTimeStamp endTime = se.second;
215 // Reduce the time by the margin in both sides
216 startTime.Add(TTimeStamp(fTimeStartMarginInSeconds));
217 endTime.Add(TTimeStamp(-fTimeEndMarginInSeconds));
218 auto timeDiff = endTime.AsDouble() - startTime.AsDouble();
219 if (timeDiff < 0) {
220 RESTDebug << "End time is before start time in time range: " << se.first << " to " << se.second
221 << RESTendl;
222 continue;
223 }
224 totalTime += endTime.AsDouble() - startTime.AsDouble();
225 }
226 return totalTime;
227}
228
233 fEvent = inputEvent;
234
235 TTimeStamp eventTime = fEvent->GetTimeStamp();
236 eventTime.Add(TTimeStamp(fTimeOffsetInSeconds));
237
238 Bool_t isInsideAnyTimeRange = false;
239 for (auto se : fStartEndTimes) {
240 TTimeStamp startTime = se.first;
241 TTimeStamp endTime = se.second;
242 if (fIsActiveTime) {
243 // Reduce the active time window by the margin in both sides
244 startTime.Add(TTimeStamp(fTimeStartMarginInSeconds));
245 endTime.Add(TTimeStamp(-fTimeEndMarginInSeconds));
246 } else {
247 // Increase the dead time window by the margin in both sides
248 startTime.Add(TTimeStamp(-fTimeStartMarginInSeconds));
249 endTime.Add(TTimeStamp(fTimeEndMarginInSeconds));
250 }
251
252 if (eventTime >= startTime && eventTime <= endTime) {
253 isInsideAnyTimeRange = true;
254 break;
255 }
256 }
257
258 // Decide if the event is selected or rejected based on the time ranges
259 // and their meaning (active or dead periods of time).
260 if (fIsActiveTime) { // time ranges represent active periods of time
261 if (isInsideAnyTimeRange) { // time is inside an active period of time
262 fNEventsSelected++;
263 return fEvent;
264 }
265 } else { // time ranges represent dead periods of time
266 if (!isInsideAnyTimeRange) { // time is outside all dead period of time
267 fNEventsSelected++;
268 return fEvent;
269 }
270 }
271
272 // rejected events are not returned
274 return nullptr;
275}
276
282 // Write here the jobs to do when all the events are processed
283}
284
285void TRestEventTimeSelectionProcess::ApplyStartRunTime(const TTimeStamp& runStart) {
286 size_t startIndex = 0;
287 bool isInsideTimeRange = false;
288 for (auto se : fStartEndTimes) {
289 TTimeStamp s = se.first;
290 TTimeStamp e = se.second;
291
292 if (runStart < s) {
293 isInsideTimeRange = false;
294 break;
295 }
296
297 if (runStart >= s && runStart <= e) {
298 isInsideTimeRange = true;
299 break;
300 }
301
302 startIndex++;
303 }
304
305 if (isInsideTimeRange) {
306 // modify the start time of the found interval
307 fStartEndTimes[startIndex].first = runStart;
308 }
309 // remove all intervals before the run start time
310 fStartEndTimes.erase(fStartEndTimes.begin(), fStartEndTimes.begin() + startIndex);
311}
312
313void TRestEventTimeSelectionProcess::ApplyEndRunTime(const TTimeStamp& runEnd) {
314 size_t endIndex = 0;
315 bool isInsideTimeRange = false;
316 for (auto se : fStartEndTimes) {
317 TTimeStamp s = se.first;
318 TTimeStamp e = se.second;
319
320 if (runEnd < s) {
321 isInsideTimeRange = false;
322 break;
323 }
324
325 if (runEnd >= s && runEnd <= e) {
326 isInsideTimeRange = true;
327 break;
328 }
329
330 endIndex++;
331 }
332
333 if (isInsideTimeRange) {
334 // modify the end time of the found interval
335 fStartEndTimes[endIndex].second = runEnd;
336 endIndex++; // to erase from the next interval
337 }
338 // remove all intervals after the run end time
339 fStartEndTimes.erase(fStartEndTimes.begin() + endIndex, fStartEndTimes.end());
340}
341
354std::string TRestEventTimeSelectionProcess::GetTimeStampCut(std::string timeStampObsName, Bool_t useOffset,
355 Bool_t useMargins, Int_t nTimes) {
356 std::string timeCut = "";
357 std::string timeStampObsNameWithOffset = timeStampObsName;
358 if (useOffset && fTimeOffsetInSeconds != 0) {
359 timeStampObsNameWithOffset += "+" + to_string(fTimeOffsetInSeconds);
360 }
361 if (nTimes < 0) nTimes = fStartEndTimes.size();
362 Int_t c = 0;
363 for (auto se : fStartEndTimes) {
364 if (c++ >= nTimes) break;
365 auto startTime = se.first;
366 auto endTime = se.second;
367 // Reduce the time by the margin in both sides
368 if (useMargins) {
369 if (fIsActiveTime) {
370 // Reduce the active time window by the margin in both sides
371 startTime.Add(fTimeStartMarginInSeconds);
372 endTime.Add(-fTimeEndMarginInSeconds);
373 } else {
374 // Increase the dead time window by the margin in both sides
375 startTime.Add(-fTimeStartMarginInSeconds);
376 endTime.Add(fTimeEndMarginInSeconds);
377 }
378 }
379
380 if (startTime >= endTime) {
381 continue;
382 }
383
384 // Build the cut string
385 if (!timeCut.empty()) {
386 if (fIsActiveTime)
387 timeCut += " || "; // inside ANY time range
388 else
389 timeCut += " && "; // outside ALL time ranges
390 }
391 if (!fIsActiveTime) timeCut += "!"; // NOT inside the time range
392 // inside the time range
393 timeCut += "(";
394 timeCut += "(" + timeStampObsNameWithOffset + ">=" + to_string(startTime) + ")";
395 timeCut += " && ";
396 timeCut += "(" + timeStampObsNameWithOffset + "<=" + to_string(endTime) + ")";
397 timeCut += ")";
398 }
399 return timeCut;
400}
406 std::string typeOfTime = fIsActiveTime ? "Active" : "Dead";
407
408 RESTMetadata << "File with times: " << fFileWithTimes << RESTendl;
409 // print periods
410 RESTMetadata << "Use run start and end: " << (fUseRunStartAndEndTimes ? "true" : "false") << RESTendl;
411 RESTMetadata << "Offset time: " << fTimeOffsetInSeconds << " seconds" << RESTendl;
412 RESTMetadata << "Start margin time: " << fTimeStartMarginInSeconds << " seconds" << RESTendl;
413 RESTMetadata << "End margin time: " << fTimeEndMarginInSeconds << " seconds" << RESTendl;
414 RESTMetadata << typeOfTime << " time periods: " << RESTendl;
415 for (auto se : fStartEndTimes) {
416 std::string startStr = ToDateTimeString(se.first);
417 std::string endStr = ToDateTimeString(se.second);
418 RESTMetadata << startStr << " to " << endStr << RESTendl;
419 }
420
421 // Get total time in seconds
422 TTimeStamp totalTime = TTimeStamp(fTotalTimeInSeconds, 0);
423 if (!fStartEndTimes.empty()) {
424 TTimeStamp firstTime = fStartEndTimes.front().first;
425 TTimeStamp lastTime = fStartEndTimes.back().second;
426 totalTime = lastTime - firstTime;
427 }
428
429 double fractionOfTime = fTotalTimeInSeconds / totalTime.AsDouble() * 100;
430 std::string fractionOfTimeStr = StringWithPrecision(fractionOfTime, 4) + " %";
431 if ((Int_t)(fTotalTimeInSeconds / 24 / 3600) != 0) // order of days
432 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 24 / 3600 << " days"
433 << " (" << fractionOfTimeStr << ")" << RESTendl;
434 else if ((Int_t)(fTotalTimeInSeconds / 3600) != 0) // order of hours
435 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 3600 << " hours"
436 << " (" << fractionOfTimeStr << ")" << RESTendl;
437 else if ((Int_t)(fTotalTimeInSeconds / 60) != 0) // order of minutes
438 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 60 << " minutes"
439 << " (" << fractionOfTimeStr << ")" << RESTendl;
440 else
441 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds << " seconds"
442 << " (" << fractionOfTimeStr << ")" << RESTendl;
443
444 RESTMetadata << "Number of events rejected: " << fNEventsRejected << " ("
445 << fNEventsRejected * 1. / (fNEventsRejected + fNEventsSelected) * 100 << " %)" << RESTendl;
446 RESTMetadata << "Number of events selected: " << fNEventsSelected << " ("
447 << fNEventsSelected * 1. / (fNEventsRejected + fNEventsSelected) * 100 << " %)" << RESTendl;
448
449 EndPrintProcess();
450}
TRestRun * GetRunInfo() const
Return the pointer of the hosting TRestRun object.
void BeginPrintProcess()
[name, cut range]
Double_t CalculateTotalTimeInSeconds()
Function to calculate the total time in seconds of all the time ranges (active or dead periods of tim...
void PrintMetadata() override
Prints on screen the process data members.
void EndProcess() override
Function to include required actions after all events have been processed.
Int_t fNEventsRejected
Information about the events processed.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
void Initialize() override
Function to initialize input/output event members and define the section name.
std::string GetTimeStampCut(std::string timeStampObsName="timeStamp", Bool_t useOffset=true, Bool_t useMargins=true, Int_t nTimes=-1)
Function to get the cut string that reproduce the time selection done by this process (useful for TRe...
void InitProcess() override
Process initialization.
A base class for any REST event.
Definition TRestEvent.h:38
endl_t RESTendl
Termination flag object for TRestStringOutput.
void SetSectionName(std::string sName)
set the section name, clear the section content
Data provider and manager in REST.
Definition TRestRun.h:18
time_t StringToTimeStamp(std::string time)
A method to convert a date/time formatted string to a timestamp.
std::string ToDateTimeString(time_t time)
Format time_t into string.