Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
@@ -46,32 +46,31 @@
#include "G4RootAnalysisManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4H1Wrapper::G4H1Wrapper(G4VAnalysisManager* const analysisManager,
const G4int histoIndex) :
fAnalysisManager(analysisManager),
fHistoIndex(histoIndex),
fHisto(dynamic_cast<G4RootAnalysisManager*>(analysisManager)->GetH1(histoIndex)),
//fAxis(fHisto->axis()),
fNumBins(fHisto->axis().bins()),
fIsSet(false),
fUnderflow(0.),
fOverflow(0.),
fSumSquaredEventTotals(0.),
fSumSquaredEventInRangeTotals(0.)
G4H1Wrapper::G4H1Wrapper(G4VAnalysisManager* const analysisManager, const G4int histoIndex)
: fAnalysisManager(analysisManager),
fHistoIndex(histoIndex),
fHisto(dynamic_cast<G4RootAnalysisManager*>(analysisManager)->GetH1(histoIndex)),
// fAxis(fHisto->axis()),
fNumBins(fHisto->axis().bins()),
fIsSet(false),
fUnderflow(0.),
fOverflow(0.),
fSumSquaredEventTotals(0.),
fSumSquaredEventInRangeTotals(0.)
{
fEventData.assign(fNumBins, 0.);
}
// ***************************************************************************
// Fill data WITHIN THE EVENT. Can be called an arbitrary number of times.
// ***************************************************************************
void G4H1Wrapper::Fill(const G4double abscissaValue,
const G4double weight) {
if (!fIsSet) { fIsSet = true; }
void G4H1Wrapper::Fill(const G4double abscissaValue, const G4double weight)
{
if (!fIsSet) {
fIsSet = true;
}
const G4int binIndex = fHisto->axis().coord_to_index(abscissaValue);
@@ -91,30 +90,24 @@ void G4H1Wrapper::Fill(const G4double abscissaValue,
}
}
// ***************************************************************************
// End of event: flush all data collected during the event
// End of event: flush all data collected during the event
// to G4VAnalysisManager's G4H1, then reset event data.
// ***************************************************************************
void G4H1Wrapper::EndOfEvent() {
void G4H1Wrapper::EndOfEvent()
{
// Only do the flush if there was at least one fill during the event.
if (fIsSet) {
G4double eventTotal = 0.;
// FLUSH IN RANGE DATA.
for (G4int binIndex = 0; binIndex < fNumBins; ++binIndex) {
if (fEventData[binIndex] > 0.) {
const G4double binKineticEnergy = fHisto->axis().bin_center(binIndex);
const G4double binEventWeight = fEventData[binIndex];
fAnalysisManager->FillH1(fHistoIndex,
binKineticEnergy,
binEventWeight);
fAnalysisManager->FillH1(fHistoIndex, binKineticEnergy, binEventWeight);
eventTotal += binEventWeight;
fEventData[binIndex] = 0.;
fEventData[binIndex] = 0.;
}
}
// Also keep track of the event's total (INTEGRAL over abscissa range).
@@ -124,18 +117,14 @@ void G4H1Wrapper::EndOfEvent() {
// FLUSH UNDERFLOW DATA.
if (fUnderflow > 0.) {
fAnalysisManager->FillH1(fHistoIndex,
fHisto->axis().lower_edge() - 1.,
fUnderflow);
fAnalysisManager->FillH1(fHistoIndex, fHisto->axis().lower_edge() - 1., fUnderflow);
fSumSquaredEventTotals += fUnderflow;
fUnderflow = 0.;
}
// FLUSH OVERFLOW DATA.
if (fOverflow > 0.) {
fAnalysisManager->FillH1(fHistoIndex,
fHisto->axis().upper_edge() + 1.,
fOverflow);
fAnalysisManager->FillH1(fHistoIndex, fHisto->axis().upper_edge() + 1., fOverflow);
fSumSquaredEventTotals += fOverflow;
fOverflow = 0.;
}
@@ -34,298 +34,242 @@
//
/// Tools to dump any G4H1 into Flair-compatible format.
///
/// These tools are fully application-agnostic,
/// and could also be placed outside of the G4 examples,
/// These tools are fully application-agnostic,
/// and could also be placed outside of the G4 examples,
/// as a core G4 Analysis Manager extension.
//
// ***************************************************************************
#include "tools_histo_flair.hh"
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <stdarg.h>
#include <cstring>
#include <memory>
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4ios.hh"
#include <cstring>
#include <fstream>
#include <iomanip>
#include <memory>
#include <stdarg.h>
#include <stdlib.h>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
namespace tools {
namespace histo {
namespace flair {
namespace tools
{
namespace histo
{
namespace flair
{
// ***************************************************************************
// Returns abscissa name.
// ***************************************************************************
G4String getAbscissaName(const Abscissa abscissaKind) {
G4String abscissaName = "";
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaName = "kE";
}
else if (abscissaKind == Abscissa::Z) {
abscissaName = "Z";
}
else if (abscissaKind == Abscissa::A) {
abscissaName = "A";
}
return abscissaName;
}
// ***************************************************************************
// Returns abscissa name.
// ***************************************************************************
G4String getAbscissaName(const Abscissa abscissaKind)
{
G4String abscissaName = "";
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaName = "kE";
}
else if (abscissaKind == Abscissa::Z) {
abscissaName = "Z";
}
else if (abscissaKind == Abscissa::A) {
abscissaName = "A";
}
return abscissaName;
}
// ***************************************************************************
// Returns abscissa unit.
// ***************************************************************************
G4String getAbscissaUnit(const Abscissa abscissaKind)
{
G4String abscissaUnit = "";
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaUnit = "GeV";
}
return abscissaUnit;
}
// ***************************************************************************
// Returns abscissa unit.
// ***************************************************************************
G4String getAbscissaUnit(const Abscissa abscissaKind) {
G4String abscissaUnit = "";
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaUnit = "GeV";
}
return abscissaUnit;
}
// ***************************************************************************
// Returns abscissa unit value.
// ***************************************************************************
G4double getAbscissaUnitValue(const Abscissa abscissaKind)
{
G4double abscissaUnitValue = 1.;
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaUnitValue = G4UnitDefinition::GetValueOf(getAbscissaUnit(Abscissa::KineticEnergy));
}
return abscissaUnitValue;
}
// ***************************************************************************
// Returns abscissa unit value.
// ***************************************************************************
G4double getAbscissaUnitValue(const Abscissa abscissaKind) {
G4double abscissaUnitValue = 1.;
if (abscissaKind == Abscissa::KineticEnergy) {
abscissaUnitValue = G4UnitDefinition::GetValueOf(getAbscissaUnit(Abscissa::KineticEnergy));
}
return abscissaUnitValue;
}
// ***************************************************************************
// String format like printf() for strings.
// This sformat function is extracted as-is from geoviewer,
// and was written by V. Vlachoudis in 2010.
// ***************************************************************************
G4String sformat(const char* fmt, ...)
{
std::unique_ptr<char[]> formatted;
G4int n = (G4int)strlen(fmt) * 2; // Reserve two times as much as the length of the fmt_str.
while (true) {
// Wrap the plain char array into the unique_ptr.
formatted.reset(new char[n]);
strcpy(&formatted[0], fmt);
va_list ap;
va_start(ap, fmt);
G4int final_n = vsnprintf(&formatted[0], n, fmt, ap);
va_end(ap);
if (final_n < 0 || final_n >= n) {
n += std::abs(final_n - n + 1);
}
else {
break;
}
}
return G4String(formatted.get());
}
// ***************************************************************************
// Returns MC error.
// ***************************************************************************
G4double computeError(const G4double mean, const G4double sumSquares, const G4int numEvents)
{
const G4double var = std::max(0., sumSquares / numEvents - mean * mean);
const G4double err =
((mean != 0. && numEvents > 1) ? std::sqrt(var / (numEvents - 1)) / mean : 1.);
// ***************************************************************************
// String format like printf() for strings.
// This sformat function is extracted as-is from geoviewer,
// and was written by V. Vlachoudis in 2010.
// ***************************************************************************
G4String sformat(const char* fmt, ...) {
std::unique_ptr<char[]> formatted;
G4int n = (G4int)strlen(fmt) * 2; // Reserve two times as much as the length of the fmt_str.
while (true) {
// Wrap the plain char array into the unique_ptr.
formatted.reset(new char[n]);
strcpy(&formatted[0], fmt);
va_list ap;
va_start(ap, fmt);
G4int final_n = vsnprintf(&formatted[0], n, fmt, ap);
va_end(ap);
if (final_n < 0 || final_n >= n) {
n += std::abs(final_n - n + 1);
}
else {
break;
}
}
return G4String(formatted.get());
}
return err * 100.;
}
// ***************************************************************************
// Returns MC error.
// ***************************************************************************
G4double computeError(const G4double mean,
const G4double sumSquares,
const G4int numEvents) {
// ***************************************************************************
// Dump G4H1 (histo mode) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1HistoInFlairFormat(std::ofstream& output, const G4int indexInOutputFile,
const G4String& histoName, G4H1* const histo,
const Abscissa abscissaKind, const G4String& binSchemeName,
const G4int numEvents, const G4double sumSquaredEventTotals,
const G4double sumSquaredEventInRangeTotals)
{
const G4bool isProfile = false;
dumpG4H1InFlairFormat(output, indexInOutputFile, histoName, histo, abscissaKind, binSchemeName,
numEvents, isProfile, sumSquaredEventTotals, sumSquaredEventInRangeTotals);
}
const G4double var = std::max(0., sumSquares / numEvents - mean*mean);
const G4double err = ((mean != 0. && numEvents > 1) ?
std::sqrt(var / (numEvents-1)) / mean
: 1.);
// ***************************************************************************
// Dump G4H1 (profile mode, ie no stats) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1ProfileInFlairFormat(std::ofstream& output, const G4int indexInOutputFile,
const G4String& histoName, G4H1* const histo,
const Abscissa abscissaKind, const G4String& binSchemeName)
{
const G4bool isProfile = true;
const G4int numEvents = 1;
dumpG4H1InFlairFormat(output, indexInOutputFile, histoName, histo, abscissaKind, binSchemeName,
numEvents, isProfile);
}
return err * 100.;
}
// ***************************************************************************
// Dump G4H1 (profile + histo modes) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1InFlairFormat(std::ofstream& output, const G4int indexInOutputFile,
const G4String& histoName, G4H1* const histo,
const Abscissa abscissaKind, const G4String& binSchemeName,
const G4int numEvents, const G4bool isProfile,
const G4double sumSquaredEventTotals,
const G4double sumSquaredEventInRangeTotals)
{
const G4int numBins = histo->axis().bins();
const G4double minAbscissa = histo->axis().lower_edge();
const G4double maxAbscissa = histo->axis().upper_edge();
const G4String abscissaName = getAbscissaName(abscissaKind);
const G4String abscissaUnit = getAbscissaUnit(abscissaKind);
const G4double abscissaUnitValue = getAbscissaUnitValue(abscissaKind);
// ***************************************************************************
// Dump G4H1 (histo mode) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1HistoInFlairFormat(std::ofstream& output,
const G4int indexInOutputFile,
const G4String& histoName,
G4H1* const histo,
const Abscissa abscissaKind,
const G4String& binSchemeName,
const G4int numEvents,
const G4double sumSquaredEventTotals,
const G4double sumSquaredEventInRangeTotals) {
// START HEADER.
if (indexInOutputFile != 1) {
output << G4endl << G4endl;
}
output << std::left << std::setw(13) << "# Detector: " << indexInOutputFile << " " << histoName
<< G4endl;
output << std::left << std::setw(13) << "# Dim: " << histo->get_dimension() << G4endl;
output << std::left << std::setw(13) << "# Entries: " << numEvents << G4endl;
const G4bool isProfile = false;
dumpG4H1InFlairFormat(output,
indexInOutputFile,
histoName,
histo,
abscissaKind,
binSchemeName,
numEvents,
isProfile,
sumSquaredEventTotals,
sumSquaredEventInRangeTotals);
}
if (!isProfile) {
// Total integral
const G4double total = static_cast<G4double>(histo->sum_all_bin_heights()) / numEvents;
const G4double totalError = computeError(total, sumSquaredEventTotals, numEvents);
output << std::left << std::setw(13)
<< "# Total: " << sformat("%-15g [1/pr] +/- %6.2f [%] \n", total, totalError);
// In range integral
const G4double inRange = static_cast<G4double>(histo->sum_bin_heights()) / numEvents;
const G4double inRangeError = computeError(inRange, sumSquaredEventInRangeTotals, numEvents);
output << std::left << std::setw(13)
<< "# InRange: " << sformat("%-15g [1/pr] +/- %6.2f [%] \n", inRange, inRangeError);
// ***************************************************************************
// Dump G4H1 (profile mode, ie no stats) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1ProfileInFlairFormat(std::ofstream& output,
const G4int indexInOutputFile,
const G4String& histoName,
G4H1* const histo,
const Abscissa abscissaKind,
const G4String& binSchemeName) {
// Underflow
const G4double underflow = static_cast<G4double>(histo->bins_sum_w().at(0)) / numEvents;
const G4double underflowError = computeError(underflow, histo->bins_sum_w2().at(0), numEvents);
output << std::left << std::setw(13)
<< "# Under: " << sformat("%-15g [1/pr] +/- %6.2f [%] \n", underflow, underflowError);
const G4bool isProfile = true;
const G4int numEvents = 1;
dumpG4H1InFlairFormat(output,
indexInOutputFile,
histoName,
histo,
abscissaKind,
binSchemeName,
numEvents,
isProfile);
}
// Overflow
const G4double overflow =
static_cast<G4double>(histo->bins_sum_w().at(numBins + 1)) / numEvents;
const G4double overflowError =
computeError(overflow, histo->bins_sum_w2().at(numBins + 1), numEvents);
output << std::left << std::setw(13)
<< "# Over: " << sformat("%-15g [1/pr] +/- %6.2f [%] \n", overflow, overflowError);
}
// END HEADER.
output << std::left << std::setw(13) << "# Log: " << binSchemeName << G4endl;
output << std::left << std::setw(13) << "# Histogram: " << numBins << " "
<< minAbscissa / abscissaUnitValue << " " << maxAbscissa / abscissaUnitValue << " ["
<< abscissaUnit << "]" << G4endl;
// ***************************************************************************
// Dump G4H1 (profile + histo modes) to a Flair-compatible format.
// ***************************************************************************
void dumpG4H1InFlairFormat(std::ofstream& output,
const G4int indexInOutputFile,
const G4String& histoName,
G4H1* const histo,
const Abscissa abscissaKind,
const G4String& binSchemeName,
const G4int numEvents,
const G4bool isProfile,
const G4double sumSquaredEventTotals,
const G4double sumSquaredEventInRangeTotals) {
output << std::left << std::setw(13) << "# Column: "
<< "1 " << abscissaName << "_min "
<< "[" << abscissaUnit << "]" << G4endl;
output << std::left << std::setw(13) << "# Column: "
<< "2 " << abscissaName << "_max "
<< "[" << abscissaUnit << "]" << G4endl;
output << std::left << std::setw(13) << "# Column: "
<< "3 dN/d(" << abscissaName << ") "
<< "[1" << (abscissaUnit.empty() ? "" : ("/" + abscissaUnit)) << "/pr]" << G4endl;
if (!isProfile) {
output << std::left << std::setw(13) << "# Column: "
<< "4 error "
<< "[%]" << G4endl;
}
const G4int numBins = histo->axis().bins();
const G4double minAbscissa = histo->axis().lower_edge();
const G4double maxAbscissa = histo->axis().upper_edge();
// HISTO / PROFILE DATA.
for (G4int binIndex = 0; binIndex < numBins; ++binIndex) {
const G4double mean = histo->bin_height(binIndex) / numEvents;
const G4double err = computeError(mean, histo->bins_sum_w2().at(binIndex + 1), numEvents);
const G4String abscissaName = getAbscissaName(abscissaKind);
const G4String abscissaUnit = getAbscissaUnit(abscissaKind);
const G4double abscissaUnitValue = getAbscissaUnitValue(abscissaKind);
// histo mode
if (!isProfile) {
output << sformat("%15g %15g %15g %6.2f\n",
histo->axis().bin_lower_edge(binIndex) / abscissaUnitValue,
histo->axis().bin_upper_edge(binIndex) / abscissaUnitValue,
mean / histo->axis().bin_width(binIndex) * abscissaUnitValue, err);
}
// profile mode
else {
output << sformat("%15g %15g %15g\n",
histo->axis().bin_lower_edge(binIndex) / abscissaUnitValue,
histo->axis().bin_upper_edge(binIndex) / abscissaUnitValue,
mean / histo->axis().bin_width(binIndex) * abscissaUnitValue);
}
} // loop on all bins
} // dumpG4H1InFlairFormat
// START HEADER.
if (indexInOutputFile != 1) { output << G4endl << G4endl; }
output << std::left << std::setw(13) << "# Detector: " << indexInOutputFile
<< " " << histoName << G4endl;
output << std::left << std::setw(13) << "# Dim: " << histo->get_dimension() << G4endl;
output << std::left << std::setw(13) << "# Entries: " << numEvents << G4endl;
if (!isProfile) {
// Total integral
const G4double total = static_cast<G4double>(histo->sum_all_bin_heights()) / numEvents;
const G4double totalError = computeError(total,
sumSquaredEventTotals,
numEvents);
output << std::left << std::setw(13) << "# Total: "
<< sformat("%-15g [1/pr] +/- %6.2f [%] \n",
total,
totalError);
// In range integral
const G4double inRange = static_cast<G4double>(histo->sum_bin_heights()) / numEvents;
const G4double inRangeError = computeError(inRange,
sumSquaredEventInRangeTotals,
numEvents);
output << std::left << std::setw(13) << "# InRange: "
<< sformat("%-15g [1/pr] +/- %6.2f [%] \n",
inRange,
inRangeError);
// Underflow
const G4double underflow = static_cast<G4double>(histo->bins_sum_w().at(0)) / numEvents;
const G4double underflowError = computeError(underflow,
histo->bins_sum_w2().at(0),
numEvents);
output << std::left << std::setw(13) << "# Under: "
<< sformat("%-15g [1/pr] +/- %6.2f [%] \n",
underflow,
underflowError);
// Overflow
const G4double overflow = static_cast<G4double>(histo->bins_sum_w().at(numBins+1)) / numEvents;
const G4double overflowError = computeError(overflow,
histo->bins_sum_w2().at(numBins+1),
numEvents);
output << std::left << std::setw(13) << "# Over: "
<< sformat("%-15g [1/pr] +/- %6.2f [%] \n",
overflow,
overflowError);
}
// END HEADER.
output << std::left << std::setw(13) << "# Log: " << binSchemeName << G4endl;
output << std::left << std::setw(13) << "# Histogram: "
<< numBins
<< " " << minAbscissa / abscissaUnitValue
<< " " << maxAbscissa / abscissaUnitValue
<< " [" << abscissaUnit << "]"
<< G4endl;
output << std::left << std::setw(13) << "# Column: "
<< "1 " << abscissaName << "_min "
<< "[" << abscissaUnit << "]"
<< G4endl;
output << std::left << std::setw(13) << "# Column: "
<< "2 " << abscissaName << "_max "
<< "[" << abscissaUnit << "]"
<< G4endl;
output << std::left << std::setw(13) << "# Column: "
<< "3 dN/d(" << abscissaName << ") "
<< "[1" << (abscissaUnit.empty() ? "" : ("/" + abscissaUnit)) << "/pr]"
<< G4endl;
if (!isProfile) {
output << std::left << std::setw(13) << "# Column: "
<< "4 error "
<< "[%]"
<< G4endl;
}
// HISTO / PROFILE DATA.
for (G4int binIndex = 0; binIndex < numBins; ++binIndex) {
const G4double mean = histo->bin_height(binIndex) / numEvents;
const G4double err = computeError(mean,
histo->bins_sum_w2().at(binIndex+1),
numEvents);
// histo mode
if (!isProfile) {
output << sformat("%15g %15g %15g %6.2f\n",
histo->axis().bin_lower_edge(binIndex) / abscissaUnitValue,
histo->axis().bin_upper_edge(binIndex) / abscissaUnitValue,
mean / histo->axis().bin_width(binIndex) * abscissaUnitValue,
err);
}
// profile mode
else {
output << sformat("%15g %15g %15g\n",
histo->axis().bin_lower_edge(binIndex) / abscissaUnitValue,
histo->axis().bin_upper_edge(binIndex) / abscissaUnitValue,
mean / histo->axis().bin_width(binIndex) * abscissaUnitValue);
}
} // loop on all bins
} // dumpG4H1InFlairFormat
} // namespace flair
} // namespace histo
} // namespace tools
} // namespace flair
} // namespace histo
} // namespace tools
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......