ATLAS Offline Software
VP1EvtsOnServerInfo.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 // //
8 // Implementation of class VP1EvtsOnServerInfo //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial version: May 2008 //
12 // //
14 
16 #include "VP1Gui/VP1MD5Sum.h"
17 #include <QFileInfo>
18 #include <QTextStream>
19 #include <QtCoreVersion>
20 #include <map>
21 
22 
23 //____________________________________________________________________
25 public:
26  Imp(const QString& infofile)
27  {
28  error = init(infofile);
29  }
30 
31  QString error;
32  QString init(const QString& infofile);
33 
34  QList<VP1EventFile> events;//if invalid, we make a list with one dummy
35  //event (to avoid crashes if user forget to
36  //check isValid())
37 };
38 
39 
40 //____________________________________________________________________
42  : m_d(new Imp(infofile))
43 {
44 }
45 
46 //____________________________________________________________________
48 {
49  delete m_d;
50 }
51 
52 //____________________________________________________________________
54 {
55  return m_d->error.isEmpty();
56 }
57 
58 //____________________________________________________________________
60 {
61  return m_d->error;
62 }
63 
64 //____________________________________________________________________
65 QStringList VP1EvtsOnServerInfo::print() const
66 {
67  QStringList l;
68  if (!isValid()) {
69  l << "Invalid. Reason: " + error();
70  return l;
71  }
72  l << "Valid with "+QString::number(numberOfEvents())+" files:";
73  for(VP1EventFile evt : events())
74  l << " "+evt.print();
75  l << "Events within 10 minutes of latest:";
76  for(VP1EventFile evt : events(10*60))
77  l << " "+evt.print();
78  l << "Events with same run number as latest:";
79  for(VP1EventFile evt : events(-1,true))
80  l << " "+evt.print();
81  l << "Events with same run number as latest and within 1 minute:";
82  for(VP1EventFile evt : events(1*60,true))
83  l << " "+evt.print();
84 
85  return l;
86 }
87 
88 //____________________________________________________________________
89 QString VP1EvtsOnServerInfo::Imp::init(const QString& infofile)
90 {
91  //Example of file we are trying to parse:
92  //
93  //begin_copyresult
94  //source dir /client/VP1_events
95  //dest dir /www/web_files/html/vp1events
96  //vp1_69629_5487_1211316972.pool.root copy success
97  //end_copyresult
98  //begin_checksums
99  //vp1_69629_5487_1211316972.pool.root 30fa3c9a05251a4d741fce52c304a341
100  //vp1_69629_5270_1211316960.pool.root 7a38564cdd2f2951e76ec37c565dbbf9
101  //vp1_69629_3968_1211316900.pool.root 6c716952a7fdb0371b1541a45d0029f8
102  //end_checksums
103  //
104  //The format of the event file names are: vp1_[run#]_[evt#]_[unixtime].pool.root
105  //
106  //In principle we are only interested in the checksums section, but
107  //it might be a good sanity check to see that the last copied file
108  //(from copyresult) is also the one with the highest time.
109 
111  // Basic check that file exists, is readable, etc. //
113 
114  if (infofile.isEmpty())
115  return "Given empty path to info file";
116  QFileInfo fi(infofile);
117  if (!fi.exists())
118  return "infofile "+infofile+" does not exist";
119  if (!fi.isReadable())
120  return "infofile "+infofile+" is not readable";
121  if (fi.size()==0)
122  return "infofile "+infofile+" is not empty";
123 
125  // Read file into stringlist, ignoring empty lines and excess whitespace //
127 
128  int i_begin_copyresult(-1), i_end_copyresult(-1);
129  int i_begin_checksums(-1), i_end_checksums(-1);
130 
131 
132  QStringList lines;
133  QFile file(infofile);
134  if (!file.open(QFile::ReadOnly))
135  return "Could not open file in readonly mode";
136 
137  //Just to avoid any potential performance problems if pointed to a
138  //wrong input file:
139  const qint64 max_linelength(1000);
140  const qint64 max_numberoflines(2000);
141  qint64 ilines(0);
142 
143  QTextStream stream(&file);
144  while (!stream.atEnd()) {
145 
146  if (ilines++>max_numberoflines)
147  return "Too many lines in file";
148 
149  //Read and prune next line:
150  QString rawline = stream.readLine(max_linelength).simplified();
151  if (rawline.isEmpty())
152  continue;
153 
154  //Get section boundaries:
155  if (rawline=="begin_copyresult") {
156  if (i_begin_copyresult!=-1)
157  return "Saw two lines with begin_copyresult";
158  i_begin_copyresult = lines.count();
159  } else if (rawline=="end_copyresult") {
160  if (i_end_copyresult!=-1)
161  return "Saw two lines with end_copyresult";
162  i_end_copyresult = lines.count();
163  } else if (rawline=="begin_checksums") {
164  if (i_begin_checksums!=-1)
165  return "Saw two lines with begin_checksums";
166  i_begin_checksums = lines.count();
167  } else if (rawline=="end_checksums") {
168  if (i_end_checksums!=-1)
169  return "Saw two lines with end_checksums";
170  i_end_checksums = lines.count();
171  }
172 
173  //Store line:
174  lines << rawline;
175  }
176  if (lines.isEmpty())
177  return "Did not read any lines from file";
178 
179  //copy result is only used for a sanity check, so we keep it optional
180  const bool hascopyresult(i_begin_copyresult!=-1||i_end_copyresult!=-1);
181 
182  if (i_begin_checksums==-1) return "File did not have begin_checksums line";
183  if (i_end_checksums==-1) return "File did not have end_checksums line";
184  if (i_end_checksums<=i_begin_checksums) return "checksum section delimiters out of order";
185 
186  if (hascopyresult) {
187  if (i_begin_copyresult==-1) return "File had end_copyresult but no begin_copyresult line";
188  if (i_end_copyresult==-1) return "File had begin_copyresult but no end_copyresult line";
189  if (i_end_copyresult<=i_begin_copyresult) return "copyresult section delimiters out of order";
190  if (i_begin_copyresult>i_begin_checksums&&i_begin_copyresult<i_end_checksums)
191  return "copyresult and checksum sections mixed";
192  if (i_end_copyresult>i_begin_checksums&&i_end_copyresult<i_end_checksums)
193  return "copyresult and checksum sections mixed";
194  }
195 
197  // Let the parsing begin!! //
199 
200  for (int i = i_begin_checksums+1;i < i_end_checksums; ++i) {
201 #if QTCORE_VERSION >= 0x050E00
202  QStringList parts = lines.at(i).split ( ' ', Qt::SkipEmptyParts );
203 #else
204  QStringList parts = lines.at(i).split ( ' ', QString::SkipEmptyParts );
205 #endif
206  if (parts.count()!=2)
207  return "Invalid line in checksums section";
208  QString filename(parts.at(0));
209  QString md5sum(VP1MD5Sum::sumToStandardFormat(parts.at(1)));
210  if (!VP1MD5Sum::validMD5Sum(md5sum))
211  return "Invalid md5sum in checksums section: "+md5sum;
212  VP1EventFile evt(filename,md5sum);
213  if (!evt.isValid())
214  return "Failed to decode event file information from filename: "+filename;
215  events << evt;
216  }
217 
218  std::sort(events.begin(), events.end());
219 
220  if (hascopyresult) {
221  //Todo: Use the copy result lines for a sanity check of that the
222  //newest file is also the one copied last (if copy succesful).
223  }
224 
225  return "";
226 }
227 
228 //____________________________________________________________________
229 unsigned long long VP1EvtsOnServerInfo::numberOfEvents() const
230 {
231  return m_d->events.count();
232 }
233 
234 //____________________________________________________________________
236 {
237  return m_d->events.isEmpty() ? VP1EventFile() : m_d->events.at(0);
238 }
239 
240 //____________________________________________________________________
241 QList<VP1EventFile> VP1EvtsOnServerInfo::events(int timecut, bool requireNewestRunNumber ) const
242 {
243  //Notice: Logic here must be similar to logic in VP1AvailEvents::isConsideredFresh
244 
245  if ( m_d->events.isEmpty() )
246  return m_d->events;
247 
248  if (timecut==0) {
249  QList<VP1EventFile> l;
250  l << m_d->events.at(0);
251  return l;
252  }
253  const unsigned newestRawTime = m_d->events.at(0).rawTime();
254  const int newestRunNumber = m_d->events.at(0).runNumber();
255 
256  const unsigned minTime = (timecut<0&&unsigned(timecut)>newestRawTime) ? 0 : newestRawTime-timecut;
257 
258  QList<VP1EventFile> out;
259  for (VP1EventFile evt : m_d->events) {
260  if (minTime>0&&evt.rawTime()<minTime)
261  continue;
262  if (requireNewestRunNumber&&evt.runNumber()!=newestRunNumber)
263  continue;
264  out << evt;
265  }
266  return out;
267 }
VP1EvtsOnServerInfo::Imp::error
QString error
Definition: VP1EvtsOnServerInfo.cxx:31
VP1EvtsOnServerInfo::error
QString error() const
Definition: VP1EvtsOnServerInfo.cxx:59
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
VP1EvtsOnServerInfo.h
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
VP1EvtsOnServerInfo::~VP1EvtsOnServerInfo
~VP1EvtsOnServerInfo()
Definition: VP1EvtsOnServerInfo.cxx:47
xAOD::unsigned
unsigned
Definition: RingSetConf_v1.cxx:662
VP1MD5Sum::validMD5Sum
static bool validMD5Sum(const QString &)
Definition: VP1MD5Sum.cxx:88
CaloCondBlobAlgs_fillNoiseFromASCII.lines
lines
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:104
VP1EvtsOnServerInfo::VP1EvtsOnServerInfo
VP1EvtsOnServerInfo(const QString &infofile)
Definition: VP1EvtsOnServerInfo.cxx:41
VP1EvtsOnServerInfo::Imp::Imp
Imp(const QString &infofile)
Definition: VP1EvtsOnServerInfo.cxx:26
lumiFormat.i
int i
Definition: lumiFormat.py:85
VP1EvtsOnServerInfo::Imp::events
QList< VP1EventFile > events
Definition: VP1EvtsOnServerInfo.cxx:34
file
TFile * file
Definition: tile_monitor.h:29
VP1EvtsOnServerInfo::m_d
Imp * m_d
Definition: VP1EvtsOnServerInfo.h:53
VP1EvtsOnServerInfo::print
QStringList print() const
Definition: VP1EvtsOnServerInfo.cxx:65
python.selection.number
number
Definition: selection.py:20
VP1EvtsOnServerInfo::isValid
bool isValid() const
Definition: VP1EvtsOnServerInfo.cxx:53
VP1MD5Sum::sumToStandardFormat
static QString sumToStandardFormat(const QString &)
Definition: VP1MD5Sum.cxx:96
VP1EventFile
Definition: VP1EventFile.h:23
VP1EvtsOnServerInfo::Imp
Definition: VP1EvtsOnServerInfo.cxx:24
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
VP1EvtsOnServerInfo::newestEvent
VP1EventFile newestEvent() const
Definition: VP1EvtsOnServerInfo.cxx:235
checkFileSG.fi
fi
Definition: checkFileSG.py:65
VP1MD5Sum.h
doL1CaloHVCorrections.parts
parts
Definition: doL1CaloHVCorrections.py:334
VP1EvtsOnServerInfo::numberOfEvents
unsigned long long numberOfEvents() const
Definition: VP1EvtsOnServerInfo.cxx:229
error
Definition: IImpactPoint3dEstimator.h:70
VP1EvtsOnServerInfo::events
QList< VP1EventFile > events(int timecut=-1, bool requireNewestRunNumber=false) const
Definition: VP1EvtsOnServerInfo.cxx:241
VP1EvtsOnServerInfo::Imp::init
QString init(const QString &infofile)
Definition: VP1EvtsOnServerInfo.cxx:89