Geant4 Cross Reference |
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