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 totalBytesReaded = 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 totalBytesReaded += 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 totalBytesReaded += 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 totalBytesReaded += 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 while (1) {
283 unsigned short* sh;
284 sh = (unsigned short*)&(cur_fr[2]);
285 unsigned int nb_sh;
286 int fr_sz;
287 int fr_offset;
288 int done;
289
290 nChannels = 0;
291 Bool_t endOfEvent = false;
292
293 fSignalEvent->Initialize();
294
295 fSignalEvent->SetRunOrigin(fRunOrigin);
296 fSignalEvent->SetSubRunOrigin(fSubRunOrigin);
297
298 while (!endOfEvent) {
299 done = 0;
300 while (!done) {
301 // Read one short word
302 if (fread(sh, sizeof(unsigned short), 1, fInputBinFile) != 1) {
303 RESTDebug << "End of file reached." << RESTendl;
304
305 // The processing thread will be finished when return nullptr is reached
306 return nullptr;
307 }
308 totalBytesReaded += sizeof(unsigned short);
309
310 if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_START_OF_BUILT_EVENT) {
312 printf("***** Start of Built Event *****\n");
314 } else if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_END_OF_BUILT_EVENT) {
316 printf("***** End of Built Event *****\n\n");
318 endOfEvent = true;
319 done = 1;
320 } else if ((*sh & PFX_0_BIT_CONTENT_MASK) == PFX_SOBE_SIZE) {
321 // Read two short words to get the size of the event
322 if (fread((sh + 1), sizeof(unsigned short), 2, fInputBinFile) != 2) {
323 printf("Error: could not read two short words.\n");
324 exit(1);
325 }
326 totalBytesReaded += sizeof(unsigned short) * 2;
327
328 // Get the size of the event in bytes
329 fr_sz = (int)(((*(sh + 2)) << 16) | (*(sh + 1)));
330
331 // Compute the number of short words to read for the complete event
332 nb_sh = fr_sz / 2; // number of short words is half the event size in bytes
333 nb_sh -= 3; // we have already read three short words from this event
334 fr_offset = 8;
335
336 done = 1;
337 } else if (((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_DFRAME) ||
338 ((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_CFRAME) ||
339 ((*sh & PFX_9_BIT_CONTENT_MASK) == PFX_START_OF_MFRAME)) {
340 // Read one short word
341 if (fread((sh + 1), sizeof(unsigned short), 1, fInputBinFile) != 1) {
342 printf("Error: could not read short word.\n");
343 exit(1);
344 }
345 totalBytesReaded += sizeof(unsigned short);
346
347 // Get the size of the event in bytes
348 fr_sz = (int)*(sh + 1);
349
350 // Compute the number of short word to read for this frame
351 nb_sh = fr_sz / 2; // number of short words is half the frame size in bytes
352 nb_sh -= 2; // we have already read two short words from this frame
353 fr_offset = 6;
354
355 done = 1;
356 } else {
357 printf("Error: cannot interpret short word 0x%x\n", *sh);
358 exit(1);
359 }
360 }
361
362 // Read binary frame
363 if (!endOfEvent) {
364 if (fread(&(cur_fr[fr_offset]), sizeof(unsigned short), nb_sh, fInputBinFile) != nb_sh) {
365 printf("Error: could not read %d bytes.\n", (nb_sh * 2));
366 exit(1);
367 }
368 totalBytesReaded += sizeof(unsigned short) * nb_sh;
369
370 // Zero the first two bytes because these are no longer used to specify
371 // the size of the frame
372 cur_fr[0] = 0x00;
373 cur_fr[1] = 0x00;
374
375 endOfEvent = ReadFrame((void*)&(cur_fr[2]), fr_sz);
376 }
377 }
378
379 if (fSignalEvent->GetID() == 0 && fLastEventId != 0) {
380 fSignalEvent->SetID(fLastEventId);
381 fSignalEvent->SetTime(fLastTimeStamp);
382 fLastEventId = 0;
383 }
384
386 cout << "------------------------------------------" << endl;
387 cout << "Event ID : " << fSignalEvent->GetID() << endl;
388 cout << "Time stamp : " << fSignalEvent->GetTimeStamp() << endl;
389 cout << "Number of Signals : " << fSignalEvent->GetNumberOfSignals() << endl;
390 cout << "------------------------------------------" << endl;
391
393 for (Int_t n = 0; n < fSignalEvent->GetNumberOfSignals(); n++)
394 cout << "Signal N : " << n << " daq id : " << fSignalEvent->GetSignal(n)->GetID() << endl;
395 GetChar();
396 }
397 }
398
399 if (fSignalEvent->GetNumberOfSignals() != 0) {
400 return fSignalEvent;
401 } else {
402 RESTWarning << "blank event " << fSignalEvent->GetID() << "! skipping..." << RESTendl;
403 }
404 }
405
406 // The processing thread will be finished if return nullptr is reached
407 return nullptr;
408}
409
410Bool_t TRestRawMultiFEMINOSToSignalProcess::ReadFrame(void* fr, int fr_sz) {
411 Bool_t endOfEvent = false;
412
413 unsigned short* p;
414 int done = 0;
415 unsigned short r0, r1, r2;
416 unsigned short n0, n1;
417 unsigned short cardNumber, chipNumber, daqChannel;
418 unsigned int tmp;
419 int tmp_i[10];
420 int si;
421
422 p = (unsigned short*)fr;
423
424 done = 0;
425 si = 0;
426
428 printf("ReadFrame: Frame payload: %d bytes\n", fr_sz);
429
430 Int_t showSamples = fShowSamples;
431
432 TRestRawSignal sgnl;
433 sgnl.SetSignalID(-1);
434 while (!done) {
435 // Is it a prefix for 14-bit content?
436 if ((*p & PFX_14_BIT_CONTENT_MASK) == PFX_CARD_CHIP_CHAN_HIT_IX) {
437 if (sgnl.GetSignalID() >= 0 && sgnl.GetNumberOfPoints() >= fMinPoints)
438 fSignalEvent->AddSignal(sgnl);
439
440 cardNumber = GET_CARD_IX(*p);
441 chipNumber = GET_CHIP_IX(*p);
442 daqChannel = GET_CHAN_IX(*p);
443
444 if (daqChannel >= 0) {
445 daqChannel += cardNumber * 4 * 72 + chipNumber * 72;
446 nChannels++;
447 }
448
450 printf("ReadFrame: Card %02d Chip %01d Daq Channel %02d\n", cardNumber, chipNumber,
451 daqChannel);
452 p++;
453 si = 0;
454
455 sgnl.Initialize();
456 sgnl.SetSignalID(daqChannel);
457
458 }
459 // Is it a prefix for 12-bit content?
460 else if ((*p & PFX_12_BIT_CONTENT_MASK) == PFX_ADC_SAMPLE) {
461 r0 = GET_ADC_DATA(*p);
463 if (showSamples > 0) printf("ReadFrame: %03d 0x%04x (%4d)\n", si, r0, r0);
464 showSamples--;
465 }
466 if (sgnl.GetSignalID() >= 0) sgnl.AddPoint((Short_t)r0);
467 p++;
468 si++;
469 }
470 // Is it a prefix for 4-bit content?
471 else if ((*p & PFX_4_BIT_CONTENT_MASK) == PFX_START_OF_EVENT) {
472 r0 = GET_EVENT_TYPE(*p);
474 printf("ReadFrame: -- Start of Event (Type %01d) --\n", r0);
475 p++;
476
477 // Time Stamp lower 16-bit
478 r0 = *p;
479 p++;
480
481 // Time Stamp middle 16-bit
482 r1 = *p;
483 p++;
484
485 // Time Stamp upper 16-bit
486 r2 = *p;
487 p++;
488
490 printf("ReadFrame: Time 0x%04x 0x%04x 0x%04x\n", r2, r1, r0);
491 printf("Timestamp: 0x%04x 0x%04x 0x%04x\n", r2, r1, r0);
492 cout << "TimeStamp " << tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8 << endl;
493 }
494
495 // Set timestamp and event ID
496
497 // Event Count lower 16-bit
498 n0 = *p;
499 p++;
500
501 // Event Count upper 16-bit
502 n1 = *p;
503 p++;
504
505 tmp = (((unsigned int)n1) << 16) | ((unsigned int)n0);
507 printf("ReadFrame: Event_Count 0x%08x (%d)\n", tmp, tmp);
508
509 // Some times the end of the frame contains the header of the next event.
510 // Then, in the attempt to read the header of next event, we must avoid
511 // that it overwrites the already assigned id. In that case (id != 0), we
512 // do nothing, and we store the values at fLastXX variables, that we will
513 // use that for next event.
514 if (fSignalEvent->GetID() == 0) {
515 if (fLastEventId == 0) {
516 fSignalEvent->SetID(tmp);
517 fSignalEvent->SetTime(tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8);
518 } else {
519 fSignalEvent->SetID(fLastEventId);
520 fSignalEvent->SetTime(fLastTimeStamp);
521 }
522 }
523
524 fLastEventId = tmp;
525 fLastTimeStamp = tStart + (2147483648 * r2 + 32768 * r1 + r0) * 2e-8;
526
527 // If it is the first event we use it to define the run start time
528 if (fCounter == 0) {
529 fRunInfo->SetStartTimeStamp(fLastTimeStamp);
530 fCounter++;
531 } else {
532 // and we keep updating the end run time
533 fRunInfo->SetEndTimeStamp(fLastTimeStamp);
534 }
535
536 fSignalEvent->SetRunOrigin(fRunOrigin);
537 fSignalEvent->SetSubRunOrigin(fSubRunOrigin);
538 } else if ((*p & PFX_4_BIT_CONTENT_MASK) == PFX_END_OF_EVENT) {
539 tmp = ((unsigned int)GET_EOE_SIZE(*p)) << 16;
540 p++;
541 tmp = tmp + (unsigned int)*p;
542 p++;
544 printf("ReadFrame: ----- End of Event ----- (size %d bytes)\n", tmp);
546
547 if (fElectronicsType == "SingleFeminos") endOfEvent = true;
548 }
549
550 // Is it a prefix for 0-bit content?
551 else if ((*p & PFX_0_BIT_CONTENT_MASK) == PFX_END_OF_FRAME) {
552 if (sgnl.GetSignalID() >= 0 && sgnl.GetNumberOfPoints() >= fMinPoints)
553 fSignalEvent->AddSignal(sgnl);
554
556 printf("ReadFrame: ----- End of Frame -----\n");
557 p++;
558 done = 1;
559 } else if (*p == PFX_START_OF_BUILT_EVENT) {
561 printf("ReadFrame: ***** Start of Built Event *****\n");
562 p++;
563 } else if (*p == PFX_END_OF_BUILT_EVENT) {
565 printf("ReadFrame: ***** End of Built Event *****\n\n");
566 p++;
567 } else if (*p == PFX_SOBE_SIZE) {
568 // Skip header
569 p++;
570
571 // Built Event Size lower 16-bit
572 r0 = *p;
573 p++;
574 // Built Event Size upper 16-bit
575 r1 = *p;
576 p++;
577 tmp_i[0] = (int)((r1 << 16) | (r0));
578
580 printf("ReadFrame: ***** Start of Built Event - Size = %d bytes *****\n", tmp_i[0]);
581 } else {
582 p++;
583 }
584 }
585
586 return endOfEvent;
587}
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.