Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/management/src/G4MTcoutDestination.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 /global/management/src/G4MTcoutDestination.cc (Version 11.3.0) and /global/management/src/G4MTcoutDestination.cc (Version 11.0.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4MTcoutDestination class implementation        26 // G4MTcoutDestination class implementation
 27 //                                                 27 //
 28 // Authors: M.Asai, A.Dotti (SLAC) - 23 May 20     28 // Authors: M.Asai, A.Dotti (SLAC) - 23 May 2013
 29 // -------------------------------------------     29 // ---------------------------------------------------------------
 30                                                    30 
 31 #include "G4MTcoutDestination.hh"              <<  31 #include <assert.h>
                                                   >>  32 #include <sstream>
 32                                                    33 
 33 #include "G4AutoLock.hh"                           34 #include "G4AutoLock.hh"
 34 #include "G4BuffercoutDestination.hh"              35 #include "G4BuffercoutDestination.hh"
 35 #include "G4FilecoutDestination.hh"                36 #include "G4FilecoutDestination.hh"
 36 #include "G4LockcoutDestination.hh"                37 #include "G4LockcoutDestination.hh"
                                                   >>  38 #include "G4MTcoutDestination.hh"
 37 #include "G4MasterForwardcoutDestination.hh"       39 #include "G4MasterForwardcoutDestination.hh"
 38                                                <<  40 #include "G4strstreambuf.hh"
 39 #include <cassert>                             << 
 40 #include <sstream>                             << 
 41                                                    41 
 42 namespace                                          42 namespace
 43 {                                                  43 {
 44   G4String empty = "";                             44   G4String empty = "";
 45 }                                                  45 }
 46                                                    46 
 47 // -------------------------------------------     47 // --------------------------------------------------------------------
 48 G4MTcoutDestination::G4MTcoutDestination(const     48 G4MTcoutDestination::G4MTcoutDestination(const G4int& threadId)
 49   : id(threadId)                                   49   : id(threadId)
 50 {                                                  50 {
 51   // TODO: Move this out of here and in the ca <<  51   // TODO: Move these two out of here and in the caller
 52   G4iosSetDestination(this);                   <<  52   G4coutbuf.SetDestination(this);
                                                   >>  53   G4cerrbuf.SetDestination(this);
 53                                                    54 
 54   stateMgr = G4StateManager::GetStateManager()     55   stateMgr = G4StateManager::GetStateManager();
 55   SetDefaultOutput(masterDestinationFlag, mast     56   SetDefaultOutput(masterDestinationFlag, masterDestinationFmtFlag);
 56 }                                                  57 }
 57                                                    58 
 58 // -------------------------------------------     59 // --------------------------------------------------------------------
 59 void G4MTcoutDestination::SetDefaultOutput(G4b     60 void G4MTcoutDestination::SetDefaultOutput(G4bool addmasterDestination,
 60                                            G4b     61                                            G4bool formatAlsoMaster)
 61 {                                                  62 {
 62   masterDestinationFlag    = addmasterDestinat     63   masterDestinationFlag    = addmasterDestination;
 63   masterDestinationFmtFlag = formatAlsoMaster;     64   masterDestinationFmtFlag = formatAlsoMaster;
 64   // Formatter: add prefix to each thread          65   // Formatter: add prefix to each thread
 65   const auto f = [this](G4String& msg) -> G4bo     66   const auto f = [this](G4String& msg) -> G4bool {
 66     std::ostringstream str;                        67     std::ostringstream str;
 67     str << prefix;                                 68     str << prefix;
 68     if(id != G4Threading::GENERICTHREAD_ID)        69     if(id != G4Threading::GENERICTHREAD_ID)
 69     {                                          << 
 70       str << id;                                   70       str << id;
 71     }                                          << 
 72     str << " > " << msg;                           71     str << " > " << msg;
 73     msg = str.str();                               72     msg = str.str();
 74     return true;                                   73     return true;
 75   };                                               74   };
 76   // Block cout if not in correct state            75   // Block cout if not in correct state
 77   const auto filter_out = [this](G4String&) ->     76   const auto filter_out = [this](G4String&) -> G4bool {
 78     return !(                                  <<  77     if(this->ignoreCout ||
 79       this->ignoreCout ||                      <<  78        (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Init))
 80       (this->ignoreInit && this->stateMgr->Get <<  79     {
                                                   >>  80       return false;
                                                   >>  81     }
                                                   >>  82     return true;
 81   };                                               83   };
 82                                                    84 
 83   // Default behavior, add a destination that      85   // Default behavior, add a destination that uses cout and uses a mutex
 84   auto output    = G4coutDestinationUPtr(new G     86   auto output    = G4coutDestinationUPtr(new G4LockcoutDestination);
 85   ref_defaultOut = output.get();                   87   ref_defaultOut = output.get();
 86   output->AddDebugTransformer(filter_out);     << 
 87   output->AddDebugTransformer(f);              << 
 88   output->AddCoutTransformer(filter_out);          88   output->AddCoutTransformer(filter_out);
 89   output->AddCoutTransformer(f);                   89   output->AddCoutTransformer(f);
 90   output->AddCerrTransformer(f);                   90   output->AddCerrTransformer(f);
 91   push_back(std::move(output));                    91   push_back(std::move(output));
 92   if(addmasterDestination)                         92   if(addmasterDestination)
 93   {                                                93   {
 94     AddMasterOutput(formatAlsoMaster);             94     AddMasterOutput(formatAlsoMaster);
 95   }                                                95   }
 96 }                                                  96 }
 97                                                    97 
 98 // -------------------------------------------     98 // --------------------------------------------------------------------
 99 void G4MTcoutDestination::AddMasterOutput(G4bo     99 void G4MTcoutDestination::AddMasterOutput(G4bool formatAlsoMaster)
100 {                                                 100 {
101   // Add a destination, that forwards the mess    101   // Add a destination, that forwards the message to the master thread
102   auto forwarder = G4coutDestinationUPtr(new G    102   auto forwarder = G4coutDestinationUPtr(new G4MasterForwardcoutDestination);
103   ref_masterOut  = forwarder.get();               103   ref_masterOut  = forwarder.get();
104   const auto filter_out = [this](G4String&) ->    104   const auto filter_out = [this](G4String&) -> G4bool {
105     return !(                                  << 105     if(this->ignoreCout ||
106       this->ignoreCout ||                      << 106        (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Idle))
107       (this->ignoreInit && this->stateMgr->Get << 107     {
                                                   >> 108       return false;
                                                   >> 109     }
                                                   >> 110     return true;
108   };                                              111   };
109   forwarder->AddDebugTransformer(filter_out);  << 
110   forwarder->AddCoutTransformer(filter_out);      112   forwarder->AddCoutTransformer(filter_out);
111   if(formatAlsoMaster)                            113   if(formatAlsoMaster)
112   {                                               114   {
113     // Formatter: add prefix to each thread       115     // Formatter: add prefix to each thread
114     const auto f = [this](G4String& msg) -> G4    116     const auto f = [this](G4String& msg) -> G4bool {
115       std::ostringstream str;                     117       std::ostringstream str;
116       str << prefix;                              118       str << prefix;
117       if(id != G4Threading::GENERICTHREAD_ID)     119       if(id != G4Threading::GENERICTHREAD_ID)
118       {                                        << 
119         str << id;                                120         str << id;
120       }                                        << 
121       str << " > " << msg;                        121       str << " > " << msg;
122       msg = str.str();                            122       msg = str.str();
123       return true;                                123       return true;
124     };                                            124     };
125     forwarder->AddDebugTransformer(f);         << 
126     forwarder->AddCoutTransformer(f);             125     forwarder->AddCoutTransformer(f);
127     forwarder->AddCerrTransformer(f);             126     forwarder->AddCerrTransformer(f);
128   }                                               127   }
129   push_back(std::move(forwarder));                128   push_back(std::move(forwarder));
130 }                                                 129 }
131                                                   130 
132 // -------------------------------------------    131 // --------------------------------------------------------------------
133 G4MTcoutDestination::~G4MTcoutDestination()       132 G4MTcoutDestination::~G4MTcoutDestination()
134 {                                                 133 {
135   if(useBuffer)                                   134   if(useBuffer)
136   {                                            << 
137     DumpBuffer();                                 135     DumpBuffer();
138   }                                            << 
139 }                                                 136 }
140                                                   137 
141 // -------------------------------------------    138 // --------------------------------------------------------------------
142 void G4MTcoutDestination::Reset()                 139 void G4MTcoutDestination::Reset()
143 {                                                 140 {
144   clear();                                        141   clear();
145   SetDefaultOutput(masterDestinationFlag, mast    142   SetDefaultOutput(masterDestinationFlag, masterDestinationFmtFlag);
146 }                                                 143 }
147                                                   144 
148 // -------------------------------------------    145 // --------------------------------------------------------------------
149 void G4MTcoutDestination::HandleFileCout(const << 146 void G4MTcoutDestination::HandleFileCout(G4String fileN, G4bool ifAppend,
150                                          G4boo    147                                          G4bool suppressDefault)
151 {                                                 148 {
152   // Logic: we create a file destination. We w    149   // Logic: we create a file destination. We want this to get only the G4cout
153   // stream and should discard everything in G    150   // stream and should discard everything in G4cerr.
154   // First we create the destination with the     151   // First we create the destination with the appropriate open mode
155                                                   152 
156   std::ios_base::openmode mode =                  153   std::ios_base::openmode mode =
157     (ifAppend ? std::ios_base::app : std::ios_    154     (ifAppend ? std::ios_base::app : std::ios_base::trunc);
158   auto output = G4coutDestinationUPtr(new G4Fi    155   auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
159                                                   156 
160   // This reacts only to G4cout, so let's make << 157   // This reacts only to G4cout, so let's make a filter that removes everything
161   output->AddDebugTransformer([](G4String&) {  << 158   // from G4cerr
162   output->AddCerrTransformer([](G4String&) { r    159   output->AddCerrTransformer([](G4String&) { return false; });
163   push_back(std::move(output));                   160   push_back(std::move(output));
164   // Silence G4cout from default formatter        161   // Silence G4cout from default formatter
165   if(suppressDefault)                             162   if(suppressDefault)
166   {                                               163   {
167     ref_defaultOut->AddCoutTransformer([](G4St    164     ref_defaultOut->AddCoutTransformer([](G4String&) { return false; });
168     if(ref_masterOut != nullptr)               << 165     if(ref_masterOut)
169     {                                          << 
170       ref_masterOut->AddCoutTransformer([](G4S    166       ref_masterOut->AddCoutTransformer([](G4String&) { return false; });
171     }                                          << 
172   }                                               167   }
173 }                                                 168 }
174                                                   169 
175 // -------------------------------------------    170 // --------------------------------------------------------------------
176 void G4MTcoutDestination::HandleFileCerr(const << 171 void G4MTcoutDestination::HandleFileCerr(G4String fileN, G4bool ifAppend,
177                                          G4boo    172                                          G4bool suppressDefault)
178 {                                                 173 {
179   // See HandleFileCout for explanation, switc    174   // See HandleFileCout for explanation, switching cout with cerr
180                                                   175 
181   std::ios_base::openmode mode =                  176   std::ios_base::openmode mode =
182     (ifAppend ? std::ios_base::app : std::ios_    177     (ifAppend ? std::ios_base::app : std::ios_base::trunc);
183   auto output = G4coutDestinationUPtr(new G4Fi    178   auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
184   output->AddDebugTransformer([](G4String&) {  << 
185   output->AddCoutTransformer([](G4String&) { r    179   output->AddCoutTransformer([](G4String&) { return false; });
186   push_back(std::move(output));                   180   push_back(std::move(output));
187   if(suppressDefault)                             181   if(suppressDefault)
188   {                                               182   {
189     ref_defaultOut->AddCerrTransformer([](G4St    183     ref_defaultOut->AddCerrTransformer([](G4String&) { return false; });
190     if(ref_masterOut != nullptr)               << 184     if(ref_masterOut)
191     {                                          << 
192       ref_masterOut->AddCerrTransformer([](G4S    185       ref_masterOut->AddCerrTransformer([](G4String&) { return false; });
193     }                                          << 
194   }                                               186   }
195 }                                                 187 }
196                                                   188 
197 // -------------------------------------------    189 // --------------------------------------------------------------------
198 void G4MTcoutDestination::SetCoutFileName(cons    190 void G4MTcoutDestination::SetCoutFileName(const G4String& fileN,
199                                           G4bo    191                                           G4bool ifAppend)
200 {                                                 192 {
201   // First let's go back to the default           193   // First let's go back to the default
202   Reset();                                        194   Reset();
203   if(fileN != "**Screen**")                       195   if(fileN != "**Screen**")
204   {                                               196   {
205     HandleFileCout(fileN, ifAppend, true);        197     HandleFileCout(fileN, ifAppend, true);
206   }                                               198   }
207 }                                                 199 }
208                                                   200 
209 // -------------------------------------------    201 // --------------------------------------------------------------------
210 void G4MTcoutDestination::EnableBuffering(G4bo    202 void G4MTcoutDestination::EnableBuffering(G4bool flag)
211 {                                                 203 {
212   // I was using buffered output and now I wan    204   // I was using buffered output and now I want to turn it off, dump current
213   // buffer content and reset output              205   // buffer content and reset output
214   if(useBuffer && !flag)                          206   if(useBuffer && !flag)
215   {                                               207   {
216     DumpBuffer();                                 208     DumpBuffer();
217     Reset();                                      209     Reset();
218   }                                               210   }
219   else if(useBuffer && flag)                      211   else if(useBuffer && flag)
220   { /* do nothing: already using */               212   { /* do nothing: already using */
221   }                                               213   }
222   else if(!useBuffer && !flag)                    214   else if(!useBuffer && !flag)
223   { /* do nothing: not using */                   215   { /* do nothing: not using */
224   }                                               216   }
225   else if(!useBuffer && flag)                     217   else if(!useBuffer && flag)
226   {                                               218   {
227     // Remove everything, in this case also re    219     // Remove everything, in this case also removing the forward to the master
228     // thread, we want everything to be dumple    220     // thread, we want everything to be dumpled to a file
229     clear();                                      221     clear();
230     const size_t infiniteSize = 0;                222     const size_t infiniteSize = 0;
231     push_back(G4coutDestinationUPtr(new G4Buff    223     push_back(G4coutDestinationUPtr(new G4BuffercoutDestination(infiniteSize)));
232   }                                               224   }
233   else  // Should never happen                    225   else  // Should never happen
234   {                                               226   {
235     assert(false);                                227     assert(false);
236   }                                               228   }
237   useBuffer = flag;                               229   useBuffer = flag;
238 }                                                 230 }
239                                                   231 
240 // -------------------------------------------    232 // --------------------------------------------------------------------
241 void G4MTcoutDestination::AddCoutFileName(cons    233 void G4MTcoutDestination::AddCoutFileName(const G4String& fileN,
242                                           G4bo    234                                           G4bool ifAppend)
243 {                                                 235 {
244   // This is like the equivalent SetCoutFileNa    236   // This is like the equivalent SetCoutFileName, but in this case we do not
245   // remove or silence what is already exisiti    237   // remove or silence what is already exisiting
246   HandleFileCout(fileN, ifAppend, false);         238   HandleFileCout(fileN, ifAppend, false);
247 }                                                 239 }
248                                                   240 
249 // -------------------------------------------    241 // --------------------------------------------------------------------
250 void G4MTcoutDestination::SetCerrFileName(cons    242 void G4MTcoutDestination::SetCerrFileName(const G4String& fileN,
251                                           G4bo    243                                           G4bool ifAppend)
252 {                                                 244 {
253   // See SetCoutFileName for explanation          245   // See SetCoutFileName for explanation
254   Reset();                                        246   Reset();
255   if(fileN != "**Screen**")                       247   if(fileN != "**Screen**")
256   {                                               248   {
257     HandleFileCerr(fileN, ifAppend, true);        249     HandleFileCerr(fileN, ifAppend, true);
258   }                                               250   }
259 }                                                 251 }
260                                                   252 
261 // -------------------------------------------    253 // --------------------------------------------------------------------
262 void G4MTcoutDestination::AddCerrFileName(cons    254 void G4MTcoutDestination::AddCerrFileName(const G4String& fileN,
263                                           G4bo    255                                           G4bool ifAppend)
264 {                                                 256 {
265   HandleFileCerr(fileN, ifAppend, false);         257   HandleFileCerr(fileN, ifAppend, false);
266 }                                                 258 }
267                                                   259 
268 // -------------------------------------------    260 // --------------------------------------------------------------------
269 void G4MTcoutDestination::SetIgnoreCout(G4int     261 void G4MTcoutDestination::SetIgnoreCout(G4int tid)
270 {                                                 262 {
271   if(tid < 0)                                     263   if(tid < 0)
272   {                                               264   {
273     ignoreCout = false;                           265     ignoreCout = false;
274   }                                               266   }
275   else                                            267   else
276   {                                               268   {
277     ignoreCout = (tid != id);                     269     ignoreCout = (tid != id);
278   }                                               270   }
279 }                                                 271 }
280                                                   272 
281 namespace                                         273 namespace
282 {                                                 274 {
283   G4Mutex coutm = G4MUTEX_INITIALIZER;            275   G4Mutex coutm = G4MUTEX_INITIALIZER;
284 }                                                 276 }
285                                                   277 
286 // -------------------------------------------    278 // --------------------------------------------------------------------
287 void G4MTcoutDestination::DumpBuffer()            279 void G4MTcoutDestination::DumpBuffer()
288 {                                                 280 {
289   G4AutoLock l(&coutm);                           281   G4AutoLock l(&coutm);
290   std::ostringstream msg;                         282   std::ostringstream msg;
291   G4bool sep = false;                          << 
292                                                << 
293   sep = false;                                 << 
294   msg.str("");                                 << 
295   msg.clear();                                 << 
296   msg << "=======================\n";          << 
297   msg << "debug buffer(s) for worker with ID:" << 
298   G4coutDestination::ReceiveG4cout(msg.str()); << 
299   std::for_each(begin(), end(), [this, &sep](G << 
300     auto cout = dynamic_cast<G4BuffercoutDesti << 
301     if(cout != nullptr)                        << 
302     {                                          << 
303       cout->FlushG4debug();                    << 
304       if(sep)                                  << 
305       {                                        << 
306         G4coutDestination::ReceiveG4cout("==== << 
307       }                                        << 
308       else                                     << 
309       {                                        << 
310         sep = true;                            << 
311       }                                        << 
312     }                                          << 
313   });                                          << 
314                                                << 
315   sep = false;                                 << 
316   msg.str("");                                 << 
317   msg.clear();                                 << 
318   msg << "=======================\n";             283   msg << "=======================\n";
319   msg << "cout buffer(s) for worker with ID:"     284   msg << "cout buffer(s) for worker with ID:" << id << std::endl;
320   G4coutDestination::ReceiveG4cout(msg.str());    285   G4coutDestination::ReceiveG4cout(msg.str());
                                                   >> 286   G4bool sep = false;
321   std::for_each(begin(), end(), [this, &sep](G    287   std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
322     auto cout = dynamic_cast<G4BuffercoutDesti    288     auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
323     if(cout != nullptr)                           289     if(cout != nullptr)
324     {                                             290     {
325       cout->FlushG4cout();                        291       cout->FlushG4cout();
326       if(sep)                                     292       if(sep)
327       {                                           293       {
328         G4coutDestination::ReceiveG4cout("====    294         G4coutDestination::ReceiveG4cout("==========\n");
329       }                                           295       }
330       else                                        296       else
331       {                                           297       {
332         sep = true;                               298         sep = true;
333       }                                           299       }
334     }                                             300     }
335   });                                             301   });
336                                                << 
337   sep = false;                                    302   sep = false;
338   msg.str("");                                    303   msg.str("");
339   msg.clear();                                    304   msg.clear();
340   msg << "=======================\n";             305   msg << "=======================\n";
341   msg << "cerr buffer(s) for worker with ID:"     306   msg << "cerr buffer(s) for worker with ID:" << id << " (goes to std error)"
342       << std::endl;                               307       << std::endl;
343   G4coutDestination::ReceiveG4cout(msg.str());    308   G4coutDestination::ReceiveG4cout(msg.str());
344   std::for_each(begin(), end(), [this, &sep](G    309   std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
345     auto cout = dynamic_cast<G4BuffercoutDesti    310     auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
346     if(cout != nullptr)                           311     if(cout != nullptr)
347     {                                             312     {
348       cout->FlushG4cerr();                        313       cout->FlushG4cerr();
349       if(sep)                                     314       if(sep)
350       {                                           315       {
351         G4coutDestination::ReceiveG4cout("====    316         G4coutDestination::ReceiveG4cout("==========\n");
352       }                                           317       }
353       else                                        318       else
354       {                                           319       {
355         sep = true;                               320         sep = true;
356       }                                           321       }
357     }                                             322     }
358   });                                             323   });
359                                                << 
360   G4coutDestination::ReceiveG4cout("==========    324   G4coutDestination::ReceiveG4cout("=======================\n");
361 }                                                 325 }
362                                                   326