Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/intercoms/src/G4GenericMessenger.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /intercoms/src/G4GenericMessenger.cc (Version 11.3.0) and /intercoms/src/G4GenericMessenger.cc (Version 10.7.p1)


  1 // *******************************************      1 // ********************************************************************
  2 // * License and Disclaimer                         2 // * License and Disclaimer                                           *
  3 // *                                                3 // *                                                                  *
  4 // * The  Geant4 software  is  copyright of th      4 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  5 // * the Geant4 Collaboration.  It is provided      5 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  6 // * conditions of the Geant4 Software License      6 // * conditions of the Geant4 Software License,  included in the file *
  7 // * LICENSE and available at  http://cern.ch/      7 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  8 // * include a list of copyright holders.           8 // * include a list of copyright holders.                             *
  9 // *                                                9 // *                                                                  *
 10 // * Neither the authors of this software syst     10 // * Neither the authors of this software system, nor their employing *
 11 // * institutes,nor the agencies providing fin     11 // * institutes,nor the agencies providing financial support for this *
 12 // * work  make  any representation or  warran     12 // * work  make  any representation or  warranty, express or implied, *
 13 // * regarding  this  software system or assum     13 // * regarding  this  software system or assume any liability for its *
 14 // * use.  Please see the license in the file      14 // * use.  Please see the license in the file  LICENSE  and URL above *
 15 // * for the full disclaimer and the limitatio     15 // * for the full disclaimer and the limitation of liability.         *
 16 // *                                               16 // *                                                                  *
 17 // * This  code  implementation is the result      17 // * This  code  implementation is the result of  the  scientific and *
 18 // * technical work of the GEANT4 collaboratio     18 // * technical work of the GEANT4 collaboration.                      *
 19 // * By using,  copying,  modifying or  distri     19 // * By using,  copying,  modifying or  distributing the software (or *
 20 // * any work based  on the software)  you  ag     20 // * any work based  on the software)  you  agree  to acknowledge its *
 21 // * use  in  resulting  scientific  publicati     21 // * use  in  resulting  scientific  publications,  and indicate your *
 22 // * acceptance of all terms of the Geant4 Sof     22 // * acceptance of all terms of the Geant4 Software license.          *
 23 // *******************************************     23 // ********************************************************************
 24 //                                                 24 //
 25 // G4GenericMessenger                              25 // G4GenericMessenger
 26 //                                                 26 //
 27 // Author:                                     <<  27 // Author: P.Mato, CERN - 27 September 2012
 28 //    P.Mato, CERN - 27 September 2012         << 
 29 // Updates:                                    << 
 30 //    M.Asai, SLAC - 26 November 2013          << 
 31 //      Adding methods with unit declaration a << 
 32 //      version 10.                            << 
 33 //    M.Asai, SLAC - 04 May 2014               << 
 34 //      Fix core dump when GetCurrentValue() m << 
 35 //      a command defined by DeclareMethod().  << 
 36 //    M.Asai, SLAC - 30 September 2020         << 
 37 //      Adding new parameter type 'L' for long << 
 38 //    M.Asai, SLAC - 11 July 2021              << 
 39 //      Adding G4ThreeVector type without unit << 
 40 //    M.Asai, JLab - 24 April 2024             << 
 41 //      Fix DeclareMethod() wrongly converts v << 
 42 // -------------------------------------------     28 // --------------------------------------------------------------------
 43                                                    29 
 44 #include "G4GenericMessenger.hh"                   30 #include "G4GenericMessenger.hh"
 45                                                << 
 46 #include "G4Threading.hh"                      << 
 47 #include "G4Types.hh"                              31 #include "G4Types.hh"
 48 #include "G4UIcmdWithABool.hh"                 <<  32 #include "G4UImessenger.hh"
 49 #include "G4UIcmdWith3Vector.hh"               << 
 50 #include "G4UIcmdWith3VectorAndUnit.hh"        << 
 51 #include "G4UIcmdWithADoubleAndUnit.hh"        << 
 52 #include "G4UIcommand.hh"                          33 #include "G4UIcommand.hh"
                                                   >>  34 #include "G4UIcmdWithADoubleAndUnit.hh"
                                                   >>  35 #include "G4UIcmdWith3VectorAndUnit.hh"
 53 #include "G4UIdirectory.hh"                        36 #include "G4UIdirectory.hh"
 54 #include "G4UImessenger.hh"                    <<  37 #include "G4Threading.hh"
 55 #include "G4Tokenizer.hh"                      << 
 56                                                    38 
 57 #include <iostream>                                39 #include <iostream>
 58                                                    40 
 59 class G4InvalidUICommand : public std::bad_cas     41 class G4InvalidUICommand : public std::bad_cast
 60 {                                                  42 {
 61   public:                                          43   public:
 62     G4InvalidUICommand() = default;            <<  44 
 63     const char* what() const throw() override  <<  45     G4InvalidUICommand() {}
                                                   >>  46     virtual const char* what() const throw()
 64     {                                              47     {
 65       return "G4InvalidUICommand: command does     48       return "G4InvalidUICommand: command does not exist or is of invalid type";
 66     }                                              49     }
 67 };                                                 50 };
 68                                                    51 
 69 G4GenericMessenger::G4GenericMessenger(void* o <<  52 G4GenericMessenger::G4GenericMessenger(void* obj, const G4String& dir,
 70   : directory(dir), object(obj)                <<  53                                        const G4String& doc)
 71 {                                              <<  54   : directory(dir)
                                                   >>  55   , object(obj)
                                                   >>  56 {
                                                   >>  57   // Check if parent commnand is already existing.
                                                   >>  58   // In fact there is no way to check this. UImanager->GetTree()->FindPath()
                                                   >>  59   // will always rerurn NULL is a dicrectory is given
                                                   >>  60   std::size_t pos = dir.find_last_of('/', dir.size() - 2);
                                                   >>  61   while(pos != 0 && pos != std::string::npos)
                                                   >>  62   {
                                                   >>  63     G4UIdirectory* d  = new G4UIdirectory(dir.substr(0, pos + 1).c_str());
                                                   >>  64     G4String guidance = "Commands for ";
                                                   >>  65     guidance += dir.substr(1, pos - 1);
                                                   >>  66     d->SetGuidance(guidance);
                                                   >>  67     pos = dir.find_last_of('/', pos - 1);
                                                   >>  68   }
 72   dircmd = new G4UIdirectory(dir);                 69   dircmd = new G4UIdirectory(dir);
 73   dircmd->SetGuidance(doc);                        70   dircmd->SetGuidance(doc);
 74 }                                                  71 }
 75                                                    72 
 76 G4GenericMessenger::~G4GenericMessenger()          73 G4GenericMessenger::~G4GenericMessenger()
 77 {                                                  74 {
 78   delete dircmd;                                   75   delete dircmd;
 79   for (const auto& propertie : properties) {   <<  76   for(auto i = properties.cbegin(); i != properties.cend(); ++i)
 80     delete propertie.second.command;           <<  77     delete i->second.command;
 81   }                                            <<  78   for(auto i = methods.cbegin(); i != methods.cend(); ++i)
 82   for (const auto& method : methods) {         <<  79     delete i->second.command;
 83     delete method.second.command;              << 
 84   }                                            << 
 85 }                                                  80 }
 86                                                    81 
 87 G4GenericMessenger::Command&                   <<  82 G4GenericMessenger::Command& G4GenericMessenger::DeclareProperty(
 88 G4GenericMessenger::DeclareProperty(const G4St <<  83   const G4String& name, const G4AnyType& var, const G4String& doc)
 89 {                                                  84 {
 90   G4String fullpath = directory + name;            85   G4String fullpath = directory + name;
 91   G4UIcommand* cmd = nullptr;                  <<  86   G4UIcommand* cmd  = new G4UIcommand(fullpath.c_str(), this);
 92   if (var.TypeInfo() == typeid(G4ThreeVector)) <<  87   if(doc != "")
 93     cmd = new G4UIcmdWith3Vector(fullpath.c_st << 
 94     (static_cast<G4UIcmdWith3Vector*>(cmd))    << 
 95       ->SetParameterName("valueX", "valueY", " << 
 96   }                                            << 
 97   else {                                       << 
 98     cmd = new G4UIcommand(fullpath.c_str(), th << 
 99     char ptype;                                << 
100     if (var.TypeInfo() == typeid(int) || var.T << 
101         || var.TypeInfo() == typeid(unsigned i << 
102     {                                          << 
103       ptype = 'i';                             << 
104     }                                          << 
105     else if (var.TypeInfo() == typeid(float) | << 
106       ptype = 'd';                             << 
107     }                                          << 
108     else if (var.TypeInfo() == typeid(bool)) { << 
109       ptype = 'b';                             << 
110     }                                          << 
111     else if (var.TypeInfo() == typeid(G4String << 
112       ptype = 's';                             << 
113     }                                          << 
114     else {                                     << 
115       ptype = 's';                             << 
116     }                                          << 
117     cmd->SetParameter(new G4UIparameter("value << 
118   }                                            << 
119   if (!doc.empty()) {                          << 
120     cmd->SetGuidance(doc);                         88     cmd->SetGuidance(doc);
121   }                                            <<  89   char ptype;
                                                   >>  90   if(var.TypeInfo() == typeid(int) || var.TypeInfo() == typeid(long) ||
                                                   >>  91      var.TypeInfo() == typeid(unsigned int) ||
                                                   >>  92      var.TypeInfo() == typeid(unsigned long))
                                                   >>  93     ptype = 'i';
                                                   >>  94   else if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double))
                                                   >>  95     ptype = 'd';
                                                   >>  96   else if(var.TypeInfo() == typeid(bool))
                                                   >>  97     ptype = 'b';
                                                   >>  98   else if(var.TypeInfo() == typeid(G4String))
                                                   >>  99     ptype = 's';
                                                   >> 100   else
                                                   >> 101     ptype = 's';
                                                   >> 102   cmd->SetParameter(new G4UIparameter("value", ptype, false));
122   return properties[name] = Property(var, cmd)    103   return properties[name] = Property(var, cmd);
123 }                                                 104 }
124                                                   105 
125 G4GenericMessenger::Command&                   << 106 G4GenericMessenger::Command& G4GenericMessenger::DeclarePropertyWithUnit(
126 G4GenericMessenger::DeclarePropertyWithUnit(co << 107   const G4String& name, const G4String& defaultUnit, const G4AnyType& var,
127                                             co << 108   const G4String& doc)
128 {                                                 109 {
129   if (var.TypeInfo() != typeid(float) && var.T << 110   if(var.TypeInfo() != typeid(float) && var.TypeInfo() != typeid(double) &&
130       && var.TypeInfo() != typeid(G4ThreeVecto << 111      var.TypeInfo() != typeid(G4ThreeVector))
131   {                                               112   {
132     return DeclareProperty(name, var, doc);       113     return DeclareProperty(name, var, doc);
133   }                                               114   }
134   G4String fullpath = directory + name;           115   G4String fullpath = directory + name;
135   G4UIcommand* cmd;                               116   G4UIcommand* cmd;
136   if (var.TypeInfo() == typeid(float) || var.T << 117   if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double))
                                                   >> 118   {
137     cmd = new G4UIcmdWithADoubleAndUnit(fullpa    119     cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
138     (static_cast<G4UIcmdWithADoubleAndUnit*>(c << 120     (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))
                                                   >> 121       ->SetParameterName("value", false, false);
139     (static_cast<G4UIcmdWithADoubleAndUnit*>(c    122     (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
140   }                                               123   }
141   else {                                       << 124   else
                                                   >> 125   {
142     cmd = new G4UIcmdWith3VectorAndUnit(fullpa    126     cmd = new G4UIcmdWith3VectorAndUnit(fullpath.c_str(), this);
143     (static_cast<G4UIcmdWith3VectorAndUnit*>(c    127     (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))
144       ->SetParameterName("valueX", "valueY", "    128       ->SetParameterName("valueX", "valueY", "valueZ", false, false);
145     (static_cast<G4UIcmdWith3VectorAndUnit*>(c    129     (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
146   }                                               130   }
147                                                   131 
148   if (!doc.empty()) {                          << 132   if(doc != "")
149     cmd->SetGuidance(doc);                        133     cmd->SetGuidance(doc);
150   }                                            << 
151   return properties[name] = Property(var, cmd)    134   return properties[name] = Property(var, cmd);
152 }                                                 135 }
153                                                   136 
154 G4GenericMessenger::Command&                   << 137 G4GenericMessenger::Command& G4GenericMessenger::DeclareMethod(
155 G4GenericMessenger::DeclareMethod(const G4Stri << 138   const G4String& name, const G4AnyMethod& fun, const G4String& doc)
156 {                                                 139 {
157   G4String fullpath = directory + name;           140   G4String fullpath = directory + name;
158   auto* cmd = new G4UIcommand(fullpath.c_str() << 141   G4UIcommand* cmd  = new G4UIcommand(fullpath.c_str(), this);
159   if (!doc.empty()) {                          << 142   if(doc != "")
160     cmd->SetGuidance(doc);                        143     cmd->SetGuidance(doc);
161   }                                            << 144   for(std::size_t i = 0; i < fun.NArg(); ++i)
162   for (std::size_t i = 0; i < fun.NArg(); ++i) << 145   {
163     G4String argNam = "arg" + ItoS((G4int)i);  << 146     cmd->SetParameter(new G4UIparameter("arg", 's', false));
164     char ptype = 's';                          << 
165     auto& tInfo = fun.ArgType(i);              << 
166     if (tInfo == typeid(int) || tInfo == typei << 
167         || tInfo == typeid(unsigned long))     << 
168     {                                          << 
169       ptype = 'i';                             << 
170     }                                          << 
171     else if (tInfo == typeid(float) || tInfo = << 
172       ptype = 'd';                             << 
173     }                                          << 
174     else if (tInfo == typeid(bool)) {          << 
175       ptype = 'b';                             << 
176     }                                          << 
177     else if (tInfo == typeid(G4String)) {      << 
178       ptype = 's';                             << 
179     }                                          << 
180     else {                                     << 
181       ptype = 's';                             << 
182     }                                          << 
183     cmd->SetParameter(new G4UIparameter(argNam << 
184   }                                               147   }
185   return methods[name] = Method(fun, object, c    148   return methods[name] = Method(fun, object, cmd);
186 }                                                 149 }
187                                                   150 
188 G4GenericMessenger::Command& G4GenericMessenge << 151 G4GenericMessenger::Command& G4GenericMessenger::DeclareMethodWithUnit(
189                                                << 152   const G4String& name, const G4String& defaultUnit, const G4AnyMethod& fun,
190                                                << 153   const G4String& doc)
191                                                << 
192 {                                                 154 {
193   G4String fullpath = directory + name;           155   G4String fullpath = directory + name;
194   if (fun.NArg() != 1) {                       << 156   if(fun.NArg() != 1)
                                                   >> 157   {
195     G4ExceptionDescription ed;                    158     G4ExceptionDescription ed;
196     ed << "G4GenericMessenger::DeclareMethodWi    159     ed << "G4GenericMessenger::DeclareMethodWithUnit() does not support a "
197           "method that has more than\n"           160           "method that has more than\n"
198        << "one arguments (or no argument). Ple    161        << "one arguments (or no argument). Please use "
199           "G4GenericMessenger::DeclareMethod m    162           "G4GenericMessenger::DeclareMethod method for\n"
200        << "your command <" << fullpath << ">."    163        << "your command <" << fullpath << ">.";
201     G4Exception("G4GenericMessenger::DeclareMe << 164     G4Exception("G4GenericMessenger::DeclareMethodWithUnit()", "Intercom70002",
                                                   >> 165                 FatalException, ed);
202   }                                               166   }
203   G4UIcommand* cmd = new G4UIcmdWithADoubleAnd    167   G4UIcommand* cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
204   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd << 168   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))
                                                   >> 169     ->SetParameterName("value", false, false);
205   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd    170   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
206   if (!doc.empty()) {                          << 171   if(doc != "")
207     cmd->SetGuidance(doc);                        172     cmd->SetGuidance(doc);
208   }                                            << 
209   return methods[name] = Method(fun, object, c    173   return methods[name] = Method(fun, object, cmd);
210 }                                                 174 }
211                                                   175 
212 G4String G4GenericMessenger::GetCurrentValue(G    176 G4String G4GenericMessenger::GetCurrentValue(G4UIcommand* command)
213 {                                                 177 {
214   if (properties.find(command->GetCommandName( << 178   if(properties.find(command->GetCommandName()) != properties.cend())
                                                   >> 179   {
215     Property& p = properties[command->GetComma    180     Property& p = properties[command->GetCommandName()];
216     return p.variable.ToString();                 181     return p.variable.ToString();
217   }                                               182   }
218   if (methods.find(command->GetCommandName())  << 183   else if(methods.find(command->GetCommandName()) != methods.cend())
                                                   >> 184   {
219     G4cout << " GetCurrentValue() is not avail    185     G4cout << " GetCurrentValue() is not available for a command defined by "
220               "G4GenericMessenger::DeclareMeth    186               "G4GenericMessenger::DeclareMethod()."
221            << G4endl;                             187            << G4endl;
222     return G4String();                            188     return G4String();
223   }                                               189   }
224                                                << 190   else
225   throw G4InvalidUICommand();                  << 191   {
                                                   >> 192     throw G4InvalidUICommand();
                                                   >> 193   }
226 }                                                 194 }
227                                                   195 
228 void G4GenericMessenger::SetNewValue(G4UIcomma    196 void G4GenericMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
229 {                                                 197 {
230   // Check if there are units on this commands    198   // Check if there are units on this commands
231   if (typeid(*command) == typeid(G4UIcmdWithAD << 199   if(typeid(*command) == typeid(G4UIcmdWithADoubleAndUnit))
232     newValue = G4UIcommand::ConvertToString(G4 << 200   {
233   }                                            << 201     newValue = G4UIcommand::ConvertToString(
234   else if (typeid(*command) == typeid(G4UIcmdW << 202       G4UIcommand::ConvertToDimensionedDouble(newValue));
235     newValue = G4UIcommand::ConvertToString(G4 << 
236   }                                               203   }
237   else if (typeid(*command) == typeid(G4UIcmdW << 204   else if(typeid(*command) == typeid(G4UIcmdWith3VectorAndUnit))
238     if(StoB(newValue)) {                       << 205   {
239       newValue = "1";                          << 206     newValue = G4UIcommand::ConvertToString(
240     } else {                                   << 207       G4UIcommand::ConvertToDimensioned3Vector(newValue));
241       newValue = "0";                          << 
242     }                                          << 
243   }                                               208   }
244                                                   209 
245   if (properties.find(command->GetCommandName( << 210   if(properties.find(command->GetCommandName()) != properties.cend())
                                                   >> 211   {
246     Property& p = properties[command->GetComma    212     Property& p = properties[command->GetCommandName()];
247     p.variable.FromString(newValue);              213     p.variable.FromString(newValue);
248   }                                               214   }
249   else if (methods.find(command->GetCommandNam << 215   else if(methods.find(command->GetCommandName()) != methods.cend())
                                                   >> 216   {
250     Method& m = methods[command->GetCommandNam    217     Method& m = methods[command->GetCommandName()];
251     if (m.method.NArg() == 0) {                << 218     if(m.method.NArg() == 0)
252       m.method.operator()(m.object);              219       m.method.operator()(m.object);
                                                   >> 220     else if(m.method.NArg() > 0)
                                                   >> 221     {
                                                   >> 222       m.method.operator()(m.object, newValue);
253     }                                             223     }
254     else if (m.method.NArg() > 0) {            << 224     else
255       G4Tokenizer tokens(newValue);            << 225     {
256       G4String paraValue;                      << 
257       for (std::size_t i = 0; i < m.method.NAr << 
258         G4String aToken = tokens();            << 
259         if(m.method.ArgType(i)==typeid(bool))  << 
260           if(StoB(aToken)) {                   << 
261             aToken = "1";                      << 
262           } else {                             << 
263             aToken = "0";                      << 
264           }                                    << 
265         }                                      << 
266         paraValue += aToken + " ";             << 
267       }                                        << 
268       m.method.operator()(m.object, paraValue) << 
269     }                                          << 
270     else {                                     << 
271       throw G4InvalidUICommand();                 226       throw G4InvalidUICommand();
272     }                                             227     }
273   }                                               228   }
274 }                                                 229 }
275                                                   230 
276 void G4GenericMessenger::SetGuidance(const G4S    231 void G4GenericMessenger::SetGuidance(const G4String& s)
277 {                                                 232 {
278   dircmd->SetGuidance(s);                         233   dircmd->SetGuidance(s);
279 }                                                 234 }
280                                                   235 
281 G4GenericMessenger::Command& G4GenericMessenge << 236 G4GenericMessenger::Command& G4GenericMessenger::Command::SetUnit(
282                                                << 237   const G4String& unit, UnitSpec spec)
283 {                                                 238 {
284   // Change the type of command (unfortunatell    239   // Change the type of command (unfortunatelly this is done a posteriory)
285   // We need to delete the old command before     240   // We need to delete the old command before creating the new one and therefore
286   // we need to recover the information before    241   // we need to recover the information before the deletetion
287   if (G4Threading::IsMultithreadedApplication( << 242   if(G4Threading::IsMultithreadedApplication())
                                                   >> 243   {
288     G4String cmdpath = command->GetCommandPath    244     G4String cmdpath = command->GetCommandPath();
289     G4ExceptionDescription ed;                    245     G4ExceptionDescription ed;
290     ed << "G4GenericMessenger::Command::SetUni    246     ed << "G4GenericMessenger::Command::SetUnit() is thread-unsafe and should "
291           "not be used\n"                         247           "not be used\n"
292        << "in multi-threaded mode. For your co    248        << "in multi-threaded mode. For your command <" << cmdpath << ">, use\n"
293        << " DeclarePropertyWithUnit(const G4St    249        << " DeclarePropertyWithUnit(const G4String& name, const G4String& "
294           "defaultUnit,\n"                        250           "defaultUnit,\n"
295        << "                         const G4An    251        << "                         const G4AnyType& variable, const G4String& "
296           "doc)\n"                                252           "doc)\n"
297        << "or\n"                                  253        << "or\n"
298        << " DeclareMethodWithUnit(const G4Stri    254        << " DeclareMethodWithUnit(const G4String& name, const G4String& "
299           "defaultUnit,\n"                        255           "defaultUnit,\n"
300        << "                       const G4AnyT    256        << "                       const G4AnyType& variable, const G4String& "
301           "doc)\n"                                257           "doc)\n"
302        << "to define a command with a unit <"     258        << "to define a command with a unit <" << unit << ">.";
303     if (spec != UnitDefault) {                 << 259     if(spec != UnitDefault)
                                                   >> 260     {
304       ed << "\nPlease use a default unit inste    261       ed << "\nPlease use a default unit instead of unit category.";
305     }                                             262     }
306     G4Exception("G4GenericMessenger::Command:: << 263     G4Exception("G4GenericMessenger::Command::SetUnit()", "Intercom70001",
                                                   >> 264                 FatalException, ed);
307     return *this;                                 265     return *this;
308   }                                               266   }
309                                                   267 
310   G4String cmdpath = command->GetCommandPath() << 268   G4String cmdpath         = command->GetCommandPath();
311   G4UImessenger* messenger = command->GetMesse    269   G4UImessenger* messenger = command->GetMessenger();
312   G4String range = command->GetRange();        << 270   G4String range           = command->GetRange();
313   std::vector<G4String> guidance;                 271   std::vector<G4String> guidance;
314   G4String par_name = command->GetParameter(0) << 272   G4String par_name   = command->GetParameter(0)->GetParameterName();
315   G4bool par_omitable = command->GetParameter(    273   G4bool par_omitable = command->GetParameter(0)->IsOmittable();
316   for (G4int i = 0; i < (G4int)command->GetGui << 274   for(std::size_t i = 0; i < command->GetGuidanceEntries(); ++i)
317     guidance.push_back(command->GetGuidanceLin    275     guidance.push_back(command->GetGuidanceLine(i));
318   }                                            << 
319   // Before deleting the command we need to ad    276   // Before deleting the command we need to add a fake one to avoid deleting
320   // the directory entry and with its guidance    277   // the directory entry and with its guidance
321   G4UIcommand tmp((cmdpath + "_tmp").c_str(),     278   G4UIcommand tmp((cmdpath + "_tmp").c_str(), messenger);
322   delete command;                                 279   delete command;
323                                                   280 
324   if (*type == typeid(float) || *type == typei << 281   if(*type == typeid(float) || *type == typeid(double))
325     auto* cmd_t = new G4UIcmdWithADoubleAndUni << 282   {
326     if (spec == UnitDefault) {                 << 283     G4UIcmdWithADoubleAndUnit* cmd_t =
                                                   >> 284       new G4UIcmdWithADoubleAndUnit(cmdpath, messenger);
                                                   >> 285     if(spec == UnitDefault)
327       cmd_t->SetDefaultUnit(unit);                286       cmd_t->SetDefaultUnit(unit);
328     }                                          << 287     else if(spec == UnitCategory)
329     else if (spec == UnitCategory) {           << 
330       cmd_t->SetUnitCategory(unit);               288       cmd_t->SetUnitCategory(unit);
331     }                                          << 
332     cmd_t->SetParameterName(par_name, par_omit    289     cmd_t->SetParameterName(par_name, par_omitable);
333     command = cmd_t;                              290     command = cmd_t;
334   }                                               291   }
335   else if (*type == typeid(G4ThreeVector)) {   << 292   else if(*type == typeid(G4ThreeVector))
336     auto* cmd_t = new G4UIcmdWith3VectorAndUni << 293   {
337     if (spec == UnitDefault) {                 << 294     G4UIcmdWith3VectorAndUnit* cmd_t =
                                                   >> 295       new G4UIcmdWith3VectorAndUnit(cmdpath, messenger);
                                                   >> 296     if(spec == UnitDefault)
338       cmd_t->SetDefaultUnit(unit);                297       cmd_t->SetDefaultUnit(unit);
339     }                                          << 298     else if(spec == UnitCategory)
340     else if (spec == UnitCategory) {           << 
341       cmd_t->SetUnitCategory(unit);               299       cmd_t->SetUnitCategory(unit);
342     }                                          << 
343     command = cmd_t;                              300     command = cmd_t;
344   }                                               301   }
345   else {                                       << 302   else
                                                   >> 303   {
346     G4cerr << "Only parameters of type <double    304     G4cerr << "Only parameters of type <double> or <float> can be associated "
347               "with units"                        305               "with units"
348            << G4endl;                             306            << G4endl;
349     return *this;                                 307     return *this;
350   }                                               308   }
351   for (auto& i : guidance) {                   << 309   for(std::size_t i = 0; i < guidance.size(); ++i)
352     command->SetGuidance(i);                   << 310     command->SetGuidance(guidance[i]);
353   }                                            << 
354   command->SetRange(range);                       311   command->SetRange(range);
355   return *this;                                   312   return *this;
356 }                                                 313 }
357                                                   314 
358 G4GenericMessenger::Command& G4GenericMessenge << 315 G4GenericMessenger::Command& G4GenericMessenger::Command::SetParameterName(
359                                                << 316   const G4String& name, G4bool omittable, G4bool currentAsDefault)
360                                                << 
361 {                                                 317 {
362   return SetParameterName(0, name, omittable,  << 
363 }                                              << 
364                                                << 
365 G4GenericMessenger::Command& G4GenericMessenge << 
366                                                << 
367                                                << 
368                                                << 
369 {                                              << 
370   if (pIdx < 0 || pIdx >= (G4int)(command->Get << 
371     G4cerr << "Invalid parameter index : " <<  << 
372     return *this;                              << 
373   }                                            << 
374   G4UIparameter* theParam = command->GetParame << 
375   theParam->SetParameterName(name);            << 
376   theParam->SetOmittable(omittable);           << 
377   theParam->SetCurrentAsDefault(currentAsDefau << 
378   return *this;                                << 
379 }                                              << 
380                                                << 
381 G4GenericMessenger::Command& G4GenericMessenge << 
382                                                << 
383                                                << 
384                                                << 
385                                                << 
386 {                                              << 
387   if (*type != typeid(G4ThreeVector)) {        << 
388     G4cerr << "This SetParameterName method is << 
389            << "Method ignored." << G4endl;     << 
390     return *this;                              << 
391   }                                            << 
392   G4UIparameter* theParam = command->GetParame    318   G4UIparameter* theParam = command->GetParameter(0);
393   theParam->SetParameterName(namex);           << 319   theParam->SetParameterName(name);
394   theParam->SetOmittable(omittable);           << 
395   theParam->SetCurrentAsDefault(currentAsDefau << 
396   theParam = command->GetParameter(1);         << 
397   theParam->SetParameterName(namey);           << 
398   theParam->SetOmittable(omittable);           << 
399   theParam->SetCurrentAsDefault(currentAsDefau << 
400   theParam = command->GetParameter(2);         << 
401   theParam->SetParameterName(namez);           << 
402   theParam->SetOmittable(omittable);              320   theParam->SetOmittable(omittable);
403   theParam->SetCurrentAsDefault(currentAsDefau    321   theParam->SetCurrentAsDefault(currentAsDefault);
404   return *this;                                   322   return *this;
405 }                                                 323 }
406                                                   324 
407 G4GenericMessenger::Command& G4GenericMessenge << 325 G4GenericMessenger::Command& G4GenericMessenger::Command::SetCandidates(
                                                   >> 326   const G4String& candList)
408 {                                                 327 {
409   return SetCandidates(0, candList);           << 328   G4UIparameter* theParam = command->GetParameter(0);
410 }                                              << 
411                                                << 
412 G4GenericMessenger::Command& G4GenericMessenge << 
413                                                << 
414 {                                              << 
415   if (pIdx < 0 || pIdx >= (G4int)(command->Get << 
416     G4cerr << "Invalid parameter index : " <<  << 
417     return *this;                              << 
418   }                                            << 
419   G4UIparameter* theParam = command->GetParame << 
420   theParam->SetParameterCandidates(candList);     329   theParam->SetParameterCandidates(candList);
421   return *this;                                   330   return *this;
422 }                                                 331 }
423                                                   332 
424 G4GenericMessenger::Command& G4GenericMessenge << 333 G4GenericMessenger::Command& G4GenericMessenger::Command::SetDefaultValue(
                                                   >> 334   const G4String& defVal)
425 {                                                 335 {
426   return SetDefaultValue(0, defVal);           << 336   G4UIparameter* theParam = command->GetParameter(0);
427 }                                              << 
428                                                << 
429 G4GenericMessenger::Command& G4GenericMessenge << 
430                                                << 
431 {                                              << 
432   if (pIdx < 0 || pIdx >= (G4int)(command->Get << 
433     G4cerr << "Invalid parameter index : " <<  << 
434     return *this;                              << 
435   }                                            << 
436   G4UIparameter* theParam = command->GetParame << 
437   theParam->SetDefaultValue(defVal);              337   theParam->SetDefaultValue(defVal);
438   return *this;                                   338   return *this;
439 }                                                 339 }
440                                                   340