Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaRun.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 13/05/00
2
4//
5// THaRun
6//
7// Description of a CODA run on disk.
8//
10
11#include "THaRun.h"
12#include "THaEvData.h"
13#include "THaCodaFile.h"
14#include "THaGlobals.h"
15#include "DAQconfig.h"
16#include "THaPrintOption.h"
17#include "TClass.h"
18#include "TError.h"
19#include "TSystem.h"
20#include "TRegexp.h"
21#include <iostream>
22#include <iomanip>
23#include <cassert>
24#include <stdexcept>
25#include <sstream>
26
27using namespace std;
28
29#if __cplusplus >= 201402L
30# define MKCODAFILE make_unique<Decoder::THaCodaFile>()
31#else
32# define MKCODAFILE unique_ptr<Decoder::THaCodaFile>(new Decoder::THaCodaFile)
33#endif
34
35static const int fgMaxScan = 5000;
36static const char* const fgRe1 ="\\.[0-9]+$";
37static const char* const fgRe2 ="\\.[0-9]+\\.[0-9]+$";
38
39//_____________________________________________________________________________
40THaRun::THaRun( const char* fname, const char* description )
41 : THaCodaRun(description)
42 , fFilename(fname)
43 , fMaxScan(fgMaxScan)
44 , fSegment(-1)
45 , fStream(-1)
46{
47 // Normal & default constructor
48
49 fCodaData = MKCODAFILE; //Specifying the file name would open the file
50
51 // Hall A runs normally contain all these items
53}
54
55//_____________________________________________________________________________
56THaRun::THaRun( const vector<TString>& pathList, const char* filename,
57 const char* description )
58 : THaCodaRun(description)
59 , fMaxScan(fgMaxScan)
60 , fSegment(-1)
61 , fStream(-1)
62{
63 // cout << "Looking for file:\n";
64 for(const auto & path : pathList) {
65 fFilename = Form("%s/%s", path.Data(), filename );
66 //cout << "\t'" << fFilename << "'" << endl;
67
69 break;
70 }
71 //cout << endl << "--> Opening file: " << fFilename << endl;
72
73 fCodaData = MKCODAFILE; //Specifying the file name would open the file
74
75 // Hall A runs normally contain all these items
77}
78
79//_____________________________________________________________________________
81 : THaCodaRun(rhs)
82 , fFilename(rhs.fFilename)
83 , fMaxScan(rhs.fMaxScan)
84 , fSegment(rhs.fSegment)
85 , fStream(rhs.fStream)
86{
87 // Copy ctor
88
90}
91
92//_____________________________________________________________________________
94{
95 // Assignment operator. We allow assignment to generic THaRunBase objects
96 // so that we can copy run objects through a virtual operator=.
97 // If the actual class of 'rhs' is different from this object's
98 // (e.g. THaOnlRun - an ET run), then its special properties are lost.
99
100 if( this != &rhs ) {
103 try {
104 const auto& run = dynamic_cast<const THaRun&>(rhs);
105 fFilename = run.fFilename;
106 fMaxScan = run.fMaxScan;
107 fSegment = run.fSegment;
108 fStream = run.fStream;
109 }
110 catch( const std::bad_cast& ) {
111 fFilename.Clear(); // will need to call SetFilename()
113 fSegment = -1;
114 fStream = -1;
115 }
116 }
117 return *this;
118}
119
120//_____________________________________________________________________________
121THaRun::~THaRun() = default;
122
123//_____________________________________________________________________________
125{
126 // Reset the run object.
127
128 THaPrintOption sopt(opt);
129 sopt.ToUpper();
130 bool doing_init = (sopt.Contains("INIT"));
131
133
134 // If initializing, keep explicitly set fMaxScan
135 if( !doing_init )
137}
138
139//_____________________________________________________________________________
140Int_t THaRun::Compare( const TObject* obj ) const
141{
142 // Compare a THaRun object to another run. Returns 0 when equal,
143 // -1 when 'this' is smaller and +1 when bigger (like strcmp).
144 // Used by ROOT containers.
145
146 if (this == obj) return 0;
147 const auto* rhs = dynamic_cast<const THaRunBase*>(obj);
148 if( !rhs ) return -1;
149 if( *this < *rhs ) return -1;
150 else if( *rhs < *this ) return 1;
151 const auto* rhsr = dynamic_cast<const THaRun*>(rhs);
152 if( !rhsr ) return 0;
153 if( fSegment < rhsr->fSegment ) return -1;
154 else if( rhsr->fSegment < fSegment ) return 1;
155 if( fStream < rhsr->fStream ) return -1;
156 else if( rhsr->fStream < fStream ) return 1;
157 return 0;
158}
159
160//_____________________________________________________________________________
162{
163 // Open CODA file for read-only access.
164
165 static const char* const here = "Open";
166
167 if( fFilename.IsNull() ) {
168 Error( here, "CODA file name not set. Cannot open the run." );
169 return READ_FATAL; // filename not set
170 }
171 if( !FindSegmentNumber() ) {
172 Error(here, "Malformed file name or program bug. Call expert.");
173 return READ_FATAL;
174 }
175
176 fOpened = false;
177 Int_t st = fCodaData->codaOpen( fFilename );
178 if( st == CODA_OK ) {
179 // Get CODA version from data; however, if a version was set
180 // explicitly by the user, use that instead
181 if( GetCodaVersion() < 0 ) {
182 Error( here, "Cannot determine CODA version from file. "
183 "Try analyzer->SetCodaVersion(2)");
184 st = CODA_ERROR;
185 Close();
186 }
187 cout << "in THaRun::Open: coda version "<<fDataVersion<<endl;
188 if( st == CODA_OK )
189 fOpened = true;
190 }
191 return ReturnCode( st );
192}
193
194//_____________________________________________________________________________
195void THaRun::Print( Option_t* opt ) const
196{
197 THaPrintOption sopt(opt);
198 sopt.ToUpper();
199 if( sopt.Contains("NAMEDESC") ) {
200 cout << "\"file://" << GetFilename() << "\"";
201 if( strcmp( GetTitle(), "") != 0 )
202 cout << " \"" << GetTitle() << "\"";
203 return;
204 }
205 THaCodaRun::Print( opt );
206 cout << "CODA file: " << fFilename << endl;
207}
208
209//_____________________________________________________________________________
211{
212 // Return true if this run /should/ contain the necessary data for
213 // initialization (run date etc.)
214
215 // Current configuration in Hall A/C:
216 // - If there is no segment number, the run has init info (file not split)
217 // - If there is a segment number, only segment 0 has the init info
218 return (fSegment == -1 || fSegment == 0);
219}
220
221//_____________________________________________________________________________
223{
224 static const char* const here = "THaRun::PrescanFile";
225 // Scan at least 'minscan' number of events regardless of info required
226 //FIXME: BCI: configurable member variable
228 const UInt_t minscan = ifo ? ifo->fMinScan : 50;
229
230 unique_ptr<THaEvData> evdata{static_cast<THaEvData*>(gHaDecoder->New())};
231 // Disable advanced processing
232 evdata->EnableScalers(false);
233 evdata->EnableHelicity(false);
234 evdata->EnablePrescanMode(true);
235 Int_t ver = GetCodaVersion();
236 if( evdata->SetDataVersion(ver) <= 0 ) {
237 Error( here, "Failed to set CODA version. Got %d, must be 2 or 3.", ver );
238 return READ_FATAL;
239 }
240 UInt_t nev = 0;
241 Int_t status = READ_OK;
242 while( (nev < minscan || (nev < fMaxScan && !HasInfo(fDataRequired))) &&
243 (status = ReadEvent()) == READ_OK ) {
244
245 // Decode events. Skip bad events.
246 nev++;
247 status = evdata->LoadEvent(GetEvBuffer());
248 if( status != THaEvData::HED_OK ) {
249 if( status == THaEvData::HED_ERR || status == THaEvData::HED_FATAL ) {
250 Error(here, "Error decoding event %u", nev);
251 return (status == THaEvData::HED_ERR) ? READ_ERROR : READ_FATAL;
252 }
253 Warning(here, "Skipping event %u due to warnings", nev);
254 status = READ_OK;
255 continue;
256 }
257
258 // Inspect event and extract run parameters if appropriate
259 Int_t st = Update(evdata.get());
260 if( st < 0 )
261 return READ_ERROR;
262 if( st & (1<<0) )
263 cout << "Prestart at " << nev << endl;
264 if( st & (1<<1) )
265 cout << "Prescales at " << nev << endl;
266 if( st & (1<<2) )
267 cout << "DAQ info at " << setw(2) << nev
268 << " len " << evdata->GetEvLength() << endl;
269 }//end while
270
271 if( status != READ_OK )
272 Error(here, "Failed to read CODA file at event %u", nev);
273 return status;
274}
275
276//_____________________________________________________________________________
278{
279 // Based on the given file name, get the file name pattern that matches
280 // runs containing initialization info.
281 // This version simply changes the segment number to 0.
282
283 // Extract the file base name
284 Ssiz_t dot = fname.Last('.');
285 if( dot != kNPOS) {
286 fname.Remove(dot);
287 fname.Append(".0");
288 }
289
290 return fname;
291}
292
293//_____________________________________________________________________________
295{
296 // Find a file matching the name pattern returned by GetInitInfoFile().
297 // The file must exist on disk and have at least read permissions.
298 // Search in typical directories:
299 // - First, in the same directory as the continuation segment.
300 // - Then, if the filename's dirname contains dataN or workN, with N=0...9,
301 // also try looking in all other dataNs or workN. If dataN is found, ignore
302 // any workN in the file name.
303 // Returns an empty string if no matching file can be found.
304
305 TString s = GetInitInfoFileName(fname);
307 return s;
308
309 TString dirn = gSystem->DirName(s);
310 Ssiz_t pos = dirn.Index(TRegexp("data[0-9]"));
311 if( pos == kNPOS )
312 pos = dirn.Index(TRegexp("work[0-9]"));
313 if( pos != kNPOS ) {
314 TString sN = dirn(pos + 4, 1);
315 Int_t curN = sN.Atoi();
316 TString base = gSystem->BaseName(s);
317 for( Int_t i = 0; i <= 9; i++ ) {
318 if( i == curN )
319 continue;
320 dirn[pos+4] = TString::Itoa(i,10)[0];
321 s = dirn + "/" + base;
323 return s;
324 }
325 }
326 return {}; // empty string: not found
327}
328
329//_____________________________________________________________________________
330Int_t THaRun::ReadInitInfo( Int_t level ) // NOLINT(misc-no-recursion)
331{
332 // Read initial info from the CODA file. This is done by prescanning
333 // the run file in a local mini event loop via a local decoder.
334 // 'level' is an optional recursion depth, default 0.
335
336 static const char* const here = "ReadInitInfo";
337
338 // If pre-scanning of the data file requested, read up to fMaxScan events
339 // and extract run parameters from the data.
340 if( fMaxScan == 0 )
341 return READ_OK;
342
343 Int_t status = READ_OK;
344
345 if( ProvidesInitInfo() || level > 0 ) {
346 status = PrescanFile();
347
348 if( status != READ_OK && status != READ_EOF ) {
349 Error(here, "Error %d reading CODA file %s.", status, GetFilename());
350 return status;
351 }
352
353 } else {
354 // If this is a continuation segment or parallel stream, try finding the
355 // segment and/or stream which contains the initialization data.
357
358 if( !fname.IsNull() ) {
359 cout << "THaRun: Reading init info from " << fname << endl;
360 unique_ptr<Decoder::THaCodaData> save_coda = std::move(fCodaData);
362 if( fCodaData->codaOpen(fname) == CODA_OK )
363 status = ReadInitInfo(level+1);
364 fCodaData = std::move(save_coda);
365 }
366 } //end if(fSegment==0)else
367
368 return status;
369}
370
371//_____________________________________________________________________________
372Int_t THaRun::SetFilename( const char* name )
373{
374 // Set the name of the raw data file.
375 // If the name changes, the existing input, if any, will be closed.
376 // Return -1 if illegal name, 1 if name not changed, 0 otherwise.
377
378 static const char* const here = "SetFilename";
379
380 if( !name || !*name ) {
381 Error( here, "Illegal file name." );
382 return -1;
383 }
384
385 if( fFilename == name )
386 return 1;
387
388 Close();
389
390 fFilename = name;
391 if( !FindSegmentNumber() ) {
392 Error( here, "Illegal file name or program bug. Call expert.");
393 return -1;
394 }
395
396 // Assume we have to reinitialize. A new file name generally means a new
397 // run date, run number, etc.
398 fIsInit = false;
399
400 return 0;
401}
402
403//_____________________________________________________________________________
405{
406 // Set number of events to prescan during Init(). Default is 5000.
407
408 fMaxScan = n;
409}
410
411//_____________________________________________________________________________
413{
414 // Set minimum number of events to prescan during Init(), regardless of
415 // fDataRequired. Default is 50.
416
417 //FIXME: BCI make member variable
419 if( ifo )
420 ifo->fMinScan = n;
421}
422
423//_____________________________________________________________________________
425{
426 // Determine the segment number, if any. For typical CODA disk files, this is
427 // the suffix of the file name, i.e. MM in name.MM, where MM can be one or
428 // more digits.
429 // Also set the stream number if the file name ends with .NN.MM, where
430 // NN=stream, MM=segment.
431 // Returns true if info successfully extracted
432
433 fSegment = fStream = -1; // default -1 means unset
434 if( fFilename.IsNull() )
435 return false;
436
437 TString dummy;
439}
440
441//_____________________________________________________________________________
443 Int_t& segment, Int_t& stream )
444{
445 try {
446 TRegexp re1(fgRe1);
447 TRegexp re2(fgRe2);
448 if( re1.Status() != TRegexp::kOK || re2.Status() != TRegexp::kOK ) {
449 ostringstream ostr;
450 ostr << "Error compiling regular expressions: "
451 << re1.Status() << " " << re2.Status() << endl;
452 throw std::runtime_error(ostr.str());
453 }
454 Ssiz_t pos;
455 if( (pos = filename.Index(re2)) != kNPOS ) {
456 stem = filename(0, pos);
457 ++pos;
458 assert(pos < filename.Length());
459 Ssiz_t pos2 = filename.Index(".", pos);
460 assert(pos2 != kNPOS && pos2+1 < filename.Length());
461 TString sStream = filename(pos, pos2 - pos);
462 ++pos2;
463 TString sSegmnt = filename(pos2, filename.Length() - pos2);
464 stream = sStream.Atoi();
465 segment = sSegmnt.Atoi();
466 } else if( (pos = filename.Index(re1)) != kNPOS ) {
467 stem = filename(0, pos);
468 ++pos;
469 assert(pos < filename.Length());
470 TString sSegmnt = filename(pos, filename.Length() - pos);
471 stream = -1;
472 segment = sSegmnt.Atoi();
473 } else {
474 // If neither expression matches, this run does not have the standard
475 // segment/stream info in its file name. Leave both segment and stream
476 // numbers unset and report success.
477 segment = stream = -1;
478 }
479 }
480 catch ( const exception& e ) {
481 cerr << "Error parsing segment and/or stream number in run file name "
482 << "\"" << filename << "\": " << e.what() << endl;
483 segment = stream = -1;
484 return false;
485 }
486 return true;
487}
488
489//_____________________________________________________________________________
int Int_t
unsigned int UInt_t
#define MKCODAFILE
Int_t fSegment
Definition MultiFileRun.h:7
std::ostream & fStream
#define e(i)
bool Bool_t
const Ssiz_t kNPOS
int Ssiz_t
const char Option_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
char name[80]
#define CODA_ERROR
Definition THaCodaData.h:30
#define CODA_OK
Definition THaCodaData.h:28
R__EXTERN class TClass * gHaDecoder
Definition THaGlobals.h:17
static const char *const fgRe1
Definition THaRun.cxx:36
static const int fgMaxScan
Definition THaRun.cxx:35
static const char *const fgRe2
Definition THaRun.cxx:37
static const char *const here
Definition THaVar.cxx:64
char * Form(const char *fmt,...)
kReadPermission
R__EXTERN TSystem * gSystem
static DAQInfoExtra * GetExtraInfo(TObject *p)
Definition DAQconfig.cxx:84
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
virtual const UInt_t * GetEvBuffer() const
std::unique_ptr< Decoder::THaCodaData > fCodaData
Definition THaCodaRun.h:35
static Int_t ReturnCode(Int_t coda_retcode)
Int_t GetCodaVersion()
virtual THaCodaRun & operator=(const THaRunBase &)
virtual Int_t Close()
virtual Int_t ReadEvent()
void EnableScalers(Bool_t enable=true)
Bool_t Contains(const std::string &token) const
virtual Int_t Update(const THaEvData *evdata)
Bool_t fIsInit
Definition THaRunBase.h:98
UInt_t fDataRequired
Definition THaRunBase.h:103
Bool_t fOpened
Definition THaRunBase.h:99
TObject * fExtra
Definition THaRunBase.h:107
virtual Bool_t HasInfo(UInt_t bits) const
Int_t fDataVersion
Definition THaRunBase.h:106
Int_t fStream
Definition THaRun.h:40
virtual Int_t PrescanFile()
Definition THaRun.cxx:222
virtual Bool_t ProvidesInitInfo()
Definition THaRun.cxx:210
virtual Bool_t FindSegmentNumber()
Definition THaRun.cxx:424
virtual ~THaRun()
THaRun(const char *filename="", const char *description="")
Definition THaRun.cxx:40
virtual Int_t SetFilename(const char *name)
Definition THaRun.cxx:372
virtual TString GetInitInfoFileName(TString fname)
Definition THaRun.cxx:277
void SetMinScan(UInt_t n)
Definition THaRun.cxx:412
virtual TString FindInitInfoFile(const TString &fname)
Definition THaRun.cxx:294
virtual Int_t ReadInitInfo(Int_t level)
Definition THaRun.cxx:330
TString fFilename
Definition THaRun.h:37
const char * GetFilename() const
Definition THaRun.h:26
virtual void Print(Option_t *opt="") const
Definition THaRun.cxx:195
virtual void Clear(Option_t *opt="")
Definition THaRun.cxx:124
UInt_t fMaxScan
Definition THaRun.h:38
virtual Int_t Compare(const TObject *obj) const
Definition THaRun.cxx:140
static Bool_t StdFindSegmentNumber(const TString &filename, TString &stem, Int_t &segment, Int_t &stream)
Definition THaRun.cxx:442
Int_t fSegment
Definition THaRun.h:39
virtual Int_t Open()
Definition THaRun.cxx:161
void SetNscan(UInt_t n)
Definition THaRun.cxx:404
virtual THaRun & operator=(const THaRunBase &rhs)
Definition THaRun.cxx:93
const char * GetTitle() const override
void Print(Option_t *option="") const override
void Clear(Option_t *option="") override
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
EStatVal Status()
Int_t Atoi() const
void Clear()
Ssiz_t Last(char c) const
TString & Append(char c, Ssiz_t rep=1)
Bool_t IsNull() const
TString & Remove(EStripType s, char c)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
virtual const char * DirName(const char *pathname)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual const char * BaseName(const char *pathname)
const Int_t n
STL namespace.
ClassImp(TPyArg)