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.3.p2)


  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                          << 
 26 //                                                 25 //
 27 // Author:                                     <<  26 // $Id: G4UIaliasList.cc,v 1.6 2006-06-29 19:08:33 gunter Exp $
 28 //    P.Mato, CERN - 27 September 2012         <<  27 //
 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 // ------------------------------------------- << 
 43                                                    28 
 44 #include "G4GenericMessenger.hh"                   29 #include "G4GenericMessenger.hh"
 45                                                << 
 46 #include "G4Threading.hh"                      << 
 47 #include "G4Types.hh"                              30 #include "G4Types.hh"
 48 #include "G4UIcmdWithABool.hh"                 <<  31 #include "G4UImessenger.hh"
 49 #include "G4UIcmdWith3Vector.hh"               << 
 50 #include "G4UIcmdWith3VectorAndUnit.hh"        << 
 51 #include "G4UIcmdWithADoubleAndUnit.hh"        << 
 52 #include "G4UIcommand.hh"                          32 #include "G4UIcommand.hh"
                                                   >>  33 #include "G4UIcmdWithADoubleAndUnit.hh"
                                                   >>  34 #include "G4UIcmdWith3VectorAndUnit.hh"
 53 #include "G4UIdirectory.hh"                        35 #include "G4UIdirectory.hh"
 54 #include "G4UImessenger.hh"                    <<  36 #include "G4Threading.hh"
 55 #include "G4Tokenizer.hh"                      << 
 56                                                    37 
 57 #include <iostream>                                38 #include <iostream>
 58                                                    39 
 59 class G4InvalidUICommand : public std::bad_cas <<  40 class G4InvalidUICommand: public std::bad_cast {
 60 {                                              <<  41 public:
 61   public:                                      <<  42   G4InvalidUICommand() {}
 62     G4InvalidUICommand() = default;            <<  43   virtual const char* what() const throw() {
 63     const char* what() const throw() override  <<  44     return "G4InvalidUICommand: command does not exists or is of invalid type";
 64     {                                          <<  45   }
 65       return "G4InvalidUICommand: command does << 
 66     }                                          << 
 67 };                                                 46 };
 68                                                    47 
 69 G4GenericMessenger::G4GenericMessenger(void* o <<  48 
 70   : directory(dir), object(obj)                <<  49 G4GenericMessenger::G4GenericMessenger(void* obj, const G4String& dir, const G4String& doc): directory(dir), object(obj) {
 71 {                                              <<  50   // Check if parent commnand is already existing.
                                                   >>  51   // In fact there is no way to check this. UImanager->GetTree()->FindPath() will always rerurn NULL is a dicrectory is given
                                                   >>  52   size_t pos = dir.find_last_of('/', dir.size()-2);
                                                   >>  53   while(pos != 0 && pos != std::string::npos) {
                                                   >>  54     G4UIdirectory* d = new G4UIdirectory(dir.substr(0,pos+1).c_str());
                                                   >>  55     G4String guidance = "Commands for ";
                                                   >>  56     guidance += dir.substr(1,pos-1);
                                                   >>  57     d->SetGuidance(guidance);
                                                   >>  58     pos = dir.find_last_of('/', pos-1);
                                                   >>  59   }
 72   dircmd = new G4UIdirectory(dir);                 60   dircmd = new G4UIdirectory(dir);
 73   dircmd->SetGuidance(doc);                        61   dircmd->SetGuidance(doc);
 74 }                                                  62 }
 75                                                    63 
 76 G4GenericMessenger::~G4GenericMessenger()      <<  64 G4GenericMessenger::~G4GenericMessenger() {
 77 {                                              << 
 78   delete dircmd;                                   65   delete dircmd;
 79   for (const auto& propertie : properties) {   <<  66   for (std::map<G4String, Property>::iterator i = properties.begin(); i != properties.end(); i++) delete i->second.command;
 80     delete propertie.second.command;           <<  67   for (std::map<G4String, Method>::iterator i = methods.begin(); i != methods.end(); i++) delete i->second.command;
 81   }                                            << 
 82   for (const auto& method : methods) {         << 
 83     delete method.second.command;              << 
 84   }                                            << 
 85 }                                                  68 }
 86                                                    69 
                                                   >>  70 
 87 G4GenericMessenger::Command&                       71 G4GenericMessenger::Command&
 88 G4GenericMessenger::DeclareProperty(const G4St <<  72 G4GenericMessenger::DeclareProperty(const G4String& name, const G4AnyType& var, const G4String& doc) {
 89 {                                              <<  73   G4String fullpath = directory+name;
 90   G4String fullpath = directory + name;        <<  74   G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
 91   G4UIcommand* cmd = nullptr;                  <<  75   if(doc != "") cmd->SetGuidance(doc);  
 92   if (var.TypeInfo() == typeid(G4ThreeVector)) <<  76   char ptype;
 93     cmd = new G4UIcmdWith3Vector(fullpath.c_st <<  77   if(var.TypeInfo() == typeid(int) || var.TypeInfo() == typeid(long) ||
 94     (static_cast<G4UIcmdWith3Vector*>(cmd))    <<  78      var.TypeInfo() == typeid(unsigned int) || var.TypeInfo() == typeid(unsigned long)) ptype = 'i';
 95       ->SetParameterName("valueX", "valueY", " <<  79   else if(var.TypeInfo() == typeid(float) || var.TypeInfo() == typeid(double)) ptype = 'd';
 96   }                                            <<  80   else if(var.TypeInfo() == typeid(bool)) ptype = 'b';
 97   else {                                       <<  81   else if(var.TypeInfo() == typeid(G4String)) ptype = 's';
 98     cmd = new G4UIcommand(fullpath.c_str(), th <<  82   else ptype = 's';
 99     char ptype;                                <<  83   cmd->SetParameter(new G4UIparameter("value", ptype, false));
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);                     << 
121   }                                            << 
122   return properties[name] = Property(var, cmd)     84   return properties[name] = Property(var, cmd);
123 }                                                  85 }
124                                                    86 
125 G4GenericMessenger::Command&                   <<  87 
126 G4GenericMessenger::DeclarePropertyWithUnit(co <<  88 G4GenericMessenger::Command& G4GenericMessenger::DeclarePropertyWithUnit
127                                             co <<  89 (const G4String& name, const G4String& defaultUnit, const G4AnyType& var, const G4String& doc) {
128 {                                              <<  90   if(var.TypeInfo()!=typeid(float) && var.TypeInfo()!=typeid(double) && var.TypeInfo()!= typeid(G4ThreeVector))
129   if (var.TypeInfo() != typeid(float) && var.T <<  91   { return DeclareProperty(name,var,doc); }
130       && var.TypeInfo() != typeid(G4ThreeVecto <<  92   G4String fullpath = directory+name;
131   {                                            << 
132     return DeclareProperty(name, var, doc);    << 
133   }                                            << 
134   G4String fullpath = directory + name;        << 
135   G4UIcommand* cmd;                                93   G4UIcommand* cmd;
136   if (var.TypeInfo() == typeid(float) || var.T <<  94   if(var.TypeInfo()==typeid(float) || var.TypeInfo()==typeid(double))
                                                   >>  95   {
137     cmd = new G4UIcmdWithADoubleAndUnit(fullpa     96     cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
138     (static_cast<G4UIcmdWithADoubleAndUnit*>(c <<  97     (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetParameterName("value",false,false);
139     (static_cast<G4UIcmdWithADoubleAndUnit*>(c     98     (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
140   }                                                99   }
141   else {                                       << 100   else
                                                   >> 101   {
142     cmd = new G4UIcmdWith3VectorAndUnit(fullpa    102     cmd = new G4UIcmdWith3VectorAndUnit(fullpath.c_str(), this);
143     (static_cast<G4UIcmdWith3VectorAndUnit*>(c << 103     (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetParameterName("valueX","valueY","valueZ",false,false);
144       ->SetParameterName("valueX", "valueY", " << 
145     (static_cast<G4UIcmdWith3VectorAndUnit*>(c    104     (static_cast<G4UIcmdWith3VectorAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
146   }                                               105   }
147                                                   106 
148   if (!doc.empty()) {                          << 107   if(doc != "") cmd->SetGuidance(doc);
149     cmd->SetGuidance(doc);                     << 
150   }                                            << 
151   return properties[name] = Property(var, cmd)    108   return properties[name] = Property(var, cmd);
152 }                                                 109 }
153                                                   110 
                                                   >> 111 
154 G4GenericMessenger::Command&                      112 G4GenericMessenger::Command&
155 G4GenericMessenger::DeclareMethod(const G4Stri << 113 G4GenericMessenger::DeclareMethod(const G4String& name, const G4AnyMethod& fun, const G4String& doc) {
156 {                                              << 114   G4String fullpath = directory+name;
157   G4String fullpath = directory + name;        << 115   G4UIcommand* cmd = new G4UIcommand(fullpath.c_str(), this);
158   auto* cmd = new G4UIcommand(fullpath.c_str() << 116   if(doc != "") cmd->SetGuidance(doc);
159   if (!doc.empty()) {                          << 117   for (size_t i = 0; i < fun.NArg(); i++) {
160     cmd->SetGuidance(doc);                     << 118     cmd->SetParameter(new G4UIparameter("arg", 's', false));
161   }                                            << 
162   for (std::size_t i = 0; i < fun.NArg(); ++i) << 
163     G4String argNam = "arg" + ItoS((G4int)i);  << 
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   }                                               119   }
185   return methods[name] = Method(fun, object, c    120   return methods[name] = Method(fun, object, cmd);
186 }                                                 121 }
187                                                   122 
188 G4GenericMessenger::Command& G4GenericMessenge << 123 G4GenericMessenger::Command& G4GenericMessenger::DeclareMethodWithUnit
189                                                << 124  (const G4String& name, const G4String& defaultUnit, const G4AnyMethod& fun, const G4String& doc) {
190                                                << 125   G4String fullpath = directory+name;
191                                                << 126   if(fun.NArg()!=1) {
192 {                                              << 
193   G4String fullpath = directory + name;        << 
194   if (fun.NArg() != 1) {                       << 
195     G4ExceptionDescription ed;                    127     G4ExceptionDescription ed;
196     ed << "G4GenericMessenger::DeclareMethodWi << 128     ed<<"G4GenericMessenger::DeclareMethodWithUnit() does not support a method that has more than\n"
197           "method that has more than\n"        << 129       <<"one arguments (or no argument). Please use G4GenericMessenger::DeclareMethod method for\n"
198        << "one arguments (or no argument). Ple << 130       <<"your command <"<<fullpath<<">.";
199           "G4GenericMessenger::DeclareMethod m << 131     G4Exception("G4GenericMessenger::DeclareMethodWithUnit()","Intercom70002",FatalException,ed);
200        << "your command <" << fullpath << ">." << 
201     G4Exception("G4GenericMessenger::DeclareMe << 
202   }                                               132   }
203   G4UIcommand* cmd = new G4UIcmdWithADoubleAnd    133   G4UIcommand* cmd = new G4UIcmdWithADoubleAndUnit(fullpath.c_str(), this);
204   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd << 134   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetParameterName("value",false,false);
205   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd    135   (static_cast<G4UIcmdWithADoubleAndUnit*>(cmd))->SetDefaultUnit(defaultUnit);
206   if (!doc.empty()) {                          << 136   if(doc != "") cmd->SetGuidance(doc);
207     cmd->SetGuidance(doc);                     << 
208   }                                            << 
209   return methods[name] = Method(fun, object, c    137   return methods[name] = Method(fun, object, cmd);
210 }                                                 138 }
211                                                   139 
212 G4String G4GenericMessenger::GetCurrentValue(G << 140   
213 {                                              << 141 G4String G4GenericMessenger::GetCurrentValue(G4UIcommand* command) {
214   if (properties.find(command->GetCommandName( << 142   if ( properties.find(command->GetCommandName()) != properties.end()) {
215     Property& p = properties[command->GetComma    143     Property& p = properties[command->GetCommandName()];
216     return p.variable.ToString();                 144     return p.variable.ToString();
217   }                                               145   }
218   if (methods.find(command->GetCommandName())  << 146   else if ( methods.find(command->GetCommandName()) != methods.end()) {
219     G4cout << " GetCurrentValue() is not avail << 147     G4cout<<" GetCurrentValue() is not available for a command defined by G4GenericMessenger::DeclareMethod()."<<G4endl;
220               "G4GenericMessenger::DeclareMeth << 
221            << G4endl;                          << 
222     return G4String();                            148     return G4String();
223   }                                               149   }
224                                                << 150   else {
225   throw G4InvalidUICommand();                  << 151     throw G4InvalidUICommand();
                                                   >> 152   }
226 }                                                 153 }
227                                                   154 
228 void G4GenericMessenger::SetNewValue(G4UIcomma << 155 void G4GenericMessenger::SetNewValue(G4UIcommand* command, G4String newValue) {
229 {                                              << 
230   // Check if there are units on this commands    156   // Check if there are units on this commands
231   if (typeid(*command) == typeid(G4UIcmdWithAD    157   if (typeid(*command) == typeid(G4UIcmdWithADoubleAndUnit)) {
232     newValue = G4UIcommand::ConvertToString(G4    158     newValue = G4UIcommand::ConvertToString(G4UIcommand::ConvertToDimensionedDouble(newValue));
233   }                                               159   }
234   else if (typeid(*command) == typeid(G4UIcmdW    160   else if (typeid(*command) == typeid(G4UIcmdWith3VectorAndUnit)) {
235     newValue = G4UIcommand::ConvertToString(G4    161     newValue = G4UIcommand::ConvertToString(G4UIcommand::ConvertToDimensioned3Vector(newValue));
236   }                                               162   }
237   else if (typeid(*command) == typeid(G4UIcmdW << 163   
238     if(StoB(newValue)) {                       << 164   if ( properties.find(command->GetCommandName()) != properties.end()) {
239       newValue = "1";                          << 
240     } else {                                   << 
241       newValue = "0";                          << 
242     }                                          << 
243   }                                            << 
244                                                << 
245   if (properties.find(command->GetCommandName( << 
246     Property& p = properties[command->GetComma    165     Property& p = properties[command->GetCommandName()];
247     p.variable.FromString(newValue);              166     p.variable.FromString(newValue);
248   }                                               167   }
249   else if (methods.find(command->GetCommandNam << 168   else if (methods.find(command->GetCommandName()) != methods.end()) {
250     Method& m = methods[command->GetCommandNam    169     Method& m = methods[command->GetCommandName()];
251     if (m.method.NArg() == 0) {                << 170     if(m.method.NArg() == 0)
252       m.method.operator()(m.object);              171       m.method.operator()(m.object);
253     }                                          << 
254     else if (m.method.NArg() > 0) {               172     else if (m.method.NArg() > 0) {
255       G4Tokenizer tokens(newValue);            << 173       m.method.operator()(m.object,newValue);
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     }                                             174     }
270     else {                                        175     else {
271       throw G4InvalidUICommand();                 176       throw G4InvalidUICommand();
272     }                                             177     }
273   }                                               178   }
274 }                                                 179 }
275                                                   180 
276 void G4GenericMessenger::SetGuidance(const G4S << 181 
277 {                                              << 182 void G4GenericMessenger::SetGuidance(const G4String& s) {
278   dircmd->SetGuidance(s);                         183   dircmd->SetGuidance(s);
279 }                                                 184 }
280                                                   185 
281 G4GenericMessenger::Command& G4GenericMessenge << 186 G4GenericMessenger::Command& G4GenericMessenger::Command::SetUnit(const G4String& unit, UnitSpec spec) {
282                                                << 
283 {                                              << 
284   // Change the type of command (unfortunatell    187   // Change the type of command (unfortunatelly this is done a posteriory)
285   // We need to delete the old command before  << 188   // We need to delete the old command before creating the new one and therefore we need to recover the information
286   // we need to recover the information before << 189   // before the deletetion
287   if (G4Threading::IsMultithreadedApplication( << 190   if ( G4Threading::IsMultithreadedApplication() ) {
288     G4String cmdpath = command->GetCommandPath    191     G4String cmdpath = command->GetCommandPath();
289     G4ExceptionDescription ed;                    192     G4ExceptionDescription ed;
290     ed << "G4GenericMessenger::Command::SetUni << 193     ed<<"G4GenericMessenger::Command::SetUnit() is thread-unsafe and should not be used\n"
291           "not be used\n"                      << 194       <<"in multi-threaded mode. For your command <"<<cmdpath<<">, use\n"
292        << "in multi-threaded mode. For your co << 195       <<" DeclarePropertyWithUnit(const G4String& name, const G4String& defaultUnit,\n"
293        << " DeclarePropertyWithUnit(const G4St << 196       <<"                         const G4AnyType& variable, const G4String& doc)\n"
294           "defaultUnit,\n"                     << 197       <<"or\n"
295        << "                         const G4An << 198       <<" DeclareMethodWithUnit(const G4String& name, const G4String& defaultUnit,\n"
296           "doc)\n"                             << 199       <<"                       const G4AnyType& variable, const G4String& doc)\n"
297        << "or\n"                               << 200       <<"to define a command with a unit <"<<unit<<">.";
298        << " DeclareMethodWithUnit(const G4Stri << 201     if(spec!=UnitDefault) { ed<<"\nPlease use a default unit instead of unit category."; }
299           "defaultUnit,\n"                     << 202     G4Exception("G4GenericMessenger::Command::SetUnit()","Intercom70001",FatalException,ed);
300        << "                       const G4AnyT << 
301           "doc)\n"                             << 
302        << "to define a command with a unit <"  << 
303     if (spec != UnitDefault) {                 << 
304       ed << "\nPlease use a default unit inste << 
305     }                                          << 
306     G4Exception("G4GenericMessenger::Command:: << 
307     return *this;                                 203     return *this;
308   }                                               204   }
309                                                   205 
310   G4String cmdpath = command->GetCommandPath()    206   G4String cmdpath = command->GetCommandPath();
311   G4UImessenger* messenger = command->GetMesse    207   G4UImessenger* messenger = command->GetMessenger();
312   G4String range = command->GetRange();           208   G4String range = command->GetRange();
313   std::vector<G4String> guidance;                 209   std::vector<G4String> guidance;
314   G4String par_name = command->GetParameter(0)    210   G4String par_name = command->GetParameter(0)->GetParameterName();
315   G4bool par_omitable = command->GetParameter( << 211   bool par_omitable = command->GetParameter(0)->IsOmittable();
316   for (G4int i = 0; i < (G4int)command->GetGui << 212   for (G4int i = 0; i < command->GetGuidanceEntries(); i++) guidance.push_back(command->GetGuidanceLine(i));
317     guidance.push_back(command->GetGuidanceLin << 213   // Before deleting the command we need to add a fake one to avoid deleting the directory entry and with its guidance
318   }                                            << 214   G4UIcommand tmp((cmdpath+"_tmp").c_str(), messenger);
319   // Before deleting the command we need to ad << 
320   // the directory entry and with its guidance << 
321   G4UIcommand tmp((cmdpath + "_tmp").c_str(),  << 
322   delete command;                                 215   delete command;
323                                                   216 
324   if (*type == typeid(float) || *type == typei << 217   if (*type == typeid(float) || *type == typeid(double) ) {
325     auto* cmd_t = new G4UIcmdWithADoubleAndUni << 218     G4UIcmdWithADoubleAndUnit* cmd_t = new G4UIcmdWithADoubleAndUnit(cmdpath, messenger);
326     if (spec == UnitDefault) {                 << 219     if(spec == UnitDefault) cmd_t->SetDefaultUnit(unit);
327       cmd_t->SetDefaultUnit(unit);             << 220     else if(spec == UnitCategory) cmd_t->SetUnitCategory(unit);
328     }                                          << 
329     else if (spec == UnitCategory) {           << 
330       cmd_t->SetUnitCategory(unit);            << 
331     }                                          << 
332     cmd_t->SetParameterName(par_name, par_omit    221     cmd_t->SetParameterName(par_name, par_omitable);
333     command = cmd_t;                              222     command = cmd_t;
334   }                                               223   }
335   else if (*type == typeid(G4ThreeVector)) {      224   else if (*type == typeid(G4ThreeVector)) {
336     auto* cmd_t = new G4UIcmdWith3VectorAndUni << 225     G4UIcmdWith3VectorAndUnit* cmd_t = new G4UIcmdWith3VectorAndUnit(cmdpath, messenger);
337     if (spec == UnitDefault) {                 << 226     if(spec == UnitDefault) cmd_t->SetDefaultUnit(unit);
338       cmd_t->SetDefaultUnit(unit);             << 227     else if(spec == UnitCategory) cmd_t->SetUnitCategory(unit);
339     }                                          << 
340     else if (spec == UnitCategory) {           << 
341       cmd_t->SetUnitCategory(unit);            << 
342     }                                          << 
343     command = cmd_t;                              228     command = cmd_t;
344   }                                               229   }
345   else {                                          230   else {
346     G4cerr << "Only parameters of type <double << 231     G4cerr << "Only parameters of type <double> or <float> can be associated with units" << G4endl;
347               "with units"                     << 
348            << G4endl;                          << 
349     return *this;                                 232     return *this;
350   }                                               233   }
351   for (auto& i : guidance) {                   << 234   for (size_t i = 0; i < guidance.size(); i++) command->SetGuidance(guidance[i]);
352     command->SetGuidance(i);                   << 
353   }                                            << 
354   command->SetRange(range);                       235   command->SetRange(range);
355   return *this;                                   236   return *this;
356 }                                                 237 }
357                                                   238 
358 G4GenericMessenger::Command& G4GenericMessenge << 239 G4GenericMessenger::Command& G4GenericMessenger::Command::SetParameterName(const G4String& name,G4bool omittable, G4bool currentAsDefault) {
359                                                << 
360                                                << 
361 {                                              << 
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    240   G4UIparameter* theParam = command->GetParameter(0);
393   theParam->SetParameterName(namex);           << 241   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);              242   theParam->SetOmittable(omittable);
403   theParam->SetCurrentAsDefault(currentAsDefau    243   theParam->SetCurrentAsDefault(currentAsDefault);
404   return *this;                                   244   return *this;
405 }                                                 245 }
406                                                   246 
407 G4GenericMessenger::Command& G4GenericMessenge << 247 G4GenericMessenger::Command& G4GenericMessenger::Command::SetCandidates(const G4String& candList) {
408 {                                              << 248   G4UIparameter * theParam = command->GetParameter(0);
409   return SetCandidates(0, candList);           << 
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);     249   theParam->SetParameterCandidates(candList);
421   return *this;                                   250   return *this;
422 }                                                 251 }
423                                                   252 
424 G4GenericMessenger::Command& G4GenericMessenge << 253 G4GenericMessenger::Command& G4GenericMessenger::Command::SetDefaultValue(const G4String& defVal) {
425 {                                              << 254   G4UIparameter * theParam = command->GetParameter(0);
426   return SetDefaultValue(0, defVal);           << 
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);              255   theParam->SetDefaultValue(defVal);
438   return *this;                                   256   return *this;
439 }                                                 257 }
                                                   >> 258 
                                                   >> 259 
                                                   >> 260 
440                                                   261