Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/intercoms/src/G4UIcommand.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // G4UIcommand
 27 //
 28 // Author: Makoto Asai (SLAC), 1998
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4UIcommand.hh"
 32 
 33 #include "G4StateManager.hh"
 34 #include "G4Threading.hh"
 35 #include "G4Tokenizer.hh"
 36 #include "G4UIcommandStatus.hh"
 37 #include "G4UImanager.hh"
 38 #include "G4UImessenger.hh"
 39 #include "G4UIparsing.hh"
 40 #include "G4UnitsTable.hh"
 41 #include "G4ios.hh"
 42 
 43 // --------------------------------------------------------------------
 44 G4UIcommand::G4UIcommand(const char* theCommandPath, G4UImessenger* theMessenger, G4bool tBB)
 45   : toBeBroadcasted(tBB), messenger(theMessenger)
 46 {
 47   G4String comStr = theCommandPath;
 48   G4UIcommandCommonConstructorCode(comStr);
 49   availabelStateList = {G4State_PreInit,    G4State_Init,      G4State_Idle,
 50                         G4State_GeomClosed, G4State_EventProc, G4State_Abort};
 51 }
 52 
 53 // --------------------------------------------------------------------
 54 void G4UIcommand::G4UIcommandCommonConstructorCode(const char* theCommandPath)
 55 {
 56   commandPath = theCommandPath;
 57   commandName = theCommandPath;
 58   auto commandNameIndex = (G4int)commandName.rfind('/');
 59   commandName.erase(0, commandNameIndex + 1);
 60 #ifdef G4MULTITHREADED
 61   if ((messenger != nullptr) && messenger->CommandsShouldBeInMaster()
 62       && G4Threading::IsWorkerThread())
 63   {
 64     toBeBroadcasted = false;
 65     G4UImanager::GetMasterUIpointer()->AddNewCommand(this);
 66   }
 67   else {
 68     G4UImanager::GetUIpointer()->AddNewCommand(this);
 69   }
 70 #else
 71   G4UImanager::GetUIpointer()->AddNewCommand(this);
 72 #endif
 73 }
 74 
 75 // --------------------------------------------------------------------
 76 void G4UIcommand::SetCommandType(CommandType typ)
 77 {
 78   if (messenger == nullptr) {  // this must be a directory
 79     if (typ != CmdDirectory) {
 80       G4ExceptionDescription ed;
 81       ed << "A UI command <" << commandPath << "> is defined without vaild messenger.";
 82       G4Exception("G4UIcommand::SetCommandType", "UI2031", FatalException, ed);
 83     }
 84     else if (commandPath.back() != '/') {
 85       G4ExceptionDescription ed;
 86       ed << "G4UIcommand Warning : \n"
 87          << "  <" << commandPath << "> must be a directory."
 88          << "  '/' is appended.";
 89       G4Exception("G4UIcommand::SetCommandType", "UI2032", JustWarning, ed);
 90       commandPath += "/";
 91     }
 92   }
 93   commandType = typ;
 94 }
 95 
 96 // --------------------------------------------------------------------
 97 G4UIcommand::~G4UIcommand()
 98 {
 99   G4UImanager* fUImanager = G4UImanager::GetUIpointer();
100   if (fUImanager != nullptr) {
101     fUImanager->RemoveCommand(this);
102   }
103 
104   for (const auto& p : parameter) {
105     delete p;
106   }
107 }
108 
109 // --------------------------------------------------------------------
110 G4bool G4UIcommand::operator==(const G4UIcommand& right) const
111 {
112   return (commandPath == right.GetCommandPath());
113 }
114 
115 // --------------------------------------------------------------------
116 G4bool G4UIcommand::operator!=(const G4UIcommand& right) const
117 {
118   return (commandPath != right.GetCommandPath());
119 }
120 
121 // --------------------------------------------------------------------
122 G4int G4UIcommand::DoIt(const G4String& parameterList)
123 {
124   G4String correctParameters;
125   std::size_t n_parameterEntry = parameter.size();
126   if (n_parameterEntry != 0) {
127     G4String aToken;
128     G4String correctToken;
129     G4Tokenizer parameterToken(parameterList);
130     for (std::size_t i_thParameter = 0; i_thParameter < n_parameterEntry; ++i_thParameter) {
131       if (i_thParameter > 0) {
132         correctParameters.append(" ");
133       }
134       aToken = parameterToken();
135       if (aToken.length() > 0 && aToken[0] == '"') {
136         while (aToken.back() != '"' || (aToken.length() == 1 && aToken[0] == '"')) {
137           G4String additionalToken = parameterToken();
138           if (additionalToken.empty()) {
139             return G4int(fParameterUnreadable + i_thParameter);
140           }
141           aToken += " ";
142           aToken += additionalToken;
143         }
144       }
145       else if (i_thParameter == n_parameterEntry - 1
146                && parameter[i_thParameter]->GetParameterType() == 's')
147       {
148         G4String anotherToken;
149         while (!((anotherToken = parameterToken()).empty())) {
150           std::size_t idxs = anotherToken.find('#');
151           if (idxs == std::string::npos) {
152             aToken += " ";
153             aToken += anotherToken;
154           }
155           else if (idxs > 0) {
156             aToken += " ";
157             aToken += anotherToken.substr(0, idxs);
158             break;
159           }
160           else {
161             break;
162           }
163         }
164       }
165 
166       if (aToken.empty() || aToken == "!") {
167         if (parameter[i_thParameter]->IsOmittable()) {
168           if (parameter[i_thParameter]->GetCurrentAsDefault()) {
169             G4Tokenizer cvSt(messenger->GetCurrentValue(this));
170             G4String parVal;
171             for (std::size_t ii = 0; ii < i_thParameter; ++ii) {
172               parVal = cvSt();
173               if (parVal[0] == '"') {
174                 while (parVal.back() != '"') {
175                   G4String additionalToken = cvSt();
176                   if (additionalToken.empty()) {
177                     return G4int(fParameterUnreadable + i_thParameter);
178                   }
179                   parVal += " ";
180                   parVal += additionalToken;
181                 }
182               }
183             }
184             G4String aCVToken = cvSt();
185             if (aCVToken[0] == '"') {
186               while (aCVToken.back() != '"') {
187                 G4String additionalToken = cvSt();
188                 if (additionalToken.empty()) {
189                   return G4int(fParameterUnreadable + i_thParameter);
190                 }
191                 aCVToken += " ";
192                 aCVToken += additionalToken;
193               }
194             }
195             correctParameters.append(aCVToken);
196           }
197           else {
198             correctParameters.append(parameter[i_thParameter]->GetDefaultValue());
199           }
200         }
201         else {
202           return G4int(fParameterUnreadable + i_thParameter);
203         }
204       }
205       else {
206         G4int stat = parameter[i_thParameter]->CheckNewValue(aToken);
207         if (stat != 0) {
208           return stat + G4int(i_thParameter);
209         }
210         correctParameters.append(aToken);
211       }
212     }
213   }
214 
215   if (CheckNewValue(correctParameters) != 0) {
216     return fParameterOutOfRange + 99;
217   }
218 
219   if (workerThreadOnly && G4Threading::IsMasterThread()) {
220     return 0;
221   }
222 
223   messenger->SetNewValue(this, std::move(correctParameters));
224   return 0;
225 }
226 
227 // --------------------------------------------------------------------
228 G4String G4UIcommand::GetCurrentValue()
229 {
230   return messenger->GetCurrentValue(this);
231 }
232 
233 // --------------------------------------------------------------------
234 void G4UIcommand::AvailableForStates(G4ApplicationState s1)
235 {
236   availabelStateList = {s1};
237 }
238 
239 // --------------------------------------------------------------------
240 void G4UIcommand::AvailableForStates(G4ApplicationState s1, G4ApplicationState s2)
241 {
242   availabelStateList = {s1, s2};
243 }
244 
245 // --------------------------------------------------------------------
246 void G4UIcommand::AvailableForStates(G4ApplicationState s1, G4ApplicationState s2,
247                                      G4ApplicationState s3)
248 {
249   availabelStateList = {s1, s2, s3};
250 }
251 
252 // --------------------------------------------------------------------
253 void G4UIcommand::AvailableForStates(G4ApplicationState s1, G4ApplicationState s2,
254                                      G4ApplicationState s3, G4ApplicationState s4)
255 {
256   availabelStateList = {s1, s2, s3, s4};
257 }
258 
259 // --------------------------------------------------------------------
260 void G4UIcommand::AvailableForStates(G4ApplicationState s1, G4ApplicationState s2,
261                                      G4ApplicationState s3, G4ApplicationState s4,
262                                      G4ApplicationState s5)
263 {
264   availabelStateList = {s1, s2, s3, s4, s5};
265 }
266 
267 // --------------------------------------------------------------------
268 G4bool G4UIcommand::IsAvailable()
269 {
270   G4ApplicationState currentState = G4StateManager::GetStateManager()->GetCurrentState();
271 
272   for (const auto& s : availabelStateList) {
273     if (s == currentState) {
274       return true;
275     }
276   }
277 
278   return false;
279 }
280 
281 // --------------------------------------------------------------------
282 G4double G4UIcommand::ValueOf(const char* unitName)
283 {
284   return G4UnitDefinition::GetValueOf(unitName);
285 }
286 
287 // --------------------------------------------------------------------
288 G4String G4UIcommand::CategoryOf(const char* unitName)
289 {
290   return G4UnitDefinition::GetCategory(unitName);
291 }
292 
293 // --------------------------------------------------------------------
294 G4String G4UIcommand::UnitsList(const char* unitCategory)
295 {
296   G4UnitsTable& UTbl = G4UnitDefinition::GetUnitsTable();
297 
298   auto ucatIter = std::find_if(std::cbegin(UTbl), std::cend(UTbl), [&unitCategory](const auto& ud) {
299     return ud->GetName() == unitCategory;
300   });
301 
302   if (ucatIter == std::cend(UTbl)) {
303     G4cerr << "Unit category <" << unitCategory << "> is not defined." << G4endl;
304     return G4String();
305   }
306 
307   G4String symList;
308   G4String nameList;
309   G4UnitsContainer& UCnt = (*ucatIter)->GetUnitsList();
310 
311   for (const auto& uDef : UCnt) {
312     symList += uDef->GetSymbol();
313     symList += " ";
314     nameList += uDef->GetName();
315     nameList += " ";
316   }
317   symList += nameList;
318   G4StrUtil::rstrip(symList);
319   return symList;
320 }
321 
322 // --------------------------------------------------------------------
323 void G4UIcommand::List()
324 {
325   G4cout << G4endl;
326   G4cout << G4endl;
327   if (commandPath.back() != '/') {
328     G4cout << "Command " << commandPath << G4endl;
329   }
330   if (workerThreadOnly) {
331     G4cout << "    ---- available only in worker thread" << G4endl;
332   }
333 
334   G4cout << "Guidance :" << G4endl;
335   for (const auto& i_thGuidance : commandGuidance) {
336     G4cout << i_thGuidance << G4endl;
337   }
338 
339   if (!rangeExpression.empty()) {
340     G4cout << " Range of parameters : " << rangeExpression << G4endl;
341   }
342 
343   for (const auto& i_thParameter : parameter) {
344     i_thParameter->List();
345   }
346   G4cout << G4endl;
347 }
348 
349 // --------------------------------------------------------------------
350 G4String G4UIcommand::ConvertToString(G4bool boolVal)
351 {
352   return boolVal ? "1" : "0";
353 }
354 
355 // --------------------------------------------------------------------
356 G4String G4UIcommand::ConvertToString(G4int intValue)
357 {
358   return G4UIparsing::TtoS(intValue);
359 }
360 
361 // --------------------------------------------------------------------
362 G4String G4UIcommand::ConvertToString(G4long longValue)
363 {
364   return G4UIparsing::TtoS(longValue);
365 }
366 
367 // --------------------------------------------------------------------
368 G4String G4UIcommand::ConvertToString(G4double doubleValue)
369 {
370   std::ostringstream os;
371   if (G4UImanager::DoublePrecisionStr()) {
372     os << std::setprecision(17);
373   }
374   os << doubleValue;
375   return os.str();
376 }
377 
378 // --------------------------------------------------------------------
379 G4String G4UIcommand::ConvertToString(G4double doubleValue, const char* unitName)
380 {
381   std::ostringstream os;
382   if (G4UImanager::DoublePrecisionStr()) {
383     os << std::setprecision(17);
384   }
385   os << doubleValue / ValueOf(unitName) << " " << unitName;
386   return os.str();
387 }
388 
389 // --------------------------------------------------------------------
390 G4String G4UIcommand::ConvertToString(const G4ThreeVector& vec)
391 {
392   std::ostringstream os;
393   if (G4UImanager::DoublePrecisionStr()) {
394     os << std::setprecision(17);
395   }
396   os << vec.x() << " " << vec.y() << " " << vec.z();
397   return os.str();
398 }
399 
400 // --------------------------------------------------------------------
401 G4String G4UIcommand::ConvertToString(const G4ThreeVector& vec, const char* unitName)
402 {
403   G4double uv = ValueOf(unitName);
404 
405   std::ostringstream os;
406   if (G4UImanager::DoublePrecisionStr()) {
407     os << std::setprecision(17);
408   }
409   os << vec.x() / uv << " " << vec.y() / uv << " " << vec.z() / uv << " " << unitName;
410   return os.str();
411 }
412 
413 // --------------------------------------------------------------------
414 G4bool G4UIcommand::ConvertToBool(const char* st)
415 {
416   G4String v = G4StrUtil::to_upper_copy(st);
417   return (v == "Y" || v == "YES" || v == "1" || v == "T" || v == "TRUE");
418 }
419 
420 // --------------------------------------------------------------------
421 G4int G4UIcommand::ConvertToInt(const char* st)
422 {
423   return G4UIparsing::StoT<G4int>(st);
424 }
425 
426 // --------------------------------------------------------------------
427 G4long G4UIcommand::ConvertToLongInt(const char* st)
428 {
429   return G4UIparsing::StoT<G4long>(st);
430 }
431 
432 // --------------------------------------------------------------------
433 G4double G4UIcommand::ConvertToDouble(const char* st)
434 {
435   return G4UIparsing::StoT<G4double>(st);
436 }
437 
438 // --------------------------------------------------------------------
439 G4double G4UIcommand::ConvertToDimensionedDouble(const char* st)
440 {
441   G4double vl;
442   char unts[30];
443 
444   std::istringstream is(st);
445   is >> vl >> unts;
446   G4String unt = unts;
447 
448   return (vl * ValueOf(unt));
449 }
450 
451 // --------------------------------------------------------------------
452 G4ThreeVector G4UIcommand::ConvertTo3Vector(const char* st)
453 {
454   G4double vx;
455   G4double vy;
456   G4double vz;
457   std::istringstream is(st);
458   is >> vx >> vy >> vz;
459   return G4ThreeVector(vx, vy, vz);
460 }
461 
462 // --------------------------------------------------------------------
463 G4ThreeVector G4UIcommand::ConvertToDimensioned3Vector(const char* st)
464 {
465   G4double vx;
466   G4double vy;
467   G4double vz;
468   char unts[30];
469   std::istringstream is(st);
470   is >> vx >> vy >> vz >> unts;
471   G4String unt = unts;
472   G4double uv = ValueOf(unt);
473   return G4ThreeVector(vx * uv, vy * uv, vz * uv);
474 }
475 
476 G4int G4UIcommand::CheckNewValue(const char* newValue)
477 {
478   if (!G4UIparsing::RangeCheck(*this, newValue)) {
479     return fParameterOutOfRange;
480   }
481   return 0;  // succeeded
482 }
483