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
108
109#include "TRestEventTimeSelectionProcess.h"
110
111using namespace std;
112
114
119
125 SetSectionName(this->ClassName());
126 fEvent = nullptr;
127 fFileWithTimes = "";
128 fIsActiveTime = true;
129 fDelimiter = ',';
130 fStartEndTimes.clear();
131 fTimeOffsetInSeconds = 0;
132 fTimeStartMarginInSeconds = 0;
133 fTimeEndMarginInSeconds = 0;
135 fNEventsSelected = 0;
136 fTotalTimeInSeconds = 0;
137}
138
144 // Read the file with the time ranges
145 if (!fFileWithTimes.empty()) {
146 fStartEndTimes = ReadFileWithTimes(fFileWithTimes, fDelimiter);
147 }
148 fTotalTimeInSeconds = CalculateTotalTimeInSeconds();
150 fNEventsSelected = 0;
151}
152
153std::vector<std::pair<std::string, std::string>> TRestEventTimeSelectionProcess::ReadFileWithTimes(
154 std::string fileWithTimes, Char_t delimiter) {
155 std::vector<std::pair<std::string, std::string>> startEndTimes;
156 string line;
157 ifstream file(fileWithTimes);
158 if (file.is_open()) {
159 while (getline(file, line)) {
160 if (line[0] == '#') { // understand as comment
161 continue;
162 }
163 std::istringstream lineStream(line);
164 std::string startDate, endDate;
165 if (std::getline(lineStream, startDate, delimiter) &&
166 std::getline(lineStream, endDate, delimiter)) {
167 // check if the time format is correct. TODO: use better way to check
168 // (StringToTimeStamp usually returns a negative big number if not)
169 if (StringToTimeStamp(startDate) < 0 || StringToTimeStamp(endDate) < 0) {
170 continue;
171 }
172
173 startEndTimes.emplace_back(startDate, endDate);
174 }
175 }
176 file.close();
177 }
178 return startEndTimes;
179}
180
187 Double_t totalTime = 0;
188 for (auto id : fStartEndTimes) {
189 TTimeStamp startTime = TTimeStamp(StringToTimeStamp(id.first), 0);
190 TTimeStamp endTime = TTimeStamp(StringToTimeStamp(id.second), 0);
191 // Reduce the time by the margin in both sides
192 startTime.Add(TTimeStamp(fTimeStartMarginInSeconds));
193 endTime.Add(TTimeStamp(-fTimeEndMarginInSeconds));
194 auto timeDiff = endTime.AsDouble() - startTime.AsDouble();
195 if (timeDiff < 0) {
196 RESTDebug << "End time is before start time in time range: " << id.first << " to " << id.second
197 << RESTendl;
198 continue;
199 }
200 totalTime += endTime.AsDouble() - startTime.AsDouble();
201 }
202 return totalTime;
203}
204
209 fEvent = inputEvent;
210
211 TTimeStamp eventTime = fEvent->GetTimeStamp();
212 eventTime.Add(TTimeStamp(fTimeOffsetInSeconds));
213
214 Bool_t isInsideAnyTimeRange = false;
215 for (auto id : fStartEndTimes) {
216 TTimeStamp startTime = TTimeStamp(StringToTimeStamp(id.first), 0);
217 TTimeStamp endTime = TTimeStamp(StringToTimeStamp(id.second), 0);
218 // Reduce the time by the margin in both sides
219 startTime.Add(TTimeStamp(fTimeStartMarginInSeconds));
220 endTime.Add(TTimeStamp(-fTimeEndMarginInSeconds));
221 if (eventTime >= startTime && eventTime <= endTime) {
222 isInsideAnyTimeRange = true;
223 break;
224 }
225 }
226
227 // Decide if the event is selected or rejected based on the time ranges
228 // and their meaning (active or dead periods of time).
229 if (fIsActiveTime) { // time ranges represent active periods of time
230 if (isInsideAnyTimeRange) { // time is inside an active period of time
231 fNEventsSelected++;
232 return fEvent;
233 }
234 } else { // time ranges represent dead periods of time
235 if (!isInsideAnyTimeRange) { // time is outside all dead period of time
236 fNEventsSelected++;
237 return fEvent;
238 }
239 }
240
241 // rejected events are not returned
243 return nullptr;
244}
245
251 // Write here the jobs to do when all the events are processed
252}
253
266std::string TRestEventTimeSelectionProcess::GetTimeStampCut(std::string timeStampObsName, Bool_t useOffset,
267 Bool_t useMargins, Int_t nTimes) {
268 std::string timeCut = "";
269 std::string timeStampObsNameWithOffset = timeStampObsName;
270 if (useOffset && fTimeOffsetInSeconds != 0) {
271 timeStampObsNameWithOffset += "+" + to_string(fTimeOffsetInSeconds);
272 }
273 if (nTimes < 0) nTimes = fStartEndTimes.size();
274 Int_t c = 0;
275 for (auto id : fStartEndTimes) {
276 if (c++ >= nTimes) break;
277 auto startTime = StringToTimeStamp(id.first);
278 auto endTime = StringToTimeStamp(id.second);
279 // Reduce the time by the margin in both sides
280 if (useMargins) {
281 startTime += fTimeStartMarginInSeconds;
282 endTime -= fTimeEndMarginInSeconds;
283 }
284
285 if (startTime >= endTime) {
286 continue;
287 }
288
289 // Build the cut string
290 if (!timeCut.empty()) {
291 if (fIsActiveTime)
292 timeCut += " || "; // inside ANY time range
293 else
294 timeCut += " && "; // outside ALL time ranges
295 }
296 if (!fIsActiveTime) timeCut += "!"; // NOT inside the time range
297 // inside the time range
298 timeCut += "(";
299 timeCut += "(" + timeStampObsNameWithOffset + ">=" + to_string(startTime) + ")";
300 timeCut += " && ";
301 timeCut += "(" + timeStampObsNameWithOffset + "<=" + to_string(endTime) + ")";
302 timeCut += ")";
303 }
304 return timeCut;
305}
311 std::string typeOfTime = fIsActiveTime ? "Active" : "Dead";
312
313 RESTMetadata << "File with times: " << fFileWithTimes << RESTendl;
314 // print periods
315 RESTMetadata << "Offset time: " << fTimeOffsetInSeconds << " seconds" << RESTendl;
316 RESTMetadata << "Start margin time: " << fTimeStartMarginInSeconds << " seconds" << RESTendl;
317 RESTMetadata << "End margin time: " << fTimeEndMarginInSeconds << " seconds" << RESTendl;
318 RESTMetadata << typeOfTime << " time periods: " << RESTendl;
319 for (auto id : fStartEndTimes) {
320 RESTMetadata << id.first << " to " << id.second << RESTendl;
321 TTimeStamp startTime = TTimeStamp(StringToTimeStamp(id.first), 0);
322 TTimeStamp endTime = TTimeStamp(StringToTimeStamp(id.second), 0);
323 }
324
325 // Get total time in seconds
326 TTimeStamp totalTime = TTimeStamp(fTotalTimeInSeconds, 0);
327 if (!fStartEndTimes.empty()) {
328 TTimeStamp firstTime = TTimeStamp(StringToTimeStamp(fStartEndTimes.front().first), 0);
329 TTimeStamp lastTime = TTimeStamp(StringToTimeStamp(fStartEndTimes.back().second), 0);
330 totalTime = lastTime - firstTime;
331 }
332
333 double fractionOfTime = fTotalTimeInSeconds / totalTime.AsDouble() * 100;
334 std::string fractionOfTimeStr = StringWithPrecision(fractionOfTime, 4) + " %";
335 if ((Int_t)(fTotalTimeInSeconds / 24 / 3600) != 0) // order of days
336 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 24 / 3600 << " days"
337 << " (" << fractionOfTimeStr << ")" << RESTendl;
338 else if ((Int_t)(fTotalTimeInSeconds / 3600) != 0) // order of hours
339 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 3600 << " hours"
340 << " (" << fractionOfTimeStr << ")" << RESTendl;
341 else if ((Int_t)(fTotalTimeInSeconds / 60) != 0) // order of minutes
342 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds / 60 << " minutes"
343 << " (" << fractionOfTimeStr << ")" << RESTendl;
344 else
345 RESTMetadata << "Total " << typeOfTime << " time: " << fTotalTimeInSeconds << " seconds"
346 << " (" << fractionOfTimeStr << ")" << RESTendl;
347
348 RESTMetadata << "Number of events rejected: " << fNEventsRejected << " ("
349 << fNEventsRejected * 1. / (fNEventsRejected + fNEventsSelected) * 100 << " %)" << RESTendl;
350 RESTMetadata << "Number of events selected: " << fNEventsSelected << " ("
351 << fNEventsSelected * 1. / (fNEventsRejected + fNEventsSelected) * 100 << " %)" << RESTendl;
352
353 EndPrintProcess();
354}
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
time_t StringToTimeStamp(std::string time)
A method to convert a date/time formatted string to a timestamp.