Import Geant4 10.4.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2017-06-30 10:49:55 +02:00
parent 3a5407696b
commit 1a1316fea4
2180 changed files with 237880 additions and 59109 deletions
@@ -0,0 +1,93 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/*
* G4BuffercoutDestination.cc
*
* Created on: Apr 14, 2017
* Author: adotti
*/
#include "G4BuffercoutDestination.hh"
#include "G4AutoLock.hh"
#include <iostream>
G4BuffercoutDestination::G4BuffercoutDestination(size_t max) :
m_buffer_out("") , m_buffer_err(""), m_currentSize_out(0) ,
m_currentSize_err(0), m_maxSize(max) {}
G4BuffercoutDestination::~G4BuffercoutDestination() {
Finalize();
}
void G4BuffercoutDestination::Finalize() {
FlushG4cerr();
FlushG4cout();
}
G4int G4BuffercoutDestination::ReceiveG4cout(const G4String& msg) {
m_currentSize_out += msg.size();
m_buffer_out << msg;
//If there is a max size and it has been reached, flush
if ( m_maxSize>0 && m_currentSize_out >= m_maxSize ) {
FlushG4cout();
}
return 0;
}
G4int G4BuffercoutDestination::ReceiveG4cerr(const G4String& msg) {
m_currentSize_err += msg.size();
m_buffer_err << msg;
//If there is a max size and it has been reached, flush
if ( m_maxSize>0 && m_currentSize_err >= m_maxSize ) {
FlushG4cerr();
}
return 0;
}
G4int G4BuffercoutDestination::FlushG4cout() {
std::cout<<m_buffer_out.str()<<std::flush;
ResetCout();
return 0;
}
void G4BuffercoutDestination::ResetCout() {
m_buffer_out.str("");
m_buffer_out.clear();
m_currentSize_out = 0;
}
G4int G4BuffercoutDestination::FlushG4cerr() {
std::cerr<<m_buffer_err.str()<<std::flush;
ResetCerr();
return 0;
}
void G4BuffercoutDestination::ResetCerr() {
m_buffer_err.str("");
m_buffer_err.clear();
m_currentSize_err = 0;
}
@@ -0,0 +1,78 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4FilecoutDestination.cc 103582 2017-04-18 17:24:45Z adotti $
//
// --------------------------------------------------------------------
//
// G4FilecoutDestination.cc
//
// Author: A.Dotti (SLAC), April 2017
// --------------------------------------------------------------------
#include "G4FilecoutDestination.hh"
#include <ios>
G4FilecoutDestination::~G4FilecoutDestination()
{
Close();
if ( m_output ) m_output.reset();
}
void G4FilecoutDestination::Open(std::ios_base::openmode mode)
{
if ( m_name.isNull() )
{
#ifndef __MIC
// Cannot use G4Exception, because G4cout/G4cerr is not setup
throw std::ios_base::failure("No output file name specified");
#endif
}
if ( m_output != nullptr && m_output->is_open() ) Close();
m_output.reset( new std::ofstream(m_name , std::ios_base::out|mode) );
}
void G4FilecoutDestination::Close()
{
if ( m_output && m_output->is_open() )
{
m_output->close();
}
}
G4int G4FilecoutDestination::ReceiveG4cout(const G4String& msg)
{
if ( m_output == nullptr || ! m_output->is_open() ) Open(m_mode);
*m_output << msg;
return 0;
}
G4int G4FilecoutDestination::ReceiveG4cerr(const G4String& msg)
{
if ( m_output == nullptr || ! m_output->is_open() ) Open(m_mode);
*m_output << msg;
return 0;
}
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4LockcoutDestination.cc 103582 2017-04-18 17:24:45Z adotti $
//
// --------------------------------------------------------------------
//
// G4LockcoutDestination.cc
//
// Author: A.Dotti (SLAC), April 2017
// --------------------------------------------------------------------
#include "G4LockcoutDestination.hh"
#include "G4AutoLock.hh"
namespace
{
G4Mutex out_mutex = G4MUTEX_INITIALIZER;
}
G4LockcoutDestination::~G4LockcoutDestination()
{
}
G4int G4LockcoutDestination::ReceiveG4cout(const G4String& msg )
{
G4AutoLock l(&out_mutex);
// Forward call to base class
return G4coutDestination::ReceiveG4cout(msg);
}
G4int G4LockcoutDestination::ReceiveG4cerr(const G4String& msg )
{
G4AutoLock l(&out_mutex);
return G4coutDestination::ReceiveG4cerr(msg);
}
@@ -23,160 +23,266 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4MTcoutDestination.cc 66241 2012-12-13 18:34:42Z gunter $
//
//
// ----------------------------------------------------------------------
// G4MTcoutDestination
// --------------------------------------------------------------------
//
// G4MTcoutDestination.cc
//
// --------------------------------------------------------------------
#include <sstream>
#include <assert.h>
#include "G4MTcoutDestination.hh"
#include "G4LockcoutDestination.hh"
#include "G4MasterForwardcoutDestination.hh"
#include "G4FilecoutDestination.hh"
#include "G4BuffercoutDestination.hh"
#include "G4strstreambuf.hh"
#include "G4AutoLock.hh"
G4MTcoutDestination::G4MTcoutDestination(const G4int& threadId,
std::ostream& co, std::ostream& ce)
: finalcout(co), finalcerr(ce), id(threadId), useBuffer(false),
threadCoutToFile(false), threadCerrToFile(false),
ignoreCout(false), ignoreInit(true)
namespace
{
G4String empty = "";
}
G4MTcoutDestination::G4MTcoutDestination(const G4int& threadId)
: ref_defaultOut(nullptr), ref_masterOut(nullptr),
masterDestinationFlag(true),masterDestinationFmtFlag(true),
id(threadId), useBuffer(false), ignoreCout(false), ignoreInit(true),
prefix("G4WT")
{
// TODO: Move these two out of here and in the caller
G4coutbuf.SetDestination(this);
G4cerrbuf.SetDestination(this);
prefix = "G4WT";
stateMgr=G4StateManager::GetStateManager();
SetDefaultOutput(masterDestinationFlag,masterDestinationFmtFlag);
}
void G4MTcoutDestination::SetDefaultOutput( G4bool addmasterDestination ,
G4bool formatAlsoMaster )
{
masterDestinationFlag = addmasterDestination;
masterDestinationFmtFlag = formatAlsoMaster;
// Formatter: add prefix to each thread
const auto f = [this](G4String& msg)->G4bool {
std::ostringstream str;
str<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) str<<id;
str<<" > "<<msg;
msg = str.str();
return true;
};
// Block cout if not in correct state
const auto filter_out = [this](G4String&)->G4bool {
if (this->ignoreCout ||
( this->ignoreInit &&
this->stateMgr->GetCurrentState() == G4State_Idle ) )
{ return false; }
return true;
};
// Default behavior, add a destination that uses cout and uses a mutex
auto output = G4coutDestinationUPtr( new G4LockcoutDestination );
ref_defaultOut = output.get();
output->AddCoutTransformer(filter_out);
output->AddCoutTransformer(f);
output->AddCerrTransformer(f);
push_back( std::move(output) );
if ( addmasterDestination )
{
AddMasterOutput(formatAlsoMaster);
}
}
void G4MTcoutDestination::AddMasterOutput(G4bool formatAlsoMaster )
{
// Add a destination, that forwards the message to the master thread
auto forwarder = G4coutDestinationUPtr( new G4MasterForwardcoutDestination );
ref_masterOut = forwarder.get();
const auto filter_out = [this](G4String&)->G4bool {
if (this->ignoreCout ||
( this->ignoreInit &&
this->stateMgr->GetCurrentState() == G4State_Idle ) )
{ return false; }
return true;
};
forwarder->AddCoutTransformer(filter_out);
if ( formatAlsoMaster )
{
// Formatter: add prefix to each thread
const auto f = [this](G4String& msg)->G4bool {
std::ostringstream str;
str<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) str<<id;
str<<" > "<<msg;
msg = str.str();
return true;
};
forwarder->AddCoutTransformer(f);
forwarder->AddCerrTransformer(f);
}
push_back( std::move(forwarder ) );
}
G4MTcoutDestination::~G4MTcoutDestination()
{
if( useBuffer ) DumpBuffer();
if( threadCoutToFile ) CloseCoutFile();
if( threadCerrToFile ) CloseCerrFile();
if ( useBuffer ) DumpBuffer();
}
namespace { G4Mutex coutm = G4MUTEX_INITIALIZER; }
#include "G4StateManager.hh"
G4int G4MTcoutDestination::ReceiveG4cout(const G4String& msg)
void G4MTcoutDestination::Reset()
{
if( threadCoutToFile )
{ coutFile<<msg<<std::flush; }
else if( useBuffer )
{ cout_buffer<<msg; }
else if( !ignoreCout )
clear();
SetDefaultOutput(masterDestinationFlag,masterDestinationFmtFlag);
}
void G4MTcoutDestination::HandleFileCout(G4String fileN, G4bool ifAppend,
G4bool suppressDefault)
{
// Logic: we create a file destination. We want this to get only the G4cout
// stream and should discard everything in G4cerr.
// First we create the destination with the appropriate open mode
std::ios_base::openmode mode = (ifAppend ? std::ios_base::app
: std::ios_base::trunc);
auto output = G4coutDestinationUPtr( new G4FilecoutDestination(fileN,mode));
// This reacts only to G4cout, so let's make a filter that removes everything
// from G4cerr
output->AddCerrTransformer( [](G4String&) { return false;} );
push_back(std::move(output));
// Silence G4cout from default formatter
if ( suppressDefault )
{
if(!ignoreInit ||
G4StateManager::GetStateManager()->GetCurrentState() != G4State_Idle )
{
G4AutoLock l(&coutm);
finalcout<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) finalcout<<id;
finalcout<<" > "<<msg<<std::flush;
}
ref_defaultOut->AddCoutTransformer( [](G4String&) { return false; } );
if ( ref_masterOut )
ref_masterOut->AddCoutTransformer( [](G4String&) { return false; } );
}
//forward message to master G4coutDestination if set
if ( masterG4coutDestination && !ignoreCout &&
( !ignoreInit || G4StateManager::GetStateManager()->GetCurrentState() != G4State_Idle )
){
G4AutoLock l(&coutm);
std::stringstream ss;
ss<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) ss<<id;
ss<<" > "<<msg;
masterG4coutDestination->ReceiveG4cout(ss.str());
}
return 0;
}
G4int G4MTcoutDestination::ReceiveG4cerr(const G4String& msg)
void G4MTcoutDestination::HandleFileCerr(G4String fileN, G4bool ifAppend,
G4bool suppressDefault)
{
if( threadCerrToFile )
{ cerrFile<<msg<<std::flush; }
if( useBuffer )
{ cerr_buffer<<msg; }
else
{ G4AutoLock l(&coutm);
finalcerr<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) finalcerr<<id;
finalcerr<<" > "<<msg<<std::flush;
}
//forward message to master G4coutDestination if set
if ( masterG4coutDestination && !ignoreCout &&
( !ignoreInit || G4StateManager::GetStateManager()->GetCurrentState() != G4State_Idle )
){
G4AutoLock l(&coutm);
std::stringstream ss;
ss<<prefix;
if ( id!=G4Threading::GENERICTHREAD_ID ) ss<<id;
ss<<" > "<<msg;
masterG4coutDestination->ReceiveG4cerr(ss.str());
}
return 0;
}
// See HandleFileCout for explanation, switching cout with cerr
void G4MTcoutDestination::SetCoutFileName(const G4String& fileN, G4bool ifAppend)
{
if( threadCoutToFile ) CloseCoutFile();
if( fileN == "**Screen**" ) return;
if( ! coutFile.is_open() )
std::ios_base::openmode mode = (ifAppend ? std::ios_base::app
: std::ios_base::trunc);
auto output = G4coutDestinationUPtr( new G4FilecoutDestination(fileN,mode));
output->AddCoutTransformer( [](G4String&) { return false;} );
push_back(std::move(output));
if ( suppressDefault )
{
std::ios::openmode mode = std::ios::out;
if ( ifAppend ) mode |= std::ios::app;
coutFile.open(fileN,mode);
ref_defaultOut->AddCerrTransformer( [](G4String&) { return false; } );
if ( ref_masterOut )
ref_masterOut->AddCerrTransformer( [](G4String&) { return false; } );
}
threadCoutToFile = true;
}
void G4MTcoutDestination::SetCerrFileName(const G4String& fileN, G4bool ifAppend)
void G4MTcoutDestination::SetCoutFileName(const G4String& fileN,
G4bool ifAppend)
{
if( threadCerrToFile ) CloseCerrFile();
if( fileN == "**Screen**" ) return;
if( ! cerrFile.is_open() )
// First let's go back to the default
Reset();
if ( fileN != "**Screen**" )
{
std::ios::openmode mode = std::ios::out;
if ( ifAppend ) mode |= std::ios::app;
cerrFile.open(fileN,mode);
HandleFileCout(fileN,ifAppend,true);
}
threadCerrToFile = true;
}
void G4MTcoutDestination::EnableBuffering(G4bool flag)
{
if(useBuffer && !flag) DumpBuffer();
// I was using buffered output and now I want to turn it off, dump current
// buffer content and reset output
if ( useBuffer && !flag )
{
DumpBuffer();
Reset();
}
else if ( useBuffer && flag ) { /* do nothing: already using */ }
else if ( !useBuffer && !flag ) { /* do nothing: not using */ }
else if ( !useBuffer && flag )
{
// Remove everything, in this case also removing the forward to the master
// thread, we want everything to be dumpled to a file
clear();
const size_t infiniteSize = 0;
push_back(G4coutDestinationUPtr(new G4BuffercoutDestination(infiniteSize)));
}
else { assert(false); } // Should never happen
useBuffer = flag;
}
void G4MTcoutDestination::SetPrefixString(const G4String& wd)
{ prefix = wd; }
void G4MTcoutDestination::AddCoutFileName(const G4String& fileN,
G4bool ifAppend)
{
// This is like the equivalent SetCoutFileName, but in this case we do not
// remove or silence what is already exisiting
HandleFileCout(fileN,ifAppend,false);
}
void G4MTcoutDestination::SetCerrFileName(const G4String& fileN,
G4bool ifAppend)
{
// See SetCoutFileName for explanation
Reset();
if ( fileN != "**Screen**")
{
HandleFileCerr(fileN,ifAppend,true);
}
}
void G4MTcoutDestination::AddCerrFileName(const G4String& fileN,
G4bool ifAppend)
{
HandleFileCerr(fileN,ifAppend,false);
}
void G4MTcoutDestination::SetIgnoreCout(G4int tid)
{
if(tid<0)
{ ignoreCout = false; }
else
{ ignoreCout = (tid!=id); }
if (tid<0) { ignoreCout = false; }
else { ignoreCout = (tid!=id); }
}
void G4MTcoutDestination::CloseCoutFile()
namespace
{
if( coutFile.is_open() ) coutFile.close();
threadCoutToFile = false;
}
void G4MTcoutDestination::CloseCerrFile()
{
if( cerrFile.is_open() ) cerrFile.close();
threadCerrToFile = false;
G4Mutex coutm = G4MUTEX_INITIALIZER;
}
void G4MTcoutDestination::DumpBuffer()
{
G4AutoLock l(&coutm);
finalcout<<"====================="<<std::endl;
finalcout<<"cout buffer for worker with ID:"<<id<<std::endl;
finalcout<<cout_buffer.str()<<std::endl;
finalcerr<<"====================="<<std::endl;
finalcerr<<"cerr buffer for worker with ID:"<<id<<std::endl;
finalcerr<<cerr_buffer.str()<<std::endl;
finalcerr<<"====================="<<std::endl;
std::ostringstream msg;
msg << "=======================\n";
msg << "cout buffer(s) for worker with ID:" << id << std::endl;
G4coutDestination::ReceiveG4cout(msg.str());
G4bool sep = false;
std::for_each( begin() , end(),
[this,&sep](G4coutDestinationUPtr& el) {
auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
if ( cout != nullptr ) {
cout->FlushG4cout();
if ( sep ) { G4coutDestination::ReceiveG4cout("==========\n"); }
else { sep = true; }
}
} );
sep = false;
msg.str("");
msg.clear();
msg << "=======================\n";
msg << "cerr buffer(s) for worker with ID:" << id
<< " (goes to std error)" << std::endl;
G4coutDestination::ReceiveG4cout(msg.str());
std::for_each( begin() , end(),
[this,&sep](G4coutDestinationUPtr& el) {
auto cout = dynamic_cast<G4BuffercoutDestination*>(el.get());
if ( cout != nullptr ) {
cout->FlushG4cerr();
if (sep ) { G4coutDestination::ReceiveG4cout("==========\n"); }
else { sep = true; }
}
} );
G4coutDestination::ReceiveG4cout("=======================\n");
}
@@ -0,0 +1,69 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4MasterForwardcoutDestination.cc 103582 2017-04-18 17:24:45Z adotti $
//
// --------------------------------------------------------------------
//
// G4MasterForwardcoutDestination.cc
//
// Author: A.Dotti (SLAC), April 2017
// --------------------------------------------------------------------
#include "G4MasterForwardcoutDestination.hh"
#include "G4AutoLock.hh"
namespace
{
G4Mutex out_mutex = G4MUTEX_INITIALIZER;
}
G4MasterForwardcoutDestination::~G4MasterForwardcoutDestination()
{
}
G4int G4MasterForwardcoutDestination::ReceiveG4cout(const G4String& msg )
{
// If a master destination is set check that we are not in a recursive
// situation, send the message to the master, using a lock to serialize calls
// Master is probably a (G)UI that is not thread-safe
if ( masterG4coutDestination && this!=masterG4coutDestination)
{
G4AutoLock l(&out_mutex);
return masterG4coutDestination->ReceiveG4cout_(msg);
}
return 0;
}
G4int G4MasterForwardcoutDestination::ReceiveG4cerr(const G4String& msg )
{
if ( masterG4coutDestination && this!=masterG4coutDestination)
{
G4AutoLock l(&out_mutex);
return masterG4coutDestination->ReceiveG4cerr_(msg);
}
return 0;
}
@@ -24,31 +24,72 @@
// ********************************************************************
//
//
// $Id: G4coutDestination.cc 82279 2014-06-13 14:44:00Z gcosmo $
// $Id: G4coutDestination.cc 103661 2017-04-20 14:57:11Z gcosmo $
//
//
// ----------------------------------------------------------------------
// G4coutDestination
//
// ----------------------------------------------------------------------
#include "G4coutDestination.hh"
G4coutDestination* G4coutDestination::masterG4coutDestination = 0;
#include <algorithm>
G4coutDestination::G4coutDestination()
{
}
G4coutDestination* G4coutDestination::masterG4coutDestination = 0;
G4coutDestination::~G4coutDestination()
{
}
G4int G4coutDestination::ReceiveG4cout(const G4String&)
void G4coutDestination::ResetTransformers()
{
transformersCout.clear(); transformersCerr.clear();
}
G4int G4coutDestination::ReceiveG4cout(const G4String& msg)
{
std::cout<<msg<<std::flush;
return 0;
}
G4int G4coutDestination::ReceiveG4cerr(const G4String&)
G4int G4coutDestination::ReceiveG4cerr(const G4String& msg)
{
std::cerr<<msg<<std::flush;
return 0;
}
G4int G4coutDestination::ReceiveG4cout_(const G4String& msg)
{
// Avoid copy of string if not necessary
if( transformersCout.size() > 0 )
{
G4String m = msg;
G4bool result = true;
for ( const auto& el : transformersCout )
{
result &= el(m);
if ( ! result ) break;
}
return ( result ? ReceiveG4cout(m) : 0 );
}
else
{
return ReceiveG4cout(msg);
}
}
G4int G4coutDestination::ReceiveG4cerr_(const G4String& msg)
{
if( transformersCout.size() > 0 )
{
G4String m = msg;
std::for_each( transformersCerr.begin() , transformersCerr.end() ,
[&m](const Transformer& t) { t(m); }
// Call transforming function on message
);
return ReceiveG4cerr(m);
}
else
{
return ReceiveG4cerr(msg);
}
}
@@ -0,0 +1,167 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4coutFormatters.cc 103582 2017-04-18 17:24:45Z adotti $
//
// --------------------------------------------------------------------
//
// G4coutFormatters.cc
//
// Author: A.Dotti (SLAC), April 2017
// --------------------------------------------------------------------
#include "G4coutFormatters.hh"
namespace G4coutFormatters
{
// Internal functions and utilites used to setup default formatters
namespace
{
// Split a single string in an array of strings
String_V split(const G4String& input, char separator='\n')
{
String_V output;
G4String::size_type prev_pos=0, pos=0;
while( (pos=input.find(separator,pos))!=G4String::npos)
{
G4String substr( input.substr(prev_pos,pos-prev_pos)) ;
output.push_back(substr);
prev_pos = ++pos;
}
// output.push_back( input.substr(prev_pos,pos-prev_pos));
return output;
}
// Return a syslog style message with input message, type identifies
// the type of the message
G4bool transform( G4String& input , const G4String& type)
{
std::time_t result = std::time(nullptr);
std::ostringstream newm;
#if __GNUC__ >= 5
newm << std::put_time(std::localtime(&result),"%d/%b/%Y:%H:%M:%S %z");
#else
std::tm* time_ = std::localtime(&result);
newm << time_->tm_mday << "/" << time_->tm_mon << "/" << time_->tm_year;
newm << ":" << time_->tm_hour << ":"<<time_->tm_min<<":"<<time_->tm_sec;
#endif
newm<<" "<<type<<" [";
G4String delimiter = "";
for (const auto& el : split(input) )
{
if ( !el.empty() )
{
newm << delimiter << el ;
delimiter = "\\n";
}
}
newm<<" ]"<<G4endl;
input = newm.str();
return true;
}
// Style used in master thread
G4String masterStyle = "";
// Modify output to look like syslog messages:
// DATE TIME **LOG|ERROR** [ "multi","line","message"]
SetupStyle_f SysLogStyle = [](G4coutDestination* dest)->G4int
{
if ( dest != nullptr )
{
dest->AddCoutTransformer(std::bind(&transform,std::placeholders::_1,
"INFO"));
dest->AddCerrTransformer(std::bind(&transform,std::placeholders::_1,
"ERROR"));
}
return 0;
};
// Bring back destination to original state
SetupStyle_f DefaultStyle = [](G4coutDestination* dest)->G4int
{
if ( dest != nullptr )
{
dest->ResetTransformers();
}
return 0;
};
std::unordered_map<std::string,SetupStyle_f> transformers =
{
{ID::SYSLOG,SysLogStyle},
{ID::DEFAULT,DefaultStyle}
};
}
void SetMasterStyle(const G4String& news )
{
masterStyle = news;
}
G4String GetMasterStyle()
{
return masterStyle;
}
void SetupStyleGlobally(const G4String& news)
{
static G4coutDestination ss;
G4coutbuf.SetDestination(&ss);
G4cerrbuf.SetDestination(&ss);
G4coutFormatters::HandleStyle(&ss,news);
G4coutFormatters::SetMasterStyle(news);
}
String_V Names()
{
String_V result;
for ( const auto& el : transformers )
{
result.push_back(el.first);
}
return result;
}
G4int HandleStyle( G4coutDestination* dest , const G4String& style)
{
const auto& handler = transformers.find(style);
return ( handler != transformers.end() ) ? (handler->second)(dest) : -1;
}
void RegisterNewStyle(const G4String& name , SetupStyle_f& fmt)
{
if ( transformers.find(name) != transformers.end() )
{
G4ExceptionDescription msg;
msg << "Format Style with name " << name
<< " already exists. Replacing existing.";
G4Exception("G4coutFormatters::RegisterNewStyle()",
"FORMATTER001", JustWarning, msg);
}
// transformers.insert(std::make_pair(name,fmt));
transformers[name]=fmt;
}
}