File indexing completed on 2025-01-18 09:59:11
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(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() + " " + 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 auto name = parameters[counter++];
0501 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 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 auto id = G4UIcommand::ConvertToInt(parameters[counter++]);
0518 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 auto id = G4UIcommand::ConvertToInt(parameters[counter++]);
0526 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 auto id = G4UIcommand::ConvertToInt(parameters[counter++]);
0557 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 auto id = G4UIcommand::ConvertToInt(parameters[counter++]);
0567 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 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 }