Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/intercoms/src/G4UImanager.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 // G4UImanager
 27 //
 28 // Author: Makoto Asai, 1997
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4UImanager.hh"
 32 
 33 #include "G4LocalThreadCoutMessenger.hh"
 34 #include "G4MTcoutDestination.hh"
 35 #include "G4StateManager.hh"
 36 #include "G4Threading.hh"
 37 #include "G4Tokenizer.hh"
 38 #include "G4UIaliasList.hh"
 39 #include "G4UIbatch.hh"
 40 #include "G4UIbridge.hh"
 41 #include "G4UIcommand.hh"
 42 #include "G4UIcommandTree.hh"
 43 #include "G4UIcontrolMessenger.hh"
 44 #include "G4UIsession.hh"
 45 #include "G4UnitsMessenger.hh"
 46 #include "G4ios.hh"
 47 
 48 #include <fstream>
 49 #include <sstream>
 50 
 51 G4bool G4UImanager::doublePrecisionStr = false;
 52 G4int G4UImanager::igThreadID = -1;
 53 
 54 // --------------------------------------------------------------------
 55 G4UImanager*& G4UImanager::fUImanager()
 56 {
 57   G4ThreadLocalStatic G4UImanager* _instance = nullptr;
 58   return _instance;
 59 }
 60 
 61 // --------------------------------------------------------------------
 62 G4bool& G4UImanager::fUImanagerHasBeenKilled()
 63 {
 64   G4ThreadLocalStatic G4bool _instance = false;
 65   return _instance;
 66 }
 67 
 68 // --------------------------------------------------------------------
 69 G4UImanager*& G4UImanager::fMasterUImanager()
 70 {
 71   static G4UImanager* _instance = nullptr;
 72   return _instance;
 73 }
 74 
 75 // --------------------------------------------------------------------
 76 G4UImanager* G4UImanager::GetUIpointer()
 77 {
 78   if (fUImanager() == nullptr) {
 79     if (!fUImanagerHasBeenKilled()) {
 80       fUImanager() = new G4UImanager;
 81       fUImanager()->CreateMessenger();
 82     }
 83   }
 84   return fUImanager();
 85 }
 86 
 87 // --------------------------------------------------------------------
 88 G4UImanager* G4UImanager::GetMasterUIpointer()
 89 {
 90   return fMasterUImanager();
 91 }
 92 
 93 // --------------------------------------------------------------------
 94 G4UImanager::G4UImanager() : G4VStateDependent(true)
 95 {
 96   treeTop = new G4UIcommandTree("/");
 97   aliasList = new G4UIaliasList;
 98   SetCoutDestination(session);
 99   commandStack = new std::vector<G4String>;
100 }
101 
102 // --------------------------------------------------------------------
103 void G4UImanager::CreateMessenger()
104 {
105   UImessenger = new G4UIcontrolMessenger;
106   UnitsMessenger = new G4UnitsMessenger;
107   CoutMessenger = new G4LocalThreadCoutMessenger;
108 }
109 
110 // --------------------------------------------------------------------
111 G4UImanager::~G4UImanager()
112 {
113   if (bridges != nullptr) {
114     for (auto bridge : *bridges) {
115       delete bridge;
116     }
117     delete bridges;
118   }
119   SetCoutDestination(nullptr);
120   histVec.clear();
121   if (saveHistory) {
122     historyFile.close();
123   }
124   delete CoutMessenger;
125   delete UnitsMessenger;
126   delete UImessenger;
127   delete treeTop;
128   delete aliasList;
129   fUImanagerHasBeenKilled() = true;
130   fUImanager() = nullptr;
131   if (commandStack != nullptr) {
132     commandStack->clear();
133     delete commandStack;
134   }
135   if (threadID >= 0) {
136     delete threadCout;
137     G4iosFinalization();
138     threadID = -1;
139   }
140 }
141 
142 // --------------------------------------------------------------------
143 void G4UImanager::UseDoublePrecisionStr(G4bool val)
144 {
145   doublePrecisionStr = val;
146 }
147 
148 // --------------------------------------------------------------------
149 G4bool G4UImanager::DoublePrecisionStr()
150 {
151   return doublePrecisionStr;
152 }
153 
154 // --------------------------------------------------------------------
155 G4String G4UImanager::GetCurrentValues(const char* aCommand)
156 {
157   G4String theCommand = aCommand;
158   savedCommand = treeTop->FindPath(theCommand);
159   if (savedCommand == nullptr) {
160     G4cerr << "command not found" << G4endl;
161     return G4String();
162   }
163   return savedCommand->GetCurrentValue();
164 }
165 
166 // --------------------------------------------------------------------
167 G4String G4UImanager::GetCurrentStringValue(const char* aCommand, G4int parameterNumber,
168                                             G4bool reGet)
169 {
170   if (reGet || savedCommand == nullptr) {
171     savedParameters = GetCurrentValues(aCommand);
172   }
173   G4Tokenizer savedToken(savedParameters);
174   G4String token;
175   for (G4int i_thParameter = 0; i_thParameter < parameterNumber; ++i_thParameter) {
176     token = savedToken();
177     if (token.empty()) {
178       return G4String();
179     }
180     if (token[(size_t)0] == '"') {
181       token.append(" ");
182       token.append(savedToken("\""));
183     }
184   }
185   return token;
186 }
187 
188 // --------------------------------------------------------------------
189 G4String G4UImanager::GetCurrentStringValue(const char* aCommand, const char* aParameterName,
190                                             G4bool reGet)
191 {
192   if (reGet || savedCommand == nullptr) {
193     G4String parameterValues = GetCurrentValues(aCommand);
194   }
195   for (G4int i = 0; i < (G4int)savedCommand->GetParameterEntries(); ++i) {
196     if (aParameterName == savedCommand->GetParameter(i)->GetParameterName()) {
197       return GetCurrentStringValue(aCommand, i + 1, false);
198     }
199   }
200   return G4String();
201 }
202 
203 // --------------------------------------------------------------------
204 G4int G4UImanager::GetCurrentIntValue(const char* aCommand, const char* aParameterName,
205                                       G4bool reGet)
206 {
207   G4String targetParameter = GetCurrentStringValue(aCommand, aParameterName, reGet);
208   G4int value;
209   const char* t = targetParameter;
210   std::istringstream is(t);
211   is >> value;
212   return value;
213 }
214 
215 // --------------------------------------------------------------------
216 G4int G4UImanager::GetCurrentIntValue(const char* aCommand, G4int parameterNumber, G4bool reGet)
217 {
218   G4String targetParameter = GetCurrentStringValue(aCommand, parameterNumber, reGet);
219   G4int value;
220   const char* t = targetParameter;
221   std::istringstream is(t);
222   is >> value;
223   return value;
224 }
225 
226 // --------------------------------------------------------------------
227 G4double G4UImanager::GetCurrentDoubleValue(const char* aCommand, const char* aParameterName,
228                                             G4bool reGet)
229 {
230   G4String targetParameter = GetCurrentStringValue(aCommand, aParameterName, reGet);
231   G4double value;
232   const char* t = targetParameter;
233   std::istringstream is(t);
234   is >> value;
235   return value;
236 }
237 
238 // --------------------------------------------------------------------
239 G4double G4UImanager::GetCurrentDoubleValue(const char* aCommand, G4int parameterNumber,
240                                             G4bool reGet)
241 {
242   G4String targetParameter = GetCurrentStringValue(aCommand, parameterNumber, reGet);
243   G4double value;
244   const char* t = targetParameter;
245   std::istringstream is(t);
246   is >> value;
247   return value;
248 }
249 
250 // --------------------------------------------------------------------
251 void G4UImanager::AddNewCommand(G4UIcommand* newCommand)
252 {
253   treeTop->AddNewCommand(newCommand);
254   if (fMasterUImanager() != nullptr && G4Threading::G4GetThreadId() == 0) {
255     fMasterUImanager()->AddWorkerCommand(newCommand);
256   }
257 }
258 
259 // --------------------------------------------------------------------
260 void G4UImanager::AddWorkerCommand(G4UIcommand* newCommand)
261 {
262   treeTop->AddNewCommand(newCommand, true);
263 }
264 
265 // --------------------------------------------------------------------
266 void G4UImanager::RemoveCommand(G4UIcommand* aCommand)
267 {
268   treeTop->RemoveCommand(aCommand);
269   if (fMasterUImanager() != nullptr && G4Threading::G4GetThreadId() == 0) {
270     fMasterUImanager()->RemoveWorkerCommand(aCommand);
271   }
272 }
273 
274 // --------------------------------------------------------------------
275 void G4UImanager::RemoveWorkerCommand(G4UIcommand* aCommand)
276 {
277   treeTop->RemoveCommand(aCommand, true);
278 }
279 
280 // --------------------------------------------------------------------
281 void G4UImanager::ExecuteMacroFile(const char* fileName)
282 {
283   G4UIsession* batchSession = new G4UIbatch(fileName, session);
284   session = batchSession;
285   lastRC = 0;
286   G4UIsession* previousSession = session->SessionStart();
287   lastRC = session->GetLastReturnCode();
288   delete session;
289   session = previousSession;
290 }
291 
292 // --------------------------------------------------------------------
293 void G4UImanager::LoopS(const char* valueList)
294 {
295   G4String vl = valueList;
296   G4Tokenizer parameterToken(vl);
297   G4String mf = parameterToken();
298   G4String vn = parameterToken();
299   G4String c1 = parameterToken();
300   c1 += " ";
301   c1 += parameterToken();
302   c1 += " ";
303   c1 += parameterToken();
304   const char* t1 = c1;
305   std::istringstream is(t1);
306   G4double d1;
307   G4double d2;
308   G4double d3;
309   is >> d1 >> d2 >> d3;
310   Loop(mf, vn, d1, d2, d3);
311 }
312 
313 // --------------------------------------------------------------------
314 void G4UImanager::Loop(const char* macroFile, const char* variableName, G4double initialValue,
315                        G4double finalValue, G4double stepSize)
316 {
317   G4String cd;
318   if (stepSize > 0) {
319     for (G4double d = initialValue; d <= finalValue; d += stepSize) {
320       std::ostringstream os;
321       os << d;
322       cd += os.str();
323       cd += " ";
324     }
325   }
326   else {
327     for (G4double d = initialValue; d >= finalValue; d += stepSize) {
328       std::ostringstream os;
329       os << d;
330       cd += os.str();
331       cd += " ";
332     }
333   }
334   Foreach(macroFile, variableName, cd);
335 }
336 
337 // --------------------------------------------------------------------
338 void G4UImanager::ForeachS(const char* valueList)
339 {
340   const G4String& vl = valueList;
341   G4Tokenizer parameterToken(vl);
342   const G4String& mf = parameterToken();
343   const G4String& vn = parameterToken();
344   G4String c1 = parameterToken();
345   G4String ca;
346   while (!((ca = parameterToken()).empty())) {
347     c1 += " ";
348     c1 += ca;
349   }
350 
351   G4String aliasValue = std::move(c1);
352   if (aliasValue[0] == '"') {
353     G4String strippedValue;
354     if (aliasValue.back() == '"') {
355       strippedValue = aliasValue.substr(1, aliasValue.length() - 2);
356     }
357     else {
358       strippedValue = aliasValue.substr(1, aliasValue.length() - 1);
359     }
360     aliasValue = std::move(strippedValue);
361   }
362 
363   //  Foreach(mf,vn,c1);
364   Foreach(mf, vn, aliasValue);
365 }
366 
367 // --------------------------------------------------------------------
368 void G4UImanager::Foreach(const char* macroFile, const char* variableName, const char* candidates)
369 {
370   G4String candidatesString = candidates;
371   G4Tokenizer parameterToken(candidatesString);
372   G4String cd;
373   while (!((cd = parameterToken()).empty())) {
374     G4String vl = variableName;
375     vl += " ";
376     vl += cd;
377     SetAlias(vl);
378     ExecuteMacroFile(FindMacroPath(macroFile));
379     if (lastRC != 0) {
380       G4ExceptionDescription ed;
381       ed << "Loop aborted due to a command execution error - "
382          << "error code " << lastRC;
383       G4Exception("G4UImanager::Foreach", "UIMAN0201", JustWarning, ed);
384       break;
385     }
386   }
387 }
388 
389 // --------------------------------------------------------------------
390 G4String G4UImanager::SolveAlias(const char* aCmd)
391 {
392   G4String aCommand = aCmd;
393   std::size_t ia = aCommand.find('{');
394   std::size_t iz = aCommand.find('#');
395   while ((ia != std::string::npos) && ((iz == std::string::npos) || (ia < iz))) {
396     G4int ibx = -1;
397     while (ibx < 0) {
398       std::size_t ib = aCommand.find('}');
399       if (ib == std::string::npos) {
400         G4cerr << aCommand << G4endl;
401         for (std::size_t i = 0; i < ia; ++i) {
402           G4cerr << " ";
403         }
404         G4cerr << "^" << G4endl;
405         G4cerr << "Unmatched alias parenthesis -- command ignored" << G4endl;
406         G4String nullStr;
407         return nullStr;
408       }
409       G4String ps = aCommand.substr(ia + 1, aCommand.length() - (ia + 1));
410       std::size_t ic = ps.find('{');
411       std::size_t id = ps.find('}');
412       if (ic != std::string::npos && ic < id) {
413         ia += ic + 1;
414       }
415       else {
416         ibx = (G4int)ib;
417       }
418     }
419     //--- Here ia represents the position of innermost "{"
420     //--- and ibx represents corresponding "}"
421     G4String subs;
422     if (ia > 0) {
423       subs = aCommand.substr(0, ia);
424     }
425     G4String alis = aCommand.substr(ia + 1, ibx - ia - 1);
426     G4String rems = aCommand.substr(ibx + 1, aCommand.length() - ibx);
427     const G4String* alVal = aliasList->FindAlias(alis);
428     if (alVal == nullptr) {
429       G4cerr << "Alias <" << alis << "> not found -- command ignored" << G4endl;
430       G4String nullStr;
431       return nullStr;
432     }
433     aCommand = subs + (*alVal) + rems;
434     ia = aCommand.find('{');
435   }
436   return aCommand;
437 }
438 
439 // --------------------------------------------------------------------
440 G4int G4UImanager::ApplyCommand(const G4String& aCmd)
441 {
442   return ApplyCommand(aCmd.data());
443 }
444 
445 // --------------------------------------------------------------------
446 G4int G4UImanager::ApplyCommand(const char* aCmd)
447 {
448   const G4String& aCommand = SolveAlias(aCmd);
449   if (aCommand.empty()) {
450     return fAliasNotFound;
451   }
452   if (verboseLevel != 0) {
453     if (G4Threading::IsMasterThread()) {
454       fLastCommandOutputTreated = false;
455     }
456     G4cout << aCommand << G4endl;
457   }
458   G4String commandString;
459   G4String commandParameter;
460 
461   std::size_t i = aCommand.find(' ');
462   if (i != std::string::npos) {
463     commandString = aCommand.substr(0, i);
464     commandParameter = aCommand.substr(i + 1, aCommand.length() - (i + 1));
465   }
466   else {
467     commandString = aCommand;
468   }
469 
470   // remove doubled slash
471   std::size_t len = commandString.length();
472   std::size_t ll = 0;
473   G4String a1;
474   G4String a2;
475   while (ll < len - 1) {
476     if (commandString.substr(ll, 2) == "//") {
477       if (ll == 0) {
478         // Safe because index argument always 0
479         commandString.erase(ll, 1);
480       }
481       else {
482         a1 = commandString.substr(0, ll);
483         a2 = commandString.substr(ll + 1, len - ll - 1);
484         commandString = a1 + a2;
485       }
486       --len;
487     }
488     else {
489       ++ll;
490     }
491   }
492 
493   if (isMaster && bridges != nullptr) {
494     for (auto bridge : *bridges) {
495       G4int leng = bridge->DirLength();
496       if (commandString.substr(0, leng) == bridge->DirName()) {
497         return bridge->LocalUI()->ApplyCommand(commandString + " " + commandParameter);
498       }
499     }
500   }
501 
502   G4UIcommand* targetCommand = treeTop->FindPath(commandString);
503   if (targetCommand == nullptr) {
504     if (ignoreCmdNotFound) {
505       if (stackCommandsForBroadcast) {
506         commandStack->push_back(commandString + " " + commandParameter);
507       }
508       return fCommandSucceeded;
509     }
510 
511     return fCommandNotFound;
512   }
513 
514   if (stackCommandsForBroadcast && targetCommand->ToBeBroadcasted()) {
515     commandStack->push_back(commandString + " " + commandParameter);
516   }
517 
518   if (!(targetCommand->IsAvailable())) {
519     return fIllegalApplicationState;
520   }
521 
522   if (saveHistory) {
523     historyFile << aCommand << G4endl;
524   }
525   if (G4int(histVec.size()) >= maxHistSize) {
526     histVec.erase(histVec.begin());
527   }
528   histVec.push_back(aCommand);
529 
530   targetCommand->ResetFailure();
531   G4int commandFailureCode = targetCommand->DoIt(commandParameter);
532   if (commandFailureCode == 0) {
533     G4int additionalFailureCode = targetCommand->IfCommandFailed();
534     if (additionalFailureCode > 0) {
535       G4ExceptionDescription msg;
536       msg << targetCommand->GetFailureDescription() << "\n"
537           << "Error code : " << additionalFailureCode;
538       G4Exception("G4UImanager::ApplyCommand", "UIMAN0123", JustWarning, msg);
539       commandFailureCode += additionalFailureCode;
540     }
541   }
542   return commandFailureCode;
543 }
544 
545 // --------------------------------------------------------------------
546 G4UIcommand* G4UImanager::FindCommand(const G4String& aCmd)
547 {
548   return FindCommand(aCmd.data());
549 }
550 
551 // --------------------------------------------------------------------
552 G4UIcommand* G4UImanager::FindCommand(const char* aCmd)
553 {
554   const G4String& aCommand = SolveAlias(aCmd);
555   if (aCommand.empty()) {
556     return nullptr;
557   }
558 
559   G4String commandString;
560 
561   std::size_t i = aCommand.find(' ');
562   if (i != std::string::npos) {
563     commandString = aCommand.substr(0, i);
564   }
565   else {
566     commandString = aCommand;
567   }
568 
569   return treeTop->FindPath(commandString);
570 }
571 
572 // --------------------------------------------------------------------
573 void G4UImanager::StoreHistory(const char* fileName)
574 {
575   StoreHistory(true, fileName);
576 }
577 
578 // --------------------------------------------------------------------
579 void G4UImanager::StoreHistory(G4bool historySwitch, const char* fileName)
580 {
581   if (historySwitch) {
582     if (saveHistory) {
583       historyFile.close();
584     }
585     historyFile.open((char*)fileName);
586     saveHistory = true;
587   }
588   else {
589     historyFile.close();
590     saveHistory = false;
591   }
592   saveHistory = historySwitch;
593 }
594 
595 // --------------------------------------------------------------------
596 void G4UImanager::PauseSession(const char* msg)
597 {
598   if (session != nullptr) {
599     session->PauseSessionStart(msg);
600   }
601 }
602 
603 // --------------------------------------------------------------------
604 void G4UImanager::ListCommands(const char* direct)
605 {
606   G4UIcommandTree* comTree = FindDirectory(direct);
607   if (comTree != nullptr) {
608     comTree->List();
609   }
610   else {
611     G4cout << direct << " is not found." << G4endl;
612   }
613 }
614 
615 // --------------------------------------------------------------------
616 G4UIcommandTree* G4UImanager::FindDirectory(const char* dirName)
617 {
618   const G4String& aDirName = dirName;
619   G4String targetDir = G4StrUtil::strip_copy(aDirName);
620   if (targetDir.back() != '/') {
621     targetDir += "/";
622   }
623   G4UIcommandTree* comTree = treeTop;
624   if (targetDir == "/") {
625     return comTree;
626   }
627   std::size_t idx = 1;
628   while (idx < targetDir.length() - 1) {
629     std::size_t i = targetDir.find('/', idx);
630     G4String targetDirString = targetDir.substr(0, i + 1);
631     comTree = comTree->GetTree(targetDirString);
632     if (comTree == nullptr) {
633       return nullptr;
634     }
635     idx = i + 1;
636   }
637   return comTree;
638 }
639 
640 // --------------------------------------------------------------------
641 G4bool G4UImanager::Notify(G4ApplicationState requestedState)
642 {
643   if (pauseAtBeginOfEvent) {
644     if (requestedState == G4State_EventProc
645         && G4StateManager::GetStateManager()->GetPreviousState() == G4State_GeomClosed)
646     {
647       PauseSession("BeginOfEvent");
648     }
649   }
650   if (pauseAtEndOfEvent) {
651     if (requestedState == G4State_GeomClosed
652         && G4StateManager::GetStateManager()->GetPreviousState() == G4State_EventProc)
653     {
654       PauseSession("EndOfEvent");
655     }
656   }
657   return true;
658 }
659 
660 // --------------------------------------------------------------------
661 void G4UImanager::SetCoutDestination(G4UIsession* const value)
662 {
663   G4iosSetDestination(value);
664 }
665 
666 // --------------------------------------------------------------------
667 void G4UImanager::SetAlias(const char* aliasLine)
668 {
669   const G4String& aLine = aliasLine;
670   std::size_t i = aLine.find(' ');
671   const G4String& aliasName = aLine.substr(0, i);
672   G4String aliasValue = aLine.substr(i + 1, aLine.length() - (i + 1));
673   if (aliasValue[0] == '"') {
674     G4String strippedValue;
675     if (aliasValue.back() == '"') {
676       strippedValue = aliasValue.substr(1, aliasValue.length() - 2);
677     }
678     else {
679       strippedValue = aliasValue.substr(1, aliasValue.length() - 1);
680     }
681     aliasValue = std::move(strippedValue);
682   }
683 
684   aliasList->ChangeAlias(aliasName, aliasValue);
685 }
686 
687 // --------------------------------------------------------------------
688 void G4UImanager::RemoveAlias(const char* aliasName)
689 {
690   const G4String& aL = aliasName;
691   G4String targetAlias = G4StrUtil::strip_copy(aL);
692   aliasList->RemoveAlias(targetAlias);
693 }
694 
695 // --------------------------------------------------------------------
696 void G4UImanager::ListAlias()
697 {
698   aliasList->List();
699 }
700 
701 // --------------------------------------------------------------------
702 void G4UImanager::CreateHTML(const char* dir)
703 {
704   G4UIcommandTree* tr = FindDirectory(dir);
705   if (tr != nullptr) {
706     tr->CreateHTML();
707   }
708   else {
709     G4cerr << "Directory <" << dir << "> is not found." << G4endl;
710   }
711 }
712 
713 // --------------------------------------------------------------------
714 void G4UImanager::ParseMacroSearchPath()
715 {
716   searchDirs.clear();
717 
718   std::size_t idxfirst = 0;
719   std::size_t idxend = 0;
720   G4String pathstring = "";
721   while ((idxend = searchPath.find(':', idxfirst)) != G4String::npos) {
722     pathstring = searchPath.substr(idxfirst, idxend - idxfirst);
723     if (!pathstring.empty()) {
724       searchDirs.push_back(pathstring);
725     }
726     idxfirst = idxend + 1;
727   }
728 
729   pathstring = searchPath.substr(idxfirst, searchPath.size() - idxfirst);
730   if (!pathstring.empty()) {
731     searchDirs.push_back(std::move(pathstring));
732   }
733 }
734 
735 // --------------------------------------------------------------------
736 static G4bool FileFound(const G4String& fname)
737 {
738   G4bool qopen = false;
739   std::ifstream fs;
740   fs.open(fname.c_str(), std::ios::in);
741   if (fs.good()) {
742     fs.close();
743     qopen = true;
744   }
745   return qopen;
746 }
747 
748 // --------------------------------------------------------------------
749 G4String G4UImanager::FindMacroPath(const G4String& fname) const
750 {
751   G4String macrofile = fname;
752 
753   for (const auto& searchDir : searchDirs) {
754     const G4String& fullpath = searchDir + "/" + fname;
755     if (FileFound(fullpath)) {
756       macrofile = fullpath;
757       break;
758     }
759   }
760   return macrofile;
761 }
762 
763 // --------------------------------------------------------------------
764 std::vector<G4String>* G4UImanager::GetCommandStack()
765 {
766   std::vector<G4String>* returnValue = commandStack;
767   commandStack = new std::vector<G4String>;
768   return returnValue;
769 }
770 
771 // --------------------------------------------------------------------
772 void G4UImanager::RegisterBridge(G4UIbridge* brg)
773 {
774   if (brg->LocalUI() == this) {
775     G4Exception("G4UImanager::RegisterBridge()", "UI7002", FatalException,
776                 "G4UIBridge cannot bridge between same object.");
777   }
778   else {
779     bridges->push_back(brg);
780   }
781 }
782 
783 // --------------------------------------------------------------------
784 void G4UImanager::SetUpForAThread(G4int tId)
785 {
786   threadID = tId;
787   G4iosInitialization();
788   threadCout = new G4MTcoutDestination(threadID);
789   threadCout->SetIgnoreCout(igThreadID);
790 }
791 
792 // --------------------------------------------------------------------
793 void G4UImanager::SetUpForSpecialThread(const G4String& pref)
794 {
795   threadID = G4Threading::GENERICTHREAD_ID;
796   G4Threading::G4SetThreadId(threadID);
797   G4iosInitialization();
798   threadCout = new G4MTcoutDestination(threadID);
799   threadCout->SetPrefixString(pref);
800   threadCout->SetIgnoreCout(igThreadID);
801 }
802 
803 // --------------------------------------------------------------------
804 void G4UImanager::SetCoutFileName(const G4String& fileN, G4bool ifAppend)
805 {
806   // for sequential mode, ignore this method.
807   if (threadID < 0) {
808     return;
809   }
810 
811   if (fileN == "**Screen**") {
812     threadCout->SetCoutFileName(fileN, ifAppend);
813   }
814   else {
815     std::stringstream fn;
816     fn << "G4W_" << threadID << "_" << fileN;
817     threadCout->SetCoutFileName(fn.str(), ifAppend);
818   }
819 }
820 
821 // --------------------------------------------------------------------
822 void G4UImanager::SetCerrFileName(const G4String& fileN, G4bool ifAppend)
823 {
824   // for sequential mode, ignore this method.
825   if (threadID < 0) {
826     return;
827   }
828 
829   if (fileN == "**Screen**") {
830     threadCout->SetCerrFileName(fileN, ifAppend);
831   }
832   else {
833     std::stringstream fn;
834     fn << "G4W_" << threadID << "_" << fileN;
835     threadCout->SetCerrFileName(fn.str(), ifAppend);
836   }
837 }
838 
839 // --------------------------------------------------------------------
840 void G4UImanager::SetThreadPrefixString(const G4String& s)
841 {
842   // for sequential mode, ignore this method.
843   if (threadID < 0) {
844     return;
845   }
846   threadCout->SetPrefixString(s);
847 }
848 
849 // --------------------------------------------------------------------
850 void G4UImanager::SetThreadUseBuffer(G4bool flg)
851 {
852   // for sequential mode, ignore this method.
853   if (threadID < 0) {
854     return;
855   }
856   threadCout->EnableBuffering(flg);
857 }
858 
859 // --------------------------------------------------------------------
860 void G4UImanager::SetThreadIgnore(G4int tid)
861 {
862   // for sequential mode, ignore this method.
863   if (threadID < 0) {
864     igThreadID = tid;
865     return;
866   }
867   threadCout->SetIgnoreCout(tid);
868 }
869 
870 // --------------------------------------------------------------------
871 void G4UImanager::SetThreadIgnoreInit(G4bool flg)
872 {
873   // for sequential mode, ignore this method.
874   if (threadID < 0) {
875     return;
876   }
877   threadCout->SetIgnoreInit(flg);
878 }
879 
880 G4UIsession* G4UImanager::GetBaseSession() const
881 {
882   // There may be no session - pure batch mode (session == nullptr)
883   // If there is a session, it may be a batch session used for processing macros.
884   // Find base session of this hierarchy of batch sessions.
885   G4UIsession* baseSession = session;
886   while (auto aBatchSession = dynamic_cast<G4UIbatch*>(baseSession)) {
887     auto previousSession = aBatchSession->GetPreviousSession();
888     if (previousSession == nullptr) {
889       // No previouse session - aBatchSession is the desired base session
890       baseSession = aBatchSession;
891       break;
892     }
893     // There is a previous session, which may or may not be a batch.
894     // If not, it will be our desired base - so record and test again.
895     baseSession = previousSession;
896   }
897   return baseSession;
898 }
899