Belle II Software  release-05-01-25
b2file-metadata-add.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Thomas Kuhr *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <framework/logging/Logger.h>
12 #include <framework/core/FileCatalog.h>
13 #include <framework/dataobjects/FileMetaData.h>
14 
15 #include <TFile.h>
16 #include <TTree.h>
17 #include <TError.h>
18 
19 #include <boost/program_options.hpp>
20 
21 #include <string>
22 #include <iostream>
23 
24 using namespace std;
25 using namespace Belle2;
26 namespace prog = boost::program_options;
27 
28 int main(int argc, char* argv[])
29 {
30  std::string fileName;
31  std::string lfn;
32  std::vector<std::string> dataDescriptions;
33  // define command line options
34  prog::options_description options("Options");
35  options.add_options()
36  ("help,h", "print all available options")
37  ("file", prog::value<string>(&fileName), "file name")
38  ("lfn,l", prog::value<string>(&lfn), "logical file name")
39  ("description,d", prog::value<std::vector<std::string>>(&dataDescriptions),
40  "data description to set of the form key=value. If the argument does not contain an equal sign it's interpeted as a key to delete from the dataDescriptions")
41  ;
42 
43  prog::positional_options_description posOptDesc;
44  posOptDesc.add("file", -1);
45 
46  prog::variables_map varMap;
47  prog::store(prog::command_line_parser(argc, argv).
48  options(options).positional(posOptDesc).run(), varMap);
49  prog::notify(varMap);
50 
51  // check for help option
52  if (varMap.count("help")) {
53  cout << "Usage: " << argv[0] << " [OPTIONS] [FILE]\n";
54  cout << "Add/edit LFN in given file or modify the data description stored in the file, also update file catalog.\n\n";
55  cout << options << endl;
56  return 0;
57  }
58 
59  // check parameters
60  if (!varMap.count("file")) {
61  B2ERROR("The filename is missing.");
62  return 1;
63  }
64  if (!varMap.count("lfn") && !varMap.count("description")) {
65  B2ERROR("Neither lfn nor data descriptions to be modified, nothing to do");
66  return 1;
67  }
68 
69  // open the root file
70  gErrorIgnoreLevel = kError;
71  TFile* file = TFile::Open(fileName.c_str(), "UPDATE");
72  if (!file || !file->IsOpen()) {
73  B2ERROR("Failed to open the file " << fileName);
74  return 1;
75  }
76 
77  // read the FileMetaData object or create a new one if it doesn't exist
78  FileMetaData* fileMetaData = nullptr;
79  auto* tree = dynamic_cast<TTree*>(file->Get("persistent"));
80  TTree* newTree = nullptr;
81  if (!tree) {
82  fileMetaData = dynamic_cast<FileMetaData*>(file->Get("FileMetaData"));
83  if (!fileMetaData) {
84  B2WARNING("Failed to get persistent tree in the file " << fileName);
85  tree = new TTree("persistent", "persistent");
86  fileMetaData = new FileMetaData;
87  tree->Branch("FileMetaData", &fileMetaData);
88  newTree = tree;
89  }
90  } else {
91  tree->SetBranchAddress("FileMetaData", &fileMetaData);
92  newTree = tree->CloneTree(0);
93  tree->GetEntry(0);
94  }
95 
96  // remember old lfn in case this file was registered in file catalog
97  const std::string oldLFN = fileMetaData->getLfn();
98 
99  // update the IDs and write the updated FileMetaData to the file
100  if (varMap.count("lfn")) fileMetaData->setLfn(lfn);
101  if (!dataDescriptions.empty()) {
102  for (const auto& keyvalue : dataDescriptions) {
103  size_t pos = keyvalue.find('=');
104  if (pos == std::string::npos) {
105  // no '=' in -d argument, assume deletion
106  fileMetaData->removeDataDescription(keyvalue);
107  } else {
108  const std::string key = keyvalue.substr(0, pos);
109  const std::string value = keyvalue.substr(pos + 1);
110  fileMetaData->setDataDescription(key, value);
111  }
112  }
113  }
114  if (newTree) {
115  newTree->Fill();
116  newTree->Write(newTree->GetName(), TObject::kWriteDelete);
117  } else {
118  fileMetaData->Write("FileMetaData");
119  }
120 
121  // properly close file
122  file->Close();
123 
124  // update the local file catalog but only *if* the file was already registered
125  std::string oldPFN = oldLFN;
126  FileMetaData localMetaData;
127  if (FileCatalog::Instance().getMetaData(oldPFN, localMetaData)) {
128  localMetaData = *fileMetaData;
129  FileCatalog::Instance().registerFile(fileName, localMetaData, oldLFN);
130  }
131  return 0;
132 }
133 
Belle2::FileMetaData::removeDataDescription
void removeDataDescription(const std::string &key)
remove an existing data description
Definition: FileMetaData.h:217
Belle2::FileMetaData
Metadata information about a file.
Definition: FileMetaData.h:39
Belle2::FileMetaData::setLfn
void setLfn(const std::string &lfn)
Setter for LFN.
Definition: FileMetaData.h:145
main
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:77
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::FileMetaData::setDataDescription
void setDataDescription(const std::string &key, const std::string &value)
describe the data, if the key exists contents will be overwritten.
Definition: FileMetaData.h:214
Belle2::FileMetaData::getLfn
const std::string & getLfn() const
Logical file name getter.
Definition: FileMetaData.h:47