Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:11

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 
0027 // Author: Ivana Hrivnacova, 26/08/2022  (ivana@ipno.in2p3.fr)
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   // Initialize data
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 // private functions
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 // Create [nbins], valMin, valMax, valUnit, valFcn, [valBinScheme] parameters.
0113 // The parameters in [] are omitted for the last dimension for profiles  
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   // add parameter
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       // the first three parameters can be omittes in create command
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   // Add Id parameter
0265   AddIdParameter(*fSetCmd);
0266 
0267   // Update guidance
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   // Add Id parameter
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   // Add Id parameter
0311   AddIdParameter(*command);
0312 
0313   // Update guidance
0314   G4String guidance =
0315     "\n  nAXISbins; AXISvalMin; AXISvalMax; AXISunit; AXISfunction; AXISbinScheme";
0316   // update AXIS with xyz
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   // Add Id parameter
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   // Add Id parameter
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   // Add Id parameter
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   // get bin data (this will shift the counter for hnInfo data)
0432   GetBinData(idim, counter, parameters, bins);
0433 
0434   // get dimension information data
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   // apply unit to minValue and maxValue
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     // get bin data (this will shift the counter for hnInfo data)
0458     GetBinInfoData(idim, counter, parameters, bins[idim], info[idim]);
0459   }
0460 }
0461 
0462 //
0463 // public functions
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   // tokenize parameters in a vector
0482   std::vector<G4String> parameters;
0483   G4Analysis::Tokenize(newValues, parameters);
0484   // check consistency
0485   if ( parameters.size() != command->GetParameterEntries() ) {
0486     // Should never happen but let's check anyway for consistency
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         // the setX, setY, setZ must be apply consequently
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         // Apply parameters when all dimensions are set
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 }