ATLAS Offline Software
Loading...
Searching...
No Matches
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
32VP1FileUtilities::VP1FileUtilities(const std::string& inputDirectory,
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
66
67void 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}
void produceNewFile(const std::string &sourceFile, unsigned int runNumber, unsigned long long eventNumber, unsigned int timeStamp, const std::string &textLabel="")
VP1FileUtilities(const std::string &inputDirectory, unsigned int fileLimit, const std::string &outputDir="", bool forceMakeOutputDir=false, bool removeInputFile=true)
std::string m_inputDirectory
static bool fileExistsAndReadable(const std::string &)
std::string m_outputDirectory
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
std::string cwd
Definition listroot.cxx:38
TFile * file