REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawMultiFEMINOSToSignalProcess.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
64// int counter = 0;
65
66// Prefix Codes for 8-bit data content
67//
68#define PFX_8_BIT_CONTENT_MASK 0xFF00 // Mask to select 8 MSB's of prefix
69#define PFX_ASCII_MSG_LEN 0x0100 // ASCII message length
70//
71// Prefix Codes for 9-bit data content
72//
73#define PFX_9_BIT_CONTENT_MASK 0xFE00 // Mask to select 7 MSB's of prefix
74#define PFX_TIME_BIN_IX 0x0E00 // Time-bin Index
75#define PFX_HISTO_BIN_IX 0x0C00 // Histogram bin Index
76#define PFX_PEDTHR_LIST 0x0A00 // List of pedestal or thresholds
77#define PFX_START_OF_DFRAME 0x0800 // Start of Data Frame + 5 bit source + 4 bit Version
78#define PFX_START_OF_MFRAME 0x0600 // Start of Monitoring Frame + 4 bit Version + 5 bit source
79#define PFX_START_OF_CFRAME 0x0400 // Start of Configuration Frame + 4 bit Version + 5 bit source
80//
81// Macros to act on 8-bit data content
82//
83#define GET_ASCII_LEN(w) (((w)&0x00FF) >> 0)
84#define PUT_ASCII_LEN(w) (PFX_ASCII_MSG_LEN | ((w)&0x00FF))
85//
86// Prefix Codes for 0-bit data content
87//
88#define PFX_0_BIT_CONTENT_MASK 0xFFFF // Mask to select 16 MSB's of prefix
89#define PFX_END_OF_FRAME 0x000F // End of Frame (any type)
90#define PFX_DEADTIME_HSTAT_BINS 0x000E // Deadtime statistics and histogram
91#define PFX_PEDESTAL_HSTAT 0x000D // Pedestal histogram statistics
92#define PFX_PEDESTAL_H_MD 0x000C // Pedestal histogram Mean and Deviation
93#define PFX_SHISTO_BINS 0x000B // Hit S-curve histogram
94#define PFX_CMD_STATISTICS 0x000A // Command server statistics
95#define PFX_START_OF_BUILT_EVENT 0x0009 // Start of built event
96#define PFX_END_OF_BUILT_EVENT 0x0008 // End of built event
97#define PFX_EVPERIOD_HSTAT_BINS 0x0007 // Inter Event Time statistics and histogram
98#define PFX_SOBE_SIZE 0x0006 // Start of built event + Size
99#define PFX_NULL_CONTENT 0x0000 // NULL content
100//
101// Prefix Codes for 14-bit data content
102//
103#define PFX_14_BIT_CONTENT_MASK 0xC000 // Mask to select 2 MSB's of prefix
104#define PFX_CARD_CHIP_CHAN_HIT_IX 0xC000 // Index of Card, Chip and Channel Hit
105#define PFX_CARD_CHIP_CHAN_HIT_CNT 0x8000 // Nb of Channel hit for given Card and Chip
106#define PFX_CARD_CHIP_CHAN_HISTO 0x4000 // Pedestal Histogram for given Card and Chip
107//
108// Prefix Codes for 12-bit data content
109//
110#define PFX_12_BIT_CONTENT_MASK 0xF000 // Mask to select 4 MSB's of prefix
111#define PFX_ADC_SAMPLE 0x3000 // ADC sample
112#define PFX_LAT_HISTO_BIN 0x2000 // latency or inter event time histogram bin
113#define PFX_CHIP_LAST_CELL_READ 0x1000 // Chip index and last cell read
114//
115// Prefix Codes for 4-bit data content
116//
117#define PFX_4_BIT_CONTENT_MASK 0xFFF0 // Mask to select 12 MSB's of prefix
118#define PFX_START_OF_EVENT 0x00F0 // Start of Event + 1 bit free + Event Trigger Type
119#define PFX_END_OF_EVENT 0x00E0 // End of Event + 4 MSB of size
120
121//
122// Macros to act on 4-bit data content
123//
124#define GET_EVENT_TYPE(w) (((w)&0x0007) >> 0)
125#define GET_EOE_SIZE(w) (((w)&0x000F) >> 0)
126
127//
128// Macros to extract 14-bit data content
129//
130#define GET_CARD_IX(w) (((w)&0x3E00) >> 9)
131#define GET_CHIP_IX(w) (((w)&0x0180) >> 7)
132#define GET_CHAN_IX(w) (((w)&0x007F) >> 0)
133
134//
135// Macros to extract 12-bit data content
136//
137#define GET_ADC_DATA(w) (((w)&0x0FFF) >> 0)
138#define GET_LAT_HISTO_BIN(w) (((w)&0x0FFF) >> 0)
139#define PUT_LAT_HISTO_BIN(w) (PFX_LAT_HISTO_BIN | (((w)&0x0FFF) >> 0))
140#define GET_LST_READ_CELL(w) (((w)&0x03FF) >> 0)
141#define GET_LST_READ_CELL_CHIP_IX(w) (((w)&0x0C00) >> 10)
142
143//
144// Macros to extract 9-bit data content
145//
146#define GET_TIME_BIN(w) (((w)&0x01FF) >> 0)
147#define GET_HISTO_BIN(w) (((w)&0x01FF) >> 0)
148#define GET_PEDTHR_LIST_FEM(w) (((w)&0x01F0) >> 4)
149#define GET_PEDTHR_LIST_ASIC(w) (((w)&0x000C) >> 2)
150#define GET_PEDTHR_LIST_MODE(w) (((w)&0x0002) >> 1)
151#define GET_PEDTHR_LIST_TYPE(w) (((w)&0x0001) >> 0)
152#define PUT_FVERSION_FEMID(w, fv, id) (((w)&0xFE00) | (((fv)&0x0003) << 7) | (((id)&0x001F) << 0))
153#define GET_FRAMING_VERSION(w) (((w)&0x0180) >> 7)
154#define GET_FEMID(w) (((w)&0x001F) >> 0)
155
156// Definition of verboseness flags used by MFrame_Print
157#define FRAME_PRINT_ALL 0x00000001
158#define FRAME_PRINT_SIZE 0x00000002
159#define FRAME_PRINT_HIT_CH 0x00000004
160#define FRAME_PRINT_HIT_CNT 0x00000008
161#define FRAME_PRINT_CHAN_DATA 0x00000010
162#define FRAME_PRINT_HISTO_BINS 0x00000020
163#define FRAME_PRINT_ASCII 0x00000040
164#define FRAME_PRINT_FRBND 0x00000080
165#define FRAME_PRINT_EVBND 0x00000100
166#define FRAME_PRINT_NULLW 0x00000200
167#define FRAME_PRINT_HISTO_STAT 0x00000400
168#define FRAME_PRINT_LISTS 0x00000800
169#define FRAME_PRINT_LAST_CELL_READ_0 0x00001000
170#define FRAME_PRINT_LAST_CELL_READ_1 0x00002000
171#define FRAME_PRINT_LAST_CELL_READ_2 0x00004000
172#define FRAME_PRINT_LAST_CELL_READ_3 0x00008000
173#define FRAME_PRINT_EBBND 0x00010000
174
175#define MAX_FRAME_SIZE 8192
176
177// Maximum event size is:
178// 24 Feminos * 4 ASICs * 80 channels * 512 time-bins * 2 bytes = 7.5 MByte
179
180#define MAX_EVENT_SIZE (24 * 4 * 80 * 512 * 2)
181
182#define ORIGINAL_MCLIENT 0
183unsigned char cur_fr[MAX_EVENT_SIZE]; // Current frame
184
185#include "TRestRawMultiFEMINOSToSignalProcess.h"
186
187using namespace std;
188
189#include "TTimeStamp.h"
190
191Int_t nChannels = 0;
192
194
195TRestRawMultiFEMINOSToSignalProcess::TRestRawMultiFEMINOSToSignalProcess() { Initialize(); }
196
197TRestRawMultiFEMINOSToSignalProcess::TRestRawMultiFEMINOSToSignalProcess(const char* configFilename)
198 : TRestRawToSignalProcess(configFilename) {
199 Initialize();
200}
201
202TRestRawMultiFEMINOSToSignalProcess::~TRestRawMultiFEMINOSToSignalProcess() {}
203
204void TRestRawMultiFEMINOSToSignalProcess::LoadDetectorSetupData() {
205 if (fRunInfo == nullptr) {
206 cout << "'fRunInfo' is nullptr" << endl;
207 return;
208 }
209}
210
212 fLastEventId = 0;
213 fLastTimeStamp = 0;
214
215 SetLibraryVersion(LIBRARY_VERSION);
216}
217
219 RESTDebug << "TRestRawMultiFeminos::InitProcess" << RESTendl;
220 // Reading binary file header
222
223 if (!fInputFileNames.empty() && TRestTools::GetFileNameExtension(fInputFileNames[0]) != "aqs") {
224 RESTError << "The input file extension should be .aqs" << RESTendl;
225 RESTError << "Filename : " << fInputFileNames[0] << RESTendl;
226 exit(1);
227 }
228
229 LoadDetectorSetupData();
230
231 unsigned short sh;
232 unsigned short al;
233
234 totalbytesRead = 0;
235
236 // Read prefix
237 if (fread(&sh, sizeof(unsigned short), 1, fInputBinFile) != 1) {
238 printf("Error: could not read first prefix.\n");
239 exit(1);
240 }
241 totalbytesRead += sizeof(unsigned short);
242
243 // f->tot_file_rd+= sizeof(unsigned short);
244
245 // This must be the prefix for an ASCII string
246 if ((sh & PFX_8_BIT_CONTENT_MASK) != PFX_ASCII_MSG_LEN) {
247 printf("Error: missing string prefix in 0x%x\n", sh);
248 exit(1);
249 }
250 al = GET_ASCII_LEN(sh);
251
252 if (!ORIGINAL_MCLIENT) {
253 int tt;
254 int z = fread(&tt, sizeof(int), 1, fInputBinFile);
255 if (z == 0)
256 RESTError << "TRestRawMultiFEMINOSToSignalProcess::InitProcess. Problem reading from inputfile"
257 << RESTendl;
258 totalbytesRead += sizeof(int);
259
260 tStart = tt;
261 RESTDebug << "Timestamp : " << tt << " - " << tStart << RESTendl;
262 }
263
264 if (ORIGINAL_MCLIENT) {
265 char run_str[256];
266 // Read Run information string
267 if (fread(&(run_str[0]), sizeof(char), al, fInputBinFile) != al) {
268 printf("Error: could not read %d characters.\n", al);
269 exit(1);
270 }
271 totalbytesRead += sizeof(char);
272
273 // Show run string information if desired
274 printf("Run string: %s\n", &(run_str[0]));
275 }
276}
277
280 cout << "TRestRawMultiFEMINOSToSignalProcess::ProcessEvent" << endl;
281 }
282
283 while (true) {
284 unsigned short* sh;
285 sh = (unsigned short*)&(cur_fr[2]);
286 unsigned int nb_sh;
287 int fr_sz;
288 int fr_offset;
289 int done;
290
291 nChannels = 0;
292 Bool_t endOfEvent = false;
293
294 fSignalEvent->Initialize();
295
296 fSignalEvent->SetRunOrigin(fRunOrigin);
297 fSignalEvent->SetSubRunOrigin(fSubRunOrigin);
298
299 while (!endOfEvent) {
300 done = 0;
301 while (!done) {
302 // Read one short word
303 if (fread(sh, sizeof(unsigned short), 1, fInputBinFile) != 1) {
304 RESTDebug << "End of file reached." << RESTendl;
305
306 // The processing thread will be finished when return nullptr is reached
307 return nullptr;
308 }
309 totalbytesRead += sizeof(unsigned short);
310
311 if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_START_OF_BUILT_EVENT) {
313 printf("***** Start of Built Event *****\n");
315 } else if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_END_OF_BUILT_EVENT) {
317 printf("***** End of Built Event *****\n\n");
319 endOfEvent = true;
320 done = 1;
321 } else if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_SOBE_SIZE) {
322 // Read two short words to get the size of the event
323 if (fread((sh + 1), sizeof(unsigned short), 2, fInputBinFile) != 2) {
324 printf("Error: could not read two short words.\n");
325 exit(1);
326 }
327 totalbytesRead += sizeof(unsigned short) * 2;
328
329 // Get the size of the event in bytes
330 fr_sz = (int)(((*(sh + 2)) << 16) | (*(sh + 1)));
331
332 // Compute the number of short words to read for the complete event
333 nb_sh = fr_sz / 2; // number of short words is half the event size in bytes
334 nb_sh -= 3; // we have already read three short words from this event
335 fr_offset = 8;
336
337 done = 1;
338 } else if (((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_DFRAME) ||
339 ((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_CFRAME) ||
340 ((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_MFRAME)) {
341 // Read one short word
342 if (fread((sh + 1), sizeof(unsigned short), 1, fInputBinFile) != 1) {
343 printf("Error: could not read short word.\n");
344 exit(1);
345 }
346 totalbytesRead += sizeof(unsigned short);
347
348 // Get the size of the event in bytes
349 fr_sz = (int)*(sh + 1);
350
351 // Compute the number of short word to read for this frame
352 nb_sh = fr_sz / 2; // number of short words is half the frame size in bytes
353 nb_sh -= 2; // we have already read two short words from this frame
354 fr_offset = 6;
355
356 done = 1;
357 } else {
358 printf("Error: cannot interpret short word 0x%x\n", *sh);
359 exit(1);
360 }
361 }
362
363 // Read binary frame
364 if (!endOfEvent) {
365 if (fread(&(cur_fr[fr_offset]), sizeof(unsigned short), nb_sh, fInputBinFile) != nb_sh) {
366 printf("Error: could not read %d bytes.\n", (nb_sh * 2));
367 return nullptr; // exit(1);
368 }
369 totalbytesRead += sizeof(unsigned short) * nb_sh;
370
371 // Zero the first two bytes because these are no longer used to specify
372 // the size of the frame
373 cur_fr[0] = 0x00;
374 cur_fr[1] = 0x00;
375
376 endOfEvent = ReadFrame((void*)&(cur_fr[2]), fr_sz);
377 }
378 }
379
380 if (fSignalEvent->GetID() == 0 && fLastEventId != 0) {
381 fSignalEvent->SetID(fLastEventId);
382 fSignalEvent->SetTime(fLastTimeStamp);
383 fLastEventId = 0;
384 }
385
387 cout << "------------------------------------------" << endl;
388 cout << "Event ID : " << fSignalEvent->GetID() << endl;
389 cout << "Time stamp : " << fSignalEvent->GetTimeStamp() << endl;
390 cout << "Number of Signals : " << fSignalEvent->GetNumberOfSignals() << endl;
391 cout << "------------------------------------------" << endl;
392
394 for (Int_t n = 0; n < fSignalEvent->GetNumberOfSignals(); n++)
395 cout << "Signal N : " << n << " daq id : " << fSignalEvent->GetSignal(n)->GetID() << endl;
396 GetChar();
397 }
398 }
399
400 if (fSignalEvent->GetNumberOfSignals() != 0) {
401 return fSignalEvent;
402 } else {
403 RESTWarning << "blank event " << fSignalEvent->GetID() << "! skipping..." << RESTendl;
404 }
405 }
406
407 // The processing thread will be finished if return nullptr is reached
408 return nullptr;
409}
410
411Bool_t TRestRawMultiFEMINOSToSignalProcess::ReadFrame(void* fr, int fr_sz) {
412 Bool_t endOfEvent = false;
413
414 unsigned short* p;
415 int done = 0;
416 unsigned short r0, r1, r2;
417 unsigned short n0, n1;
418 unsigned short cardNumber, chipNumber, daqChannel;
419 unsigned int tmp;
420 int tmp_i[10];
421 int si;
422
423 p = (unsigned short*)fr;
424
425 done = 0;
426 si = 0;
427
429 printf("ReadFrame: Frame payload: %d bytes\n", fr_sz);
430
431 Int_t showSamples = fShowSamples;
432
433 TRestRawSignal sgnl;
434 sgnl.SetSignalID(-1);
435 while (!done) {
436 // Is it a prefix for 14-bit content?
437 if ((*p & PFX_14_BIT_CONTENT_MASK) == PFX_CARD_CHIP_CHAN_HIT_IX) {
438 if (sgnl.GetSignalID() >= 0 && sgnl.GetNumberOfPoints() >= fMinPoints)
439 fSignalEvent->AddSignal(sgnl);
440
441 cardNumber = GET_CARD_IX(*p);
442 chipNumber = GET_CHIP_IX(*p);
443 daqChannel = GET_CHAN_IX(*p);
444
445 if (daqChannel >= 0) {
446 daqChannel += cardNumber * 4 * 72 + chipNumber * 72;
447 nChannels++;
448 }
449
451 printf("ReadFrame: Card %02d Chip %01d Daq Channel %02d\n", cardNumber, chipNumber,
452 daqChannel);
453 p++;
454 si = 0;
455
456 sgnl.Initialize();
457 sgnl.SetSignalID(daqChannel);
458
459 }
460 // Is it a prefix for 12-bit content?
461 else if ((*p & PFX_12_BIT_CONTENT_MASK) == PFX_ADC_SAMPLE) {
462 r0 = GET_ADC_DATA(*p);
464 if (showSamples > 0) printf("ReadFrame: %03d 0x%04x (%4d)\n", si, r0, r0);
465 showSamples--;
466 }
467 if (sgnl.GetSignalID() >= 0) sgnl.AddPoint((Short_t)r0);
468 p++;
469 si++;
470 }
471 // Is it a prefix for 4-bit content?
472 else if ((*p & PFX_4_BIT_CONTENT_MASK) == PFX_START_OF_EVENT) {
473 r0 = GET_EVENT_TYPE(*p);
475 printf("ReadFrame: -- Start of Event (Type %01d) --\n", r0);
476 p++;
477
478 // Time Stamp lower 16-bit
479 r0 = *p;
480 p++;
481
482 // Time Stamp middle 16-bit
483 r1 = *p;
484 p++;
485
486 // Time Stamp upper 16-bit
487 r2 = *p;
488 p++;
489
491 printf("ReadFrame: Time 0x%04x 0x%04x 0x%04x\n", r2, r1, r0);
492 printf("Timestamp: 0x%04x 0x%04x 0x%04x\n", r2, r1, r0);
493 cout << "TimeStamp " << tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8 << endl;
494 }
495
496 // Set timestamp and event ID
497
498 // Event Count lower 16-bit
499 n0 = *p;
500 p++;
501
502 // Event Count upper 16-bit
503 n1 = *p;
504 p++;
505
506 tmp = (((unsigned int)n1) << 16) | ((unsigned int)n0);
508 printf("ReadFrame: Event_Count 0x%08x (%d)\n", tmp, tmp);
509
510 // Some times the end of the frame contains the header of the next event.
511 // Then, in the attempt to read the header of next event, we must avoid
512 // that it overwrites the already assigned id. In that case (id != 0), we
513 // do nothing, and we store the values at fLastXX variables, that we will
514 // use that for next event.
515 if (fSignalEvent->GetID() == 0) {
516 if (fLastEventId == 0) {
517 fSignalEvent->SetID(tmp);
518 fSignalEvent->SetTime(tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8);
519 } else {
520 fSignalEvent->SetID(fLastEventId);
521 fSignalEvent->SetTime(fLastTimeStamp);
522 }
523 }
524
525 fLastEventId = tmp;
526 fLastTimeStamp = tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8;
527
528 // If it is the first event we use it to define the run start time
529 if (fCounter == 0) {
530 fRunInfo->SetStartTimeStamp(fLastTimeStamp);
531 fCounter++;
532 } else {
533 // and we keep updating the end run time
534 fRunInfo->SetEndTimeStamp(fLastTimeStamp);
535 }
536
537 fSignalEvent->SetRunOrigin(fRunOrigin);
538 fSignalEvent->SetSubRunOrigin(fSubRunOrigin);
539 } else if ((*p & PFX_4_BIT_CONTENT_MASK) == PFX_END_OF_EVENT) {
540 tmp = ((unsigned int)GET_EOE_SIZE(*p)) << 16;
541 p++;
542 tmp = tmp + (unsigned int)*p;
543 p++;
545 printf("ReadFrame: ----- End of Event ----- (size %d bytes)\n", tmp);
547
548 if (fElectronicsType == "SingleFeminos") endOfEvent = true;
549 }
550
551 // Is it a prefix for 0-bit content?
552 else if ((*p & PFX_0_BIT_CONTENT_MASK) == PFX_END_OF_FRAME) {
553 if (sgnl.GetSignalID() >= 0 && sgnl.GetNumberOfPoints() >= fMinPoints)
554 fSignalEvent->AddSignal(sgnl);
555
557 printf("ReadFrame: ----- End of Frame -----\n");
558 p++;
559 done = 1;
560 } else if (*p == PFX_START_OF_BUILT_EVENT) {
562 printf("ReadFrame: ***** Start of Built Event *****\n");
563 p++;
564 } else if (*p == PFX_END_OF_BUILT_EVENT) {
566 printf("ReadFrame: ***** End of Built Event *****\n\n");
567 p++;
568 } else if (*p == PFX_SOBE_SIZE) {
569 // Skip header
570 p++;
571
572 // Built Event Size lower 16-bit
573 r0 = *p;
574 p++;
575 // Built Event Size upper 16-bit
576 r1 = *p;
577 p++;
578 tmp_i[0] = (int)((r1 << 16) | (r0));
579
581 printf("ReadFrame: ***** Start of Built Event - Size = %d bytes *****\n", tmp_i[0]);
582 } else {
583 p++;
584 }
585 }
586
587 return endOfEvent;
588}
TRestRun * fRunInfo
< Pointer to TRestRun object where to find metadata.
A base class for any REST event.
Definition: TRestEvent.h:38
void SetTime(Double_t time)
Definition: TRestEvent.cxx:85
endl_t RESTendl
Termination flag object for TRestStringOutput.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
A process to read Feminos acquisition cards in single or TCM mode.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
Process one event.
void InitProcess() override
To be executed at the beginning of the run (outside event loop)
void Initialize() override
Making default settings.
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
Int_t GetID() const
Returns the value of signal ID.
void Initialize()
Initialization of TRestRawSignal members.
void SetSignalID(Int_t sID)
It sets the id number of the signal.
void AddPoint(Short_t)
Adds a new point to the end of the signal data array.
Int_t GetSignalID() const
Returns the value of signal ID.
Int_t GetNumberOfPoints() const
Returns the actual number of points, or size of the signal.
A base class for any process reading a binary external file as input to REST.
virtual void InitProcess() override
To be executed at the beginning of the run (outside event loop)
Int_t fShowSamples
true if need to open all raw files at the beginning
@ REST_Info
+show most of the information for each steps
@ REST_Debug
+show the defined debug messages
static std::string GetFileNameExtension(const std::string &fullname)
Gets the file extension as the substring found after the latest ".".
Definition: TRestTools.cxx:823
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.