ATLAS Offline Software
VP1AvailEvents.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 // //
8 // Implementation of class VP1AvailEvents //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial version: May 2008 //
12 // //
14 
15 #include "VP1Gui/VP1AvailEvents.h"
16 #include "VP1Base/VP1Msg.h"
17 #include <QFileInfo>
18 #include <QDirIterator>
19 #include <QTimer>
20 
21 #include <algorithm>
22 #include <set>
23 #include <map>
24 #include <iostream>
25 
26 //____________________________________________________________________
28 public:
31  QString tmpDir;
33  //subdirs in tmpDir, generated on the fly:
34  QString tmpLocalFileDir;
36 
37  //Returns empty in case of problems:
38  QString attemptGenerationOfTmpSubdir(const QString& preferredname, QString& cachevar);
39 
40  class EventID {
41  public:
42  EventID(int r, unsigned long long e) : eventNumber(e), runNumber(r) {}
43  unsigned long long eventNumber;
44  int runNumber;
45  bool operator==(const EventID & o) const{
47  }
48  bool operator<(const EventID & o) const
49  {
50  //This ordering is not "newer". It is solely to be able to use in a set.
52  }
53  };
54 
55  static EventID evtToID(const VP1EventFile& evt) {
56  return EventID(evt.runNumber(),evt.eventNumber());
57  }
58 
59  QList<EventID> historyOrdered;
60  std::set<EventID> historySorted;
61  QList<VP1EventFile> lastAllLocal;
62  QList<VP1EventFile> lastFresh;
63 
64  std::map<QString,std::pair<QDateTime,QList<VP1EventFile> > > dircache;//dirname -> (modtime,result)
65 
66  void cleanupTmpLocalFiles();
67 };
68 
69 
70 //____________________________________________________________________
71 VP1AvailEvents::VP1AvailEvents(int timeCutForNew, const QString& td, int maxLocalFilesToKeep, QObject * parent)
72  : QObject(parent), m_d(new Imp)
73 {
74  m_d->theclass = this;
76  m_d->tmpDir = QString(td + (td.endsWith("/")?"":"/")).replace("//","/");
78 }
79 
80 //____________________________________________________________________
82 {
83  //Fixme: These two remove commands only has an effect when dir is empty!!
84  if (!m_d->tmpActiveRetrievalDir.isEmpty()&&m_d->tmpActiveRetrievalDir!="bad")
86  if (!m_d->tmpLocalFileDir.isEmpty()&&m_d->tmpLocalFileDir!="bad")
88  delete m_d;
89 }
90 
91 //____________________________________________________________________
93 {
94  return m_d->timeCutForNew;
95 }
96 
97 //____________________________________________________________________
99 {
100  return m_d->maxLocalFilesToKeep;
101 }
102 
103 //____________________________________________________________________
104 const QString& VP1AvailEvents::tmpDir() const
105 {
106  return m_d->tmpDir;
107 }
108 
109 //____________________________________________________________________
110 QList<VP1EventFile> VP1AvailEvents::freshEvents(VP1EventFile newestEvt, const QList<VP1EventFile>& inputEventList) const
111 {
112  QList<VP1EventFile> l;
113  if (!newestEvt.isValid())
114  return l;
115  std::set<Imp::EventID>::const_iterator histIt, histItE(m_d->historySorted.end());
116  if (m_d->timeCutForNew==0) {
117  if (m_d->historySorted.find(Imp::evtToID(newestEvt))==histItE)
118  l << newestEvt;
119  return l;
120  }
121  for(VP1EventFile evt : inputEventList)
122  if (m_d->historySorted.find(Imp::evtToID(evt))==histItE && isConsideredFresh(evt,newestEvt))
123  l << evt;
124  return l;
125 }
126 
127 
128 //____________________________________________________________________
129 QList<VP1EventFile> VP1AvailEvents::freshEvents() const
130 {
132 }
133 
134 //____________________________________________________________________
136 {
137  QList<VP1EventFile> evts(allLocalEvents());
138  if (evts.isEmpty())
139  return VP1EventFile();//invalid
140  return evts.front();
141 }
142 
143 //____________________________________________________________________
145 {
148 }
149 
150 //____________________________________________________________________
152 {
153  //First we cleanup:
155 
156  //Then we schedule a check for event list changes:
157  QTimer::singleShot(10, this, SLOT(actualCheckForEventListChanges()));
158 }
159 
160 //____________________________________________________________________
162 {
163  QList<VP1EventFile> allLocal = allLocalEvents();
164  QList<VP1EventFile> fresh = freshEvents();
165  if (m_d->lastAllLocal != allLocal) {
166  m_d->lastAllLocal = allLocal;
168  }
169  if (m_d->lastFresh != fresh) {
170  m_d->lastFresh = fresh;
172  }
173 }
174 
175 //____________________________________________________________________
177 {
178  //We schedule the cleanup to take place shortly. The check for event
179  //list changes will be scheduled after the cleanup:
180 
181  //Then we schedule a check for event list changes:
182  QTimer::singleShot(10, this, SLOT(actualCleanup()));
183 
184 }
185 
186 //____________________________________________________________________
187 bool VP1AvailEvents::inHistory(int run, int event) const
188 {
189  return m_d->historySorted.find(Imp::EventID(run,event))!=m_d->historySorted.end();
190 }
191 
192 
193 //____________________________________________________________________
195 {
196  std::map<QString,std::pair<QDateTime,QList<VP1EventFile> > >::iterator it = m_d->dircache.find(dir);
197  if (it!=m_d->dircache.end())
198  m_d->dircache.erase(it);
199 }
200 
201 //____________________________________________________________________
202 QList<VP1EventFile> VP1AvailEvents::allEventFilesInDir(const QString& dir) const
203 {
204  if (dir.isEmpty())
205  return QList<VP1EventFile>();
206 
207  QFileInfo fi_dir(dir);
208  if (!fi_dir.exists()||!fi_dir.isDir())
209  return QList<VP1EventFile>();
210 
211  QDateTime modtime = fi_dir.lastModified();
212  if (abs(modtime.time().msecsTo(QTime::currentTime()))>50) {
213  std::map<QString,std::pair<QDateTime,QList<VP1EventFile> > >::iterator it = m_d->dircache.find(dir);
214  if (it!=m_d->dircache.end()&&it->second.first==modtime)
215  return it->second.second;
216  }
217 
218  QStringList filters;
219  filters << "*_*.pool.root";
220  //fixme
221  QDirIterator itDir(dir,filters,QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::CaseSensitive);
222 
223  QList<VP1EventFile> l;
224  while (itDir.hasNext()) {
225  QString fn = itDir.next();
226  fn.replace("//","/");
228  if (evt.isValid())
229  l << evt;
230  else
231  message("Could not decode event file name: "+fn);
232  }
233 
234  std::sort(l.begin(), l.end());
235 
236  m_d->dircache[dir]=std::make_pair(modtime,l);
237  return l;
238 }
239 
240 //____________________________________________________________________
241 QList<VP1EventFile> VP1AvailEvents::allLocalEvents() const
242 {
244 }
245 
246 
247 //____________________________________________________________________
248 QString VP1AvailEvents::Imp::attemptGenerationOfTmpSubdir(const QString& preferredname, QString& cachevar)
249 {
250  if (!cachevar.isEmpty())
251  return cachevar=="bad"?"":cachevar;
252 
253  QFileInfo fi(tmpDir);
254  if (!( fi.exists()&&fi.isDir())) {
255  theclass->message("Could not create subdir in "+tmpDir+", since it does not exists or is not a directory" );
256  cachevar="bad";
257  return "";
258  }
259  int i(0);
260  while (true) {
261  ++i;
262  QString dir = tmpDir+(tmpDir.endsWith("/")?"":"/")+preferredname+(i==1?QString(""):QString::number(i))+"/";
263  if (!QFile::exists(dir)) {
264  bool ok = QDir().mkdir(dir);
265  if (!ok) {
266  theclass->message("Could not create directory:: "+dir );
267  cachevar="bad";
268  return "";
269  }
270  cachevar = dir;
271  return dir;
272  }
273  }
274 }
275 
276 //____________________________________________________________________
278 {
279  return m_d->attemptGenerationOfTmpSubdir("activeretrievals",m_d->tmpActiveRetrievalDir);
280 }
281 
282 //____________________________________________________________________
284 {
285  return m_d->attemptGenerationOfTmpSubdir("eventfiles",m_d->tmpLocalFileDir);
286 }
287 
288 //____________________________________________________________________
290 {
291  if (maxLocalFilesToKeep<=2)
292  return;
293  if (tmpLocalFileDir.isEmpty())
294  return;
295  QString dir = theclass->tmpLocalFileDir();
296  if (dir.isEmpty())
297  return;
298 
299  QList<VP1EventFile> events = theclass->allLocalEvents();
300  int ntoremove = events.count()-maxLocalFilesToKeep;
301  if (ntoremove<=3)//3 instead of 0 to keep down the times we call the machinery below.
302  return;
303 
304  //Rules of engagement:
305  //We never delete the current event. We never delete the previous
306  //event. We never delete the maxLocalFilesToKeep newest of the fresh
307  //events.
308 
309  QList<Imp::EventID> protectedEvents;
310  if (!historyOrdered.isEmpty()) {
311  protectedEvents << historyOrdered.back();
312  if (historyOrdered.count()>1)
313  protectedEvents << historyOrdered.at(historyOrdered.count()-2);
314  }
315  QList<VP1EventFile> freshEvts = theclass->freshEvents();
316  int ifreshkept(0);
317  for (VP1EventFile evt : theclass->freshEvents()) {
318  protectedEvents << Imp::evtToID(evt);
319  if (++ifreshkept==maxLocalFilesToKeep)
320  break;
321  }
322 
323  //Remove:
324  for (int i = events.count()-1; i>=0; --i ) {
325  if (protectedEvents.contains(Imp::evtToID(events.at(i)))) {
326  continue;
327  }
328  QFile::remove(events.at(i).fileName());
329  if (--ntoremove<=0)
330  break;
331  }
332  theclass->invalidateDirCache(theclass->tmpLocalFileDir());
333 }
334 
335 //____________________________________________________________________
336 bool VP1AvailEvents::isConsideredFresh ( const VP1EventFile& evt, const VP1EventFile& newestEvt ) const
337 {
338  //Notice: Logic here must be similar to logic in VP1EvtsOnServerInfo::events
339 
340  if (m_d->timeCutForNew==0) {
341  //Special case where only the newest event is fresh
342  return evt.rawTime()==newestEvt.rawTime() && evt.runNumber()==newestEvt.runNumber();
343  }
344  if (requireNewestRunNumber()&&evt.runNumber()!=newestEvt.runNumber())
345  return false;
346  const unsigned oldest_time = (m_d->timeCutForNew<0||unsigned(m_d->timeCutForNew)>newestEvt.rawTime()) ? 0 : newestEvt.rawTime() - m_d->timeCutForNew;
347  return evt.rawTime() >= oldest_time;
348 }
349 
350 //____________________________________________________________________
351 void VP1AvailEvents::messageDebug(const QString& s) const
352 {
353  std::cout<<VP1Msg::prefix_verbose()<<": "<<s.toStdString()<<std::endl;
354 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
VP1AvailEvents::Imp::EventID::EventID
EventID(int r, unsigned long long e)
Definition: VP1AvailEvents.cxx:42
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
beamspotman.r
def r
Definition: beamspotman.py:676
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
VP1AvailEvents::tmpLocalFileDir
QString tmpLocalFileDir() const
Definition: VP1AvailEvents.cxx:283
VP1AvailEvents::actualCheckForEventListChanges
void actualCheckForEventListChanges()
Definition: VP1AvailEvents.cxx:161
VP1AvailEvents::tmpDir
const QString & tmpDir() const
Definition: VP1AvailEvents.cxx:104
VP1Msg.h
VP1AvailEvents::Imp::EventID::operator==
bool operator==(const EventID &o) const
Definition: VP1AvailEvents.cxx:45
VP1AvailEvents.h
VP1AvailEvents::allLocalEvents
QList< VP1EventFile > allLocalEvents() const
Definition: VP1AvailEvents.cxx:241
VP1AvailEvents::allLocalEventsChanged
void allLocalEventsChanged()
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
skel.it
it
Definition: skel.GENtoEVGEN.py:396
VP1AvailEvents::cleanupAndCheckForEventListChanges
void cleanupAndCheckForEventListChanges()
Definition: VP1AvailEvents.cxx:176
VP1AvailEvents::tmpActiveRetrievalDir
QString tmpActiveRetrievalDir()
Definition: VP1AvailEvents.cxx:277
VP1AvailEvents::actualCleanup
void actualCleanup()
Definition: VP1AvailEvents.cxx:151
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
VP1AvailEvents::Imp::tmpDir
QString tmpDir
Definition: VP1AvailEvents.cxx:31
AthenaPoolTestRead.Files
Files
Definition: AthenaPoolTestRead.py:10
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
VP1AvailEvents::freshEventsChanged
void freshEventsChanged()
VP1AvailEvents::Imp::EventID
Definition: VP1AvailEvents.cxx:40
python.DataFormatRates.events
events
Definition: DataFormatRates.py:105
xAOD::unsigned
unsigned
Definition: RingSetConf_v1.cxx:662
VP1AvailEvents::message
void message(const QString &) const
VP1AvailEvents::inHistory
bool inHistory(int run, int event) const
Definition: VP1AvailEvents.cxx:187
VP1AvailEvents::freshEvents
QList< VP1EventFile > freshEvents() const
Definition: VP1AvailEvents.cxx:129
VP1AvailEvents::~VP1AvailEvents
virtual ~VP1AvailEvents()
Definition: VP1AvailEvents.cxx:81
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
python.getCurrentFolderTag.fn
fn
Definition: getCurrentFolderTag.py:65
VP1AvailEvents::VP1AvailEvents
VP1AvailEvents(int timeCutForNew, const QString &tmpdir, int maxLocalFilesToKeep=-1, QObject *parent=0)
Definition: VP1AvailEvents.cxx:71
VP1AvailEvents::newestEvent
VP1EventFile newestEvent() const
Definition: VP1AvailEvents.cxx:135
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
VP1AvailEvents::Imp::timeCutForNew
int timeCutForNew
Definition: VP1AvailEvents.cxx:30
lumiFormat.i
int i
Definition: lumiFormat.py:85
VP1AvailEvents::Imp::cleanupTmpLocalFiles
void cleanupTmpLocalFiles()
Definition: VP1AvailEvents.cxx:289
VP1AvailEvents::Imp::maxLocalFilesToKeep
int maxLocalFilesToKeep
Definition: VP1AvailEvents.cxx:32
VP1AvailEvents::Imp
Definition: VP1AvailEvents.cxx:27
VP1AvailEvents::Imp::EventID::operator<
bool operator<(const EventID &o) const
Definition: VP1AvailEvents.cxx:48
test_pyathena.parent
parent
Definition: test_pyathena.py:15
VP1AvailEvents::timeCutForNew
int timeCutForNew() const
Definition: VP1AvailEvents.cxx:92
run
Definition: run.py:1
VP1EventFile::isValid
bool isValid() const
Definition: VP1EventFile.cxx:158
VP1AvailEvents::setCurrentEvent
void setCurrentEvent(int run, int event)
Definition: VP1AvailEvents.cxx:144
VP1AvailEvents::requireNewestRunNumber
bool requireNewestRunNumber() const
Definition: VP1AvailEvents.h:62
VP1EventFile::runNumber
int runNumber() const
Definition: VP1EventFile.cxx:176
beamspotman.dir
string dir
Definition: beamspotman.py:623
VP1AvailEvents::m_d
Imp * m_d
Definition: VP1AvailEvents.h:78
VP1AvailEvents::Imp::historyOrdered
QList< EventID > historyOrdered
Definition: VP1AvailEvents.cxx:59
python.selection.number
number
Definition: selection.py:20
VP1EventFile::rawTime
unsigned rawTime() const
Definition: VP1EventFile.cxx:188
VP1AvailEvents::Imp::tmpActiveRetrievalDir
QString tmpActiveRetrievalDir
Definition: VP1AvailEvents.cxx:35
VP1AvailEvents::Imp::historySorted
std::set< EventID > historySorted
Definition: VP1AvailEvents.cxx:60
VP1AvailEvents::maxLocalFilesToKeep
int maxLocalFilesToKeep() const
Definition: VP1AvailEvents.cxx:98
VP1Msg::prefix_verbose
static const char * prefix_verbose()
Definition: VP1Msg.h:59
VP1AvailEvents::Imp::tmpLocalFileDir
QString tmpLocalFileDir
Definition: VP1AvailEvents.cxx:34
VP1EventFile
Definition: VP1EventFile.h:23
VP1AvailEvents::Imp::lastFresh
QList< VP1EventFile > lastFresh
Definition: VP1AvailEvents.cxx:62
VP1AvailEvents::Imp::EventID::runNumber
int runNumber
Definition: VP1AvailEvents.cxx:44
checkFileSG.fi
fi
Definition: checkFileSG.py:65
VP1AvailEvents::Imp::theclass
VP1AvailEvents * theclass
Definition: VP1AvailEvents.cxx:29
VP1AvailEvents::allEventFilesInDir
QList< VP1EventFile > allEventFilesInDir(const QString &dir) const
Definition: VP1AvailEvents.cxx:202
VP1AvailEvents
Definition: VP1AvailEvents.h:25
VP1AvailEvents::Imp::lastAllLocal
QList< VP1EventFile > lastAllLocal
Definition: VP1AvailEvents.cxx:61
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
VP1AvailEvents::Imp::evtToID
static EventID evtToID(const VP1EventFile &evt)
Definition: VP1AvailEvents.cxx:55
VP1AvailEvents::messageDebug
void messageDebug(const QString &) const
Definition: VP1AvailEvents.cxx:351
VP1AvailEvents::isConsideredFresh
bool isConsideredFresh(const VP1EventFile &evt, const VP1EventFile &newestEvt) const
Definition: VP1AvailEvents.cxx:336
VP1AvailEvents::Imp::attemptGenerationOfTmpSubdir
QString attemptGenerationOfTmpSubdir(const QString &preferredname, QString &cachevar)
Definition: VP1AvailEvents.cxx:248
VP1AvailEvents::Imp::dircache
std::map< QString, std::pair< QDateTime, QList< VP1EventFile > > > dircache
Definition: VP1AvailEvents.cxx:64
VP1AvailEvents::Imp::EventID::eventNumber
unsigned long long eventNumber
Definition: VP1AvailEvents.cxx:43
VP1AvailEvents::invalidateDirCache
void invalidateDirCache(const QString &dir)
Definition: VP1AvailEvents.cxx:194