2// ********************************************************************
 
    3// * License and Disclaimer                                           *
 
    5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
 
    6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
 
    7// * conditions of the Geant4 Software License,  included in the file *
 
    8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
 
    9// * include a list of copyright holders.                             *
 
   11// * Neither the authors of this software system, nor their employing *
 
   12// * institutes,nor the agencies providing financial support for this *
 
   13// * work  make  any representation or  warranty, express or implied, *
 
   14// * regarding  this  software system or assume any liability for its *
 
   15// * use.  Please see the license in the file  LICENSE  and URL above *
 
   16// * for the full disclaimer and the limitation of liability.         *
 
   18// * This  code  implementation is the result of  the  scientific and *
 
   19// * technical work of the GEANT4 collaboration.                      *
 
   20// * By using,  copying,  modifying or  distributing the software (or *
 
   21// * any work based  on the software)  you  agree  to acknowledge its *
 
   22// * use  in  resulting  scientific  publications,  and indicate your *
 
   23// * acceptance of all terms of the Geant4 Software license.          *
 
   24// ********************************************************************
 
   27// Author: Ivana Hrivnacova, 18/06/2013  (ivana@ipno.in2p3.fr)
 
   29#include "G4AnalysisUtilities.hh"
 
   31//_____________________________________________________________________________
 
   34G4TFileManager<FT>::G4TFileManager(const G4AnalysisManagerState& state)
 
   38//_____________________________________________________________________________
 
   41G4TFileManager<FT>::~G4TFileManager()
 
   43  for ( const auto& mapElement : fFileMap ) {
 
   44    delete mapElement.second;
 
   52//_____________________________________________________________________________
 
   56G4TFileManager<FT>::FileNotFoundWarning(const G4String& fileName,
 
   57                      std::string_view functionName) const
 
   59  G4Analysis::Warn("Failed to get file " + fileName, fkClass, functionName);
 
   62//_____________________________________________________________________________
 
   65G4TFileInformation<FT>*
 
   66G4TFileManager<FT>::GetFileInfoInFunction(const G4String& fileName,
 
   67                      std::string_view functionName, G4bool warn ) const
 
   69  // Find the file information in the map
 
   70  auto it = fFileMap.find(fileName);
 
   71  if ( it == fFileMap.end() ) {
 
   73      FileNotFoundWarning(fileName, functionName);
 
   81//_____________________________________________________________________________
 
   85G4TFileManager<FT>::GetFileInFunction(const G4String& fileName,
 
   86                      std::string_view functionName, G4bool warn) const
 
   88  // Find the file information in the map
 
   89  auto fileInfo = GetFileInfoInFunction(fileName, functionName, warn);
 
   90  if (! fileInfo) return nullptr;
 
   92  // Check if the file is open
 
   93  if ( ! fileInfo->fFile ) {
 
   95      FileNotFoundWarning(fileName, functionName);
 
  100  return fileInfo->fFile;
 
  103//_____________________________________________________________________________
 
  104template <typename FT>
 
  106G4bool G4TFileManager<FT>::WriteTFile(std::shared_ptr<FT> file,
 
  107                                      [[maybe_unused]] const G4String& fileName)
 
  109  fAMState.Message(G4Analysis::kVL4, "write", "file", fileName);
 
  111  // Write the found file
 
  112  auto result = WriteFileImpl(file);
 
  114  fAMState.Message(G4Analysis::kVL1, "write", "file", fileName, result);
 
  119//_____________________________________________________________________________
 
  120template <typename FT>
 
  122G4bool G4TFileManager<FT>::CloseTFile(std::shared_ptr<FT> file,
 
  123                                      [[maybe_unused]] const G4String& fileName)
 
  125  fAMState.Message(G4Analysis::kVL4, "close", "file", fileName);
 
  127  // Close the found file
 
  128  auto result = CloseFileImpl(file);
 
  130  fAMState.Message(G4Analysis::kVL1, "close", "file", fileName, result);
 
  135//_____________________________________________________________________________
 
  136template <typename FT>
 
  138G4bool G4TFileManager<FT>::DeleteEmptyFile(const G4String& fileName)
 
  140  fAMState.Message(G4Analysis::kVL4, "delete", "empty file", fileName);
 
  142  auto result = ! std::remove(fileName);
 
  144  fAMState.Message(G4Analysis::kVL1, "delete", "empty file", fileName, result);
 
  149//_____________________________________________________________________________
 
  150template <typename FT>
 
  152void G4TFileManager<FT>::ClearData()
 
  154  for ( const auto& mapElement : fFileMap ) {
 
  155    delete mapElement.second;
 
  159  fAMState.Message(G4Analysis::kVL2, "clear", "files");
 
  166//_____________________________________________________________________________
 
  167template <typename FT>
 
  169std::shared_ptr<FT> G4TFileManager<FT>::CreateTFile(const G4String& fileName)
 
  171  // Check if file already exists
 
  172  if ( GetFileInFunction(fileName, "CreateTFile", false) ) {
 
  173    G4Analysis::Warn("File " + fileName + " already exists.",
 
  174      fkClass, "CreateTFile");
 
  178  auto fileInformation = GetFileInfoInFunction(fileName, "CreateTFile", false);
 
  179  if ( ! fileInformation ) {
 
  180    fAMState.Message(G4Analysis::kVL4, "create", "fileInformation", fileName);
 
  182    // Create file information and save it in the map
 
  183    fileInformation = new G4TFileInformation<FT>(fileName);
 
  184    fFileMap[fileName] = fileInformation;
 
  187  // Create file and save it in fileInformation
 
  188  fAMState.Message(G4Analysis::kVL4, "create", "file", fileName);
 
  190  // Let concrete class create a file
 
  191  auto file = CreateFileImpl(fileName);
 
  193    G4Analysis::Warn("Failed to create file " + fileName, fkClass, "CreateTFile");
 
  196  // Save file in fileInformation
 
  197  fileInformation->fFile = file;
 
  198  fileInformation->fIsOpen = true;
 
  199  fileInformation->fIsEmpty = true;
 
  200  fileInformation->fIsDeleted = false;
 
  202  fAMState.Message(G4Analysis::kVL1, "create", "file", fileName);
 
  204  // Return created file
 
  208//_____________________________________________________________________________
 
  209template <typename FT>
 
  211G4bool G4TFileManager<FT>::WriteTFile(const G4String& fileName)
 
  213  // Find the file in the map
 
  214  auto file = GetFileInFunction(fileName, "WriteTFile");
 
  215  // Warning is issued in GetFileInfoFunction
 
  216  if (! file) return false;
 
  218  return WriteTFile(file, fileName);
 
  221//_____________________________________________________________________________
 
  222template <typename FT>
 
  224G4bool G4TFileManager<FT>::CloseTFile(const G4String& fileName)
 
  226  // Find the file information in the map
 
  227  auto fileInfo = GetFileInfoInFunction(fileName, "CloseTFile");
 
  228  // Warning is issued in GetFileInfoFunction
 
  229  if ( ! fileInfo ) return false;
 
  231  // Do nothing if file is not open
 
  232  if ( ! fileInfo->fIsOpen ) return false;
 
  234  // Get file from the file information
 
  235  auto file = fileInfo->fFile;
 
  237    FileNotFoundWarning(fileName, "CloseTFile");
 
  241  auto result = CloseTFile(file, fileName);
 
  243  // Update the file information
 
  244  fileInfo->fFile.reset();
 
  245  fileInfo->fIsOpen = false;
 
  250//_____________________________________________________________________________
 
  251template <typename FT>
 
  253G4bool G4TFileManager<FT>::SetIsEmpty(const G4String& fileName, G4bool isEmpty)
 
  255  // Find the file information in the map
 
  256  auto fileInfo = GetFileInfoInFunction(fileName, "SetIsEmpty");
 
  258  // Warning is issued in GetFileFunction
 
  259  if ( ! fileInfo ) return false;
 
  261  fAMState.Message(G4Analysis::kVL4, "notify not empty", "file", fileName);
 
  263  // Set notification to file information
 
  264  if ( fileInfo->fIsEmpty ) {
 
  265    // do not revert information if file is not empty
 
  266    fileInfo->fIsEmpty = isEmpty;
 
  269      fAMState.Message(G4Analysis::kVL3, "notify not empty", "file", fileName);
 
  276//_____________________________________________________________________________
 
  277template <typename FT>
 
  279std::shared_ptr<FT> G4TFileManager<FT>::GetTFile(
 
  280  const G4String& fileName, G4bool warn) const
 
  282  // Find the file information in the map
 
  283  return GetFileInFunction(fileName, "GetTFile", warn);
 
  286//_____________________________________________________________________________
 
  287template <typename FT>
 
  289G4bool G4TFileManager<FT>::OpenFiles()
 
  292  for ( const auto& mapElement : fFileMap ) {
 
  293     auto fileInformation = mapElement.second;
 
  294     // Do nothing if file was open by user explicitly
 
  295     if ( fileInformation->fFile ) {
 
  296       // G4cout << "... skipping open file for " << fileInformation->fFileName << G4endl;
 
  300     result &= (CreateTFile(fileInformation->fFileName) != nullptr);
 
  305//_____________________________________________________________________________
 
  306template <typename FT>
 
  308G4bool G4TFileManager<FT>::WriteFiles()
 
  311  for ( const auto& mapElement : fFileMap ) {
 
  312     auto fileInformation = mapElement.second;
 
  313     if ( ! fileInformation->fIsOpen ) {
 
  314       // G4cout << "skipping write for file " << fileInformation->fFileName << G4endl;
 
  317     result &= WriteTFile(fileInformation->fFile, fileInformation->fFileName);
 
  322//_____________________________________________________________________________
 
  323template <typename FT>
 
  325G4bool G4TFileManager<FT>::CloseFiles()
 
  328  for ( const auto& mapElement : fFileMap ) {
 
  329     auto fileInformation = mapElement.second;
 
  330     if ( ! fileInformation->fIsOpen ) {
 
  331       // G4cout << "skipping close for file " << fileInformation->fFileName << G4endl;
 
  334     result &= CloseTFile(fileInformation->fFile, fileInformation->fFileName);
 
  336     // Update file information
 
  337     fileInformation->fFile.reset();
 
  338     fileInformation->fIsOpen = false;
 
  341  // As the files were set to nullptr, clear should not be needed
 
  347//_____________________________________________________________________________
 
  348template <typename FT>
 
  350G4bool G4TFileManager<FT>::DeleteEmptyFiles()
 
  353  for ( const auto& mapElement : fFileMap ) {
 
  354    auto fileInformation = mapElement.second;
 
  355    if ( (! fileInformation->fIsEmpty) || fileInformation->fIsDeleted ) {
 
  356      // G4cout << "skipping delete for file " << fileInformation->fFileName << G4endl;
 
  360    result &= DeleteEmptyFile(fileInformation->fFileName);
 
  362    // Update file information
 
  363    fileInformation->fIsDeleted = true;