18 #include "cetlib_except/exception.h" 28 fGeneratePerFileMetadata(false),
29 fRenameOverwrite(false),
61 std::vector<std::string> md = pset.
get<std::vector<std::string> >(
"Metadata");
71 <<
"Metadata array has odd number of entries.\n";
72 for(
unsigned int i=0; i<md.size(); i += 2)
73 fPerJobMetadata.insert(std::pair<std::string, std::string>(md[i], md[i+1]));
92 const std::string& name = i->first;
93 const std::string&
value = i->second;
97 if(value.size() > 0) {
104 for(
auto const & nvp : md) {
105 if(nvp.first == name) {
110 if(nvp.second != value) {
112 <<
"Found duplicate name " << name <<
" with non-matching value.\n";
170 <<
"no metadata for output file '" << fn <<
"'\n";
195 <<
"Output file " << fn <<
" already has metadata.\n";
210 if(file != 0 && !file->IsZombie() && file->IsOpen()) {
219 sqlite3_stmt *stmt = 0;
220 int ok = sqlite3_prepare_v2(sqliteDB,
"SELECT Name, Value FROM FileCatalog_metadata;",
226 if(ok == SQLITE_OK) {
230 while((ok = sqlite3_step(stmt)) == SQLITE_ROW) {
237 std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
239 std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
246 md.
fNVPairs.insert(std::pair<std::string, std::string>(name, value));
249 sqlite3_finalize(stmt);
263 const std::string& fn = finfo.
fileName();
288 file = TFile::Open(fn.c_str(),
"READ");
294 if(file != 0 && !file->IsZombie() && file->IsOpen()) {
299 TKey* key = file->GetKey(
"RootFileDB");
335 std::vector<std::string> output_files;
336 TIter next(gROOT->GetListOfFiles());
337 while(TFile*
file = (TFile*)next()) {
338 if(
file->GetBytesWritten() > 0)
339 output_files.push_back(
file->GetName());
341 std::sort(output_files.begin(), output_files.end());
345 std::vector<std::string> opened_files(output_files.size());
346 std::vector<std::string> closed_files(
fOutputFiles.size());
348 it = std::set_difference(output_files.begin(), output_files.end(),
350 opened_files.begin());
351 opened_files.resize(it - opened_files.begin());
353 output_files.begin(), output_files.end(),
354 closed_files.begin());
355 closed_files.resize(it - closed_files.begin());
361 for(
auto const& of : opened_files)
387 std::string map_fn = fn;
389 std::vector<std::string> renamed_files;
391 std::string filename = map_ele.first;
392 std::ifstream
file(filename);
393 if(file.good() && file.is_open())
396 renamed_files.push_back(filename);
399 if(renamed_files.size() == 1)
400 map_fn = renamed_files.front();
403 <<
"Could not access metadata because there is more than one renamed output file.\n";
408 info <<
"No metadata for file " << fn
409 <<
"\nUsing renamed file " << map_fn <<
" metadata instead.";
414 <<
"No metadata found for file " << map_fn <<
".\n";
424 TFile*
file = TFile::Open(fn.c_str(),
"UPDATE");
425 if(file != 0 && !file->IsZombie() && file->IsOpen()) {
440 sqlite3_exec(sqliteDB,
"BEGIN TRANSACTION;", 0, 0, errMsg);
441 sqlite3_stmt *stmt = 0;
442 int ok = sqlite3_prepare_v2(sqliteDB,
"SELECT 1 FROM FileCatalog_metadata;",
444 if(ok == SQLITE_OK) {
446 ok = sqlite3_finalize(stmt);
448 if(ok == SQLITE_OK) {
455 std::multimap<std::string, std::string> mdmap;
461 sqlite3_prepare_v2(sqliteDB,
462 "INSERT INTO FileCatalog_metadata(Name, Value) VALUES(?, ?);",
464 sqlite3_stmt *delete_stmt = 0;
465 sqlite3_prepare_v2(sqliteDB,
466 "DELETE FROM FileCatalog_metadata WHERE Name=?;",
467 -1, &delete_stmt, NULL);
468 std::string lastName;
469 for (
auto const & nvp : mdmap ) {
470 std::string
const & theName (nvp.first);
471 std::string
const & theValue (nvp.second);
477 if(theName != lastName) {
479 if(theName.size() != 0) {
480 sqlite3_bind_text(delete_stmt, 1, theName.c_str(),
481 theName.size() + 1, SQLITE_STATIC);
482 sqlite3_step(delete_stmt);
483 sqlite3_reset(delete_stmt);
484 sqlite3_clear_bindings(delete_stmt);
487 sqlite3_bind_text(stmt, 1, theName.c_str(),
488 theName.size() + 1, SQLITE_STATIC);
489 sqlite3_bind_text(stmt, 2, theValue.c_str(),
490 theValue.size() + 1, SQLITE_STATIC);
493 sqlite3_clear_bindings(stmt);
495 sqlite3_finalize(stmt);
496 sqlite3_finalize(delete_stmt);
497 sqlite3_exec(sqliteDB,
"END TRANSACTION;", 0, 0, errMsg);
504 sqlite3_exec(sqliteDB,
"ROLLBACK TRANSACTION;", 0, 0, errMsg);
529 for(
auto run : fRunNumbers) {
530 std::ostringstream ostr;
532 md.insert(std::pair<std::string, std::string>(
"run", ostr.str()));
534 for(
auto subrun : fSubRunNumbers) {
535 std::ostringstream ostr;
537 md.insert(std::pair<std::string, std::string>(
"subRun", ostr.str()));
540 std::ostringstream ostr;
542 md.insert(std::pair<std::string, std::string>(
"firstEvent", ostr.str()));
545 std::ostringstream ostr;
547 md.insert(std::pair<std::string, std::string>(
"lastEvent", ostr.str()));
550 std::ostringstream ostr;
552 md.insert(std::pair<std::string, std::string>(
"eventCount", ostr.str()));
555 std::ostringstream ostr;
557 md.insert(std::pair<std::string, std::string>(
"startTime", ostr.str()));
560 std::ostringstream ostr;
562 md.insert(std::pair<std::string, std::string>(
"endTime", ostr.str()));
564 for(
auto parent : fParents) {
565 size_t n = parent.find_last_of(
'/');
566 size_t f = (n == std::string::npos ? 0 : n+1);
567 md.insert(std::pair<std::string, std::string>(
"parent", parent.substr(f)));
569 for(
auto const& nvp : fNVPairs)
591 if(new_fn.size() != 0) {
597 bool do_rename =
false;
598 std::ifstream
file(new_fn);
605 remove(new_fn.c_str());
614 <<
"Rename failed because a file already exists with name " << new_fn << std::endl;
629 <<
"Renaming " << fn <<
" to " << new_fn << std::endl;
630 rename(fn.c_str(), new_fn.c_str());
652 if(filename.find_first_of(
"${}") == std::string::npos) {
653 size_t n = filename.find_last_of(
'.');
654 if(n == std::string::npos)
656 std::string head = filename.substr(0, n);
657 std::string tail = filename.substr(n);
658 filename = head + std::string(
"${bnum 0}") + tail;
663 time_t curtime = time(0);
673 while((f = filename.find(
"${")) != std::string::npos) {
677 size_t n = filename.substr(f).find(
"}");
678 if(n == std::string::npos)
680 <<
"Output file name template: " << filename
681 <<
" has mismatched braces.\n";
686 std::string head = filename.substr(0, f);
687 std::string arg = filename.substr(f+2, n-2);
688 std::string tail = filename.substr(f+n+1);
695 if(head.find_first_of(
"${}") != std::string::npos ||
696 arg.find_first_of(
"${}") != std::string::npos)
698 <<
"Problem parsing output file name template: " << filename <<
".\n";
706 std::istringstream istr(arg);
713 std::string expanded;
714 if(keyword ==
"base") {
719 size_t f = (n == std::string::npos ? 0 : n+1);
721 if(subarg.size() != 0 && expanded.rfind(subarg) == expanded.size() - subarg.size())
722 expanded = expanded.substr(0, expanded.size() - subarg.size());
724 else if(keyword ==
"dir") {
730 if(n != std::string::npos)
735 else if(keyword ==
"path") {
740 if(subarg.size() != 0 && expanded.rfind(subarg) == expanded.size() - subarg.size())
741 expanded = expanded.substr(0, expanded.size() - subarg.size());
743 else if(keyword ==
"num") {
750 unsigned int offset = 1;
751 if(subarg.size() != 0) {
752 std::istringstream istr(subarg);
755 std::ostringstream ostr;
757 expanded = ostr.str();
759 else if(keyword ==
"bnum") {
764 unsigned int offset = 1;
765 if(subarg.size() != 0) {
766 std::istringstream istr(subarg);
770 std::ostringstream ostr;
772 expanded = ostr.str();
775 else if(keyword ==
"date") {
781 pts = localtime_r(&curtime, &ts);
783 std::ostringstream ostr;
784 ostr << std::setw(4) << std::setfill(
'0') << pts->tm_year + 1900
785 << std::setw(2) << pts->tm_mon + 1
786 << std::setw(2) << pts->tm_mday;
787 expanded = ostr.str();
793 expanded =
"00000000";
796 else if(keyword ==
"time") {
802 pts = localtime_r(&curtime, &ts);
804 std::ostringstream ostr;
805 ostr << std::setw(2) << std::setfill(
'0') << pts->tm_hour
806 << std::setw(2) << pts->tm_min
807 << std::setw(2) << pts->tm_sec;
808 expanded = ostr.str();
822 const char* p = getenv(keyword.c_str());
823 if(p != 0 && *p != 0)
830 <<
"Unknown keyword " << keyword
831 <<
" in output file name template " << filename <<
".\n";
839 if(expanded.find_first_of(
"${}") != std::string::npos)
841 <<
"Problem parsing output file name template: " << filename <<
".\n";
845 filename = head + expanded + tail;
851 if(filename.find_first_of(
"${}") != std::string::npos)
853 <<
"Problem parsing output file name template: "<< filename <<
".\n";
SubRunNumber_t subRun() const
Namespace for general, non-LArSoft-specific utilities.
GlobalSignal< detail::SignalResponseType::FIFO, void()> sPostBeginJob
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
#define DEFINE_ART_SERVICE(svc)
GlobalSignal< detail::SignalResponseType::LIFO, void()> sPostEndJob
std::string const & fileName() const
T get(std::string const &key) const
IDNumber_t< Level::SubRun > SubRunNumber_t
EventNumber_t event() const
std::string value(boost::any const &)
GlobalSignal< detail::SignalResponseType::FIFO, void(Event const &)> sPreProcessEvent
GlobalSignal< detail::SignalResponseType::LIFO, void(std::string const &)> sPostOpenFile
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
IDNumber_t< Level::Event > EventNumber_t
GlobalSignal< detail::SignalResponseType::LIFO, void(OutputFileInfo const &)> sPostCloseOutputFile
GlobalSignal< detail::SignalResponseType::LIFO, void(Event const &)> sPostProcessEvent
GlobalSignal< detail::SignalResponseType::LIFO, void()> sPostCloseFile
cet::coded_exception< error, detail::translate > exception
Event finding and building.
IDNumber_t< Level::Run > RunNumber_t