Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // 27 // Author: Ivana Hrivnacova, 04/10/2016 (ivan 27 // Author: Ivana Hrivnacova, 04/10/2016 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4NtupleBookingManager.hh" 29 #include "G4NtupleBookingManager.hh" 30 #include "G4RootPNtupleManager.hh" 30 #include "G4RootPNtupleManager.hh" 31 #include "G4AnalysisUtilities.hh" 31 #include "G4AnalysisUtilities.hh" 32 32 33 #include "tools/wroot/file" 33 #include "tools/wroot/file" 34 #include "tools/wroot/ntuple" 34 #include "tools/wroot/ntuple" 35 35 36 using namespace G4Analysis; 36 using namespace G4Analysis; 37 using std::to_string; 37 using std::to_string; 38 38 39 // mutex in a file scope 39 // mutex in a file scope 40 namespace { 40 namespace { 41 41 42 //Mutex to lock master manager when adding ntu 42 //Mutex to lock master manager when adding ntuple row and ending fill 43 G4Mutex pntupleMutex = G4MUTEX_INITIALIZER; 43 G4Mutex pntupleMutex = G4MUTEX_INITIALIZER; 44 //Mutex to lock master manager when createing 44 //Mutex to lock master manager when createing main ntuples at new cycle 45 G4Mutex createMainMutex = G4MUTEX_INITIALIZER; 45 G4Mutex createMainMutex = G4MUTEX_INITIALIZER; 46 46 47 //____________________________________________ 47 //_____________________________________________________________________________ 48 void NotExistWarning(const G4String& what, G4i 48 void NotExistWarning(const G4String& what, G4int id, 49 std::string_view classNam 49 std::string_view className, 50 std::string_view function 50 std::string_view functionName) 51 { 51 { 52 Warn(what + " id= " + to_string(id) + " does 52 Warn(what + " id= " + to_string(id) + " does not exist.", 53 className, functionName); 53 className, functionName); 54 54 55 } 55 } 56 56 57 } 57 } 58 58 59 //____________________________________________ 59 //_____________________________________________________________________________ 60 G4RootPNtupleManager::G4RootPNtupleManager(con 60 G4RootPNtupleManager::G4RootPNtupleManager(const G4AnalysisManagerState& state, 61 std::shared_ptr<G4Ntup 61 std::shared_ptr<G4NtupleBookingManager> bookingManger, 62 std::shared_ptr<G4Root 62 std::shared_ptr<G4RootMainNtupleManager> main, 63 G4bool rowWise, G4bool 63 G4bool rowWise, G4bool rowMode) 64 : G4BaseNtupleManager(state), 64 : G4BaseNtupleManager(state), 65 fBookingManager(std::move(bookingManger)), 65 fBookingManager(std::move(bookingManger)), 66 fMainNtupleManager(std::move(main)), 66 fMainNtupleManager(std::move(main)), 67 fRowWise(rowWise), 67 fRowWise(rowWise), 68 fRowMode(rowMode) 68 fRowMode(rowMode) 69 {} 69 {} 70 70 71 //____________________________________________ 71 //_____________________________________________________________________________ 72 G4RootPNtupleManager::~G4RootPNtupleManager() 72 G4RootPNtupleManager::~G4RootPNtupleManager() 73 { 73 { 74 for ( auto ntupleDescription : fNtupleDescri 74 for ( auto ntupleDescription : fNtupleDescriptionVector ) { 75 delete ntupleDescription; 75 delete ntupleDescription; 76 } 76 } 77 } 77 } 78 78 79 // 79 // 80 // private functions 80 // private functions 81 // 81 // 82 82 83 //____________________________________________ 83 //_____________________________________________________________________________ 84 G4RootPNtupleDescription* 84 G4RootPNtupleDescription* 85 G4RootPNtupleManager::GetNtupleDescriptionInFu 85 G4RootPNtupleManager::GetNtupleDescriptionInFunction( 86 G4int id, std::string_view functionName, G4b 86 G4int id, std::string_view functionName, G4bool warn) const 87 { 87 { 88 auto index = id - fFirstId; 88 auto index = id - fFirstId; 89 if ( index < 0 || index >= G4int(fNtupleDesc 89 if ( index < 0 || index >= G4int(fNtupleDescriptionVector.size()) ) { 90 if ( warn) { 90 if ( warn) { 91 NotExistWarning("ntuple description", id 91 NotExistWarning("ntuple description", id, fkClass, functionName); 92 } 92 } 93 return nullptr; 93 return nullptr; 94 } 94 } 95 95 96 return fNtupleDescriptionVector[index]; 96 return fNtupleDescriptionVector[index]; 97 } 97 } 98 98 99 //____________________________________________ 99 //_____________________________________________________________________________ 100 tools::wroot::base_pntuple* 100 tools::wroot::base_pntuple* 101 G4RootPNtupleManager::GetNtupleInFunction( 101 G4RootPNtupleManager::GetNtupleInFunction( 102 G4int id, std::string_view functionName, G4b 102 G4int id, std::string_view functionName, G4bool warn) const 103 { 103 { 104 auto ntupleDescription = GetNtupleDescriptio 104 auto ntupleDescription = GetNtupleDescriptionInFunction(id, functionName); 105 if (ntupleDescription == nullptr) return nul 105 if (ntupleDescription == nullptr) return nullptr; 106 106 107 if (ntupleDescription->GetBasePNtuple() == n 107 if (ntupleDescription->GetBasePNtuple() == nullptr) { 108 if ( warn ) { 108 if ( warn ) { 109 NotExistWarning("ntuple", id, fkClass, f 109 NotExistWarning("ntuple", id, fkClass, functionName); 110 } 110 } 111 return nullptr; 111 return nullptr; 112 } 112 } 113 return ntupleDescription->GetBasePNtuple(); 113 return ntupleDescription->GetBasePNtuple(); 114 } 114 } 115 115 116 //____________________________________________ 116 //_____________________________________________________________________________ 117 tools::wroot::ntuple* 117 tools::wroot::ntuple* 118 G4RootPNtupleManager::GetMainNtupleInFunction( 118 G4RootPNtupleManager::GetMainNtupleInFunction( 119 G4int id, std::string_view functionName, G4b 119 G4int id, std::string_view functionName, G4bool warn) const 120 { 120 { 121 auto& mainNtupleVector = fMainNtupleManager- 121 auto& mainNtupleVector = fMainNtupleManager->GetNtupleVector(); 122 122 123 auto index = id - fFirstId; 123 auto index = id - fFirstId; 124 if ( index < 0 || index >= G4int(mainNtupleV 124 if ( index < 0 || index >= G4int(mainNtupleVector.size()) ) { 125 if ( warn) { 125 if ( warn) { 126 NotExistWarning("main ntuple", id, fkCla 126 NotExistWarning("main ntuple", id, fkClass, functionName); 127 } 127 } 128 return nullptr; 128 return nullptr; 129 } 129 } 130 130 131 return mainNtupleVector[index]; 131 return mainNtupleVector[index]; 132 } 132 } 133 133 134 // 134 // 135 // protected functions 135 // protected functions 136 // 136 // 137 137 138 //____________________________________________ 138 //_____________________________________________________________________________ 139 void G4RootPNtupleManager::CreateNtupleFromMai 139 void G4RootPNtupleManager::CreateNtupleFromMain( 140 G4RootPNtupleDesc 140 G4RootPNtupleDescription* ntupleDescription, 141 tools::wroot::ntu 141 tools::wroot::ntuple* mainNtuple) 142 { 142 { 143 // Do not create pntuple if ntuple was delet 143 // Do not create pntuple if ntuple was deleted 144 if (mainNtuple == nullptr) { 144 if (mainNtuple == nullptr) { 145 ntupleDescription->SetNtuple(nullptr); 145 ntupleDescription->SetNtuple(nullptr); 146 ntupleDescription->SetBasePNtuple(nullptr) 146 ntupleDescription->SetBasePNtuple(nullptr); 147 return; 147 return; 148 } 148 } 149 149 150 Message(kVL4, "create from main", "pntuple", 150 Message(kVL4, "create from main", "pntuple", mainNtuple->name()); 151 151 152 auto file = fMainNtupleManager->GetNtupleFil 152 auto file = fMainNtupleManager->GetNtupleFile(&ntupleDescription->GetDescription()); 153 if ( ! file ) { 153 if ( ! file ) { 154 Warn("Cannot create pntuple. Main ntuple f 154 Warn("Cannot create pntuple. Main ntuple file does not exist.", 155 fkClass, "CreateNtupleFromMain"); 155 fkClass, "CreateNtupleFromMain"); 156 return; 156 return; 157 } 157 } 158 158 159 ntupleDescription->GetDescription().SetFile( 159 ntupleDescription->GetDescription().SetFile(file); 160 160 161 // Get parameters from ntupleDescription 161 // Get parameters from ntupleDescription 162 mainNtuple->get_branches(ntupleDescription-> 162 mainNtuple->get_branches(ntupleDescription->GetMainBranches()); 163 163 164 auto rfile = std::get<0>(*file); 164 auto rfile = std::get<0>(*file); 165 G4bool verbose = true; 165 G4bool verbose = true; 166 if ( fRowWise ) { 166 if ( fRowWise ) { 167 auto mainBranch = mainNtuple->get_row_wise 167 auto mainBranch = mainNtuple->get_row_wise_branch(); 168 auto mtNtuple 168 auto mtNtuple 169 = new tools::wroot::mt_ntuple_row_wise( 169 = new tools::wroot::mt_ntuple_row_wise( 170 G4cout, rfile->byte_swap(), rfil 170 G4cout, rfile->byte_swap(), rfile->compression(), 171 mainNtuple->dir().seek_directory 171 mainNtuple->dir().seek_directory(), 172 *mainBranch, mainBranch->basket_ 172 *mainBranch, mainBranch->basket_size(), 173 ntupleDescription->GetDescriptio 173 ntupleDescription->GetDescription().GetNtupleBooking(), verbose); 174 174 175 ntupleDescription->SetNtuple( 175 ntupleDescription->SetNtuple( 176 static_cast<tools::wroot::imt_ntuple*>(m 176 static_cast<tools::wroot::imt_ntuple*>(mtNtuple)); 177 ntupleDescription->SetBasePNtuple( 177 ntupleDescription->SetBasePNtuple( 178 static_cast<tools::wroot::base_pntuple*> 178 static_cast<tools::wroot::base_pntuple*>(mtNtuple)); 179 } 179 } 180 else { 180 else { 181 std::vector<tools::uint32> basketSizes; 181 std::vector<tools::uint32> basketSizes; 182 tools_vforcit(tools::wroot::branch*, ntupl 182 tools_vforcit(tools::wroot::branch*, ntupleDescription->GetMainBranches(), it) { 183 basketSizes.push_back((*it)->basket_size 183 basketSizes.push_back((*it)->basket_size()); 184 } 184 } 185 auto basketEntries = fMainNtupleManager->G 185 auto basketEntries = fMainNtupleManager->GetBasketEntries(); 186 186 187 auto mtNtuple = 187 auto mtNtuple = 188 new tools::wroot::mt_ntuple_column_wise( 188 new tools::wroot::mt_ntuple_column_wise( 189 G4cout, rfile->byte_swap(), rfile- 189 G4cout, rfile->byte_swap(), rfile->compression(), 190 mainNtuple->dir().seek_directory() 190 mainNtuple->dir().seek_directory(), 191 ntupleDescription->GetMainBranches 191 ntupleDescription->GetMainBranches(), basketSizes, 192 ntupleDescription->GetDescription( 192 ntupleDescription->GetDescription().GetNtupleBooking(), 193 fRowMode, basketEntries, verbose); 193 fRowMode, basketEntries, verbose); 194 194 195 ntupleDescription->SetNtuple( 195 ntupleDescription->SetNtuple( 196 static_cast<tools::wroot::imt_ntuple*>(m 196 static_cast<tools::wroot::imt_ntuple*>(mtNtuple)); 197 ntupleDescription->SetBasePNtuple( 197 ntupleDescription->SetBasePNtuple( 198 static_cast<tools::wroot::base_pntuple*> 198 static_cast<tools::wroot::base_pntuple*>(mtNtuple)); 199 } 199 } 200 200 201 ntupleDescription->GetDescription().SetIsNtu 201 ntupleDescription->GetDescription().SetIsNtupleOwner(true); 202 // // pntuple object is not deleted a 202 // // pntuple object is not deleted automatically 203 fNtupleVector.push_back(ntupleDescription->G 203 fNtupleVector.push_back(ntupleDescription->GetNtuple()); 204 204 205 Message(kVL3, "create from main", "pntuple", 205 Message(kVL3, "create from main", "pntuple", mainNtuple->name()); 206 } 206 } 207 207 208 //____________________________________________ 208 //_____________________________________________________________________________ 209 void G4RootPNtupleManager::CreateNtupleDescrip 209 void G4RootPNtupleManager::CreateNtupleDescriptionsFromBooking() 210 { 210 { 211 // Create ntuple descriptions from booking. 211 // Create ntuple descriptions from booking. 212 // This function is called from the first Fill 212 // This function is called from the first Fill call. 213 213 214 // Create pntuple descriptions from ntuple b 214 // Create pntuple descriptions from ntuple booking. 215 auto g4NtupleBookings = fBookingManager->Get 215 auto g4NtupleBookings = fBookingManager->GetNtupleBookingVector(); 216 216 217 for ( auto g4NtupleBooking : g4NtupleBooking 217 for ( auto g4NtupleBooking : g4NtupleBookings ) { 218 auto ntupleDescription = new G4RootPNtuple 218 auto ntupleDescription = new G4RootPNtupleDescription(g4NtupleBooking); 219 // Save g4booking, activation in pntuple b 219 // Save g4booking, activation in pntuple booking 220 fNtupleDescriptionVector.push_back(ntupleD 220 fNtupleDescriptionVector.push_back(ntupleDescription); 221 } 221 } 222 } 222 } 223 223 224 //____________________________________________ 224 //_____________________________________________________________________________ 225 void G4RootPNtupleManager::CreateNtuplesFromMa 225 void G4RootPNtupleManager::CreateNtuplesFromMain() 226 { 226 { 227 // Create slave ntuples from main ntuple. 227 // Create slave ntuples from main ntuple. 228 // This function is called from the first Fill 228 // This function is called from the first Fill call. 229 229 230 auto& mainNtupleVector = fMainNtupleManager- 230 auto& mainNtupleVector = fMainNtupleManager->GetNtupleVector(); 231 231 232 G4int lcounter = 0; 232 G4int lcounter = 0; 233 for ( auto mainNtuple : mainNtupleVector ) { 233 for ( auto mainNtuple : mainNtupleVector ) { 234 auto& ntupleDescription = fNtupleDescripti 234 auto& ntupleDescription = fNtupleDescriptionVector[lcounter++]; 235 CreateNtupleFromMain(ntupleDescription, ma 235 CreateNtupleFromMain(ntupleDescription, mainNtuple); 236 } 236 } 237 } 237 } 238 238 239 //____________________________________________ 239 //_____________________________________________________________________________ 240 void G4RootPNtupleManager::CreateNtuplesIfNeed 240 void G4RootPNtupleManager::CreateNtuplesIfNeeded() 241 { 241 { 242 // The ntuples on workers are created at first 242 // The ntuples on workers are created at first FillColumn or AddRow 243 // (if only columns of vector type) call. 243 // (if only columns of vector type) call. 244 // When writing multiple times in teh same fil 244 // When writing multiple times in teh same file, the main ntuples have 245 // to be recreated as well. 245 // to be recreated as well. 246 246 247 // G4cout << "G4RootPNtupleManager::CreateNt 247 // G4cout << "G4RootPNtupleManager::CreateNtuplesIfNeeded: " 248 // << " fCreateNtuple: " << fCreateNtuples 248 // << " fCreateNtuple: " << fCreateNtuples << " " 249 // << " fNewCycle: " << fNewCycle 249 // << " fNewCycle: " << fNewCycle 250 // << " fMainNtupleManager->GetNewCycle(): 250 // << " fMainNtupleManager->GetNewCycle(): " << fMainNtupleManager->GetNewCycle() 251 // << " fNtupleDescriptionVector.size(): " 251 // << " fNtupleDescriptionVector.size(): " << fNtupleDescriptionVector.size() 252 // << " fNtupleVector.size(): " << fNtuple 252 // << " fNtupleVector.size(): " << fNtupleVector.size() 253 // << G4endl; 253 // << G4endl; 254 254 255 if (fCreateNtuples) { 255 if (fCreateNtuples) { 256 // create ntuple descriptions 256 // create ntuple descriptions 257 CreateNtupleDescriptionsFromBooking(); 257 CreateNtupleDescriptionsFromBooking(); 258 258 259 // create main ntuples if needed 259 // create main ntuples if needed 260 G4AutoLock lock(&createMainMutex); 260 G4AutoLock lock(&createMainMutex); 261 if (fMainNtupleManager->GetNewCycle()) { 261 if (fMainNtupleManager->GetNewCycle()) { 262 fMainNtupleManager->CreateNtuplesFromBoo 262 fMainNtupleManager->CreateNtuplesFromBooking(); 263 } 263 } 264 lock.unlock(); 264 lock.unlock(); 265 265 266 // create slave ntuples 266 // create slave ntuples 267 CreateNtuplesFromMain(); 267 CreateNtuplesFromMain(); 268 fCreateNtuples = false; 268 fCreateNtuples = false; 269 } 269 } 270 270 271 if (fNewCycle) { 271 if (fNewCycle) { 272 // create main ntuples if needed 272 // create main ntuples if needed 273 G4AutoLock lock(&createMainMutex); 273 G4AutoLock lock(&createMainMutex); 274 if (fMainNtupleManager->GetNewCycle()) { 274 if (fMainNtupleManager->GetNewCycle()) { 275 fMainNtupleManager->CreateNtuplesFromBoo 275 fMainNtupleManager->CreateNtuplesFromBooking(); 276 } 276 } 277 lock.unlock(); 277 lock.unlock(); 278 278 279 // create slave ntuples 279 // create slave ntuples 280 CreateNtuplesFromMain(); 280 CreateNtuplesFromMain(); 281 fNewCycle = false; 281 fNewCycle = false; 282 } 282 } 283 } 283 } 284 284 285 //____________________________________________ 285 //_____________________________________________________________________________ 286 G4int G4RootPNtupleManager::CreateNtuple(G4Ntu 286 G4int G4RootPNtupleManager::CreateNtuple(G4NtupleBooking* /*booking*/) 287 { 287 { 288 // Create pntuple from g4 ntuple booking. 288 // Create pntuple from g4 ntuple booking. 289 // Nothing to be done here. 289 // Nothing to be done here. 290 290 291 return G4Analysis::kInvalidId; 291 return G4Analysis::kInvalidId; 292 } 292 } 293 293 294 //____________________________________________ 294 //_____________________________________________________________________________ 295 G4bool G4RootPNtupleManager::FillNtupleIColumn 295 G4bool G4RootPNtupleManager::FillNtupleIColumn( 296 G4int ntupleId, G4int columnId, G4int value) 296 G4int ntupleId, G4int columnId, G4int value) 297 { 297 { 298 return FillNtupleTColumn<int>(ntupleId, colu 298 return FillNtupleTColumn<int>(ntupleId, columnId, value); 299 } 299 } 300 300 301 //____________________________________________ 301 //_____________________________________________________________________________ 302 G4bool G4RootPNtupleManager::FillNtupleFColumn 302 G4bool G4RootPNtupleManager::FillNtupleFColumn( 303 G4int ntupleId, G4int columnId, G4float valu 303 G4int ntupleId, G4int columnId, G4float value) 304 { 304 { 305 return FillNtupleTColumn<float>(ntupleId, co 305 return FillNtupleTColumn<float>(ntupleId, columnId, value); 306 } 306 } 307 307 308 //____________________________________________ 308 //_____________________________________________________________________________ 309 G4bool G4RootPNtupleManager::FillNtupleDColumn 309 G4bool G4RootPNtupleManager::FillNtupleDColumn( 310 G4int ntupleId, G4int columnId, G4double val 310 G4int ntupleId, G4int columnId, G4double value) 311 { 311 { 312 return FillNtupleTColumn<double>(ntupleId, c 312 return FillNtupleTColumn<double>(ntupleId, columnId, value); 313 } 313 } 314 314 315 //____________________________________________ 315 //_____________________________________________________________________________ 316 G4bool G4RootPNtupleManager::FillNtupleSColumn 316 G4bool G4RootPNtupleManager::FillNtupleSColumn( 317 G4int ntupleId, G4int columnId, const G4Stri 317 G4int ntupleId, G4int columnId, const G4String& value) 318 { 318 { 319 return FillNtupleTColumn<std::string>(ntuple 319 return FillNtupleTColumn<std::string>(ntupleId, columnId, value); 320 } 320 } 321 321 322 //____________________________________________ 322 //_____________________________________________________________________________ 323 G4bool G4RootPNtupleManager::AddNtupleRow(G4in 323 G4bool G4RootPNtupleManager::AddNtupleRow(G4int ntupleId) 324 { 324 { 325 if ( fState.GetIsActivation() && ( ! GetActi 325 if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) { 326 //G4cout << "Skipping AddNtupleRow for " < 326 //G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl; 327 return false; 327 return false; 328 } 328 } 329 329 330 if ( IsVerbose(kVL4) ) { 330 if ( IsVerbose(kVL4) ) { 331 Message(kVL4, "add", "pntuple row", " ntup 331 Message(kVL4, "add", "pntuple row", " ntupleId " + to_string(ntupleId)); 332 } 332 } 333 333 334 // Creating ntuples on workers is triggered 334 // Creating ntuples on workers is triggered with the first FillColumn 335 // or AddRow (in only columns of vector type 335 // or AddRow (in only columns of vector type call) 336 CreateNtuplesIfNeeded(); 336 CreateNtuplesIfNeeded(); 337 337 338 auto ntupleDescription = GetNtupleDescriptio 338 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "AddNtupleRow"); 339 if (ntupleDescription == nullptr) return fal 339 if (ntupleDescription == nullptr) return false; 340 340 341 auto rfile = std::get<0>(*ntupleDescription- 341 auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile()); 342 342 343 G4AutoLock lock(&pntupleMutex); 343 G4AutoLock lock(&pntupleMutex); 344 lock.unlock(); 344 lock.unlock(); 345 mutex toolsLock(lock); 345 mutex toolsLock(lock); 346 auto result 346 auto result 347 = ntupleDescription->GetNtuple()->add_row( 347 = ntupleDescription->GetNtuple()->add_row(toolsLock, *rfile); 348 348 349 if ( ! result ) { 349 if ( ! result ) { 350 Warn("NtupleId " + to_string(ntupleId) + " 350 Warn("NtupleId " + to_string(ntupleId) + "adding row failed.", 351 fkClass, "AddNtupleRow"); 351 fkClass, "AddNtupleRow"); 352 } 352 } 353 353 354 ntupleDescription->GetDescription().SetHasFi 354 ntupleDescription->GetDescription().SetHasFill(true); 355 355 356 if ( IsVerbose(kVL3) ) { 356 if ( IsVerbose(kVL3) ) { 357 Message(kVL3, "add", "pntuple row", " ntup 357 Message(kVL3, "add", "pntuple row", " ntupleId " + to_string(ntupleId)); 358 } 358 } 359 359 360 360 361 return true; 361 return true; 362 } 362 } 363 363 364 //____________________________________________ 364 //_____________________________________________________________________________ 365 G4bool G4RootPNtupleManager::Merge() 365 G4bool G4RootPNtupleManager::Merge() 366 { 366 { 367 for ( auto ntupleDescription : fNtupleDescri 367 for ( auto ntupleDescription : fNtupleDescriptionVector) { 368 368 369 // skip inactivated ntuples 369 // skip inactivated ntuples 370 if (! ntupleDescription->GetDescription(). 370 if (! ntupleDescription->GetDescription().GetActivation() || 371 (ntupleDescription->GetNtuple() == nul 371 (ntupleDescription->GetNtuple() == nullptr)) { 372 // G4cout << "skipping inactive ntuple " 372 // G4cout << "skipping inactive ntuple " << G4endl; 373 continue; 373 continue; 374 } 374 } 375 375 376 if ( IsVerbose(kVL4) ) { 376 if ( IsVerbose(kVL4) ) { 377 Message(kVL4, "merge", "pntuple", 377 Message(kVL4, "merge", "pntuple", 378 ntupleDescription->GetDescription().Ge 378 ntupleDescription->GetDescription().GetNtupleBooking().name()); 379 } 379 } 380 380 381 auto rfile = std::get<0>(*ntupleDescriptio 381 auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile()); 382 382 383 G4AutoLock lock(&pntupleMutex); 383 G4AutoLock lock(&pntupleMutex); 384 lock.unlock(); 384 lock.unlock(); 385 mutex toolsLock(lock); 385 mutex toolsLock(lock); 386 auto result 386 auto result 387 = ntupleDescription->GetNtuple()->end_fi 387 = ntupleDescription->GetNtuple()->end_fill(toolsLock, *rfile); 388 388 389 if ( ! result ) { 389 if ( ! result ) { 390 Warn("Ntuple " + ntupleDescription->GetD 390 Warn("Ntuple " + ntupleDescription->GetDescription().GetNtupleBooking().name() + 391 "end fill has failed.", fkClass, "M 391 "end fill has failed.", fkClass, "Merge"); 392 } 392 } 393 393 394 if ( IsVerbose(kVL3) ) { 394 if ( IsVerbose(kVL3) ) { 395 Message(kVL3, "merge", "pntuple", 395 Message(kVL3, "merge", "pntuple", 396 ntupleDescription->GetDescription().Ge 396 ntupleDescription->GetDescription().GetNtupleBooking().name()); 397 } 397 } 398 398 399 } 399 } 400 400 401 // Set new cycle 401 // Set new cycle 402 fNewCycle = true; 402 fNewCycle = true; 403 403 404 return true; 404 return true; 405 } 405 } 406 406 407 //____________________________________________ 407 //_____________________________________________________________________________ 408 G4bool G4RootPNtupleManager::Reset() 408 G4bool G4RootPNtupleManager::Reset() 409 { 409 { 410 // Reset ntuple description, this will delet 410 // Reset ntuple description, this will delete ntuple if present and 411 // we have its ownership. 411 // we have its ownership. 412 // The ntuples will be recreated with new cy 412 // The ntuples will be recreated with new cycle or new open file. 413 413 414 for ( auto ntupleDescription : fNtupleDescri 414 for ( auto ntupleDescription : fNtupleDescriptionVector ) { 415 ntupleDescription->Reset(); 415 ntupleDescription->Reset(); 416 } 416 } 417 417 418 fNtupleVector.clear(); 418 fNtupleVector.clear(); 419 419 420 return true; 420 return true; 421 } 421 } 422 422 423 //____________________________________________ 423 //_____________________________________________________________________________ 424 void G4RootPNtupleManager::Clear() 424 void G4RootPNtupleManager::Clear() 425 { 425 { 426 for ( auto ntupleDescription : fNtupleDescri 426 for ( auto ntupleDescription : fNtupleDescriptionVector ) { 427 delete ntupleDescription->GetNtuple(); 427 delete ntupleDescription->GetNtuple(); 428 } 428 } 429 429 430 fNtupleDescriptionVector.clear(); 430 fNtupleDescriptionVector.clear(); 431 fNtupleVector.clear(); 431 fNtupleVector.clear(); 432 432 433 Message(kVL2, "clear", "pntuples"); 433 Message(kVL2, "clear", "pntuples"); 434 } 434 } 435 435 436 //____________________________________________ 436 //_____________________________________________________________________________ 437 G4bool G4RootPNtupleManager::Delete(G4int id) 437 G4bool G4RootPNtupleManager::Delete(G4int id) 438 { 438 { 439 if ( IsVerbose(G4Analysis::kVL4) ) { 439 if ( IsVerbose(G4Analysis::kVL4) ) { 440 Message(G4Analysis::kVL4, "delete", "pntup 440 Message(G4Analysis::kVL4, "delete", "pntuple ntupleId " + to_string(id)); 441 } 441 } 442 442 443 auto ntupleDescription = GetNtupleDescriptio 443 auto ntupleDescription = GetNtupleDescriptionInFunction(id, "Delete", true); 444 444 445 if (ntupleDescription == nullptr) return fal 445 if (ntupleDescription == nullptr) return false; 446 446 447 // Delete/clear ntuple data 447 // Delete/clear ntuple data 448 delete ntupleDescription->GetNtuple(); 448 delete ntupleDescription->GetNtuple(); 449 ntupleDescription->SetNtuple(nullptr); 449 ntupleDescription->SetNtuple(nullptr); 450 ntupleDescription->SetBasePNtuple(nullptr); 450 ntupleDescription->SetBasePNtuple(nullptr); 451 ntupleDescription->GetMainBranches().clear() 451 ntupleDescription->GetMainBranches().clear(); 452 452 453 // Update ntuple vector 453 // Update ntuple vector 454 auto index = id - GetFirstId(); 454 auto index = id - GetFirstId(); 455 fNtupleVector[index] = nullptr; 455 fNtupleVector[index] = nullptr; 456 456 457 Message(G4Analysis::kVL2, "delete", "pntuple 457 Message(G4Analysis::kVL2, "delete", "pntuple ntupleId " + to_string(id)); 458 458 459 return true; 459 return true; 460 } 460 } 461 461 462 //____________________________________________ 462 //_____________________________________________________________________________ 463 463 464 void G4RootPNtupleManager::SetActivation( 464 void G4RootPNtupleManager::SetActivation( 465 G4bool activation) 465 G4bool activation) 466 { 466 { 467 for ( auto ntupleDescription : fNtupleDescri 467 for ( auto ntupleDescription : fNtupleDescriptionVector ) { 468 ntupleDescription->GetDescription().SetAct 468 ntupleDescription->GetDescription().SetActivation(activation); 469 } 469 } 470 } 470 } 471 471 472 //____________________________________________ 472 //_____________________________________________________________________________ 473 473 474 void G4RootPNtupleManager::SetActivation( 474 void G4RootPNtupleManager::SetActivation( 475 G4int ntupleId, G4bool activation) 475 G4int ntupleId, G4bool activation) 476 { 476 { 477 auto ntupleDescription = GetNtupleDescriptio 477 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "SetActivation"); 478 if (ntupleDescription == nullptr) return; 478 if (ntupleDescription == nullptr) return; 479 479 480 ntupleDescription->GetDescription().SetActiv 480 ntupleDescription->GetDescription().SetActivation(activation); 481 } 481 } 482 482 483 //____________________________________________ 483 //_____________________________________________________________________________ 484 G4bool G4RootPNtupleManager::GetActivation( 484 G4bool G4RootPNtupleManager::GetActivation( 485 G4int ntupleId) const 485 G4int ntupleId) const 486 { 486 { 487 auto ntupleDescription = GetNtupleDescriptio 487 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "GetActivation"); 488 if (ntupleDescription == nullptr) return fal 488 if (ntupleDescription == nullptr) return false; 489 489 490 return ntupleDescription->GetDescription().G 490 return ntupleDescription->GetDescription().GetActivation(); 491 } 491 } 492 492 493 //____________________________________________ 493 //_____________________________________________________________________________ 494 void G4RootPNtupleManager::SetNewCycle(G4bool 494 void G4RootPNtupleManager::SetNewCycle(G4bool value) 495 { 495 { 496 fNewCycle = value; 496 fNewCycle = value; 497 } 497 } 498 498 499 //____________________________________________ 499 //_____________________________________________________________________________ 500 G4bool G4RootPNtupleManager::GetNewCycle() con 500 G4bool G4RootPNtupleManager::GetNewCycle() const 501 { 501 { 502 return fNewCycle; 502 return fNewCycle; 503 } 503 } 504 504 505 //____________________________________________ 505 //_____________________________________________________________________________ 506 void G4RootPNtupleManager::SetNtupleRowWise(G4 506 void G4RootPNtupleManager::SetNtupleRowWise(G4bool rowWise, G4bool rowMode) 507 { 507 { 508 fRowWise = rowWise; 508 fRowWise = rowWise; 509 fRowMode = rowMode; 509 fRowMode = rowMode; 510 } 510 } 511 511