Warning, file /include/Geant4/G4THnMessenger.icc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "G4AnalysisUtilities.hh"
0030
0031 #include "G4UIdirectory.hh"
0032 #include "G4UIcommand.hh"
0033 #include "G4UIparameter.hh"
0034 #include "G4Tokenizer.hh"
0035
0036 #include <vector>
0037
0038 using namespace G4Analysis;
0039
0040
0041 template <unsigned int DIM, typename HT>
0042 G4THnMessenger<DIM, HT>::G4THnMessenger(G4THnToolsManager<DIM, HT>* manager)
0043 : fManager(manager)
0044 {
0045 CreateDirectory();
0046
0047 CreateCmd();
0048 SetCmd();
0049 for (unsigned int idim = 0; idim < DIM; ++idim) {
0050 fSetDimensionCmd[idim] = CreateSetBinsCommand(idim);
0051 }
0052
0053 DeleteCmd();
0054
0055 CreateSetTitleCommand();
0056
0057 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kMaxDim;
0058 for (unsigned int idim = 0; idim < maxDim; ++idim) {
0059 fSetAxisCmd[idim] = CreateSetAxisCommand(idim);
0060 }
0061
0062 CreateListCommand();
0063 CreateGetCommand();
0064 CreateGetVectorCommand();
0065
0066
0067 for (unsigned int idim = 0; idim < DIM; ++idim) {
0068 fTmpId[idim] = G4Analysis::kInvalidId;
0069 fTmpBins[idim] = G4HnDimension();
0070 fTmpInfo[idim] = G4HnDimensionInformation();
0071 }
0072 }
0073
0074
0075
0076
0077
0078
0079 template <unsigned int DIM, typename HT>
0080 G4String G4THnMessenger<DIM, HT>::GetObjectType() const
0081 {
0082 return (G4Analysis::IsProfile<HT>()) ?
0083 std::to_string(DIM - 1) + "D profile " : std::to_string(DIM) + "D histogram";
0084 }
0085
0086
0087 template <unsigned int DIM, typename HT>
0088 G4bool G4THnMessenger<DIM, HT>::IsProfileLastDimension(unsigned int idim) const
0089 {
0090 return (idim == DIM - 1) && (G4Analysis::IsProfile<HT>());
0091 }
0092
0093
0094 template <unsigned int DIM, typename HT>
0095 std::unique_ptr<G4UIcommand> G4THnMessenger<DIM, HT>::CreateCommand(
0096 G4String name, G4String guidance)
0097 {
0098 G4String fullName = "/analysis/" + G4Analysis::GetHnType<HT>() + "/" + name;
0099 G4String fullGuidance = guidance + GetObjectType();
0100
0101 auto command = std::make_unique<G4UIcommand>(fullName, this);
0102 command->SetGuidance(fullGuidance);
0103
0104 return command;
0105 }
0106
0107
0108 template <unsigned int DIM, typename HT>
0109 void G4THnMessenger<DIM, HT>::CreateDimensionParameters(
0110 unsigned int idim, std::vector<G4UIparameter*>& parameters) const
0111 {
0112
0113
0114
0115 std::string xyz{"xyz"};
0116 std::string axis = xyz.substr(idim, 1);
0117
0118 if (! IsProfileLastDimension(idim)) {
0119 auto parName = axis + "nBins";
0120 auto guidance =
0121 std::string("Number of ") + axis + "-bins (default = 100)\n"
0122 "Can be reset with /analysis/hn/set command";
0123
0124 auto param = new G4UIparameter(parName.c_str(), 'i', false);
0125 param->SetGuidance(guidance.c_str());
0126 param->SetDefaultValue(100);
0127 parameters.push_back(param);
0128 }
0129
0130 auto parName = axis + "valMin";
0131 auto guidance =
0132 std::string("Minimum ") + axis + "-value, expressed in unit (default = 0.)\n"
0133 "Can be reset with /analysis/hn/set command";
0134 auto param = new G4UIparameter(parName.c_str(), 'd', false);
0135 param->SetGuidance(guidance.c_str());
0136 param->SetDefaultValue(0.);
0137 parameters.push_back(param);
0138
0139 parName = axis + "valMax";
0140 guidance =
0141 std::string("Maximum ") + axis + "-value, expressed in unit (default = 1.)\n"
0142 "Can be reset with /analysis/hn/set command";
0143 param = new G4UIparameter(parName.c_str(), 'd', false);
0144 param->SetGuidance(guidance.c_str());
0145 param->SetDefaultValue(1.);
0146 parameters.push_back(param);
0147
0148 parName = axis + "valUnit";
0149 guidance =
0150 std::string("The unit applied to filled ") + axis + "-values and \n"
0151 "Can be reset with /analysis/hn/set command";
0152 param = new G4UIparameter(parName.c_str(), 's', true);
0153 param->SetGuidance(guidance.c_str());
0154 param->SetDefaultValue("none");
0155 parameters.push_back(param);
0156
0157 parName = axis + "valFcn";
0158 guidance =
0159 std::string("The function applied to filled ") + axis + "-values (log, log10, exp, none).\n"
0160 "Note that the unit parameter cannot be omitted in this case,\n"
0161 "but none value should be used instead.";
0162 param = new G4UIparameter(parName.c_str(), 's', true);
0163 param->SetGuidance(guidance.c_str());
0164 param->SetParameterCandidates("log log10 exp none");
0165 param->SetDefaultValue("none");
0166 parameters.push_back(param);
0167
0168 if (! IsProfileLastDimension(idim)) {
0169 parName = axis + "valBinScheme";
0170 guidance =
0171 std::string("The binning scheme (linear, log).\n"
0172 "Note that the unit and fcn parameters cannot be omitted in this case,\n"
0173 "but none value should be used instead.");
0174 param = new G4UIparameter(parName.c_str(), 's', true);
0175 param->SetGuidance(guidance.c_str());
0176 param->SetParameterCandidates("linear log");
0177 param->SetDefaultValue("linear");
0178 parameters.push_back(param);
0179 }
0180 }
0181
0182
0183 template <unsigned int DIM, typename HT>
0184 void G4THnMessenger<DIM, HT>::AddIdParameter(G4UIcommand& command)
0185 {
0186
0187 auto htId = new G4UIparameter("id", 'i', false);
0188 htId->SetGuidance("Histogram id");
0189 htId->SetParameterRange("id>=0");
0190 command.SetParameter(htId);
0191 }
0192
0193
0194 template <unsigned int DIM, typename HT>
0195 G4String G4THnMessenger<DIM, HT>::GetTAddress(G4int id) const
0196 {
0197 auto ht = fManager->GetT(id);
0198 if ( ht != nullptr ) {
0199 std::ostringstream os;
0200 os << static_cast<void*>(ht);
0201 return os.str();
0202 }
0203 return {};
0204 }
0205
0206
0207 template <unsigned int DIM, typename HT>
0208 G4String G4THnMessenger<DIM, HT>::GetTVectorAddress() const
0209 {
0210 auto htVector = fManager->GetTVector();
0211 if ( htVector != nullptr ) {
0212 std::ostringstream os;
0213 os << static_cast<void*>(htVector);
0214 return os.str();
0215 }
0216 return {};
0217 }
0218
0219
0220 template <unsigned int DIM, typename HT>
0221 void G4THnMessenger<DIM, HT>::CreateDirectory() const
0222 {
0223 G4String dirName = "/analysis/" + G4Analysis::GetHnType<HT>() + "/";
0224 G4String guidance = GetObjectType() + " control";
0225
0226 auto directory = std::make_unique<G4UIdirectory>(dirName);
0227 directory->SetGuidance(guidance.c_str());
0228 }
0229
0230
0231 template <unsigned int DIM, typename HT>
0232 void G4THnMessenger<DIM, HT>::CreateCmd()
0233 {
0234 fCreateCmd = CreateCommand("create", "Create ");
0235 fCreateCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
0236
0237 auto htName = new G4UIparameter("name", 's', false);
0238 htName->SetGuidance("Histogram name (label)");
0239 fCreateCmd->SetParameter(htName);
0240
0241 auto htTitle = new G4UIparameter("title", 's', false);
0242 htTitle->SetGuidance("Histogram title");
0243 fCreateCmd->SetParameter(htTitle);
0244
0245 std::vector<G4UIparameter*> parameters;
0246 for (unsigned int idim = 0; idim < DIM; ++idim) {
0247 CreateDimensionParameters(idim, parameters);
0248 for (size_t ipar = 0; ipar < parameters.size(); ++ipar) {
0249
0250 if (ipar < 3) parameters[ipar]->SetOmittable(true);
0251 fCreateCmd->SetParameter(parameters[ipar]);
0252 }
0253 parameters.clear();
0254 }
0255 }
0256
0257
0258 template <unsigned int DIM, typename HT>
0259 void G4THnMessenger<DIM, HT>::SetCmd()
0260 {
0261 fSetCmd = CreateCommand("set", "Set ");
0262 fSetCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
0263
0264
0265 AddIdParameter(*fSetCmd);
0266
0267
0268 fSetCmd->SetGuidance("\n nbins; valMin; valMax; unit; function; binScheme");
0269
0270 std::vector<G4UIparameter*> parameters;
0271 for (unsigned int idim = 0; idim < DIM; ++idim) {
0272 CreateDimensionParameters(idim, parameters);
0273 for (auto parameter: parameters) {
0274 fSetCmd->SetParameter(parameter);
0275 }
0276 parameters.clear();
0277 }
0278 }
0279
0280
0281 template <unsigned int DIM, typename HT>
0282 void G4THnMessenger<DIM, HT>::DeleteCmd()
0283 {
0284 fDeleteCmd = CreateCommand("delete", "Delete ");
0285 fDeleteCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
0286
0287
0288 AddIdParameter(*fDeleteCmd);
0289
0290 auto parKeepSetting = new G4UIparameter("keepSetting", 'b', true);
0291 G4String guidance =
0292 "If set true, activation, plotting, etc. options will be kept\n"
0293 "and applied when a new object with the same id is created.";
0294 parKeepSetting->SetGuidance(guidance.c_str());
0295 parKeepSetting->SetDefaultValue("false");
0296 fDeleteCmd->SetParameter(parKeepSetting);
0297 }
0298
0299
0300 template <unsigned int DIM, typename HT>
0301 std::unique_ptr<G4UIcommand>
0302 G4THnMessenger<DIM, HT>::CreateSetBinsCommand(unsigned int idim)
0303 {
0304 G4String xyz{"XYZ"};
0305 auto axis = xyz.substr(idim, 1);
0306
0307 auto command = CreateCommand("set" + axis, "Set " + axis + " parameters for the ");
0308 command->AvailableForStates(G4State_PreInit, G4State_Idle);
0309
0310
0311 AddIdParameter(*command);
0312
0313
0314 G4String guidance =
0315 "\n nAXISbins; AXISvalMin; AXISvalMax; AXISunit; AXISfunction; AXISbinScheme";
0316
0317 std::string::size_type n = 0;
0318 std::string ts{"AXIS"};
0319 while ( ( n = guidance.find(ts, n)) != std::string::npos ) {
0320 guidance.replace(n, ts.size(), axis);
0321 n += ts.size();
0322 }
0323 command->SetGuidance(guidance);
0324
0325 std::vector<G4UIparameter*> parameters;
0326 CreateDimensionParameters(idim, parameters);
0327 for (auto parameter: parameters) {
0328 command->SetParameter(parameter);
0329 }
0330
0331 return command;
0332 }
0333
0334
0335 template <unsigned int DIM, typename HT>
0336 void G4THnMessenger<DIM, HT>::CreateSetTitleCommand()
0337 {
0338 fSetTitleCmd = CreateCommand("setTitle", "Set title for the ");
0339 fSetTitleCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
0340
0341
0342 AddIdParameter(*fSetTitleCmd);
0343
0344 auto parTitle = new G4UIparameter("title", 's', true);
0345 auto guidance = GetObjectType() + " title";
0346 parTitle->SetGuidance(guidance.c_str());
0347 parTitle->SetDefaultValue("none");
0348 fSetTitleCmd->SetParameter(parTitle);
0349 }
0350
0351
0352 template <unsigned int DIM, typename HT>
0353 std::unique_ptr<G4UIcommand>
0354 G4THnMessenger<DIM, HT>::CreateSetAxisCommand(unsigned int idim)
0355 {
0356 G4String xyz{"XYZ"};
0357 auto axis = xyz.substr(idim, 1);
0358
0359 G4String commandName = "set" + axis + "axis";
0360 G4String guidance = "Set " + axis + "-axis title for the ";;
0361
0362 auto command = CreateCommand(std::move(commandName), guidance);
0363 command->AvailableForStates(G4State_PreInit, G4State_Idle);
0364
0365
0366 AddIdParameter(*command);
0367
0368 auto parAxis = new G4UIparameter("axis", 's', false);
0369 guidance = GetObjectType() + " " + std::move(axis) + "-axis title";
0370 parAxis->SetGuidance(guidance.c_str());
0371 command->SetParameter(parAxis);
0372
0373 return command;
0374 }
0375
0376
0377 template <unsigned int DIM, typename HT>
0378 void G4THnMessenger<DIM, HT>::CreateListCommand()
0379 {
0380 fListCmd = CreateCommand("list", "List all/activate ");
0381 fListCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc);
0382
0383 auto parOnlyIfActive = new G4UIparameter("onlyIfActive", 'b', true);
0384 parOnlyIfActive->SetGuidance("Option whether to list only active objects");
0385 parOnlyIfActive->SetDefaultValue("true");
0386 fListCmd->SetParameter(parOnlyIfActive);
0387 }
0388
0389
0390 template <unsigned int DIM, typename HT>
0391 void G4THnMessenger<DIM, HT>::CreateGetCommand()
0392 {
0393 fGetTCmd = CreateCommand("get", "Get the address of the ");
0394 fGetTCmd->SetGuidance( "This command is only for Geant4 internal use.");
0395 fGetTCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc);
0396
0397
0398 AddIdParameter(*fGetTCmd);
0399 }
0400
0401
0402 template <unsigned int DIM, typename HT>
0403 void G4THnMessenger<DIM, HT>::CreateGetVectorCommand()
0404 {
0405 fGetTVectorCmd = CreateCommand("getVector", "Get the address of the vector of the ");
0406 fGetTVectorCmd->SetGuidance( "This command is only for Geant4 internal use.");
0407 fGetTVectorCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc);
0408 }
0409
0410
0411 template <unsigned int DIM, typename HT>
0412 void G4THnMessenger<DIM, HT>::GetBinData(
0413 unsigned int idim, G4int& counter, const std::vector<G4String>& parameters,
0414 G4HnDimension& bins) const
0415 {
0416 G4int nbins = (! IsProfileLastDimension(idim)) ?
0417 G4UIcommand::ConvertToInt(parameters[counter++]) : 0;
0418
0419 bins = {nbins,
0420 G4UIcommand::ConvertToDouble(parameters[counter]),
0421 G4UIcommand::ConvertToDouble(parameters[counter + 1])};
0422 counter += 2;
0423 }
0424
0425
0426 template <unsigned int DIM, typename HT>
0427 void G4THnMessenger<DIM, HT>::GetBinInfoData(
0428 unsigned int idim, G4int& counter, const std::vector<G4String>& parameters,
0429 G4HnDimension& bins, G4HnDimensionInformation& info) const
0430 {
0431
0432 GetBinData(idim, counter, parameters, bins);
0433
0434
0435 if (! IsProfileLastDimension(idim)) {
0436 info = {parameters[counter], parameters[counter + 1], parameters[counter + 2]};
0437 counter += 3;
0438 }
0439 else {
0440 info = {parameters[counter], parameters[counter + 1]};
0441 counter += 2;
0442 }
0443
0444
0445 bins.fMinValue *= info.fUnit;
0446 bins.fMaxValue *= info.fUnit;
0447 }
0448
0449
0450 template <unsigned int DIM, typename HT>
0451 void G4THnMessenger<DIM, HT>::GetData(
0452 G4int& counter, const std::vector<G4String>& parameters,
0453 std::array<G4HnDimension, DIM>& bins,
0454 std::array<G4HnDimensionInformation, DIM>& info) const
0455 {
0456 for (unsigned int idim = 0; idim < DIM; ++idim) {
0457
0458 GetBinInfoData(idim, counter, parameters, bins[idim], info[idim]);
0459 }
0460 }
0461
0462
0463
0464
0465
0466
0467 template <unsigned int DIM, typename HT>
0468 G4String G4THnMessenger<DIM, HT>::GetCurrentValue (G4UIcommand* command)
0469 {
0470 if ( command == fGetTCmd.get() ) return fTValue;
0471
0472 if ( command == fGetTVectorCmd.get() ) return fTVectorValue;
0473
0474 return "";
0475 }
0476
0477
0478 template <unsigned int DIM, typename HT>
0479 void G4THnMessenger<DIM, HT>::SetNewValue(G4UIcommand* command, G4String newValues)
0480 {
0481
0482 std::vector<G4String> parameters;
0483 G4Analysis::Tokenize(newValues, parameters);
0484
0485 if ( parameters.size() != command->GetParameterEntries() ) {
0486
0487 G4Analysis::Warn(
0488 "Got wrong number of \"" + command->GetCommandName() +
0489 "\" parameters: " + to_string(parameters.size()) +
0490 " instead of " + to_string(command->GetParameterEntries()) + " expected",
0491 fkClass, "WarnAboutParameters");
0492 return;
0493 }
0494
0495 std::array<G4HnDimension, DIM> bins;
0496 std::array<G4HnDimensionInformation, DIM> info;
0497
0498 if ( command == fCreateCmd.get() ) {
0499 auto counter = 0;
0500 const auto& name = parameters[counter++];
0501 const auto& title = parameters[counter++];
0502 GetData(counter, parameters, bins, info);
0503 fManager->Create(name, title, bins, info);
0504 return;
0505 }
0506
0507 if ( command == fSetCmd.get() ) {
0508 auto counter = 0;
0509 const auto& id = G4UIcommand::ConvertToInt(parameters[counter++]);
0510 GetData(counter, parameters, bins, info);
0511 fManager->Set(id, bins, info);
0512 return;
0513 }
0514
0515 if ( command == fDeleteCmd.get() ) {
0516 auto counter = 0;
0517 const auto& id = G4UIcommand::ConvertToInt(parameters[counter++]);
0518 const auto& keepSetting = G4UIcommand::ConvertToBool(parameters[counter++]);
0519 fManager->Delete(id, keepSetting);
0520 return;
0521 }
0522
0523 if ( command == fSetTitleCmd.get() ) {
0524 auto counter = 0;
0525 const auto& id = G4UIcommand::ConvertToInt(parameters[counter++]);
0526 const auto& title = parameters[counter++];
0527 fManager->SetTitle(id, title);
0528 return;
0529 }
0530
0531 for (unsigned int idim = 0; idim < DIM; ++idim) {
0532 if ( command == fSetDimensionCmd[idim].get() ) {
0533 auto counter = 0;
0534 fTmpId[idim] = G4UIcommand::ConvertToInt(parameters[counter++]);
0535 GetBinInfoData(idim, counter, parameters, fTmpBins[idim], fTmpInfo[idim]);
0536
0537 if ( DIM > 1 && idim > 0) {
0538
0539 if (fTmpId[idim - 1] != fTmpId[idim]) {
0540 G4Analysis::Warn(
0541 "Command setX, setY, setZ must be called successively in this order.\n"
0542 "Command was ignored.", fkClass, "SetNewValue");
0543 return;
0544 }
0545 }
0546 if ( idim == DIM - 1) {
0547
0548 fManager->Set(fTmpId[idim], fTmpBins, fTmpInfo);
0549 return;
0550 }
0551 }
0552 }
0553
0554 if ( command == fSetTitleCmd.get() ) {
0555 auto counter = 0;
0556 const auto& id = G4UIcommand::ConvertToInt(parameters[counter++]);
0557 const auto& title = parameters[counter++];
0558 fManager->SetTitle(id, title);
0559 return;
0560 }
0561
0562 auto maxDim = (DIM < kMaxDim) ? DIM + 1 : kMaxDim;
0563 for (unsigned int idim = 0; idim < maxDim; ++idim) {
0564 if ( command == fSetAxisCmd[idim].get() ) {
0565 auto counter = 0;
0566 const auto& id = G4UIcommand::ConvertToInt(parameters[counter++]);
0567 const auto& axisTitle = parameters[counter++];
0568 fManager->SetAxisTitle(idim, id, axisTitle);
0569 return;
0570 }
0571 }
0572
0573 if ( command == fListCmd.get() ) {
0574 auto onlyIfActive = G4UIcommand::ConvertToBool(parameters[0]);
0575 fManager->List(G4cout, onlyIfActive);
0576 return;
0577 }
0578
0579 if ( command == fGetTCmd.get() ) {
0580 const auto& id = G4UIcommand::ConvertToInt(newValues);
0581 fTValue = GetTAddress(id);
0582 return;
0583 }
0584
0585 if ( command == fGetTVectorCmd.get() ) {
0586 fTVectorValue = GetTVectorAddress();
0587 return;
0588 }
0589 }