Belle II Software  release-08-01-10
PyBasf2.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <boost/python.hpp>
10 #include <framework/utilities/RegisterPythonModule.h>
11 
12 #include <framework/pybasf2/Framework.h>
13 #include <framework/pybasf2/LogPythonInterface.h>
14 #include <framework/pybasf2/ProcessStatisticsPython.h>
15 #include <framework/core/Module.h>
16 #include <framework/core/Path.h>
17 #include <framework/core/PyObjROOTUtils.h>
18 #include <framework/core/RandomNumbers.h>
19 #include <framework/core/ModuleParamInfoPython.h>
20 #include <framework/core/FileCatalog.h>
21 #include <framework/dataobjects/FileMetaData.h>
22 #include <framework/database/Database.h>
23 #include <framework/io/RootFileInfo.h>
24 
25 #include <TFile.h>
26 #include <TTree.h>
27 
28 using namespace Belle2;
29 using namespace boost::python;
30 
31 
32 FileMetaData updateFileMetaData(const std::string& fileName, const std::string& lfn)
33 {
34  // open the root file
35  TFile* file = TFile::Open(fileName.c_str(), "UPDATE");
36  if (!file || !file->IsOpen()) {
37  B2ERROR("Failed to open the file " << fileName);
38  return FileMetaData();
39  }
40 
41  // read the FileMetaData object or create a new one if it doesn't exist
42  FileMetaData* fileMetaData = nullptr;
43  auto* tree = dynamic_cast<TTree*>(file->Get("persistent"));
44  TTree* newTree = nullptr;
45  if (!tree) {
46  fileMetaData = dynamic_cast<FileMetaData*>(file->Get("FileMetaData"));
47  if (!fileMetaData) {
48  B2WARNING("Failed to get persistent tree in the file " << fileName);
49  tree = new TTree("persistent", "persistent");
50  fileMetaData = new FileMetaData;
51  tree->Branch("FileMetaData", &fileMetaData);
52  newTree = tree;
53  }
54  } else {
55  tree->SetBranchAddress("FileMetaData", &fileMetaData);
56  newTree = tree->CloneTree(0);
57  tree->GetEntry(0);
58  }
59  if (!fileMetaData) {
60  B2ERROR("Failed to load FileMetaData from file " << fileName);
61  return FileMetaData();
62  }
63 
64  // update the IDs and write the updated FileMetaData to the file
65  const std::string oldLFN = fileMetaData->getLfn();
66  fileMetaData->setLfn(lfn);
67  if (newTree) {
68  newTree->Fill();
69  newTree->Write();
70  } else {
71  fileMetaData->Write("FileMetaData");
72  }
73 
74  // update the local file catalog but only *if* the file was already registered
75  std::string oldPFN = oldLFN;
76  FileMetaData localMetaData;
77  if (FileCatalog::Instance().getMetaData(oldPFN, localMetaData)) {
78  localMetaData = *fileMetaData;
79  FileCatalog::Instance().registerFile(fileName, localMetaData, oldLFN);
80  }
81  return *fileMetaData;
82 }
83 
84 object getFileMetadata(const std::string& filename)
85 {
86  RootIOUtilities::RootFileInfo fileInfo(filename);
87  return createROOTObjectPyCopy(fileInfo.getFileMetaData());
88 }
89 
90 //-----------------------------------
91 // Define the pybasf2 python module
92 //-----------------------------------
93 BOOST_PYTHON_MODULE(pybasf2)
94 {
105 
106  //don't show c++ signature in python doc to keep it simple
107  docstring_options options(true, true, false);
108  def("update_file_metadata", &updateFileMetaData);
109  def("get_file_metadata", &getFileMetadata, R"DOC(
110 Return the FileMetaData object for the given output file.
111 )DOC");
112 }
113 
114 //register the module during library load
115 REGISTER_PYTHON_MODULE(pybasf2)
static FileCatalog & Instance()
Static method to get a reference to the FileCatalog instance.
Definition: FileCatalog.cc:23
virtual bool registerFile(const std::string &fileName, FileMetaData &metaData, const std::string &oldLFN="")
Register a file in the (local) file catalog.
Definition: FileCatalog.cc:90
Metadata information about a file.
Definition: FileMetaData.h:29
static void exposePythonAPI()
Exposes methods of the FileMetaData class to Python.
Definition: FileMetaData.cc:48
const std::string & getLfn() const
Logical file name getter.
Definition: FileMetaData.h:37
void setLfn(const std::string &lfn)
Setter for LFN.
Definition: FileMetaData.h:139
static void exposePythonAPI()
Exposes methods of the Framework class to Python.
Definition: Framework.cc:291
static void exposePythonAPI()
expose python API
static void exposePythonAPI()
Exposes methods of the ModuleCondition class to Python.
static void exposePythonAPI()
Exposes methods of the ModuleParam class to Python.
static void exposePythonAPI()
Exposes methods of the Module class to Python.
Definition: Module.cc:325
static void exposePythonAPI()
Exposes methods of the Path class to Python.
Definition: Path.cc:238
static void exposePythonAPI()
Define python wrappers to make functionality avaiable in python.
static void exposePythonAPI()
Exposes methods of the RandomNumbers class to Python.
Helper class to factorize some necessary tasks when working with Belle2 output files.
Definition: RootFileInfo.h:27
static void exposePythonAPI()
Exposes setGlobalTag function of the Database class to Python.
Definition: Database.cc:272
boost::python::object createROOTObjectPyCopy(const T &instance)
Create a python wrapped copy from a class instance which has a ROOT dictionary.
#define REGISTER_PYTHON_MODULE(moduleName)
Register a python module to make available when loading the library.
Abstract base class for different kinds of events.