ATLAS Offline Software
VP1FileUtilities.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // //
7 // Implementation of class VP1FileUtilities //
8 // //
9 // Author: Vakho Tsulaia <tsulaia@mail.cern.ch> //
10 // //
11 // Initial version: October 2007 //
12 // //
14 
16 
17 #include <QDir>
18 #include <QFile>
19 #include <QFileInfo>
20 #include <QStringList>
21 #include <QFileInfoList>
22 #include <QThread>
23 
24 #include <string>
25 #include <sstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <stdexcept>
29 #include <thread> // std::this_thread::sleep_for // C++11
30 #include <chrono> // std::chrono::seconds // C++11
31 
33  unsigned int fileLimit, const std::string& outputDir, bool forceMakeOutputDir, bool removeInputFile):
34  m_inputDirectory(inputDirectory),
35  m_fileLimit(fileLimit),
36  m_outputDirectory(outputDir),
37  m_forceMakeOutputDir(forceMakeOutputDir),
38  m_removeInputFile(removeInputFile)
39 {
40  // Check if the input directory exists and is writable
41  QFileInfo inpDir(m_inputDirectory.c_str());
42  if(!inpDir.exists()||!inpDir.isDir()||!inpDir.isReadable()||!inpDir.isWritable()) {
43  std::string errMessage = std::string("VP1FileUtilities: ERROR!! The directory ") + inputDirectory + std::string(" either does not exist or is not writable");
44  throw std::runtime_error(errMessage.c_str());
45  }
46 
47  // Check if the output directory exists and is writable
48  if (m_outputDirectory != "") {
49  QFileInfo inpDir(m_outputDirectory.c_str());
50  if(!inpDir.exists()||!inpDir.isDir()||!inpDir.isReadable()||!inpDir.isWritable()) {
51  std::string errMessage = std::string("VP1FileUtilities: ERROR!! The directory ") + m_outputDirectory + std::string(" does not exist.");
53  errMessage += "\nforceMakeOutputDir=True --> Creating the output folder now...";
54  QDir().mkdir(m_outputDirectory.c_str());
55  } else {
56  throw std::runtime_error(errMessage.c_str());
57  }
58  }
59  }
60 
61 }
62 
64 {
65 }
66 
67 void VP1FileUtilities::produceNewFile(const std::string& sourceFile,
68  unsigned int runNumber,
69  unsigned long long eventNumber,
70  unsigned int timeStamp,
71  const std::string& textLabel)
72 {
73  // Check if the sourceFile exists
74  QString srcName(sourceFile.c_str());
75  QFile srcFile(srcName);
76 
77  if(!srcFile.exists())
78  throw std::runtime_error("Source file does not exist!");
79 
80  QString inpDirName(m_inputDirectory.c_str());
81  QString outDirName(m_outputDirectory.c_str());
82 
83  // Construct new filename
84  QString newFileName = inpDirName;
85  std::ostringstream newFileStr;
86 
87  // if input directory name is empty don't add / to the file name
88  // also take into account a possibility of trailing slash in directory name
89  if(m_inputDirectory!="" && m_inputDirectory.rfind('/')!=m_inputDirectory.size()-1)
90  newFileStr << "/";
91 
92  QString latestEventFileName = inpDirName + QString(newFileStr.str().c_str()) + QString("latest_vp1event");
93 
94  if (textLabel != "" ) {
95  newFileStr << "vp1_r" << runNumber << "_ev" << eventNumber << "_u" << timeStamp << "_t" << textLabel << ".pool.root";
96  } else {
97  newFileStr << "vp1_r" << runNumber << "_ev" << eventNumber << "_u" << timeStamp << ".pool.root";
98  }
99 
100  newFileName += QString(newFileStr.str().c_str());
101 
102 
103  // adding the output folder, if not empty
104  if (outDirName != "")
105  newFileName = outDirName + QDir::separator() + newFileName;
106 
107  // do copy
108  std::cout << "VP1FileUtilities -- copying '" << (srcFile.fileName()).toStdString() << "' to: '" << newFileName.toStdString() << "'..." << std::endl;
109 
110 
111  // get size of the file to be copied
112  qint64 inputSize = srcFile.size();
113  std::cout << "VP1FileUtilities -- Size of the input file to be copied: " << inputSize << std::endl;
114 
115 
116  if(!srcFile.copy(newFileName)) {
117  throw std::runtime_error("VP1FileUtilities -- Unable to copy the temp file to the new file, so unable to produce the new vp1 event file");
118  }
119 
120  // remove the input file (if not disabled by user)
121  std::cout << "VP1FileUtilities -- delete temp file? --> " << m_removeInputFile << std::endl;
122  if (m_removeInputFile) {
123  bool copyDone = false;
124  std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now() ;
125  typedef std::chrono::duration<int,std::milli> millisecs_t ;
126  while (!copyDone) {
127 
128  // get handle on new file
129  QFileInfo checkFile(newFileName);
130 
131 
132  // check if file exists (and it is a file, and not a directory)
133  if (checkFile.exists() && checkFile.isFile() && (checkFile.size() == inputSize) )
134  {
135  std::cout << "VP1FileUtilities -- Size of the file to be deleted: " << checkFile.size() << std::endl;
136  copyDone = true;
137  if(!srcFile.remove())
138  std::cerr << "VP1FileUtilities -- WARNING! Unable to delete " << sourceFile << std::endl;
139  }
140  else
141  {
142  std::cout << "VP1FileUtilities -- I could not find the output file, so probably the copy action is not finished yet. I'll wait for a short while and I will retry..." << std::endl;
143  std::this_thread::sleep_for(std::chrono::milliseconds(500)); //make the program waiting for 0.5 seconds
144  std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now() ;
145  millisecs_t duration( std::chrono::duration_cast<millisecs_t>(end-start) ) ;
146  if (duration.count() > 2000.0 )
147  {
148  std::cout << "VP1FileUtilities -- WARNING!!! " << duration.count() << " milliseconds passed and still I cannot find the output file. Probably there was a problem. Giving up with the removal of the source file...\n" ;
149  copyDone = true;
150  }
151  }
152  }
153  }
154 
155  // create/update the latest event file
156  QFile latestEvent(latestEventFileName);
157  if(latestEvent.exists() && !latestEvent.remove())
158  throw std::runtime_error("VP1FileUtilities -- Unable to overwrite the existing latest event file");
159 
160  if(!latestEvent.open(QIODevice::WriteOnly | QIODevice::Text))
161  throw std::runtime_error("VP1FileUtilities -- Unable to create new latest event file");
162  latestEvent.write(newFileName.toStdString().c_str());
163  latestEvent.close();
164 
165  // do cleanup if requested. '-1' means 'KEEP ALL FILES'
166  if (m_fileLimit != -1) {
167  std::cout << "VP1FileUtilities -- cleaning up..." << std::endl;
168  cleanUp();
169  }
170 }
171 
172 // if the user set a "m_fileLimit" then clean the outputDirectory,
173 // to only keep this predefined number of output files.
174 // Please notice: default behaviours is: keep ALL output events.
176 {
177  //std::cout << "VP1FileUtilities::cleanUp()" << std::endl;
178 
179  QDir dir;
180  dir.setPath(QString(m_outputDirectory.c_str()));
181 
182  QStringList nameFilters;
183  nameFilters << "vp1_*.pool.root";
184 
185  dir.setFilter(QDir::Files);
186  dir.setNameFilters(nameFilters);
187  dir.setSorting(QDir::Time|QDir::Reversed);
188  QFileInfoList list = dir.entryInfoList();
189 
190  if(int(list.size()) > m_fileLimit)
191  {
192  const QFileInfo& fileInfo = list.at(0);
193 
194  if(!dir.remove(fileInfo.fileName()))
195  throw std::runtime_error("VP1FileUtilities::cleanup() - WARNING: Unable to do the clean up!");
196  }
197 
198  QString poolCatalog("PoolFileCatalog.xml");
199  std::string poolCatalogStr = poolCatalog.toStdString();
200  std::cout << "looking for " << poolCatalogStr << " in " << QDir::currentPath().toStdString() << std::endl;
201  if ( QDir::current().entryList().contains( poolCatalog ) ) {
202  std::cout << "VP1FileUtilities::cleanUp() - removing the file '" << poolCatalogStr << "' because it causes problems for subsequent Athena commands opening the copied file." << std::endl;
203  QDir cwd = QDir::currentPath();
204  if ( ! cwd.remove( poolCatalog ) )
205  std::cerr << "VP1FileUtilities WARNING! Unable to delete " << poolCatalogStr << std::endl;
206  }
207 
208  return;
209 }
210 
212 {
213  return !file.empty() && QFileInfo(file.c_str()).exists();
214 }
fillPileUpNoiseLumi.current
current
Definition: fillPileUpNoiseLumi.py:52
VP1FileUtilities::m_removeInputFile
bool m_removeInputFile
Definition: VP1FileUtilities.h:67
VP1FileUtilities::~VP1FileUtilities
virtual ~VP1FileUtilities()
Definition: VP1FileUtilities.cxx:63
VP1FileUtilities::fileExistsAndReadable
static bool fileExistsAndReadable(const std::string &)
Definition: VP1FileUtilities.cxx:211
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
VP1FileUtilities::m_fileLimit
int m_fileLimit
Definition: VP1FileUtilities.h:64
AthenaPoolTestRead.Files
Files
Definition: AthenaPoolTestRead.py:10
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
VP1FileUtilities::m_forceMakeOutputDir
bool m_forceMakeOutputDir
Definition: VP1FileUtilities.h:66
AthExHiveOpts.Time
Time
Definition: AthExHiveOpts.py:63
VP1FileUtilities::cleanUp
void cleanUp()
Definition: VP1FileUtilities.cxx:175
python.handimod.now
now
Definition: handimod.py:675
VP1FileUtilities::VP1FileUtilities
VP1FileUtilities(const std::string &inputDirectory, unsigned int fileLimit, const std::string &outputDir="", bool forceMakeOutputDir=false, bool removeInputFile=true)
Definition: VP1FileUtilities.cxx:32
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
file
TFile * file
Definition: tile_monitor.h:29
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
xAOD::eventNumber
eventNumber
Definition: EventInfo_v1.cxx:124
checkFile
Definition: checkFile.py:1
CscCalibQuery.outputDir
string outputDir
Definition: CscCalibQuery.py:261
PixelAthHitMonAlgCfg.duration
duration
Definition: PixelAthHitMonAlgCfg.py:152
beamspotman.dir
string dir
Definition: beamspotman.py:623
xAOD::timeStamp
setEventNumber timeStamp
Definition: EventInfo_v1.cxx:128
cwd
std::string cwd
Definition: listroot.cxx:38
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
fitman.srcFile
srcFile
Definition: fitman.py:373
VP1FileUtilities::produceNewFile
void produceNewFile(const std::string &sourceFile, unsigned int runNumber, unsigned long long eventNumber, unsigned int timeStamp, const std::string &textLabel="")
Definition: VP1FileUtilities.cxx:67
TileLaserCalibAlgConfig.inputDirectory
inputDirectory
Definition: TileLaserCalibAlgConfig.py:84
VP1FileUtilities::m_outputDirectory
std::string m_outputDirectory
Definition: VP1FileUtilities.h:65
VP1FileUtilities.h
VP1FileUtilities::m_inputDirectory
std::string m_inputDirectory
Definition: VP1FileUtilities.h:63
python.trfValidateRootFile.checkFile
def checkFile(fileName, the_type, requireTree)
Definition: trfValidateRootFile.py:227