Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MTcoutDestination.cc
Go to the documentation of this file.
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// G4MTcoutDestination class implementation
27//
28// Authors: M.Asai, A.Dotti (SLAC) - 23 May 2013
29// ---------------------------------------------------------------
30
32
33#include "G4AutoLock.hh"
38#include "G4strstreambuf.hh"
39
40#include <cassert>
41#include <sstream>
42
43namespace
44{
45 G4String empty = "";
46}
47
48// --------------------------------------------------------------------
50 : id(threadId)
51{
52 // TODO: Move these two out of here and in the caller
55
57 SetDefaultOutput(masterDestinationFlag, masterDestinationFmtFlag);
58}
59
60// --------------------------------------------------------------------
62 G4bool formatAlsoMaster)
63{
64 masterDestinationFlag = addmasterDestination;
65 masterDestinationFmtFlag = formatAlsoMaster;
66 // Formatter: add prefix to each thread
67 const auto f = [this](G4String& msg) -> G4bool {
68 std::ostringstream str;
69 str << prefix;
71 {
72 str << id;
73 }
74 str << " > " << msg;
75 msg = str.str();
76 return true;
77 };
78 // Block cout if not in correct state
79 const auto filter_out = [this](G4String&) -> G4bool {
80 return !(
81 this->ignoreCout ||
82 (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Init));
83 };
84
85 // Default behavior, add a destination that uses cout and uses a mutex
87 ref_defaultOut = output.get();
88 output->AddCoutTransformer(filter_out);
89 output->AddCoutTransformer(f);
90 output->AddCerrTransformer(f);
91 push_back(std::move(output));
92 if(addmasterDestination)
93 {
94 AddMasterOutput(formatAlsoMaster);
95 }
96}
97
98// --------------------------------------------------------------------
100{
101 // Add a destination, that forwards the message to the master thread
103 ref_masterOut = forwarder.get();
104 const auto filter_out = [this](G4String&) -> G4bool {
105 return !(
106 this->ignoreCout ||
107 (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Idle));
108 };
109 forwarder->AddCoutTransformer(filter_out);
110 if(formatAlsoMaster)
111 {
112 // Formatter: add prefix to each thread
113 const auto f = [this](G4String& msg) -> G4bool {
114 std::ostringstream str;
115 str << prefix;
117 {
118 str << id;
119 }
120 str << " > " << msg;
121 msg = str.str();
122 return true;
123 };
124 forwarder->AddCoutTransformer(f);
125 forwarder->AddCerrTransformer(f);
126 }
127 push_back(std::move(forwarder));
128}
129
130// --------------------------------------------------------------------
132{
133 if(useBuffer)
134 {
135 DumpBuffer();
136 }
137}
138
139// --------------------------------------------------------------------
141{
142 clear();
143 SetDefaultOutput(masterDestinationFlag, masterDestinationFmtFlag);
144}
145
146// --------------------------------------------------------------------
148 G4bool suppressDefault)
149{
150 // Logic: we create a file destination. We want this to get only the G4cout
151 // stream and should discard everything in G4cerr.
152 // First we create the destination with the appropriate open mode
153
154 std::ios_base::openmode mode =
155 (ifAppend ? std::ios_base::app : std::ios_base::trunc);
156 auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
157
158 // This reacts only to G4cout, so let's make a filter that removes everything
159 // from G4cerr
160 output->AddCerrTransformer([](G4String&) { return false; });
161 push_back(std::move(output));
162 // Silence G4cout from default formatter
163 if(suppressDefault)
164 {
165 ref_defaultOut->AddCoutTransformer([](G4String&) { return false; });
166 if(ref_masterOut != nullptr)
167 {
168 ref_masterOut->AddCoutTransformer([](G4String&) { return false; });
169 }
170 }
171}
172
173// --------------------------------------------------------------------
175 G4bool suppressDefault)
176{
177 // See HandleFileCout for explanation, switching cout with cerr
178
179 std::ios_base::openmode mode =
180 (ifAppend ? std::ios_base::app : std::ios_base::trunc);
181 auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
182 output->AddCoutTransformer([](G4String&) { return false; });
183 push_back(std::move(output));
184 if(suppressDefault)
185 {
186 ref_defaultOut->AddCerrTransformer([](G4String&) { return false; });
187 if(ref_masterOut != nullptr)
188 {
189 ref_masterOut->AddCerrTransformer([](G4String&) { return false; });
190 }
191 }
192}
193
194// --------------------------------------------------------------------
196 G4bool ifAppend)
197{
198 // First let's go back to the default
199 Reset();
200 if(fileN != "**Screen**")
201 {
202 HandleFileCout(fileN, ifAppend, true);
203 }
204}
205
206// --------------------------------------------------------------------
208{
209 // I was using buffered output and now I want to turn it off, dump current
210 // buffer content and reset output
211 if(useBuffer && !flag)
212 {
213 DumpBuffer();
214 Reset();
215 }
216 else if(useBuffer && flag)
217 { /* do nothing: already using */
218 }
219 else if(!useBuffer && !flag)
220 { /* do nothing: not using */
221 }
222 else if(!useBuffer && flag)
223 {
224 // Remove everything, in this case also removing the forward to the master
225 // thread, we want everything to be dumpled to a file
226 clear();
227 const size_t infiniteSize = 0;
228 push_back(G4coutDestinationUPtr(new G4BuffercoutDestination(infiniteSize)));
229 }
230 else // Should never happen
231 {
232 assert(false);
233 }
234 useBuffer = flag;
235}
236
237// --------------------------------------------------------------------
239 G4bool ifAppend)
240{
241 // This is like the equivalent SetCoutFileName, but in this case we do not
242 // remove or silence what is already exisiting
243 HandleFileCout(fileN, ifAppend, false);
244}
245
246// --------------------------------------------------------------------
248 G4bool ifAppend)
249{
250 // See SetCoutFileName for explanation
251 Reset();
252 if(fileN != "**Screen**")
253 {
254 HandleFileCerr(fileN, ifAppend, true);
255 }
256}
257
258// --------------------------------------------------------------------
260 G4bool ifAppend)
261{
262 HandleFileCerr(fileN, ifAppend, false);
263}
264
265// --------------------------------------------------------------------
267{
268 if(tid < 0)
269 {
270 ignoreCout = false;
271 }
272 else
273 {
274 ignoreCout = (tid != id);
275 }
276}
277
278namespace
279{
281}
282
283// --------------------------------------------------------------------
284void G4MTcoutDestination::DumpBuffer()
285{
286 G4AutoLock l(&coutm);
287 std::ostringstream msg;
288 msg << "=======================\n";
289 msg << "cout buffer(s) for worker with ID:" << id << std::endl;
291 G4bool sep = false;
292 std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
293 auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
294 if(cout != nullptr)
295 {
296 cout->FlushG4cout();
297 if(sep)
298 {
299 G4coutDestination::ReceiveG4cout("==========\n");
300 }
301 else
302 {
303 sep = true;
304 }
305 }
306 });
307 sep = false;
308 msg.str("");
309 msg.clear();
310 msg << "=======================\n";
311 msg << "cerr buffer(s) for worker with ID:" << id << " (goes to std error)"
312 << std::endl;
314 std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
315 auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
316 if(cout != nullptr)
317 {
318 cout->FlushG4cerr();
319 if(sep)
320 {
321 G4coutDestination::ReceiveG4cout("==========\n");
322 }
323 else
324 {
325 sep = true;
326 }
327 }
328 });
329 G4coutDestination::ReceiveG4cout("=======================\n");
330}
@ G4State_Init
@ G4State_Idle
std::unique_ptr< G4coutDestination > G4coutDestinationUPtr
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL G4strstreambuf G4coutbuf
Definition: G4ios.cc:114
G4GLOB_DLL G4strstreambuf G4cerrbuf
Definition: G4ios.cc:115
void AddCerrFileName(const G4String &fileN="G4cerr.txt", G4bool ifAppend=true)
void SetDefaultOutput(G4bool addMasterDestination=true, G4bool formatAlsoMaster=true)
void EnableBuffering(G4bool flag=true)
void SetCoutFileName(const G4String &fileN="G4cout.txt", G4bool ifAppend=true)
G4MTcoutDestination(const G4int &threadId)
void AddCoutFileName(const G4String &fileN="G4cout.txt", G4bool ifAppend=true)
void HandleFileCout(const G4String &fileN, G4bool appendFlag, G4bool suppressDefault)
void HandleFileCerr(const G4String &fileN, G4bool appendFlag, G4bool suppressDefault)
void SetIgnoreCout(G4int tid=0)
void SetCerrFileName(const G4String &fileN="G4cerr.txt", G4bool ifAppend=true)
void AddMasterOutput(G4bool formatAlsoMaster)
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
void AddCerrTransformer(const Transformer &t)
virtual G4int ReceiveG4cout(const G4String &msg)
void AddCoutTransformer(const Transformer &t)
void SetDestination(G4coutDestination *dest)