Geant4-11
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
31#include <assert.h>
32#include <sstream>
33
34#include "G4AutoLock.hh"
40#include "G4strstreambuf.hh"
41
42namespace
43{
45}
46
47// --------------------------------------------------------------------
49 : id(threadId)
50{
51 // TODO: Move these two out of here and in the caller
54
57}
58
59// --------------------------------------------------------------------
61 G4bool formatAlsoMaster)
62{
63 masterDestinationFlag = addmasterDestination;
64 masterDestinationFmtFlag = formatAlsoMaster;
65 // Formatter: add prefix to each thread
66 const auto f = [this](G4String& msg) -> G4bool {
67 std::ostringstream str;
68 str << prefix;
70 str << id;
71 str << " > " << msg;
72 msg = str.str();
73 return true;
74 };
75 // Block cout if not in correct state
76 const auto filter_out = [this](G4String&) -> G4bool {
77 if(this->ignoreCout ||
78 (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Init))
79 {
80 return false;
81 }
82 return true;
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 if(this->ignoreCout ||
106 (this->ignoreInit && this->stateMgr->GetCurrentState() == G4State_Idle))
107 {
108 return false;
109 }
110 return true;
111 };
112 forwarder->AddCoutTransformer(filter_out);
113 if(formatAlsoMaster)
114 {
115 // Formatter: add prefix to each thread
116 const auto f = [this](G4String& msg) -> G4bool {
117 std::ostringstream str;
118 str << prefix;
120 str << id;
121 str << " > " << msg;
122 msg = str.str();
123 return true;
124 };
125 forwarder->AddCoutTransformer(f);
126 forwarder->AddCerrTransformer(f);
127 }
128 push_back(std::move(forwarder));
129}
130
131// --------------------------------------------------------------------
133{
134 if(useBuffer)
135 DumpBuffer();
136}
137
138// --------------------------------------------------------------------
140{
141 clear();
143}
144
145// --------------------------------------------------------------------
147 G4bool suppressDefault)
148{
149 // Logic: we create a file destination. We want this to get only the G4cout
150 // stream and should discard everything in G4cerr.
151 // First we create the destination with the appropriate open mode
152
153 std::ios_base::openmode mode =
154 (ifAppend ? std::ios_base::app : std::ios_base::trunc);
155 auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
156
157 // This reacts only to G4cout, so let's make a filter that removes everything
158 // from G4cerr
159 output->AddCerrTransformer([](G4String&) { return false; });
160 push_back(std::move(output));
161 // Silence G4cout from default formatter
162 if(suppressDefault)
163 {
164 ref_defaultOut->AddCoutTransformer([](G4String&) { return false; });
165 if(ref_masterOut)
166 ref_masterOut->AddCoutTransformer([](G4String&) { return false; });
167 }
168}
169
170// --------------------------------------------------------------------
172 G4bool suppressDefault)
173{
174 // See HandleFileCout for explanation, switching cout with cerr
175
176 std::ios_base::openmode mode =
177 (ifAppend ? std::ios_base::app : std::ios_base::trunc);
178 auto output = G4coutDestinationUPtr(new G4FilecoutDestination(fileN, mode));
179 output->AddCoutTransformer([](G4String&) { return false; });
180 push_back(std::move(output));
181 if(suppressDefault)
182 {
183 ref_defaultOut->AddCerrTransformer([](G4String&) { return false; });
184 if(ref_masterOut)
185 ref_masterOut->AddCerrTransformer([](G4String&) { return false; });
186 }
187}
188
189// --------------------------------------------------------------------
191 G4bool ifAppend)
192{
193 // First let's go back to the default
194 Reset();
195 if(fileN != "**Screen**")
196 {
197 HandleFileCout(fileN, ifAppend, true);
198 }
199}
200
201// --------------------------------------------------------------------
203{
204 // I was using buffered output and now I want to turn it off, dump current
205 // buffer content and reset output
206 if(useBuffer && !flag)
207 {
208 DumpBuffer();
209 Reset();
210 }
211 else if(useBuffer && flag)
212 { /* do nothing: already using */
213 }
214 else if(!useBuffer && !flag)
215 { /* do nothing: not using */
216 }
217 else if(!useBuffer && flag)
218 {
219 // Remove everything, in this case also removing the forward to the master
220 // thread, we want everything to be dumpled to a file
221 clear();
222 const size_t infiniteSize = 0;
223 push_back(G4coutDestinationUPtr(new G4BuffercoutDestination(infiniteSize)));
224 }
225 else // Should never happen
226 {
227 assert(false);
228 }
229 useBuffer = flag;
230}
231
232// --------------------------------------------------------------------
234 G4bool ifAppend)
235{
236 // This is like the equivalent SetCoutFileName, but in this case we do not
237 // remove or silence what is already exisiting
238 HandleFileCout(fileN, ifAppend, false);
239}
240
241// --------------------------------------------------------------------
243 G4bool ifAppend)
244{
245 // See SetCoutFileName for explanation
246 Reset();
247 if(fileN != "**Screen**")
248 {
249 HandleFileCerr(fileN, ifAppend, true);
250 }
251}
252
253// --------------------------------------------------------------------
255 G4bool ifAppend)
256{
257 HandleFileCerr(fileN, ifAppend, false);
258}
259
260// --------------------------------------------------------------------
262{
263 if(tid < 0)
264 {
265 ignoreCout = false;
266 }
267 else
268 {
269 ignoreCout = (tid != id);
270 }
271}
272
273namespace
274{
276}
277
278// --------------------------------------------------------------------
280{
281 G4AutoLock l(&coutm);
282 std::ostringstream msg;
283 msg << "=======================\n";
284 msg << "cout buffer(s) for worker with ID:" << id << std::endl;
286 G4bool sep = false;
287 std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
288 auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
289 if(cout != nullptr)
290 {
291 cout->FlushG4cout();
292 if(sep)
293 {
294 G4coutDestination::ReceiveG4cout("==========\n");
295 }
296 else
297 {
298 sep = true;
299 }
300 }
301 });
302 sep = false;
303 msg.str("");
304 msg.clear();
305 msg << "=======================\n";
306 msg << "cerr buffer(s) for worker with ID:" << id << " (goes to std error)"
307 << std::endl;
309 std::for_each(begin(), end(), [this, &sep](G4coutDestinationUPtr& el) {
310 auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
311 if(cout != nullptr)
312 {
313 cout->FlushG4cerr();
314 if(sep)
315 {
316 G4coutDestination::ReceiveG4cout("==========\n");
317 }
318 else
319 {
320 sep = true;
321 }
322 }
323 });
324 G4coutDestination::ReceiveG4cout("=======================\n");
325}
@ 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:108
G4GLOB_DLL G4strstreambuf G4cerrbuf
Definition: G4ios.cc:109
G4coutDestination * ref_masterOut
void AddCerrFileName(const G4String &fileN="G4cerr.txt", G4bool ifAppend=true)
void SetDefaultOutput(G4bool addMasterDestination=true, G4bool formatAlsoMaster=true)
void HandleFileCout(G4String fileN, G4bool appendFlag, G4bool suppressDefault)
void EnableBuffering(G4bool flag=true)
void HandleFileCerr(G4String fileN, G4bool appendFlag, G4bool suppressDefault)
void SetCoutFileName(const G4String &fileN="G4cout.txt", G4bool ifAppend=true)
G4MTcoutDestination(const G4int &threadId)
G4coutDestination * ref_defaultOut
void AddCoutFileName(const G4String &fileN="G4cout.txt", G4bool ifAppend=true)
G4StateManager * stateMgr
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)
app
Definition: demo.py:189