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, 26/08/2022 (ivan 27 // Author: Ivana Hrivnacova, 26/08/2022 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4AnalysisUtilities.hh" 29 #include "G4AnalysisUtilities.hh" 30 30 31 #include "G4UIdirectory.hh" 31 #include "G4UIdirectory.hh" 32 #include "G4UIcommand.hh" 32 #include "G4UIcommand.hh" 33 #include "G4UIparameter.hh" 33 #include "G4UIparameter.hh" 34 #include "G4Tokenizer.hh" 34 #include "G4Tokenizer.hh" 35 35 36 #include <vector> 36 #include <vector> 37 37 38 using namespace G4Analysis; 38 using namespace G4Analysis; 39 39 40 //____________________________________________ 40 //_____________________________________________________________________________ 41 template <unsigned int DIM, typename HT> 41 template <unsigned int DIM, typename HT> 42 G4THnMessenger<DIM, HT>::G4THnMessenger(G4THnT 42 G4THnMessenger<DIM, HT>::G4THnMessenger(G4THnToolsManager<DIM, HT>* manager) 43 : fManager(manager) 43 : fManager(manager) 44 { 44 { 45 CreateDirectory(); 45 CreateDirectory(); 46 46 47 CreateCmd(); 47 CreateCmd(); 48 SetCmd(); 48 SetCmd(); 49 for (unsigned int idim = 0; idim < DIM; ++id 49 for (unsigned int idim = 0; idim < DIM; ++idim) { 50 fSetDimensionCmd[idim] = CreateSetBinsComm 50 fSetDimensionCmd[idim] = CreateSetBinsCommand(idim); 51 } 51 } 52 52 53 DeleteCmd(); 53 DeleteCmd(); 54 54 55 CreateSetTitleCommand(); 55 CreateSetTitleCommand(); 56 56 57 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kM 57 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kMaxDim; 58 for (unsigned int idim = 0; idim < maxDim; + 58 for (unsigned int idim = 0; idim < maxDim; ++idim) { 59 fSetAxisCmd[idim] = CreateSetAxisCommand(i 59 fSetAxisCmd[idim] = CreateSetAxisCommand(idim); 60 } 60 } 61 61 62 CreateListCommand(); 62 CreateListCommand(); 63 CreateGetCommand(); 63 CreateGetCommand(); 64 CreateGetVectorCommand(); 64 CreateGetVectorCommand(); 65 65 66 // Initialize data 66 // Initialize data 67 for (unsigned int idim = 0; idim < DIM; ++id 67 for (unsigned int idim = 0; idim < DIM; ++idim) { 68 fTmpId[idim] = G4Analysis::kInvalidId; 68 fTmpId[idim] = G4Analysis::kInvalidId; 69 fTmpBins[idim] = G4HnDimension(); 69 fTmpBins[idim] = G4HnDimension(); 70 fTmpInfo[idim] = G4HnDimensionInformation( 70 fTmpInfo[idim] = G4HnDimensionInformation(); 71 } 71 } 72 } 72 } 73 73 74 // 74 // 75 // private functions 75 // private functions 76 // 76 // 77 77 78 //____________________________________________ 78 //_____________________________________________________________________________ 79 template <unsigned int DIM, typename HT> 79 template <unsigned int DIM, typename HT> 80 G4String G4THnMessenger<DIM, HT>::GetObjectTyp 80 G4String G4THnMessenger<DIM, HT>::GetObjectType() const 81 { 81 { 82 return (G4Analysis::IsProfile<HT>()) ? 82 return (G4Analysis::IsProfile<HT>()) ? 83 std::to_string(DIM - 1) + "D profile " : 83 std::to_string(DIM - 1) + "D profile " : std::to_string(DIM) + "D histogram"; 84 } 84 } 85 85 86 //____________________________________________ 86 //_____________________________________________________________________________ 87 template <unsigned int DIM, typename HT> 87 template <unsigned int DIM, typename HT> 88 G4bool G4THnMessenger<DIM, HT>::IsProfileLastD 88 G4bool G4THnMessenger<DIM, HT>::IsProfileLastDimension(unsigned int idim) const 89 { 89 { 90 return (idim == DIM - 1) && (G4Analysis::IsP 90 return (idim == DIM - 1) && (G4Analysis::IsProfile<HT>()); 91 } 91 } 92 92 93 //____________________________________________ 93 //_____________________________________________________________________________ 94 template <unsigned int DIM, typename HT> 94 template <unsigned int DIM, typename HT> 95 std::unique_ptr<G4UIcommand> G4THnMessenger<DI 95 std::unique_ptr<G4UIcommand> G4THnMessenger<DIM, HT>::CreateCommand( 96 G4String name, G4String guidance) 96 G4String name, G4String guidance) 97 { 97 { 98 G4String fullName = "/analysis/" + G4Analysi 98 G4String fullName = "/analysis/" + G4Analysis::GetHnType<HT>() + "/" + name; 99 G4String fullGuidance = guidance + GetObject 99 G4String fullGuidance = guidance + GetObjectType(); 100 100 101 auto command = std::make_unique<G4UIcommand> 101 auto command = std::make_unique<G4UIcommand>(fullName, this); 102 command->SetGuidance(fullGuidance); 102 command->SetGuidance(fullGuidance); 103 103 104 return command; 104 return command; 105 } 105 } 106 106 107 //____________________________________________ 107 //_____________________________________________________________________________ 108 template <unsigned int DIM, typename HT> 108 template <unsigned int DIM, typename HT> 109 void G4THnMessenger<DIM, HT>::CreateDimensionP 109 void G4THnMessenger<DIM, HT>::CreateDimensionParameters( 110 unsigned int idim, std::vector<G4UIparameter 110 unsigned int idim, std::vector<G4UIparameter*>& parameters) const 111 { 111 { 112 // Create [nbins], valMin, valMax, valUnit, va 112 // Create [nbins], valMin, valMax, valUnit, valFcn, [valBinScheme] parameters. 113 // The parameters in [] are omitted for the la 113 // The parameters in [] are omitted for the last dimension for profiles 114 114 115 std::string xyz{"xyz"}; 115 std::string xyz{"xyz"}; 116 std::string axis = xyz.substr(idim, 1); 116 std::string axis = xyz.substr(idim, 1); 117 117 118 if (! IsProfileLastDimension(idim)) { 118 if (! IsProfileLastDimension(idim)) { 119 auto parName = axis + "nBins"; 119 auto parName = axis + "nBins"; 120 auto guidance = 120 auto guidance = 121 std::string("Number of ") + axis + "-bin 121 std::string("Number of ") + axis + "-bins (default = 100)\n" 122 "Can be reset with /analysis/hn/set comm 122 "Can be reset with /analysis/hn/set command"; 123 123 124 auto param = new G4UIparameter(parName.c_s 124 auto param = new G4UIparameter(parName.c_str(), 'i', false); 125 param->SetGuidance(guidance.c_str()); 125 param->SetGuidance(guidance.c_str()); 126 param->SetDefaultValue(100); 126 param->SetDefaultValue(100); 127 parameters.push_back(param); 127 parameters.push_back(param); 128 } 128 } 129 129 130 auto parName = axis + "valMin"; 130 auto parName = axis + "valMin"; 131 auto guidance = 131 auto guidance = 132 std::string("Minimum ") + axis + "-value, 132 std::string("Minimum ") + axis + "-value, expressed in unit (default = 0.)\n" 133 "Can be reset with /analysis/hn/set comman 133 "Can be reset with /analysis/hn/set command"; 134 auto param = new G4UIparameter(parName.c_str 134 auto param = new G4UIparameter(parName.c_str(), 'd', false); 135 param->SetGuidance(guidance.c_str()); 135 param->SetGuidance(guidance.c_str()); 136 param->SetDefaultValue(0.); 136 param->SetDefaultValue(0.); 137 parameters.push_back(param); 137 parameters.push_back(param); 138 138 139 parName = axis + "valMax"; 139 parName = axis + "valMax"; 140 guidance = 140 guidance = 141 std::string("Maximum ") + axis + "-value, 141 std::string("Maximum ") + axis + "-value, expressed in unit (default = 1.)\n" 142 "Can be reset with /analysis/hn/set comman 142 "Can be reset with /analysis/hn/set command"; 143 param = new G4UIparameter(parName.c_str(), ' 143 param = new G4UIparameter(parName.c_str(), 'd', false); 144 param->SetGuidance(guidance.c_str()); 144 param->SetGuidance(guidance.c_str()); 145 param->SetDefaultValue(1.); 145 param->SetDefaultValue(1.); 146 parameters.push_back(param); 146 parameters.push_back(param); 147 147 148 parName = axis + "valUnit"; 148 parName = axis + "valUnit"; 149 guidance = 149 guidance = 150 std::string("The unit applied to filled ") 150 std::string("The unit applied to filled ") + axis + "-values and \n" 151 "Can be reset with /analysis/hn/set comman 151 "Can be reset with /analysis/hn/set command"; 152 param = new G4UIparameter(parName.c_str(), ' 152 param = new G4UIparameter(parName.c_str(), 's', true); 153 param->SetGuidance(guidance.c_str()); 153 param->SetGuidance(guidance.c_str()); 154 param->SetDefaultValue("none"); 154 param->SetDefaultValue("none"); 155 parameters.push_back(param); 155 parameters.push_back(param); 156 156 157 parName = axis + "valFcn"; 157 parName = axis + "valFcn"; 158 guidance = 158 guidance = 159 std::string("The function applied to fille 159 std::string("The function applied to filled ") + axis + "-values (log, log10, exp, none).\n" 160 "Note that the unit parameter cannot be om 160 "Note that the unit parameter cannot be omitted in this case,\n" 161 "but none value should be used instead."; 161 "but none value should be used instead."; 162 param = new G4UIparameter(parName.c_str(), ' 162 param = new G4UIparameter(parName.c_str(), 's', true); 163 param->SetGuidance(guidance.c_str()); 163 param->SetGuidance(guidance.c_str()); 164 param->SetParameterCandidates("log log10 exp 164 param->SetParameterCandidates("log log10 exp none"); 165 param->SetDefaultValue("none"); 165 param->SetDefaultValue("none"); 166 parameters.push_back(param); 166 parameters.push_back(param); 167 167 168 if (! IsProfileLastDimension(idim)) { 168 if (! IsProfileLastDimension(idim)) { 169 parName = axis + "valBinScheme"; 169 parName = axis + "valBinScheme"; 170 guidance = 170 guidance = 171 std::string("The binning scheme (linear 171 std::string("The binning scheme (linear, log).\n" 172 "Note that the unit and fcn parameters 172 "Note that the unit and fcn parameters cannot be omitted in this case,\n" 173 "but none value should be used instead. 173 "but none value should be used instead."); 174 param = new G4UIparameter(parName.c_str(), 174 param = new G4UIparameter(parName.c_str(), 's', true); 175 param->SetGuidance(guidance.c_str()); 175 param->SetGuidance(guidance.c_str()); 176 param->SetParameterCandidates("linear log" 176 param->SetParameterCandidates("linear log"); 177 param->SetDefaultValue("linear"); 177 param->SetDefaultValue("linear"); 178 parameters.push_back(param); 178 parameters.push_back(param); 179 } 179 } 180 } 180 } 181 181 182 //____________________________________________ 182 //_____________________________________________________________________________ 183 template <unsigned int DIM, typename HT> 183 template <unsigned int DIM, typename HT> 184 void G4THnMessenger<DIM, HT>::AddIdParameter(G 184 void G4THnMessenger<DIM, HT>::AddIdParameter(G4UIcommand& command) 185 { 185 { 186 // add parameter 186 // add parameter 187 auto htId = new G4UIparameter("id", 'i', fal 187 auto htId = new G4UIparameter("id", 'i', false); 188 htId->SetGuidance("Histogram id"); 188 htId->SetGuidance("Histogram id"); 189 htId->SetParameterRange("id>=0"); 189 htId->SetParameterRange("id>=0"); 190 command.SetParameter(htId); 190 command.SetParameter(htId); 191 } 191 } 192 192 193 //____________________________________________ 193 //_____________________________________________________________________________ 194 template <unsigned int DIM, typename HT> 194 template <unsigned int DIM, typename HT> 195 G4String G4THnMessenger<DIM, HT>::GetTAddress( 195 G4String G4THnMessenger<DIM, HT>::GetTAddress(G4int id) const 196 { 196 { 197 auto ht = fManager->GetT(id); 197 auto ht = fManager->GetT(id); 198 if ( ht != nullptr ) { 198 if ( ht != nullptr ) { 199 std::ostringstream os; 199 std::ostringstream os; 200 os << static_cast<void*>(ht); 200 os << static_cast<void*>(ht); 201 return os.str(); 201 return os.str(); 202 } 202 } 203 return {}; 203 return {}; 204 } 204 } 205 205 206 //____________________________________________ 206 //_____________________________________________________________________________ 207 template <unsigned int DIM, typename HT> 207 template <unsigned int DIM, typename HT> 208 G4String G4THnMessenger<DIM, HT>::GetTVectorAd 208 G4String G4THnMessenger<DIM, HT>::GetTVectorAddress() const 209 { 209 { 210 auto htVector = fManager->GetTVector(); 210 auto htVector = fManager->GetTVector(); 211 if ( htVector != nullptr ) { 211 if ( htVector != nullptr ) { 212 std::ostringstream os; 212 std::ostringstream os; 213 os << static_cast<void*>(htVector); 213 os << static_cast<void*>(htVector); 214 return os.str(); 214 return os.str(); 215 } 215 } 216 return {}; 216 return {}; 217 } 217 } 218 218 219 //____________________________________________ 219 //_____________________________________________________________________________ 220 template <unsigned int DIM, typename HT> 220 template <unsigned int DIM, typename HT> 221 void G4THnMessenger<DIM, HT>::CreateDirectory( 221 void G4THnMessenger<DIM, HT>::CreateDirectory() const 222 { 222 { 223 G4String dirName = "/analysis/" + G4Analysis 223 G4String dirName = "/analysis/" + G4Analysis::GetHnType<HT>() + "/"; 224 G4String guidance = GetObjectType() + " cont 224 G4String guidance = GetObjectType() + " control"; 225 225 226 auto directory = std::make_unique<G4UIdirect 226 auto directory = std::make_unique<G4UIdirectory>(dirName); 227 directory->SetGuidance(guidance.c_str()); 227 directory->SetGuidance(guidance.c_str()); 228 } 228 } 229 229 230 //____________________________________________ 230 //_____________________________________________________________________________ 231 template <unsigned int DIM, typename HT> 231 template <unsigned int DIM, typename HT> 232 void G4THnMessenger<DIM, HT>::CreateCmd() 232 void G4THnMessenger<DIM, HT>::CreateCmd() 233 { 233 { 234 fCreateCmd = CreateCommand("create", "Create 234 fCreateCmd = CreateCommand("create", "Create "); 235 fCreateCmd->AvailableForStates(G4State_PreIn 235 fCreateCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 236 236 237 auto htName = new G4UIparameter("name", 's', 237 auto htName = new G4UIparameter("name", 's', false); 238 htName->SetGuidance("Histogram name (label)" 238 htName->SetGuidance("Histogram name (label)"); 239 fCreateCmd->SetParameter(htName); 239 fCreateCmd->SetParameter(htName); 240 240 241 auto htTitle = new G4UIparameter("title", 's 241 auto htTitle = new G4UIparameter("title", 's', false); 242 htTitle->SetGuidance("Histogram title"); 242 htTitle->SetGuidance("Histogram title"); 243 fCreateCmd->SetParameter(htTitle); 243 fCreateCmd->SetParameter(htTitle); 244 244 245 std::vector<G4UIparameter*> parameters; 245 std::vector<G4UIparameter*> parameters; 246 for (unsigned int idim = 0; idim < DIM; ++id 246 for (unsigned int idim = 0; idim < DIM; ++idim) { 247 CreateDimensionParameters(idim, parameters 247 CreateDimensionParameters(idim, parameters); 248 for (size_t ipar = 0; ipar < parameters.si 248 for (size_t ipar = 0; ipar < parameters.size(); ++ipar) { 249 // the first three parameters can be omi 249 // the first three parameters can be omittes in create command 250 if (ipar < 3) parameters[ipar]->SetOmitt 250 if (ipar < 3) parameters[ipar]->SetOmittable(true); 251 fCreateCmd->SetParameter(parameters[ipar 251 fCreateCmd->SetParameter(parameters[ipar]); 252 } 252 } 253 parameters.clear(); 253 parameters.clear(); 254 } 254 } 255 } 255 } 256 256 257 //____________________________________________ 257 //_____________________________________________________________________________ 258 template <unsigned int DIM, typename HT> 258 template <unsigned int DIM, typename HT> 259 void G4THnMessenger<DIM, HT>::SetCmd() 259 void G4THnMessenger<DIM, HT>::SetCmd() 260 { 260 { 261 fSetCmd = CreateCommand("set", "Set "); 261 fSetCmd = CreateCommand("set", "Set "); 262 fSetCmd->AvailableForStates(G4State_PreInit, 262 fSetCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 263 263 264 // Add Id parameter 264 // Add Id parameter 265 AddIdParameter(*fSetCmd); 265 AddIdParameter(*fSetCmd); 266 266 267 // Update guidance 267 // Update guidance 268 fSetCmd->SetGuidance("\n nbins; valMin; val 268 fSetCmd->SetGuidance("\n nbins; valMin; valMax; unit; function; binScheme"); 269 269 270 std::vector<G4UIparameter*> parameters; 270 std::vector<G4UIparameter*> parameters; 271 for (unsigned int idim = 0; idim < DIM; ++id 271 for (unsigned int idim = 0; idim < DIM; ++idim) { 272 CreateDimensionParameters(idim, parameters 272 CreateDimensionParameters(idim, parameters); 273 for (auto parameter: parameters) { 273 for (auto parameter: parameters) { 274 fSetCmd->SetParameter(parameter); 274 fSetCmd->SetParameter(parameter); 275 } 275 } 276 parameters.clear(); 276 parameters.clear(); 277 } 277 } 278 } 278 } 279 279 280 //____________________________________________ 280 //_____________________________________________________________________________ 281 template <unsigned int DIM, typename HT> 281 template <unsigned int DIM, typename HT> 282 void G4THnMessenger<DIM, HT>::DeleteCmd() 282 void G4THnMessenger<DIM, HT>::DeleteCmd() 283 { 283 { 284 fDeleteCmd = CreateCommand("delete", "Delete 284 fDeleteCmd = CreateCommand("delete", "Delete "); 285 fDeleteCmd->AvailableForStates(G4State_PreIn 285 fDeleteCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 286 286 287 // Add Id parameter 287 // Add Id parameter 288 AddIdParameter(*fDeleteCmd); 288 AddIdParameter(*fDeleteCmd); 289 289 290 auto parKeepSetting = new G4UIparameter("kee 290 auto parKeepSetting = new G4UIparameter("keepSetting", 'b', true); 291 G4String guidance = 291 G4String guidance = 292 "If set true, activation, plotting, etc. o 292 "If set true, activation, plotting, etc. options will be kept\n" 293 "and applied when a new object with the sa 293 "and applied when a new object with the same id is created."; 294 parKeepSetting->SetGuidance(guidance.c_str() 294 parKeepSetting->SetGuidance(guidance.c_str()); 295 parKeepSetting->SetDefaultValue("false"); 295 parKeepSetting->SetDefaultValue("false"); 296 fDeleteCmd->SetParameter(parKeepSetting); 296 fDeleteCmd->SetParameter(parKeepSetting); 297 } 297 } 298 298 299 //____________________________________________ 299 //_____________________________________________________________________________ 300 template <unsigned int DIM, typename HT> 300 template <unsigned int DIM, typename HT> 301 std::unique_ptr<G4UIcommand> 301 std::unique_ptr<G4UIcommand> 302 G4THnMessenger<DIM, HT>::CreateSetBinsCommand( 302 G4THnMessenger<DIM, HT>::CreateSetBinsCommand(unsigned int idim) 303 { 303 { 304 G4String xyz{"XYZ"}; 304 G4String xyz{"XYZ"}; 305 auto axis = xyz.substr(idim, 1); 305 auto axis = xyz.substr(idim, 1); 306 306 307 auto command = CreateCommand("set" + axis, " 307 auto command = CreateCommand("set" + axis, "Set " + axis + " parameters for the "); 308 command->AvailableForStates(G4State_PreInit, 308 command->AvailableForStates(G4State_PreInit, G4State_Idle); 309 309 310 // Add Id parameter 310 // Add Id parameter 311 AddIdParameter(*command); 311 AddIdParameter(*command); 312 312 313 // Update guidance 313 // Update guidance 314 G4String guidance = 314 G4String guidance = 315 "\n nAXISbins; AXISvalMin; AXISvalMax; AX 315 "\n nAXISbins; AXISvalMin; AXISvalMax; AXISunit; AXISfunction; AXISbinScheme"; 316 // update AXIS with xyz 316 // update AXIS with xyz 317 std::string::size_type n = 0; 317 std::string::size_type n = 0; 318 std::string ts{"AXIS"}; 318 std::string ts{"AXIS"}; 319 while ( ( n = guidance.find(ts, n)) != std:: 319 while ( ( n = guidance.find(ts, n)) != std::string::npos ) { 320 guidance.replace(n, ts.size(), axis); 320 guidance.replace(n, ts.size(), axis); 321 n += ts.size(); 321 n += ts.size(); 322 } 322 } 323 command->SetGuidance(guidance); 323 command->SetGuidance(guidance); 324 324 325 std::vector<G4UIparameter*> parameters; 325 std::vector<G4UIparameter*> parameters; 326 CreateDimensionParameters(idim, parameters); 326 CreateDimensionParameters(idim, parameters); 327 for (auto parameter: parameters) { 327 for (auto parameter: parameters) { 328 command->SetParameter(parameter); 328 command->SetParameter(parameter); 329 } 329 } 330 330 331 return command; 331 return command; 332 } 332 } 333 333 334 //____________________________________________ 334 //_____________________________________________________________________________ 335 template <unsigned int DIM, typename HT> 335 template <unsigned int DIM, typename HT> 336 void G4THnMessenger<DIM, HT>::CreateSetTitleCo 336 void G4THnMessenger<DIM, HT>::CreateSetTitleCommand() 337 { 337 { 338 fSetTitleCmd = CreateCommand("setTitle", "Se 338 fSetTitleCmd = CreateCommand("setTitle", "Set title for the "); 339 fSetTitleCmd->AvailableForStates(G4State_Pre 339 fSetTitleCmd->AvailableForStates(G4State_PreInit, G4State_Idle); 340 340 341 // Add Id parameter 341 // Add Id parameter 342 AddIdParameter(*fSetTitleCmd); 342 AddIdParameter(*fSetTitleCmd); 343 343 344 auto parTitle = new G4UIparameter("title", ' 344 auto parTitle = new G4UIparameter("title", 's', true); 345 auto guidance = GetObjectType() + " title"; 345 auto guidance = GetObjectType() + " title"; 346 parTitle->SetGuidance(guidance.c_str()); 346 parTitle->SetGuidance(guidance.c_str()); 347 parTitle->SetDefaultValue("none"); 347 parTitle->SetDefaultValue("none"); 348 fSetTitleCmd->SetParameter(parTitle); 348 fSetTitleCmd->SetParameter(parTitle); 349 } 349 } 350 350 351 //____________________________________________ 351 //_____________________________________________________________________________ 352 template <unsigned int DIM, typename HT> 352 template <unsigned int DIM, typename HT> 353 std::unique_ptr<G4UIcommand> 353 std::unique_ptr<G4UIcommand> 354 G4THnMessenger<DIM, HT>::CreateSetAxisCommand( 354 G4THnMessenger<DIM, HT>::CreateSetAxisCommand(unsigned int idim) 355 { 355 { 356 G4String xyz{"XYZ"}; 356 G4String xyz{"XYZ"}; 357 auto axis = xyz.substr(idim, 1); 357 auto axis = xyz.substr(idim, 1); 358 358 359 G4String commandName = "set" + axis + "axis" 359 G4String commandName = "set" + axis + "axis"; 360 G4String guidance = "Set " + axis + "-axis t 360 G4String guidance = "Set " + axis + "-axis title for the ";; 361 361 362 auto command = CreateCommand(std::move(comma << 362 auto command = CreateCommand(commandName, guidance); 363 command->AvailableForStates(G4State_PreInit, 363 command->AvailableForStates(G4State_PreInit, G4State_Idle); 364 364 365 // Add Id parameter 365 // Add Id parameter 366 AddIdParameter(*command); 366 AddIdParameter(*command); 367 367 368 auto parAxis = new G4UIparameter("axis", 's' 368 auto parAxis = new G4UIparameter("axis", 's', false); 369 guidance = GetObjectType() + " " + std::move << 369 guidance = GetObjectType() + " " + axis + "-axis title"; 370 parAxis->SetGuidance(guidance.c_str()); 370 parAxis->SetGuidance(guidance.c_str()); 371 command->SetParameter(parAxis); 371 command->SetParameter(parAxis); 372 372 373 return command; 373 return command; 374 } 374 } 375 375 376 //____________________________________________ 376 //_____________________________________________________________________________ 377 template <unsigned int DIM, typename HT> 377 template <unsigned int DIM, typename HT> 378 void G4THnMessenger<DIM, HT>::CreateListComman 378 void G4THnMessenger<DIM, HT>::CreateListCommand() 379 { 379 { 380 fListCmd = CreateCommand("list", "List all/a 380 fListCmd = CreateCommand("list", "List all/activate "); 381 fListCmd->AvailableForStates(G4State_Idle, G 381 fListCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc); 382 382 383 auto parOnlyIfActive = new G4UIparameter("on 383 auto parOnlyIfActive = new G4UIparameter("onlyIfActive", 'b', true); 384 parOnlyIfActive->SetGuidance("Option whether 384 parOnlyIfActive->SetGuidance("Option whether to list only active objects"); 385 parOnlyIfActive->SetDefaultValue("true"); 385 parOnlyIfActive->SetDefaultValue("true"); 386 fListCmd->SetParameter(parOnlyIfActive); 386 fListCmd->SetParameter(parOnlyIfActive); 387 } 387 } 388 388 389 //____________________________________________ 389 //_____________________________________________________________________________ 390 template <unsigned int DIM, typename HT> 390 template <unsigned int DIM, typename HT> 391 void G4THnMessenger<DIM, HT>::CreateGetCommand 391 void G4THnMessenger<DIM, HT>::CreateGetCommand() 392 { 392 { 393 fGetTCmd = CreateCommand("get", "Get the add 393 fGetTCmd = CreateCommand("get", "Get the address of the "); 394 fGetTCmd->SetGuidance( "This command is only 394 fGetTCmd->SetGuidance( "This command is only for Geant4 internal use."); 395 fGetTCmd->AvailableForStates(G4State_Idle, G 395 fGetTCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc); 396 396 397 // Add Id parameter 397 // Add Id parameter 398 AddIdParameter(*fGetTCmd); 398 AddIdParameter(*fGetTCmd); 399 } 399 } 400 400 401 //____________________________________________ 401 //_____________________________________________________________________________ 402 template <unsigned int DIM, typename HT> 402 template <unsigned int DIM, typename HT> 403 void G4THnMessenger<DIM, HT>::CreateGetVectorC 403 void G4THnMessenger<DIM, HT>::CreateGetVectorCommand() 404 { 404 { 405 fGetTVectorCmd = CreateCommand("getVector", 405 fGetTVectorCmd = CreateCommand("getVector", "Get the address of the vector of the "); 406 fGetTVectorCmd->SetGuidance( "This command i 406 fGetTVectorCmd->SetGuidance( "This command is only for Geant4 internal use."); 407 fGetTVectorCmd->AvailableForStates(G4State_I 407 fGetTVectorCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc); 408 } 408 } 409 409 410 //____________________________________________ 410 //_____________________________________________________________________________ 411 template <unsigned int DIM, typename HT> 411 template <unsigned int DIM, typename HT> 412 void G4THnMessenger<DIM, HT>::GetBinData( 412 void G4THnMessenger<DIM, HT>::GetBinData( 413 unsigned int idim, G4int& counter, const std 413 unsigned int idim, G4int& counter, const std::vector<G4String>& parameters, 414 G4HnDimension& bins) const 414 G4HnDimension& bins) const 415 { 415 { 416 G4int nbins = (! IsProfileLastDimension(id 416 G4int nbins = (! IsProfileLastDimension(idim)) ? 417 G4UIcommand::ConvertToInt(parameters[cou 417 G4UIcommand::ConvertToInt(parameters[counter++]) : 0; 418 418 419 bins = {nbins, 419 bins = {nbins, 420 G4UIcommand::ConvertToDouble(param 420 G4UIcommand::ConvertToDouble(parameters[counter]), 421 G4UIcommand::ConvertToDouble(param 421 G4UIcommand::ConvertToDouble(parameters[counter + 1])}; 422 counter += 2; 422 counter += 2; 423 } 423 } 424 424 425 //____________________________________________ 425 //_____________________________________________________________________________ 426 template <unsigned int DIM, typename HT> 426 template <unsigned int DIM, typename HT> 427 void G4THnMessenger<DIM, HT>::GetBinInfoData( 427 void G4THnMessenger<DIM, HT>::GetBinInfoData( 428 unsigned int idim, G4int& counter, const std 428 unsigned int idim, G4int& counter, const std::vector<G4String>& parameters, 429 G4HnDimension& bins, G4HnDimensionInformatio 429 G4HnDimension& bins, G4HnDimensionInformation& info) const 430 { 430 { 431 // get bin data (this will shift the counter 431 // get bin data (this will shift the counter for hnInfo data) 432 GetBinData(idim, counter, parameters, bins); 432 GetBinData(idim, counter, parameters, bins); 433 433 434 // get dimension information data 434 // get dimension information data 435 if (! IsProfileLastDimension(idim)) { 435 if (! IsProfileLastDimension(idim)) { 436 info = {parameters[counter], parameters[co 436 info = {parameters[counter], parameters[counter + 1], parameters[counter + 2]}; 437 counter += 3; 437 counter += 3; 438 } 438 } 439 else { 439 else { 440 info = {parameters[counter], parameters[co 440 info = {parameters[counter], parameters[counter + 1]}; 441 counter += 2; 441 counter += 2; 442 } 442 } 443 443 444 // apply unit to minValue and maxValue 444 // apply unit to minValue and maxValue 445 bins.fMinValue *= info.fUnit; 445 bins.fMinValue *= info.fUnit; 446 bins.fMaxValue *= info.fUnit; 446 bins.fMaxValue *= info.fUnit; 447 } 447 } 448 448 449 //____________________________________________ 449 //_____________________________________________________________________________ 450 template <unsigned int DIM, typename HT> 450 template <unsigned int DIM, typename HT> 451 void G4THnMessenger<DIM, HT>::GetData( 451 void G4THnMessenger<DIM, HT>::GetData( 452 G4int& counter, const std::vector<G4String>& 452 G4int& counter, const std::vector<G4String>& parameters, 453 std::array<G4HnDimension, DIM>& bins, 453 std::array<G4HnDimension, DIM>& bins, 454 std::array<G4HnDimensionInformation, DIM>& i 454 std::array<G4HnDimensionInformation, DIM>& info) const 455 { 455 { 456 for (unsigned int idim = 0; idim < DIM; ++id 456 for (unsigned int idim = 0; idim < DIM; ++idim) { 457 // get bin data (this will shift the count 457 // get bin data (this will shift the counter for hnInfo data) 458 GetBinInfoData(idim, counter, parameters, 458 GetBinInfoData(idim, counter, parameters, bins[idim], info[idim]); 459 } 459 } 460 } 460 } 461 461 462 // 462 // 463 // public functions 463 // public functions 464 // 464 // 465 465 466 //____________________________________________ 466 //_____________________________________________________________________________ 467 template <unsigned int DIM, typename HT> 467 template <unsigned int DIM, typename HT> 468 G4String G4THnMessenger<DIM, HT>::GetCurrentVa 468 G4String G4THnMessenger<DIM, HT>::GetCurrentValue (G4UIcommand* command) 469 { 469 { 470 if ( command == fGetTCmd.get() ) return fTVa 470 if ( command == fGetTCmd.get() ) return fTValue; 471 471 472 if ( command == fGetTVectorCmd.get() ) retur 472 if ( command == fGetTVectorCmd.get() ) return fTVectorValue; 473 473 474 return ""; 474 return ""; 475 } 475 } 476 476 477 //____________________________________________ 477 //_____________________________________________________________________________ 478 template <unsigned int DIM, typename HT> 478 template <unsigned int DIM, typename HT> 479 void G4THnMessenger<DIM, HT>::SetNewValue(G4UI 479 void G4THnMessenger<DIM, HT>::SetNewValue(G4UIcommand* command, G4String newValues) 480 { 480 { 481 // tokenize parameters in a vector 481 // tokenize parameters in a vector 482 std::vector<G4String> parameters; 482 std::vector<G4String> parameters; 483 G4Analysis::Tokenize(newValues, parameters); 483 G4Analysis::Tokenize(newValues, parameters); 484 // check consistency 484 // check consistency 485 if ( parameters.size() != command->GetParame 485 if ( parameters.size() != command->GetParameterEntries() ) { 486 // Should never happen but let's check any 486 // Should never happen but let's check anyway for consistency 487 G4Analysis::Warn( 487 G4Analysis::Warn( 488 "Got wrong number of \"" + command->GetC 488 "Got wrong number of \"" + command->GetCommandName() + 489 "\" parameters: " + to_string(parameters 489 "\" parameters: " + to_string(parameters.size()) + 490 " instead of " + to_string(command->GetP 490 " instead of " + to_string(command->GetParameterEntries()) + " expected", 491 fkClass, "WarnAboutParameters"); 491 fkClass, "WarnAboutParameters"); 492 return; 492 return; 493 } 493 } 494 494 495 std::array<G4HnDimension, DIM> bins; 495 std::array<G4HnDimension, DIM> bins; 496 std::array<G4HnDimensionInformation, DIM> in 496 std::array<G4HnDimensionInformation, DIM> info; 497 497 498 if ( command == fCreateCmd.get() ) { 498 if ( command == fCreateCmd.get() ) { 499 auto counter = 0; 499 auto counter = 0; 500 const auto& name = parameters[counter++]; << 500 auto name = parameters[counter++]; 501 const auto& title = parameters[counter++]; << 501 auto title = parameters[counter++]; 502 GetData(counter, parameters, bins, info); 502 GetData(counter, parameters, bins, info); 503 fManager->Create(name, title, bins, info); 503 fManager->Create(name, title, bins, info); 504 return; 504 return; 505 } 505 } 506 506 507 if ( command == fSetCmd.get() ) { 507 if ( command == fSetCmd.get() ) { 508 auto counter = 0; 508 auto counter = 0; 509 const auto& id = G4UIcommand::ConvertToInt << 509 auto id = G4UIcommand::ConvertToInt(parameters[counter++]); 510 GetData(counter, parameters, bins, info); 510 GetData(counter, parameters, bins, info); 511 fManager->Set(id, bins, info); 511 fManager->Set(id, bins, info); 512 return; 512 return; 513 } 513 } 514 514 515 if ( command == fDeleteCmd.get() ) { 515 if ( command == fDeleteCmd.get() ) { 516 auto counter = 0; 516 auto counter = 0; 517 const auto& id = G4UIcommand::ConvertToInt << 517 auto id = G4UIcommand::ConvertToInt(parameters[counter++]); 518 const auto& keepSetting = G4UIcommand::Con << 518 auto keepSetting = G4UIcommand::ConvertToBool(parameters[counter++]); 519 fManager->Delete(id, keepSetting); 519 fManager->Delete(id, keepSetting); 520 return; 520 return; 521 } 521 } 522 522 523 if ( command == fSetTitleCmd.get() ) { 523 if ( command == fSetTitleCmd.get() ) { 524 auto counter = 0; 524 auto counter = 0; 525 const auto& id = G4UIcommand::ConvertToInt << 525 auto id = G4UIcommand::ConvertToInt(parameters[counter++]); 526 const auto& title = parameters[counter++]; << 526 auto title = parameters[counter++]; 527 fManager->SetTitle(id, title); 527 fManager->SetTitle(id, title); 528 return; 528 return; 529 } 529 } 530 530 531 for (unsigned int idim = 0; idim < DIM; ++id 531 for (unsigned int idim = 0; idim < DIM; ++idim) { 532 if ( command == fSetDimensionCmd[idim].get 532 if ( command == fSetDimensionCmd[idim].get() ) { 533 auto counter = 0; 533 auto counter = 0; 534 fTmpId[idim] = G4UIcommand::ConvertToInt 534 fTmpId[idim] = G4UIcommand::ConvertToInt(parameters[counter++]); 535 GetBinInfoData(idim, counter, parameters 535 GetBinInfoData(idim, counter, parameters, fTmpBins[idim], fTmpInfo[idim]); 536 536 537 if ( DIM > 1 && idim > 0) { 537 if ( DIM > 1 && idim > 0) { 538 // the setX, setY, setZ must be apply 538 // the setX, setY, setZ must be apply consequently 539 if (fTmpId[idim - 1] != fTmpId[idim]) 539 if (fTmpId[idim - 1] != fTmpId[idim]) { 540 G4Analysis::Warn( 540 G4Analysis::Warn( 541 "Command setX, setY, setZ must be 541 "Command setX, setY, setZ must be called successively in this order.\n" 542 "Command was ignored.", fkClass, " 542 "Command was ignored.", fkClass, "SetNewValue"); 543 return; 543 return; 544 } 544 } 545 } 545 } 546 if ( idim == DIM - 1) { 546 if ( idim == DIM - 1) { 547 // Apply parameters when all dimension 547 // Apply parameters when all dimensions are set 548 fManager->Set(fTmpId[idim], fTmpBins, 548 fManager->Set(fTmpId[idim], fTmpBins, fTmpInfo); 549 return; 549 return; 550 } 550 } 551 } 551 } 552 } 552 } 553 553 554 if ( command == fSetTitleCmd.get() ) { 554 if ( command == fSetTitleCmd.get() ) { 555 auto counter = 0; 555 auto counter = 0; 556 const auto& id = G4UIcommand::ConvertToInt << 556 auto id = G4UIcommand::ConvertToInt(parameters[counter++]); 557 const auto& title = parameters[counter++]; << 557 auto title = parameters[counter++]; 558 fManager->SetTitle(id, title); 558 fManager->SetTitle(id, title); 559 return; 559 return; 560 } 560 } 561 561 562 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kM 562 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kMaxDim; 563 for (unsigned int idim = 0; idim < maxDim; + 563 for (unsigned int idim = 0; idim < maxDim; ++idim) { 564 if ( command == fSetAxisCmd[idim].get() ) 564 if ( command == fSetAxisCmd[idim].get() ) { 565 auto counter = 0; 565 auto counter = 0; 566 const auto& id = G4UIcommand::ConvertToI << 566 auto id = G4UIcommand::ConvertToInt(parameters[counter++]); 567 const auto& axisTitle = parameters[count << 567 auto axisTitle = parameters[counter++]; 568 fManager->SetAxisTitle(idim, id, axisTit 568 fManager->SetAxisTitle(idim, id, axisTitle); 569 return; 569 return; 570 } 570 } 571 } 571 } 572 572 573 if ( command == fListCmd.get() ) { 573 if ( command == fListCmd.get() ) { 574 auto onlyIfActive = G4UIcommand::ConvertTo 574 auto onlyIfActive = G4UIcommand::ConvertToBool(parameters[0]); 575 fManager->List(G4cout, onlyIfActive); 575 fManager->List(G4cout, onlyIfActive); 576 return; 576 return; 577 } 577 } 578 578 579 if ( command == fGetTCmd.get() ) { 579 if ( command == fGetTCmd.get() ) { 580 const auto& id = G4UIcommand::ConvertToInt << 580 auto id = G4UIcommand::ConvertToInt(newValues); 581 fTValue = GetTAddress(id); 581 fTValue = GetTAddress(id); 582 return; 582 return; 583 } 583 } 584 584 585 if ( command == fGetTVectorCmd.get() ) { 585 if ( command == fGetTVectorCmd.get() ) { 586 fTVectorValue = GetTVectorAddress(); 586 fTVectorValue = GetTVectorAddress(); 587 return; 587 return; 588 } 588 } 589 } 589 } 590 590