Import Geant4 11.4.1 source tree

This commit is contained in:
Gabriele Cosmo
2026-03-19 16:51:22 +01:00
parent b4a16de652
commit 41f2dd7996
352 changed files with 26342 additions and 24532 deletions
+4
View File
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-19 Gabriele Cosmo (field-V11-03-10)
- Fixed reported Coverity defect for restoring original stream precision in
G4FieldManager::ReportBadEpsilonValue().
## 2025-11-03 Vladimir Ivanchenko (field-V11-03-09)
- G4TClassicalRK4 - fixed typo identified by CMS
@@ -419,7 +419,7 @@ ReportBadEpsilonValue(G4ExceptionDescription& erm, G4double value, const G4Strin
<< " Its value is outside the permitted range from "
<< fMinAcceptedEpsilon << " to " << fMaxAcceptedEpsilon << G4endl
<< " Clarification: " << G4endl;
G4long oldPrec = erm.precision();
G4long oldPrec = erm.precision(8);
if(value < fMinAcceptedEpsilon )
{
erm << " a) The value must be positive and enough larger than the accuracy limit"
@@ -230,8 +230,9 @@ G4double G4VSIntegration::SampleValue()
if ((gg > gmax || n >= nmax) && fVerbose > 0) {
++fnWarn;
if (fnWarn < fWarnLimit) {
G4double xg = (gmax > 0.0) ? gg/gmax : 0.0;
G4cout << "### G4VSIntegration::SampleValue() for " << ModelName()
<< " in area=" << idx << " n=" << n << " gg/gmax=" << gg/gmax
<< " in area=" << idx << " n=" << n << " gg/gmax=" << xg
<< " prob=" << gg << " gmax=" << gmax << G4endl;
G4cout << " E=" << e << " Emin=" << fEmin << " Emax=" << fEmax
<< " E1=" << fE1 << " E2=" << fE2 << " E3=" << E3
+14
View File
@@ -6,6 +6,20 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-03-06 Ben Morgan (global-V11-03-32)
- Always initialize G4CacheReference for a G4Cache instance on construction of latter.
- Prevents fatal G4Exception when only low ID G4Cache elements are accessed,
see Issue #281 for details.
## 2026-02-12 Gabriele Cosmo
- Protect debug warning printout from G4Cache destructor within 'g4cdebug' flag
as it was originally intended. Addressing long-standing false-positive issue
happening in MT mode (G4MTRunManager only) on macOS/clang.
Also problem report #2696.
## 2026-01-03 Vladimir Ivantchenko
- G4VSIntegration - fixed Coverity warning.
## 2025-12-05 Gabriele Cosmo (global-V11-03-31)
- Updated tag IDs for geant4-11-04-ref-00.
+8 -7
View File
@@ -211,6 +211,7 @@ G4Cache<V>::G4Cache()
{
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
id = instancesctr++;
theCache.Initialize(id);
#ifdef g4cdebug
std::cout << "G4Cache id: " << id << std::endl;
#endif
@@ -290,15 +291,15 @@ G4Cache<V>::~G4Cache()
} catch(std::system_error& e)
{
// the error that comes from locking an unavailable mutex
#ifdef G4VERBOSE
G4cout << "Non-critical error: mutex lock failure in ~G4Cache<"
<< typeid(V).name() << ">. " << G4endl
#ifdef g4cdebug
std::cout << "Non-critical error: mutex lock failure in ~G4Cache<"
<< typeid(V).name() << ">. " << std::endl
<< "If the RunManagerKernel has been deleted, it failed to "
<< "delete an allocated resource" << G4endl
<< "delete an allocated resource" << std::endl
<< "and this destructor is being called after the statics "
<< "were destroyed." << G4endl;
G4cout << "Exception: [code: " << e.code() << "] caught: " << e.what()
<< G4endl;
<< "were destroyed." << std::endl;
std::cout << "Exception: [code: " << e.code() << "] caught: " << e.what()
<< std::endl;
#endif
}
++dstrctr;
@@ -43,7 +43,7 @@
/// |--> patch number (single digit)
///
#ifndef G4VERSION_NUMBER
#define G4VERSION_NUMBER 1140
#define G4VERSION_NUMBER 1141
#endif
/// @def G4VERSION_REFERENCE_TAG
@@ -59,7 +59,7 @@
#endif
#ifndef G4VERSION_TAG
#define G4VERSION_TAG "$Name: geant4-11-04 $"
#define G4VERSION_TAG "$Name: geant4-11-04-patch-01 $"
#endif
// as variables
@@ -68,10 +68,10 @@
#include "G4Types.hh"
#ifdef G4MULTITHREADED
static const G4String G4Version = "$Name: geant4-11-04 [MT]$";
static const G4String G4Version = "$Name: geant4-11-04-patch-01 [MT]$";
#else
static const G4String G4Version = "$Name: geant4-11-04 $";
static const G4String G4Version = "$Name: geant4-11-04-patch-01 $";
#endif
static const G4String G4Date = "(5-December-2025)";
static const G4String G4Date = "(13-March-2026)";
#endif
+19 -4
View File
@@ -5,6 +5,21 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-20 Gabriele Cosmo (interfaces-V11-03-13)
- Fix in G4UIQt::ComputeStringMatchScore(..) in setting number of elements
for a QVector; restored use of G4int in place of std::size_t, according
to QVector signature.
## 2026-02-17 Gabriele Cosmo
- G4UIQt: Use std::size_t and G4 types where appropriate.
## 2026-02-16 John Allison
- G4UIQt: Fix "Implicit conversion loses integer precision" warnings on Mac Xcode.
## 2026-01-30 Andrea Barresi
- G4UIQt: Reimplemented the command search feature for the Help tree.
## 2025-10-31 Andrea Barresi (interfaces-V11-03-12)
-G4VInteractiveSession:
- Added UpdateDrawingStyle, UpdateProjectionStyle, UpdateTransparencySlider
@@ -70,16 +85,16 @@ It must **not** be used as a substitute for writing good git commit messages!
- Introduce Time Window tab.
- This exploits generic time windowing recently introduced in modeling an
management.
- Try it with example B1. Hit Prepare, then Go. It is more spectacular
- Try it with example B1. Hit "Prepare", then "Go". It is more spectacular
if you prepare, say, 100 events.
- However, it doesnt work with OGL in Qt6. (Try it with Qt5 if you can.)
- However, it doesn't work with OGL in Qt6. (Try it with Qt5 if you can.)
TSG works fine with both Qt5 and Qt6, except line width is not implemented.
- I have noticed that in Qt5, mouse events seem to processed in strict order.
Values of boxes dont get updated until the windowing is finished. But with
Values of boxes don't get updated until the windowing is finished. But with
Qt6, events seem to be processed in parallel. Values in other boxes are
continuously updated during time evolution. How do they do that? Is each
slot executed on a different thread? This could cause the problem with OGL,
but I dont have sufficient knowledge of Qt protocols.
but I don't have sufficient knowledge of Qt protocols.
- Change "bar" to "toolbar" to avoid conflict with G4PhysicalConstants.
## 2025-01-06 John Allison (interfaces-V11-03-00)
@@ -25,8 +25,8 @@
//
//
//
#ifndef G4UIQt_h
#define G4UIQt_h
#ifndef G4UIQT_HH
#define G4UIQT_HH
#include "G4VBasicShell.hh"
#include "G4VInteractiveSession.hh"
@@ -307,11 +307,9 @@ private:
G4int&) override; // have to be implemeted because we heritate from G4VBasicShell
bool eventFilter(QObject*, QEvent*) override;
void ActivateCommand(G4String);
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
QMap<G4int, QString> LookForHelpStringInChildTree(G4UIcommandTree*, const QString&);
#else
QMultiMap<G4int, QString> LookForHelpStringInChildTree(G4UIcommandTree*, const QString&);
#endif
QMultiMap<G4double, QString> LookForHelpStringInChildTree(G4UIcommandTree*, const QString&);
G4double ComputeStringMatchScore(const QString&, const QString&);
QWidget* CreateVisParametersTBWidget();
QWidget* CreateHelpTBWidget();
QWidget* CreateTimeWindowWidget();
+86 -172
View File
@@ -2270,7 +2270,7 @@ QWidget* G4UIQt::CreateHelpTBWidget()
fHelpLine = new QLineEdit();
helpLayout->addWidget(new QLabel("Search :"));
helpLayout->addWidget(fHelpLine);
connect(fHelpLine, SIGNAL(editingFinished()), this, SLOT(LookForHelpStringCallback()));
connect(fHelpLine, SIGNAL(textChanged(const QString&)), this, SLOT(LookForHelpStringCallback()));
// Create Help tree
FillHelpTree();
@@ -4134,10 +4134,8 @@ void G4UIQt::FillHelpTree()
QString searchText = fHelpLine->text();
if (searchText == "") {
// clear old help tree
// fHelpTreeWidget->clear();
}
else {
fHelpTreeWidget->clear();
} else {
return;
}
@@ -4146,10 +4144,6 @@ void G4UIQt::FillHelpTree()
fParameterHelpTable->setVisible(false);
}
if (fHelpLine != nullptr) {
fHelpLine->setText("");
}
G4UImanager* UI = G4UImanager::GetUIpointer();
if (UI == nullptr) return;
G4UIcommandTree* treeTop = UI->GetTree();
@@ -5012,7 +5006,7 @@ void G4UIQt::UpdateCommandCompleter()
G4UIcommandTree* commandTreeTop = UI->GetTree();
G4UIcommandTree* aTree = commandTreeTop->FindCommandTree("/");
if (aTree != nullptr) {
int Ndir = aTree->GetTreeEntry();
G4int Ndir = aTree->GetTreeEntry();
fCompleter->setMaxVisibleItems(Ndir);
}
fCommandArea->setCompleter(fCompleter);
@@ -5521,9 +5515,9 @@ void G4UIQt::FilterAllOutputTextArea()
}
}
/** Callback called when user give a new string to look for<br>
Display a list of matching commands descriptions. If no string is set,
will display the complete help tree
/* Callback called when user give a new string to look for
Display a list of matching commands.
If no string is set, will display the complete help tree
*/
void G4UIQt::LookForHelpStringCallback()
{
@@ -5533,92 +5527,34 @@ void G4UIQt::LookForHelpStringCallback()
fParameterHelpLabel->setText("");
fParameterHelpTable->setVisible(false);
if (searchText == "") {
// clear old help tree
fHelpTreeWidget->clear();
FillHelpTree();
return;
}
OpenHelpTreeOnCommand(searchText);
}
void G4UIQt::OpenHelpTreeOnCommand(const QString& searchText)
{
// Invoke textual help (writes guidance to output window)
ApplyShellCommand("help "+G4String(searchText.toStdString()), exitSession, exitPause);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
// The code below searches the help tree and offers a list of commands matching searchText.
// All is OK with Qt5, but there is an undiagnosed crash with Qt6, so disable this feature.
// FIXME : JA 8/8/25
// the help tree
// Get the help tree
G4UImanager* UI = G4UImanager::GetUIpointer();
if (UI == nullptr) return;
G4UIcommandTree* treeTop = UI->GetTree();
G4int treeSize = treeTop->GetTreeEntry();
// clear old help tree
// Clear old help tree
fHelpTreeWidget->clear();
// look for new items
// Look for matching commands
QMultiMap<G4double, QString> commandResultMap;
commandResultMap = LookForHelpStringInChildTree(treeTop, searchText);
int tmp = 0;
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
// Before Qt5.15
QMap<G4int, QString> commandResultMap;
QMap<G4int, QString> commandChildResultMap;
for (G4int a = 0; a < treeSize; ++a) {
G4UIcommand* command = treeTop->FindPath(treeTop->GetTree(a + 1)->GetPathName().data());
tmp = GetCommandList(command).count(searchText, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insertMulti(
tmp, QString((char*)(treeTop->GetTree(a + 1)->GetPathName()).data()));
}
// look for childs
commandChildResultMap = LookForHelpStringInChildTree(treeTop->GetTree(a + 1), searchText);
// insert new childs
if (! commandChildResultMap.empty()) {
QMap<int, QString>::const_iterator i = commandChildResultMap.constBegin();
while (i != commandChildResultMap.constEnd()) {
commandResultMap.insertMulti(i.key(), i.value());
i++;
}
commandChildResultMap.clear();
}
}
#else
// Qt5.15 and beyond
QMultiMap<G4int, QString> commandResultMap;
QMultiMap<G4int, QString> commandChildResultMap;
for (G4int a = 0; a < treeSize; ++a) {
G4UIcommand* command = treeTop->FindPath(treeTop->GetTree(a + 1)->GetPathName().data());
tmp = (int)GetCommandList(command).count(searchText, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insert(tmp, QString((char*)(treeTop->GetTree(a + 1)->GetPathName()).data()));
}
// look for childs
commandChildResultMap = LookForHelpStringInChildTree(treeTop->GetTree(a + 1), searchText);
// insert new childs
if (! commandChildResultMap.empty()) {
auto i = commandChildResultMap.constBegin();
while (i != commandChildResultMap.constEnd()) {
commandResultMap.insert(i.key(), i.value());
++i;
}
commandChildResultMap.clear();
}
}
#endif
// build new help tree
// Build new help tree
fHelpTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
fHelpTreeWidget->setColumnCount(2);
QStringList labels;
labels << QString("Command") << QString("Match");
QStringList labels = {"Command", "Match"};
fHelpTreeWidget->setHeaderLabels(labels);
if (commandResultMap.empty()) {
@@ -5627,123 +5563,101 @@ void G4UIQt::OpenHelpTreeOnCommand(const QString& searchText)
return;
}
auto i = commandResultMap.constEnd();
i--;
// 10 maximum progress values
G4float multValue = 10.0 / (G4float)(i.key());
QString progressChar = "|";
QString progressStr = "|";
QTreeWidgetItem* newItem;
G4bool end = false;
while (! end) {
if (i == commandResultMap.constBegin()) {
end = true;
}
for (G4int a = 0; a < G4int(i.key() * multValue); ++a) {
G4int nItems = 0;
for (auto it = commandResultMap.end(); it != commandResultMap.begin();) {
it--;
if (nItems >= 50) break;
// 20 maximum progress values
for (G4int i = 0; i < G4int(it.key() * 10); ++i) {
progressStr += progressChar;
}
newItem = new QTreeWidgetItem();
QString commandStr = i.value().trimmed();
QString commandStr = it.value().trimmed();
if (commandStr.indexOf("/") == 0) {
commandStr = commandStr.right(commandStr.size() - 1);
commandStr.remove(0, 1);
}
newItem->setText(0, commandStr);
newItem->setText(1, progressStr);
fHelpTreeWidget->addTopLevelItem(newItem);
newItem->setForeground(1, QBrush(Qt::blue));
if (it.key() > 1) {
newItem->setForeground(1, QBrush(Qt::red));
} else {
newItem->setForeground(1, QBrush(Qt::blue));
}
progressStr = "|";
i--;
++nItems;
}
fHelpTreeWidget->resizeColumnToContents(0);
fHelpTreeWidget->sortItems(1, Qt::DescendingOrder);
// fHelpTreeWidget->setColumnWidth(1,10);//resizeColumnToContents (1);
#endif
}
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
// Before Qt5.15
QMap<G4int, QString> G4UIQt::LookForHelpStringInChildTree(
G4UIcommandTree* aCommandTree, const QString& text)
QMultiMap<G4double, QString> G4UIQt::LookForHelpStringInChildTree(
G4UIcommandTree* aCommandTree, const QString& searchText)
{
QMap<G4int, QString> commandResultMap;
if (aCommandTree == NULL) return commandResultMap;
// Get the Sub directories
G4int tmp = 0;
QMap<G4int, QString> commandChildResultMap;
for (G4int a = 0; a < aCommandTree->GetTreeEntry(); ++a) {
const G4UIcommand* command = aCommandTree->GetGuidance();
tmp = GetCommandList(command).count(text, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insertMulti(
tmp, QString((char*)(aCommandTree->GetTree(a + 1)->GetPathName()).data()));
}
// look for childs
commandChildResultMap = LookForHelpStringInChildTree(aCommandTree->GetTree(a + 1), text);
if (! commandChildResultMap.empty()) {
// insert new childs
QMap<G4int, QString>::const_iterator i = commandChildResultMap.constBegin();
while (i != commandChildResultMap.constEnd()) {
commandResultMap.insertMulti(i.key(), i.value());
++i;
}
commandChildResultMap.clear();
}
}
// Get the Commands
for (G4int a = 0; a < aCommandTree->GetCommandEntry(); ++a) {
const G4UIcommand* command = aCommandTree->GetCommand(a + 1);
tmp = GetCommandList(command).count(text, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insertMulti(
tmp, QString((char*)(aCommandTree->GetCommand(a + 1)->GetCommandPath()).data()));
}
}
return commandResultMap;
}
#else
// Qt5.15 and beyond
QMultiMap<G4int, QString> G4UIQt::LookForHelpStringInChildTree(
G4UIcommandTree* aCommandTree, const QString& text)
{
QMultiMap<G4int, QString> commandResultMap;
QMultiMap<G4double, QString> commandResultMap;
if (aCommandTree == nullptr) return commandResultMap;
// Get the Sub directories
G4int tmp = 0;
QMultiMap<G4int, QString> commandChildResultMap;
for (G4int a = 0; a < aCommandTree->GetTreeEntry(); ++a) {
const G4UIcommand* command = aCommandTree->GetGuidance();
tmp = (int)GetCommandList(command).count(text, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insert(
tmp, QString((char*)(aCommandTree->GetTree(a + 1)->GetPathName()).data()));
}
// look for childs
commandChildResultMap = LookForHelpStringInChildTree(aCommandTree->GetTree(a + 1), text);
if (! commandChildResultMap.empty()) {
// insert new childs
auto i = commandChildResultMap.constBegin();
while (i != commandChildResultMap.constEnd()) {
commandResultMap.insert(i.key(), i.value());
++i;
}
commandChildResultMap.clear();
}
// Loop over sub trees
QMultiMap<G4double, QString> commandChildResultMap;
for (G4int i = 0; i < aCommandTree->GetTreeEntry(); ++i) {
commandChildResultMap = LookForHelpStringInChildTree(aCommandTree->GetTree(i + 1), searchText);
commandResultMap += commandChildResultMap;
commandChildResultMap.clear();
}
// Get the Commands
for (G4int a = 0; a < aCommandTree->GetCommandEntry(); ++a) {
const G4UIcommand* command = aCommandTree->GetCommand(a + 1);
tmp = (int)GetCommandList(command).count(text, Qt::CaseInsensitive);
if (tmp > 0) {
commandResultMap.insert(
tmp, QString((char*)(aCommandTree->GetCommand(a + 1)->GetCommandPath()).data()));
}
// Loop over the commands and compute match score
for (G4int i = 0; i < aCommandTree->GetCommandEntry(); ++i) {
const G4UIcommand* command = aCommandTree->GetCommand(i + 1);
if (command == nullptr) continue;
G4double score = ComputeStringMatchScore(QString(command->GetCommandPath().data()), searchText);
if (score > 0) commandResultMap.insert(score, QString(command->GetCommandPath().data()));
}
return commandResultMap;
}
#endif
G4double G4UIQt::ComputeStringMatchScore(const QString& string, const QString& searchText)
{
if (string.contains(searchText, Qt::CaseInsensitive)) {
//Score (1,2] for matched string
return 1 + G4double(searchText.size()) / string.size();
} else {
//Score (0,1) for similar string (Normalized Levenshtein distance)
const auto nSize = (G4int)string.size();
const auto mSize = (G4int)searchText.size();
QVector<QVector<G4int>> dp(nSize + 1, QVector<G4int>(mSize + 1));
for (G4int i = 0; i <= nSize; ++i) dp[i][0] = i;
for (G4int j = 0; j <= mSize; ++j) dp[0][j] = j;
for (G4int i = 1; i <= nSize; ++i) {
for (G4int j = 1; j <= mSize; ++j) {
G4int cost = (string[i - 1] == searchText[j - 1]) ? 0 : 1;
dp[i][j] = std::min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost});
}
}
return 1.0 - G4double(dp[nSize][mSize]) / std::max(nSize, mSize);
}
}
QString G4UIQt::GetShortCommandPath(QString& commandPath)
{
+8
View File
@@ -5,6 +5,14 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-25 Vladimir Ivanchenko (particles-V11-03-02)
- Attempt to fixed data race in ion creation (Bugzilla #2680) by extention
of excited isomer name from 3 to 5 digits after dot.
## 2026-01-14 Shogo Okada
- Fixed energy conservation in G4MuonDecayChannel (Bugzilla #2678).
## 2025-11-4 Shogo Okada (particles-V11-03-01)
- Scanned all mesons and baryons, including their resonances, to compare their
particle properties with PDG-2025. Then, updated mass, decay width, and
@@ -826,7 +826,7 @@ G4String G4IonTable::GetIonName(G4int Z, G4int A, G4double E,
if (E > 0 || flb != G4Ions::G4FloatLevelBase::no_Float) {
std::ostringstream os;
os.setf(std::ios::fixed);
os.precision(3);
os.precision(5);
// Excited nucleus
os << '[' << E / keV;
if (flb != G4Ions::G4FloatLevelBase::no_Float) {
@@ -29,6 +29,10 @@
// Contributions:
// - 2005 - M.Melissas, J.Brunner CPPM/IN2P3
// Added V-A fluxes for neutrinos using a new algorithm, 2005
// - S.Okada KEK/CRC, 14 January 2026
// Fixed energy conservation in G4MuonDecayChannel (Bugzilla #2678):
// Corrected EMax definition to parentmass/2 and applied standard relativistic
// formula (p=sqrt(E^2-m^2)) to compute momenta for all decay products.
// --------------------------------------------------------------------
#include "G4MuonDecayChannel.hh"
@@ -142,7 +146,7 @@ G4DecayProducts* G4MuonDecayChannel::DecayIt(G4double)
G4double Ee, Ene;
G4double gam;
G4double EMax = parentmass / 2 - daughtermass[0];
G4double EMax = parentmass / 2;
const std::size_t MAX_LOOP = 1000;
// Generating Random Energy
@@ -174,7 +178,7 @@ G4DecayProducts* G4MuonDecayChannel::DecayIt(G4double)
rot.set(rphi, rtheta, rpsi);
// electron 0
daughtermomentum[0] = std::sqrt(Ee * Ee * EMax * EMax + 2.0 * Ee * EMax * daughtermass[0]);
daughtermomentum[0] = std::sqrt(Ee * Ee * EMax * EMax - daughtermass[0] * daughtermass[0]);
G4ThreeVector direction0(0.0, 0.0, 1.0);
direction0 *= rot;
@@ -186,7 +190,7 @@ G4DecayProducts* G4MuonDecayChannel::DecayIt(G4double)
// electronic neutrino 1
daughtermomentum[1] = std::sqrt(Ene * Ene * EMax * EMax + 2.0 * Ene * EMax * daughtermass[1]);
daughtermomentum[1] = std::sqrt(Ene * Ene * EMax * EMax - daughtermass[1] * daughtermass[1]);
G4ThreeVector direction1(sintheta, 0.0, costheta);
direction1 *= rot;
@@ -197,7 +201,7 @@ G4DecayProducts* G4MuonDecayChannel::DecayIt(G4double)
// muonnic neutrino 2
daughtermomentum[2] = std::sqrt(Enm * Enm * EMax * EMax + 2.0 * Enm * EMax * daughtermass[2]);
daughtermomentum[2] = std::sqrt(Enm * Enm * EMax * EMax - daughtermass[2] * daughtermass[2]);
G4ThreeVector direction2(-Ene / Enm * sintheta, 0, -Ee / Enm - Ene / Enm * costheta);
direction2 *= rot;
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-24 Vladimir Ivanchenko (phys-ctor-em-V11-03-16)
- G4EmStandardPhysics_option4 - added a possibility to use external dEdx tables
for ions (problem #2703). It is done by substitution of the
G4LindhardSorencenIonModel model class by G4IonParameterisedModel.
## 2025-10-29 Vladimir Ivanchenko (phys-ctor-em-V11-03-15)
- G4OpticalPhysics - instantiate a process only if it is activated,
added option to instantiate a new G4GeneralCerenkov.
@@ -41,8 +41,8 @@
// and intermediate energies
//
#ifndef G4EmStandardPhysics_option4_h
#define G4EmStandardPhysics_option4_h 1
#ifndef G4EMSTANDARDPHYSICS_OPTION4_HH
#define G4EMSTANDARDPHYSICS_OPTION4_HH
#include "G4VPhysicsConstructor.hh"
#include "globals.hh"
@@ -55,10 +55,13 @@ public:
explicit G4EmStandardPhysics_option4(G4int ver=1, const G4String& name="");
~G4EmStandardPhysics_option4() override;
~G4EmStandardPhysics_option4() override = default;
void ConstructParticle() override;
void ConstructProcess() override;
private:
G4bool fUseExternalDEDX{false};
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -106,7 +106,7 @@ G4_DECLARE_PHYSCONSTR_FACTORY(G4EmStandardPhysics_option4);
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmStandardPhysics_option4::G4EmStandardPhysics_option4(G4int ver,
const G4String&)
const G4String& nam)
: G4VPhysicsConstructor("G4EmStandard_opt4")
{
SetVerboseLevel(ver);
@@ -134,14 +134,11 @@ G4EmStandardPhysics_option4::G4EmStandardPhysics_option4(G4int ver,
param->SetMaxNIELEnergy(1*CLHEP::MeV);
param->SetPositronAtRestModelType(fAllisonPositronium);
SetPhysicsType(bElectromagnetic);
if (!nam.empty()) { fUseExternalDEDX = true; }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmStandardPhysics_option4::~G4EmStandardPhysics_option4() = default;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4EmStandardPhysics_option4::ConstructParticle()
{
// minimal set of particles for EM physics
@@ -318,7 +315,11 @@ void G4EmStandardPhysics_option4::ConstructProcess()
// generic ion
particle = G4GenericIon::GenericIon();
G4ionIonisation* ionIoni = new G4ionIonisation();
ionIoni->SetEmModel(new G4LindhardSorensenIonModel());
if (fUseExternalDEDX) {
ionIoni->SetEmModel(new G4IonParametrisedLossModel());
} else {
ionIoni->SetEmModel(new G4LindhardSorensenIonModel());
}
ph->RegisterProcess(hmsc, particle);
ph->RegisterProcess(ionIoni, particle);
if(nullptr != pnuc) { ph->RegisterProcess(pnuc, particle); }
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-01-21 Vladimir Ivanchenko (phys-ctor-helastic-V11-03-01)
- G4ChargeExchangePhysics, G4ChargeExchangemessenger - added two
different biasing factors for pions and kaons (urgent request of NA64).
## 2025-04-15 Vladimir Ivanchenko (phys-ctor-helastic-V11-03-00)
- G4ChargeExchangePhysics - fixed usage of the messenger
@@ -35,8 +35,8 @@
//----------------------------------------------------------------------------
//
#ifndef G4ChargeExchangeMessenger_h
#define G4ChargeExchangeMessenger_h 1
#ifndef G4CHARGEEXCHANGEMESSENGER_HH
#define G4CHARGEEXCHANGEMESSENGER_HH
#include "G4UImessenger.hh"
#include "G4UIdirectory.hh"
@@ -62,6 +62,7 @@ private:
G4ChargeExchangePhysics* theB;
G4UIcmdWithADouble* fCmd;
G4UIcmdWithADouble* fCmd1;
G4UIcmdWithADoubleAndUnit* lCmd;
G4UIdirectory* aDir;
};
@@ -35,8 +35,8 @@
//----------------------------------------------------------------------------
//
#ifndef G4ChargeExchangePhysics_h
#define G4ChargeExchangePhysics_h 1
#ifndef G4CHARGEEXCHANGEPHYSICS_HH
#define G4CHARGEEXCHANGEPHYSICS_HH
#include "globals.hh"
#include "G4VPhysicsConstructor.hh"
@@ -55,8 +55,10 @@ public:
void SetLowEnergyLimit(G4double val) { fLowEnergyLimit = val; }
void SetCrossSectionFactor(G4double val) { fXSFactor = val; }
void SetPionCrossSectionFactor(G4double val) { fXSFactorPi = val; }
void SetKaonCrossSectionFactor(G4double val) { fXSFactorK = val; }
G4ChargeExchangePhysics& operator=
(const G4ChargeExchangePhysics& right) = delete;
G4ChargeExchangePhysics(const G4ChargeExchangePhysics&) = delete;
@@ -66,10 +68,10 @@ private:
G4ChargeExchangeMessenger* theMessenger;
G4double fLowEnergyLimit;
G4double fXSFactor{1.0};
G4double fXSFactorPi{1.0};
G4double fXSFactorK{1.0};
};
#endif
@@ -77,5 +79,3 @@ private:
@@ -45,11 +45,16 @@ G4ChargeExchangeMessenger::G4ChargeExchangeMessenger(G4ChargeExchangePhysics* a)
aDir = new G4UIdirectory("/physics_lists/cex/", false);
aDir->SetGuidance("tailoring the hadronic charge exchange processes.");
fCmd = new G4UIcmdWithADouble("/physics_lists/cex/BiasFactor",this);
fCmd->SetGuidance("Charge exchange cross section factor");
fCmd = new G4UIcmdWithADouble("/physics_lists/cex/PionBiasFactor",this);
fCmd->SetGuidance("Pion charge exchange cross section factor");
fCmd->AvailableForStates(G4State_PreInit);
fCmd->SetToBeBroadcasted(false);
fCmd1 = new G4UIcmdWithADouble("/physics_lists/cex/KaonBiasFactor",this);
fCmd1->SetGuidance("Kaon charge exchange cross section factor");
fCmd1->AvailableForStates(G4State_PreInit);
fCmd1->SetToBeBroadcasted(false);
lCmd = new G4UIcmdWithADoubleAndUnit("/process/cex/LowEnergyLimit",this);
lCmd->SetGuidance("Low-energy energy limit for charge exchange process");
lCmd->SetParameterName("cexLowE",true);
@@ -61,14 +66,18 @@ G4ChargeExchangeMessenger::G4ChargeExchangeMessenger(G4ChargeExchangePhysics* a)
G4ChargeExchangeMessenger::~G4ChargeExchangeMessenger()
{
delete fCmd;
delete fCmd1;
delete lCmd;
delete aDir;
}
void G4ChargeExchangeMessenger::SetNewValue(G4UIcommand* aComm, G4String aS)
{
if (aComm == fCmd)
theB->SetCrossSectionFactor(fCmd->GetNewDoubleValue(aS));
else if (aComm == lCmd)
if (aComm == fCmd) {
theB->SetPionCrossSectionFactor(fCmd->GetNewDoubleValue(aS));
} else if (aComm == fCmd1) {
theB->SetKaonCrossSectionFactor(fCmd1->GetNewDoubleValue(aS));
} else if (aComm == lCmd) {
theB->SetLowEnergyLimit(lCmd->GetNewDoubleValue(aS));
}
}
@@ -96,14 +96,15 @@ void G4ChargeExchangePhysics::ConstructProcess()
{
auto xs = new G4ChargeExchangeXS();
xs->SetEnergyLimit(fLowEnergyLimit);
xs->SetCrossSectionFactor(fXSFactor);
xs->SetPionCrossSectionFactor(fXSFactorPi);
xs->SetKaonCrossSectionFactor(fXSFactorK);
auto model = new G4ChargeExchange(xs);
if (G4HadronicParameters::Instance()->GetVerboseLevel() > 1) {
G4cout << "### ChargeExchangePhysics Construct Processes with the model <"
<< model->GetModelName() << "> and x-section <"
<< xs->GetName() << "> XSFactor=" << fXSFactor
<< xs->GetName() << "> XSFactorPi=" << fXSFactorPi << ", XSFactorK=" << fXSFactorK
<< G4endl;
}
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-01-27 Vladimir Ivanchenko (phys-ctor-hinelastic-V11-03-07)
- G4HadronInelasticQBBC - return back cross section G4ParticleInelasticXS
for protons, as it was in 11.3.
## 2026-01-23 Ben Morgan
- Fix segfault on gcc15/Debug/CXX23 build caused by destruction of G4NeutronPHPBuilder
instance used by G4NeutronBuilder in G4HadronPhysicsShielding.
- Triaged and fix proposed by Gunter Folger.
- See Issue #270
## 2025-11-19 Vladimir Ivanchenko (phys-ctor-hinelastic-V11-03-06)
- G4HadronPhysicsQGSP_BERT. G4HadronInelasticQBBC - return back cross section
G4BGGNucleonInelasticXS for protons, as it was in 11.3. There are problems
@@ -152,7 +152,7 @@ void G4HadronInelasticQBBC::ConstructProcess()
G4ParticleDefinition* particle = G4Proton::Proton();
G4HadronicProcess* hp =
new G4HadronInelasticProcess( particle->GetParticleName()+"Inelastic", particle );
hp->AddDataSet( new G4BGGNucleonInelasticXS(particle) );
hp->AddDataSet( new G4ParticleInelasticXS(particle) );
hp->RegisterMe(theFTFP);
hp->RegisterMe(theBERT);
hp->RegisterMe(theBIC);
@@ -126,8 +126,8 @@ void G4HadronPhysicsShielding::Neutron()
bertneu.SetMinEnergy( minBERT_neutron );
neu.RegisterMe( &bertneu );
G4NeutronPHPBuilder hpneu;
if ( !useLEND_) {
G4NeutronPHPBuilder hpneu;
neu.RegisterMe( &hpneu );
}
neu.Build();
+3
View File
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-07 Vladimir Ivanchenko (phys-list-V11-03-06)
- G4PhysListFactory - fixed trivial Coverity warning
## 2025-11-12 Vladimir Ivanchenko (phys-list-V11-03-05)
- G4PhysListFactory - for HP physics use the default EM constructor as it was
in Geant4 11.3.
@@ -146,7 +146,7 @@ G4PhysListFactory::GetReferencePhysList(const G4String& name)
for (std::size_t i=1; i<nlists_em; ++i) {
if (listnames_em[i] == ss) {
em_opt = i;
em_name = ss;
em_name = std::move(ss);
n -= 4;
break;
}
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-15 J. Allison (emlowen-V11-03-07)
- G4LivermorePolarizedComptonModel.cc:
- Improve/correct references to quantum entanglement papers.
## 2025-11-24 V. Ivanchenko (emlowen-V11-03-06)
- G4eIonisationSpectrum - removed compilation warnings by removal of checks of
numerical conditions which never happens.
@@ -33,10 +33,10 @@
// If the photons have been "tagged" as "quantum-entangled", for example by
// G4eplusAnnihilation for annihilation into 2 photons, they are "analysed"
// here if - and only if - both photons suffer Compton scattering. Theoretical
// predictions from Pryce and Ward, Nature No 4065 (1947) p.435, and Snyder et al,
// Physical Review 73 (1948) p.440. Experimental validation in "Photon quantum
// predictions from Pryce and Ward, Nature 160, 435 (1947), and Snyder et al,
// Phys. Rev. 73, 440 (1948). Experimental validation in "Photon quantum
// entanglement in the MeV regime and its application in PET imaging",
// D. Watts, J. Allison et al., Nature Communications (2021)12:2646
// D. Watts et al., Nature Communications 12, 2646 (2021),
// https://doi.org/10.1038/s41467-021-22907-5.
//
// 02 May 2009 S Incerti as V. Ivanchenko proposed in G4LivermoreComptonModel.cc
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-01-21 Vladimir Ivanchenko (hadr-cross-V11-03-10)
- G4ChargeExchangeXS - added two different biasing factors for pions and
kaons (urgent request NA64).
## 2026-01-11 Vladimir Ivanchenko
- G4ChargeExchangeXS - removed debug printout
## 2025-12-30 Vladimir Ivanchenko
- G4ChargeExchangeXS - fixed trivial Coverity warning
## 2025-11-24 Vladimir Ivanchenko (hadr-cross-V11-03-09)
- G4EMDissociationCrossSection - fixed compilation warning
@@ -48,8 +48,8 @@
// where Y = KS, KL
//
#ifndef G4ChargeExchangeXS_h
#define G4ChargeExchangeXS_h
#ifndef G4CHARGEEXCHANGEXS_HH
#define G4CHARGEEXCHANGEXS_HH
#include "G4VCrossSectionDataSet.hh"
#include "globals.hh"
@@ -86,10 +86,12 @@ public:
void SetEnergyLimit(G4double val) { fEnergyLimit = val; };
void SetCrossSectionFactor(G4double val) { fFactor = val; };
void SetPionCrossSectionFactor(G4double val) { fFactorPi = val; };
void SetKaonCrossSectionFactor(G4double val) { fFactorK = val; };
G4double GetCrossSectionFactor() const { return fFactor; };
G4bool isPion() const { return findex >= 0; };
G4double SampleTforPion(const G4double etot,
@@ -110,6 +112,8 @@ private:
const G4ParticleDefinition* fPionSecPD[5];
G4double fXSecPion[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
G4double fEnergyLimit{0.0};
G4double fFactorPi{1.0};
G4double fFactorK{1.0};
G4double fFactor{1.0};
G4double fMassPi;
};
@@ -121,6 +121,7 @@ G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
G4int ZZ, G4double pEtot)
{
G4double result = 0.0;
fFactor = fFactorK;
G4int pdg = part->GetPDGEncoding();
// Get or calculate the proton mass, particle mass, and s(Lorentz invariant)
@@ -145,6 +146,7 @@ G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
// pi- + p -> n + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
if (pdg == -211) {
fFactor = fFactorPi;
G4double z23 = g4calc->Z23(Z);
G4double x = lorentz_s*inv1e7;
G4double logX = G4Log(x);
@@ -163,6 +165,7 @@ G4double G4ChargeExchangeXS::GetCrossSection(const G4ParticleDefinition* part,
// pi+ + n -> p + meson (0- pi0, 1- eta, 2- eta', 3- omega, 4- f2(1270))
else if (pdg == 211) {
fFactor = fFactorPi;
G4double n23 = g4calc->Z23(A - Z);
G4double x = lorentz_s*inv1e7;
G4double logX = G4Log(x);
@@ -227,8 +230,7 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
GetCrossSection(part, mat, Z, etot);
const G4ParticleDefinition* pd = nullptr;
G4int pdg = std::abs(part->GetPDGEncoding());
G4cout << pdg << G4endl;
G4int pdg = std::abs(part->GetPDGEncoding());
// pi- + p / pi+ + n
if (pdg == 211) {
pd = fPionSecPD[0];
@@ -262,7 +264,7 @@ G4ChargeExchangeXS::SampleSecondaryType(const G4ParticleDefinition* part,
pd = G4KaonPlus::KaonPlus();
}
}
if (verboseLevel > 1) {
if (verboseLevel > 1 && nullptr != pd) {
G4cout << "G4ChargeExchangeXS::SampleSecondaryType for "
<< pd->GetParticleName() << " findex=" << findex
<< G4endl;
@@ -6,9 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-04 Gabriele Cosmo (had-binary-V11-03-00)
- Fixed reported Coverity defects to avoid parameter string copy in
G4BinaryCascade.
## 2025-12-23 Vladimir Ivantchenko
- G4GeneratorPrecompoundInterface - added G4HadronicException header.
## 2024-08-19 Gabriele Cosmo (had-binary-V11-02-01)
- Fixed reported Coverity defects for use of std::move() in G4BinaryCascade.
Minor code optimisation (use of nullptr, use of const iterators and pre-increment)
Minor code optimisation (use of nullptr, use of const iterators and pre-increment).
## 2024-05-22 Gunter Folger (had-binary-V11-02-00)
- Address problem reported by Atlas of throwing execption if momentum cannot
@@ -39,8 +39,8 @@
//
// -----------------------------------------------------------------------------
#ifndef G4BinaryCascade_hh
#define G4BinaryCascade_hh
#ifndef G4BINARYCASCADE_HH
#define G4BINARYCASCADE_HH
#include "G4VIntraNuclearTransportModel.hh"
#include "G4ReactionProductVector.hh"
@@ -172,8 +172,8 @@ private:
G4ReactionProductVector * ProductsAddFakeGamma(G4ReactionProductVector * products );
void PrintKTVector(G4KineticTrackVector * ktv, std::string comment=std::string(""));
void PrintKTVector(G4KineticTrack* kt, std::string comment=std::string(""));
void PrintKTVector(G4KineticTrackVector * ktv, const G4String& comment=G4String(""));
void PrintKTVector(G4KineticTrack* kt, const G4String& comment=G4String(""));
void DebugApplyCollisionFail(G4CollisionInitialState * collision,
G4KineticTrackVector * products);
void DebugApplyCollision(G4CollisionInitialState * collision,
@@ -2785,7 +2785,7 @@ void G4BinaryCascade::ClearAndDestroy(G4ReactionProductVector * rpv)
}
//----------------------------------------------------------------------------
void G4BinaryCascade::PrintKTVector(G4KineticTrackVector * ktv, std::string comment)
void G4BinaryCascade::PrintKTVector(G4KineticTrackVector * ktv, const G4String& comment)
//----------------------------------------------------------------------------
{
if (comment.size() > 0 ) G4cout << "G4BinaryCascade::PrintKTVector() " << comment << G4endl;
@@ -2806,7 +2806,7 @@ void G4BinaryCascade::PrintKTVector(G4KineticTrackVector * ktv, std::string comm
}
}
//----------------------------------------------------------------------------
void G4BinaryCascade::PrintKTVector(G4KineticTrack * kt, std::string comment)
void G4BinaryCascade::PrintKTVector(G4KineticTrack * kt, const G4String& comment)
//----------------------------------------------------------------------------
{
if (comment.size() > 0 ) G4cout << "G4BinaryCascade::PrintKTVector() "<< comment << G4endl;
@@ -92,6 +92,7 @@
#include "G4PhysicsModelCatalog.hh"
#include "G4HyperNucleiProperties.hh"
//---------------------------------------------------------------------
#include "G4HadronicException.hh"
#include "Randomize.hh"
#include "G4Log.hh"
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-16 Gabriele Cosmo (hadr-casc-V11-03-02)
- Directly use std::cbrt(double) in G4InuclSpecialFunctions, as now standard
and available in <cmath>, replacing old ad-hoc implementation.
Minor code formatting.
## 2025-11-26 Vladimir ivanchenko (hadr-casc-V11-03-01)
- G4BigBanger - fixed typo in the computation of probability, which is
identified by the new compiler and should not change any result.
@@ -23,21 +23,10 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4InuclSpecialFunctions namespace
//
// 20100114 M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
// 20100319 M. Kelsey -- Add optional mass argument to generateWithFixedTheta;
// define new generateWithRandomAngles, encapsulating code; define
// cbrt() cube-root function (in math.h, but not in <math>!)
// 20100412 M. Kelsey -- Modify paraMaker[Truncated] to take buffer as argument
// 20100914 M. Kelsey -- Migrate to integer A and Z. Discard unused binding
// energy functions
// 20120608 M. Kelsey -- Fix variable-name "shadowing" compiler warnings.
// 20130308 M. Kelsey -- New function to encapsulate INUCL power expansion
// 20130808 M. Kelsey -- Convert paraMaker[Truncated] to class object, to
// allow thread isolation
// 20130829 M. Kelsey -- Address Coverity #52158, 52161 for copy actions.
// 20150619 M. Kelsey -- Overload G4cbrt for case of integer arguments
// Original Author: Aatos Heikkinen, 2002
// --------------------------------------------------------------------
#ifndef G4INUCL_SPECIAL_FUNC_HH
#define G4INUCL_SPECIAL_FUNC_HH
@@ -48,8 +37,8 @@
template <int N> class G4CascadeInterpolator;
namespace G4InuclSpecialFunctions {
namespace G4InuclSpecialFunctions
{
G4double bindingEnergy(G4int A, G4int Z);
// NOTE: Used only by G4Fissioner
@@ -63,7 +52,7 @@ namespace G4InuclSpecialFunctions {
G4double csPN(G4double e);
G4double G4cbrt(G4double x); // Can't use "cbrt" name, clashes with <math.h>
G4double G4cbrt(G4double x); // Use std::cbrt from <cmath>
G4double G4cbrt(G4int n); // Use G4Pow::powN() here for speedup
G4double randomInuclPowers(G4double ekin, // Power series in Ekin, S
@@ -84,24 +73,26 @@ namespace G4InuclSpecialFunctions {
G4LorentzVector generateWithRandomAngles(G4double p, G4double mass=0.);
// This is an object to be instantiated by client code
class paraMaker {
public:
paraMaker(G4int verbose=0);
~paraMaker();
class paraMaker
{
public:
// NOTE: Passing Z as double here, to be used as interpolation argument
void getParams(G4double Z, std::pair<std::vector<G4double>,
std::vector<G4double> >& parms);
paraMaker(G4int verbose=0);
~paraMaker();
void getTruncated(G4double Z, std::pair<G4double, G4double>& parms);
paraMaker(const paraMaker& right) = delete;
paraMaker& operator=(const paraMaker& right) = delete;
private:
G4int verboseLevel;
G4CascadeInterpolator<5>* interp;
// NOTE: Passing Z as double here, to be used as interpolation argument
void getParams(G4double Z, std::pair<std::vector<G4double>,
std::vector<G4double> >& parms);
// No copy actions
paraMaker(const paraMaker& right);
paraMaker& operator=(const paraMaker& right);
void getTruncated(G4double Z, std::pair<G4double, G4double>& parms);
private:
G4int verboseLevel;
G4CascadeInterpolator<5>* interp;
};
}
@@ -23,17 +23,10 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4InuclSpecialFunctions namespace implementation
//
// 20100114 M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
// 20100914 M. Kelsey -- Migrate to integer A and Z. Discard pointless
// verbosity.
// 20120608 M. Kelsey -- Fix variable-name "shadowing" compiler warnings.
// 20130308 M. Kelsey -- New function to compute INUCL-style random value
// 20130314 M. Kelsey -- Restore null initializer and if-block for _TLS_.
// 20130924 M. Kelsey -- Use G4Log, G4Exp, G4Pow for CPU speedup
// 20150619 M. Kelsey -- Define G4cbrt(int) to use G4Pow::Z13, rearrange
// FermiEnergy() to use G4Pow::Z23.
// 20150622 M. Kelsey -- Use G4AutoDelete for _TLS_ buffers.
// Original Author: Aatos Heikkinen, 2002
// --------------------------------------------------------------------
#include <cmath>
@@ -52,7 +45,8 @@
G4double
G4InuclSpecialFunctions::randomInuclPowers(G4double ekin,
const G4double (&coeff)[4][4]) {
const G4double (&coeff)[4][4])
{
G4Pow* theG4Pow = G4Pow::GetInstance();
G4double S = G4UniformRand(); // Random fraction for expansion
@@ -75,11 +69,13 @@ G4InuclSpecialFunctions::randomInuclPowers(G4double ekin,
G4double G4InuclSpecialFunctions::getAL(G4int A) {
G4double G4InuclSpecialFunctions::getAL(G4int A)
{
return 0.76 + 2.2 / G4cbrt(A);
}
G4double G4InuclSpecialFunctions::csNN(G4double e) {
G4double G4InuclSpecialFunctions::csNN(G4double e)
{
G4double snn;
if (e < 40.0) {
@@ -91,7 +87,8 @@ G4double G4InuclSpecialFunctions::csNN(G4double e) {
return snn;
}
G4double G4InuclSpecialFunctions::csPN(G4double e) {
G4double G4InuclSpecialFunctions::csPN(G4double e)
{
G4double spn;
if (e < 40.0) {
@@ -105,7 +102,8 @@ G4double G4InuclSpecialFunctions::csPN(G4double e) {
// calculates the nuclei Fermi energy for 0 - neutron and 1 - proton
G4double G4InuclSpecialFunctions::FermiEnergy(G4int A, G4int Z, G4int ntype) {
G4double G4InuclSpecialFunctions::FermiEnergy(G4int A, G4int Z, G4int ntype)
{
G4Pow* g4pow = G4Pow::GetInstance();
const G4double C = 55.4 / g4pow->Z23(A);
G4double arg = (ntype==0) ? g4pow->Z23(A-Z) : g4pow->Z23(Z);
@@ -113,16 +111,18 @@ G4double G4InuclSpecialFunctions::FermiEnergy(G4int A, G4int Z, G4int ntype) {
return C * arg;
}
G4double G4InuclSpecialFunctions::G4cbrt(G4double x) {
return x==0 ? 0. : (x<0?-1.:1.)*G4Exp(G4Log(std::fabs(x))/3.);
G4double G4InuclSpecialFunctions::G4cbrt(G4double x)
{
return std::cbrt(x);
}
G4double G4InuclSpecialFunctions::G4cbrt(G4int n) {
G4double G4InuclSpecialFunctions::G4cbrt(G4int n)
{
return n==0 ? 0. : (n<0?-1.:1.)*G4Pow::GetInstance()->Z13(std::abs(n));
}
G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
G4double G4InuclSpecialFunctions::randomGauss(G4double sigma)
{
const G4double eps = 1.0e-6;
G4double r1 = G4UniformRand();
r1 = r1 > eps ? r1 : eps;
@@ -133,11 +133,13 @@ G4double G4InuclSpecialFunctions::randomGauss(G4double sigma) {
return sigma * std::sin(twopi * r1) * std::sqrt(-2.0 * G4Log(r2));
}
G4double G4InuclSpecialFunctions::randomPHI() {
G4double G4InuclSpecialFunctions::randomPHI()
{
return twopi*G4UniformRand();
}
std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN() {
std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN()
{
G4double CT = 1.0 - 2.0*G4UniformRand();
return std::pair<G4double, G4double>(CT, std::sqrt(1.0 - CT*CT));
@@ -145,7 +147,8 @@ std::pair<G4double, G4double> G4InuclSpecialFunctions::randomCOS_SIN() {
G4LorentzVector
G4InuclSpecialFunctions::generateWithFixedTheta(G4double ct, G4double p,
G4double mass) {
G4double mass)
{
G4double phi = randomPHI();
G4double pt = p * std::sqrt(std::fabs(1.0 - ct * ct));
@@ -171,7 +174,8 @@ G4InuclSpecialFunctions::generateWithFixedTheta(G4double ct, G4double p,
}
G4LorentzVector
G4InuclSpecialFunctions::generateWithRandomAngles(G4double p, G4double mass) {
G4InuclSpecialFunctions::generateWithRandomAngles(G4double p, G4double mass)
{
std::pair<G4double, G4double> COS_SIN = randomCOS_SIN();
G4double phi = randomPHI();
G4double pt = p * COS_SIN.second;
@@ -6,6 +6,12 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-01-05 Vladimir Ivanchenko (hadr-cohe-V11-03-06)
- G4ChargeExchange - fixed bug in sampling of scattering angle for kaons
## 2025-12-17 Vladimir Ivanchenko
- G4ChargeExchange, G4HadronElastic, G4LMsdGenerator - minor optimisation
## 2025-11-25 Vladimir Ivanchenko (hadr-cohe-V11-03-05)
- G4NuclNuclDiffuseElastic, G4DiffuseElastic, G4AntiNuclElastic - fixed
compilation warnings.
@@ -83,7 +83,6 @@ G4ChargeExchange::~G4ChargeExchange()
G4HadFinalState* G4ChargeExchange::ApplyYourself(
const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
{
theParticleChange.Clear();
auto part = aTrack.GetDefinition();
G4double ekin = aTrack.GetKineticEnergy();
@@ -303,8 +302,8 @@ G4double G4ChargeExchange::SampleT(const G4ParticleDefinition*,
}
G4double q1 = 1.0 - G4Exp(-std::min(bb*tmax, numLimit));
G4double q2 = 1.0 - G4Exp(-std::min(dd*tmax, numLimit));
G4double s1 = q1*aa;
G4double s2 = q2*cc;
G4double s1 = q1*aa/bb;
G4double s2 = q2*cc/dd;
if ((s1 + s2)*G4UniformRand() < s2) {
q1 = q2;
bb = dd;
@@ -66,7 +66,6 @@ G4HadronElastic::G4HadronElastic(const G4String& name)
G4HadronElastic::~G4HadronElastic()
{}
void G4HadronElastic::ModelDescription(std::ostream& outFile) const
{
outFile << "G4HadronElastic is the base class for all hadron-nucleus\n"
@@ -81,8 +80,6 @@ void G4HadronElastic::ModelDescription(std::ostream& outFile) const
G4HadFinalState* G4HadronElastic::ApplyYourself(
const G4HadProjectile& aTrack, G4Nucleus& targetNucleus)
{
theParticleChange.Clear();
const G4HadProjectile* aParticle = &aTrack;
G4double ekin = aParticle->GetKineticEnergy();
@@ -49,14 +49,10 @@ G4LMsdGenerator::G4LMsdGenerator(const G4String& name)
{
fPDGencoding = 0;
secID = G4PhysicsModelCatalog::GetModelID( "model_LMsdGenerator" );
// theParticleChange = new G4HadFinalState;
}
G4LMsdGenerator::~G4LMsdGenerator()
{
// delete theParticleChange;
}
{}
void G4LMsdGenerator::ModelDescription(std::ostream& outFile) const
{
@@ -114,8 +110,6 @@ G4HadFinalState*
G4LMsdGenerator::ApplyYourself( const G4HadProjectile& aTrack,
G4Nucleus& targetNucleus )
{
theParticleChange.Clear();
const G4HadProjectile* aParticle = &aTrack;
G4double eTkin = aParticle->GetKineticEnergy();
@@ -6,6 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-18 Gabriele Cosmo (hadr-fission-V11-03-00)
- Fixed reported Coverity defects in G4fissioner for avoiding unnecessary
copy of strings.
- Fixed layout of G4fissionEvent class.
## 2024-08-21 Gabriele Cosmo (hadr-fission-V11-02-01)
- Fixed reported Coverity defects for use of std::move().
@@ -53,40 +53,16 @@
// UCRL-CODE-224807
//
//
#ifndef G4fissionEvent_hh
#define G4fissionEvent_hh
#ifndef G4FISSIONEVENT_HH
#define G4FISSIONEVENT_HH
#include "globals.hh"
#include <string>
class G4fissionEvent {
private:
G4int neutronNu; // number of neutrons in this fission event
G4double* neutronEnergies;
G4double* neutronVelocities;
G4double* neutronDircosu;
G4double* neutronDircosv;
G4double* neutronDircosw;
G4double* neutronAges;
G4int photonNu; // number of photons in this fission event
G4double* photonEnergies;
G4double* photonVelocities;
G4double* photonDircosu;
G4double* photonDircosv;
G4double* photonDircosw;
G4double* photonAges;
// options
static G4int delayoption;
static G4int correlationoption;
static G4int nudistoption;
static G4int Cf252ndistoption;
static G4int Cf252nengoption;
static G4double (*rngdptr)(void);
static float (*rngfptr)(void);
class G4fissionEvent
{
public:
// These are all the methods of this class accessible to the caller of the object
G4fissionEvent(G4int isotope, G4double time, G4double nubar, G4double eng);
~G4fissionEvent();
@@ -167,6 +143,32 @@ class G4fissionEvent {
private:
G4int neutronNu; // number of neutrons in this fission event
G4double* neutronEnergies;
G4double* neutronVelocities;
G4double* neutronDircosu;
G4double* neutronDircosv;
G4double* neutronDircosw;
G4double* neutronAges;
G4int photonNu; // number of photons in this fission event
G4double* photonEnergies;
G4double* photonVelocities;
G4double* photonDircosu;
G4double* photonDircosv;
G4double* photonDircosw;
G4double* photonAges;
// options
static G4int delayoption;
static G4int correlationoption;
static G4int nudistoption;
static G4int Cf252ndistoption;
static G4int Cf252nengoption;
static G4double (*rngdptr)(void);
static G4float (*rngfptr)(void);
G4int G4SmpNuDistDataU232_234_236_238(G4double nubar);
G4int G4SmpNuDistDataU232_234_236_238_MC(G4double nubar);
G4int G4SmpNuDistDataU233_235(G4double nubar);
@@ -187,7 +189,7 @@ class G4fissionEvent {
G4int G4SmpSpNugDistData(G4int isotope);
G4double G4SmpTerrell(G4double nubar);
G4double G4SmpWatt(G4double ePart, G4int iso);
void G4fissionerr(G4int iSever, std::string chSubNam, std::string chMsg);
void G4fissionerr(G4int iSever, const G4String& chSubNam, const G4String& chMsg);
static G4double fisslibrng(void);
static G4double rngf2d(void);
};
@@ -178,7 +178,8 @@ G4fissionEvent::G4fissionEvent(G4int isotope, G4double time,
}
}
G4fissionEvent::~G4fissionEvent() {
G4fissionEvent::~G4fissionEvent()
{
if (neutronNu > 0) {
delete [] neutronEnergies;
delete [] neutronVelocities;
@@ -61,7 +61,7 @@
std::string itoa(const G4int& x);
void G4fissionEvent::G4fissionerr(G4int iSever, std::string chSubNam, std::string chMsg)
void G4fissionEvent::G4fissionerr(G4int iSever, const G4String& chSubNam, const G4String& chMsg)
/*
Description
@@ -80,7 +80,7 @@ void G4fissionEvent::G4fissionerr(G4int iSever, std::string chSubNam, std::strin
{
G4int doExit;
std::string ExitMsg;
G4String ExitMsg;
if (iSever <= 5) { /* warning */
@@ -92,7 +92,7 @@ void G4fissionEvent::G4fissionerr(G4int iSever, std::string chSubNam, std::strin
ExitMsg = "Error in Function "+chSubNam+", Severity=" + itoa(iSever) + " : "+chMsg;
std::cerr << "Fission " << ExitMsg << std::endl;
G4cerr << "Fission " << ExitMsg << G4endl;
if (doExit == 1) G4Exception("G4fissionEvent::G4fissionerr()", "601",
FatalException, "Fatal Error");
@@ -6,6 +6,18 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-20 Alberto Ribon (hadr-inclxx-V11-03-04)
Two independent bug-fixes provided by Jean-Christophe David and Jason Hirtz :
- G4INCLNNToNSK2piChannel.cc : replaced "if(iso==-2)" with "else if(iso==-2)".
(The problem was reported by Julia Yarba).
- G4INCLCrossSectionsAntiparticles.cc : correct wrong formulae with isospins
concerning the cross sections N Nbar -> N Nbar + 2 pions.
The fix consists in exchanging the lines number 509 and 513.
## 2025-12-09 Gabriele Cosmo
- Fixed reported Coverity defects for use of std::move() in G4INCLCascade.cc
and G4INCLNbarAtrestEntryChannel.cc. Use G4 types consistently.
## 2025-11-06 Gabriele Cosmo (hadr-inclxx-V11-03-03)
- Fixed compilation warning for implicit type conversion on macOS/XCode
in G4INCLAntinucleiAtrestEntryChannel::getAnnihilationPosition().
@@ -219,7 +219,7 @@ namespace G4INCL {
//G4double AnnihilationBarrier = kineticEnergy;
if((projectileSpecies.theType == antiProton && kineticEnergy <= theConfig->getAtrestThreshold()) || (projectileSpecies.theType == antiNeutron && kineticEnergy <= theConfig->getnbAtrestThreshold())){
double SpOverSn;
G4double SpOverSn;
if(projectileSpecies.theType == antiProton)
SpOverSn = 1.331;//from experiments with deuteron (E.Klempt)
else if(projectileSpecies.theType == antiNeutron)
@@ -258,16 +258,16 @@ namespace G4INCL {
if(Z > 30)
isModelA=false;
else if(Z > 9 && Z <=30){ //Maybe change and add another dependance than Z
double rndmA = Random::shoot();
G4double rndmA = Random::shoot();
if(rndmA > 0.5)//Random threshold : should be improved to take into account the orbit in which the separation takes place.
isModelA=false;
}
if(isModelA){
//Antideuteron Model A case : 2 annihilation at the same time
double pbarSpOverSn = 1.331;
double nbarSpOverSn = 1./1.331;
double pbarneutronprob;
double nbarneutronprob;
G4double pbarSpOverSn = 1.331;
G4double nbarSpOverSn = 1./1.331;
G4double pbarneutronprob;
G4double nbarneutronprob;
if(theConfig->isNaturalTarget()){
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 2;
nbarneutronprob = (theA + 2 - Z)/(theA + 2 - Z + nbarSpOverSn*Z);
@@ -299,8 +299,8 @@ namespace G4INCL {
}
}
} else if (!isModelA){//Model B : Antiproton is detached from antideuteron
double SpOverSn = 1.331;
double neutronprob;
G4double SpOverSn = 1.331;
G4double neutronprob;
if(theConfig->isNaturalTarget()){
theA = ParticleTable::drawRandomNaturalIsotope(Z) - 1;
neutronprob = (theA + 1 - Z)/(theA + 1 - Z + SpOverSn*Z);
@@ -312,7 +312,7 @@ namespace G4INCL {
theS = S;
double rndm = Random::shoot();
G4double rndm = Random::shoot();
if(rndm >= neutronprob){ //proton is annihilated
theEventInfo.annihilationP = true;
theZ = Z - 1;
@@ -649,7 +649,7 @@ namespace G4INCL {
G4double SpOverSn = 1./1.331; //from experiments with deuteron (E.Klempt)
ThreeVector dummy(0.,0.,0.);
double rndm = Random::shoot()*(SpOverSn+1);
G4double rndm = Random::shoot()*(SpOverSn+1);
if (rndm <= SpOverSn) { //proton is annihilated
theEventInfo.annihilationP = true;
Particle *p2 = new Particle(Neutron, dummy, dummy);
@@ -690,27 +690,27 @@ namespace G4INCL {
INCL_DEBUG("Reading nbarp kaonic final states" << dataPathnbarpk << '\n');
#endif
//read probabilities and particle types from file
std::vector<double> probabilities; //will store each FS yield
std::vector<G4double> probabilities; //will store each FS yield
std::vector<std::vector<G4String>> particle_types; //will store particle names
double sum = 0.0; //will contain a sum of probabilities of all FS in the file
double kaonicFSprob=0.05; //probability to kave kaonic FS
G4double sum = 0.0; //will contain a sum of probabilities of all FS in the file
G4double kaonicFSprob=0.05; //probability to kave kaonic FS
ParticleList starlist;
ThreeVector mommy; //momentum to be assigned later
double rdm = Random::shoot();
G4double rdm = Random::shoot();
ThreeVector annihilationPosition(0.,0.,0.);
if (rdm < (1.-kaonicFSprob)) { // pionic FS was chosen
INCL_DEBUG("pionic nn final state chosen" << '\n');
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathnbarp, probabilities, particle_types);}
{sum = read_file(std::move(dataPathnbarp), probabilities, particle_types);}
else
{sum = read_file(dataPathnbarn, probabilities, particle_types);}
{sum = read_file(std::move(dataPathnbarn), probabilities, particle_types);}
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return theEventInfo;
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
for (G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++) {
if (particle_types[n][j] == "pi0") {
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
@@ -743,7 +743,7 @@ namespace G4INCL {
starlist.push_back(pp);
} else {
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
for (G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++) {
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
#else
@@ -760,14 +760,14 @@ namespace G4INCL {
} else {
INCL_DEBUG("kaonic pp final state chosen" << '\n');
if (targetA==1 || (targetA==2 && theEventInfo.annihilationP))
{sum = read_file(dataPathnbarpk, probabilities, particle_types);}
{sum = read_file(std::move(dataPathnbarpk), probabilities, particle_types);}
else
{sum = read_file(dataPathnbarnk, probabilities, particle_types);}
{sum = read_file(std::move(dataPathnbarnk), probabilities, particle_types);}
rdm = ((1.-rdm)/kaonicFSprob)*sum; //2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return theEventInfo;
for (G4int j = 0; j < static_cast<int>(particle_types[n].size()); j++) {
for (G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++) {
if (particle_types[n][j] == "pi0") {
Particle *p = new Particle(PiZero, mommy, annihilationPosition);
starlist.push_back(p);
@@ -797,7 +797,7 @@ namespace G4INCL {
starlist.push_back(p);
} else {
INCL_ERROR("Some non-existing FS particle detected when reading pbar FS files");
for (int jj = 0; jj < static_cast<int>(particle_types[n].size()); jj++) {
for (G4int jj = 0; jj < static_cast<G4int>(particle_types[n].size()); jj++) {
#ifdef INCLXX_IN_GEANT4_MODE
G4cout << "gotcha! " << particle_types[n][jj] << G4endl;
#else
@@ -506,11 +506,11 @@ namespace G4INCL {
const G4double pLab = 0.001*KinematicsUtils::momentumInLab(antinucleon, nucleon); // GeV
if(iso == 2 || iso == -2){ // pnbar or npbar
sigma = KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(std::move(BFMM167), pLab) + KinematicsUtils::compute_xs(std::move(BFMM198), pLab);
sigma = KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(std::move(BFMM492), pLab) + KinematicsUtils::compute_xs(std::move(BFMM494), pLab);
return sigma;
}
else{ // ppbar or nnbar
sigma = KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(std::move(BFMM492), pLab) + KinematicsUtils::compute_xs(std::move(BFMM494), pLab);
sigma = KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(BFMM490, pLab) + KinematicsUtils::compute_xs(std::move(BFMM167), pLab) + KinematicsUtils::compute_xs(std::move(BFMM198), pLab);
return sigma;
}
}
@@ -97,7 +97,7 @@ namespace G4INCL{
while (iss >>type){
types.push_back(type);
}
particle_types.push_back(types);
particle_types.push_back(std::move(types));
}
}
else std::cout << "ERROR no fread_file " << filename << std::endl;
@@ -306,10 +306,10 @@ namespace G4INCL{
INCL_DEBUG("Proton is the victim" << '\n');
if(rdm < (1.-kaonicFSprob)){ // pionic FS was chosen
INCL_DEBUG("pionic pp final state chosen" << '\n');
sum = read_file(dataPathnbarp, probabilities, particle_types);
sum = read_file(std::move(dataPathnbarp), probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.88 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
@@ -361,10 +361,10 @@ namespace G4INCL{
}
else{
INCL_DEBUG("kaonic pp final state chosen" << '\n');
sum = read_file(dataPathnbarpk, probabilities, particle_types);
sum = read_file(std::move(dataPathnbarpk), probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//2670 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
@@ -417,10 +417,10 @@ namespace G4INCL{
INCL_DEBUG("Neutron is the victim" << '\n');
if(rdm < (1.-kaonicFSprob)){ // pionic/kaonic choice
INCL_DEBUG("pionic np final state chosen" << '\n');
sum = read_file(dataPathnbarn, probabilities, particle_types);
sum = read_file(std::move(dataPathnbarn), probabilities, particle_types);
rdm = (rdm/(1.-kaonicFSprob))*sum; //99.95 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
@@ -472,10 +472,10 @@ namespace G4INCL{
}
else{
INCL_DEBUG("kaonic np final state chosen" << '\n');
sum = read_file(dataPathnbarnk, probabilities, particle_types);
sum = read_file(std::move(dataPathnbarnk), probabilities, particle_types);
rdm = ((1-rdm)/kaonicFSprob)*sum;//3837 normalize by the sum of probabilities in the file
//now get the line number in the file where the FS particles are stored:
G4int n = findStringNumber(rdm, probabilities)-1;
G4int n = findStringNumber(rdm, std::move(probabilities))-1;
if ( n < 0 ) return starlist;
for(G4int j = 0; j < static_cast<G4int>(particle_types[n].size()); j++){
if(particle_types[n][j] == "pi0"){
@@ -679,4 +679,4 @@ namespace G4INCL{
fs->setTotalEnergyBeforeInteraction(energyBefore);
}
}
}
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-18 Gabriele Cosmo (hadr-nudex-V11-03-01)
- Fixed reported Coverity defects in G4NuDEXPSF for avoiding unnecessary
copy of strings.
## 2025-03-04 Ben Morgan (hadr-nudex-V11-03-00)
- Address maybe-unitialized warnings when building/linking with LTO
- Identified by ATLAS.
@@ -243,11 +243,12 @@ G4bool G4NuDEXPSF::TakePSFFromIAEA01(const char* fname){
PSFType_E1[nR_E1]=11;
nR_E1++;
in>>dum;
if(std::string(dum)==std::string("beta=")){
G4String s_dum(dum);
if(s_dum==G4String("beta=")){
in>>beta;
break;
}
else if(std::string(dum)==std::string("Er2")){
else if(s_dum==G4String("Er2")){
in>>dum>>E_E1[nR_E1]>>dum>>dum>>G_E1[nR_E1]>>dum>>dum>>s_E1[nR_E1]>>dum>>beta;
PSFType_E1[nR_E1]=11;
nR_E1++;
@@ -309,8 +310,9 @@ G4bool G4NuDEXPSF::TakePSFFromInputFile(const char* fname){
std::ifstream in(fname);
while(in>>word){
if(word[0]=='#'){in.ignore(10000,'\n');}
if(std::string(word)==std::string("END")){break;}
if(std::string(word)==std::string("PSF")){
G4String s_word(word);
if(s_word==G4String("END")){break;}
if(s_word==G4String("PSF")){
result=true;
in>>nR_E1;
for(G4int i=0;i<nR_E1;i++){
@@ -6,6 +6,17 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-23 Dmitri Konstantinov (hadr-hpp-V11-03-06)
- G4ParticleHPContAngularPar - reduced allocator fragmentation and memory
churn in BuildByInterpolation() by removing unconditional deep copies
of input angular distributions. Copies are now created only in case of
self-aliasing (this == &angparX), preserving correctness while avoiding
excessive per-call heap allocations.
## 2025-12-23 Vladimir Ivanchenko (hadr-hpp-V11-03-05)
- G4ParticleHPNBodyPhaseSpace, G4ParticleHPInelasticCompFS - added
G4HadronicException header.
## 2025-09-27 Vladimir Ivanchenko (hadr-hpp-V11-03-04)
- G4FissionFragmentGenerator, G4FissionFragmentGenerator, G4ParticleHPElementData,
G4ParticleHPKallbachMannSyst, G4ParticleHPThermalScattering,
@@ -663,14 +663,18 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
// interaction the existing table should be used
if (!fCache.Get().fresh) return;
// Make copies of angpar1 and angpar2. Since these are given by reference
// it can not be excluded that one of them is "this". Hence this code uses
// potentially the old "this" for creating the new this - which leads to
// memory corruption if the old is not stored as separarte object for lookup
const G4ParticleHPContAngularPar copyAngpar1(angpar1), copyAngpar2(angpar2);
// Guard against self-aliasing: if either source happens to be "this",
// copy it before we start overwriting our own members. In the standard
// call path (fCacheAngular vs theAngular[]) aliasing cannot occur, so
// tmp1/tmp2 remain empty and the copies cost nothing.
std::unique_ptr<G4ParticleHPContAngularPar> tmp1, tmp2;
if (this == &angpar1) { tmp1 = std::make_unique<G4ParticleHPContAngularPar>(angpar1); }
if (this == &angpar2) { tmp2 = std::make_unique<G4ParticleHPContAngularPar>(angpar2); }
const G4ParticleHPContAngularPar& p1 = tmp1 ? *tmp1 : angpar1;
const G4ParticleHPContAngularPar& p2 = tmp2 ? *tmp2 : angpar2;
nAngularParameters = copyAngpar1.nAngularParameters;
theManager = copyAngpar1.theManager;
nAngularParameters = p1.nAngularParameters;
theManager = p1.theManager;
theEnergy = anEnergy;
theMinEner = DBL_MAX; // min and max will be re-calculated after interpolation
theMaxEner = -DBL_MAX;
@@ -681,8 +685,8 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
// needs to call the explicit Set() method instead.
// First, average probabilities for those lines that are in both sets
const std::map<G4double, G4int> discEnerOwn1 = copyAngpar1.GetDiscreteEnergiesOwn();
const std::map<G4double, G4int> discEnerOwn2 = copyAngpar2.GetDiscreteEnergiesOwn();
const std::map<G4double, G4int> discEnerOwn1 = p1.GetDiscreteEnergiesOwn();
const std::map<G4double, G4int> discEnerOwn2 = p2.GetDiscreteEnergiesOwn();
std::map<G4double, G4int>::const_iterator itedeo1;
std::map<G4double, G4int>::const_iterator itedeo2;
std::vector<G4ParticleHPList*> vAngular(discEnerOwn1.size());
@@ -704,18 +708,18 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
ie2 = itedeo2->second;
}
vAngular[ie1] = new G4ParticleHPList();
vAngular[ie1]->SetLabel(copyAngpar1.theAngular[ie1].GetLabel());
vAngular[ie1]->SetLabel(p1.theAngular[ie1].GetLabel());
G4double val1, val2;
for (G4int ip = 0; ip < nAngularParameters; ++ip) {
val1 = copyAngpar1.theAngular[ie1].GetValue(ip);
val1 = p1.theAngular[ie1].GetValue(ip);
if (ie2 != -1) {
val2 = copyAngpar2.theAngular[ie2].GetValue(ip);
val2 = p2.theAngular[ie2].GetValue(ip);
}
else {
val2 = 0.;
}
G4double value = theInt.Interpolate(aScheme, anEnergy, copyAngpar1.theEnergy,
copyAngpar2.theEnergy, val1, val2);
G4double value = theInt.Interpolate(aScheme, anEnergy, p1.theEnergy,
p2.theEnergy, val1, val2);
vAngular[ie1]->SetValue(ip, value);
}
} // itedeo1 loop
@@ -745,7 +749,7 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
for (itv = vAngular.cbegin(); itv != vAngular.cend(); ++itv, ++ie) {
if (discEner2 > (*itv)->GetLabel()) {
itv = vAngular.insert(itv, new G4ParticleHPList);
(*itv)->SetLabel(copyAngpar2.theAngular[ie2].GetLabel());
(*itv)->SetLabel(p2.theAngular[ie2].GetLabel());
isInserted = true;
break;
}
@@ -753,16 +757,16 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
if (!isInserted) {
ie = (G4int)vAngular.size();
vAngular.push_back(new G4ParticleHPList);
vAngular[ie]->SetLabel(copyAngpar2.theAngular[ie2].GetLabel());
vAngular[ie]->SetLabel(p2.theAngular[ie2].GetLabel());
isInserted = true;
}
G4double val1, val2;
for (G4int ip = 0; ip < nAngularParameters; ++ip) {
val1 = 0;
val2 = copyAngpar2.theAngular[ie2].GetValue(ip);
G4double value = theInt.Interpolate(aScheme, anEnergy, copyAngpar1.theEnergy,
copyAngpar2.theEnergy, val1, val2);
val2 = p2.theAngular[ie2].GetValue(ip);
G4double value = theInt.Interpolate(aScheme, anEnergy, p1.theEnergy,
p2.theEnergy, val1, val2);
vAngular[ie]->SetValue(ip, value);
}
} // end if(notFound)
@@ -794,26 +798,25 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
// Get minimum and maximum energy interpolating
// Don't use theMinEner or theMaxEner here, since the transformed energies
// need the interpolated range from the original Angpar
G4double interMinEner = copyAngpar1.GetMinEner()
+ (theEnergy - copyAngpar1.GetEnergy())
* (copyAngpar2.GetMinEner() - copyAngpar1.GetMinEner())
/ (copyAngpar2.GetEnergy() - copyAngpar1.GetEnergy());
G4double interMaxEner = copyAngpar1.GetMaxEner()
+ (theEnergy - copyAngpar1.GetEnergy())
* (copyAngpar2.GetMaxEner() - copyAngpar1.GetMaxEner())
/ (copyAngpar2.GetEnergy() - copyAngpar1.GetEnergy());
G4double interMinEner = p1.GetMinEner()
+ (theEnergy - p1.GetEnergy())
* (p2.GetMinEner() - p1.GetMinEner())
/ (p2.GetEnergy() - p1.GetEnergy());
G4double interMaxEner = p1.GetMaxEner()
+ (theEnergy - p1.GetEnergy())
* (p2.GetMaxEner() - p1.GetMaxEner())
/ (p2.GetEnergy() - p1.GetEnergy());
// Loop to energies of new set
theEnergiesTransformed.clear();
G4int nEnergies1 = copyAngpar1.GetNEnergies();
G4int nDiscreteEnergies1 = copyAngpar1.GetNDiscreteEnergies();
G4double minEner1 = copyAngpar1.GetMinEner();
G4double maxEner1 = copyAngpar1.GetMaxEner();
G4int nEnergies2 = copyAngpar2.GetNEnergies();
G4int nDiscreteEnergies2 = copyAngpar2.GetNDiscreteEnergies();
G4double minEner2 = copyAngpar2.GetMinEner();
G4double maxEner2 = copyAngpar2.GetMaxEner();
G4int nEnergies1 = p1.GetNEnergies();
G4int nDiscreteEnergies1 = p1.GetNDiscreteEnergies();
G4double minEner1 = p1.GetMinEner();
G4double maxEner1 = p1.GetMaxEner();
G4int nEnergies2 = p2.GetNEnergies();
G4int nDiscreteEnergies2 = p2.GetNDiscreteEnergies();
G4double minEner2 = p2.GetMinEner();
G4double maxEner2 = p2.GetMaxEner();
// First build the list of transformed energies normalized
// to the new min max by assuming that the min-max range of
@@ -823,7 +826,7 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
G4double e1(0.);
G4double eTNorm1(0.);
for (ie1 = nDiscreteEnergies1; ie1 < nEnergies1; ++ie1) {
e1 = copyAngpar1.theAngular[ie1].GetLabel();
e1 = p1.theAngular[ie1].GetLabel();
eTNorm1 = (e1 - minEner1);
if (maxEner1 != minEner1) eTNorm1 /= (maxEner1 - minEner1);
if (eTNorm1 >= 0 && eTNorm1 <= 1) theEnergiesTransformed.insert(eTNorm1);
@@ -832,7 +835,7 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
G4double e2(0.);
G4double eTNorm2(0.);
for (ie2 = nDiscreteEnergies2; ie2 < nEnergies2; ++ie2) {
e2 = copyAngpar2.theAngular[ie2].GetLabel();
e2 = p2.theAngular[ie2].GetLabel();
eTNorm2 = (e2 - minEner2);
if (maxEner2 != minEner2) eTNorm2 /= (maxEner2 - minEner2);
if (eTNorm2 >= 0 && eTNorm2 <= 1) theEnergiesTransformed.insert(eTNorm2);
@@ -870,7 +873,7 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
e1Interp = (maxEner1 - minEner1) * eT + minEner1;
//----- Get parameter value corresponding to this e1Interp
for (ie1 = nDiscreteEnergies1; ie1 < nEnergies1; ++ie1) {
if ((copyAngpar1.theAngular[ie1].GetLabel() - e1Interp) > 1.E-10 * e1Interp) break;
if ((p1.theAngular[ie1].GetLabel() - e1Interp) > 1.E-10 * e1Interp) break;
}
ie1Prev = ie1 - 1;
if (ie1 == 0) ++ie1Prev;
@@ -883,7 +886,7 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
e2Interp = (maxEner2 - minEner2) * eT + minEner2;
//----- Get parameter value corresponding to this e2Interp
for (ie2 = nDiscreteEnergies2; ie2 < nEnergies2; ++ie2) {
if ((copyAngpar2.theAngular[ie2].GetLabel() - e2Interp) > 1.E-10 * e2Interp) break;
if ((p2.theAngular[ie2].GetLabel() - e2Interp) > 1.E-10 * e2Interp) break;
}
ie2Prev = ie2 - 1;
if (ie2 == 0) ++ie2Prev;
@@ -908,17 +911,17 @@ void G4ParticleHPContAngularPar::BuildByInterpolation(G4double anEnergy,
G4double value(0.);
for (G4int ip = 0; ip < nAngularParameters; ++ip) {
val1 = theInt.Interpolate2(
theManager.GetScheme(ie), e1Interp, copyAngpar1.theAngular[ie1Prev].GetLabel(),
copyAngpar1.theAngular[ie1].GetLabel(), copyAngpar1.theAngular[ie1Prev].GetValue(ip),
copyAngpar1.theAngular[ie1].GetValue(ip))
theManager.GetScheme(ie), e1Interp, p1.theAngular[ie1Prev].GetLabel(),
p1.theAngular[ie1].GetLabel(), p1.theAngular[ie1Prev].GetValue(ip),
p1.theAngular[ie1].GetValue(ip))
* (maxEner1 - minEner1);
val2 = theInt.Interpolate2(
theManager.GetScheme(ie), e2Interp, copyAngpar2.theAngular[ie2Prev].GetLabel(),
copyAngpar2.theAngular[ie2].GetLabel(), copyAngpar2.theAngular[ie2Prev].GetValue(ip),
copyAngpar2.theAngular[ie2].GetValue(ip))
theManager.GetScheme(ie), e2Interp, p2.theAngular[ie2Prev].GetLabel(),
p2.theAngular[ie2].GetLabel(), p2.theAngular[ie2Prev].GetValue(ip),
p2.theAngular[ie2].GetValue(ip))
* (maxEner2 - minEner2);
value = theInt.Interpolate(aScheme, anEnergy, copyAngpar1.theEnergy, copyAngpar2.theEnergy,
value = theInt.Interpolate(aScheme, anEnergy, p1.theEnergy, p2.theEnergy,
val1, val2);
if (interMaxEner != interMinEner) {
value /= (interMaxEner - interMinEner);
@@ -65,6 +65,7 @@
#include "G4ParticleHPDataUsed.hh"
#include "G4ParticleHPManager.hh"
#include "G4RandomDirection.hh"
#include "G4HadronicException.hh"
#include "G4SystemOfUnits.hh"
#include <fstream>
@@ -40,6 +40,7 @@
#include "G4Proton.hh"
#include "G4ThreeVector.hh"
#include "G4Triton.hh"
#include "G4HadronicException.hh"
#include "Randomize.hh"
G4ReactionProduct* G4ParticleHPNBodyPhaseSpace::Sample(G4double anEnergy, G4double massCode,
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-23 Vladimir Ivanchenko (hadr-partonstring-mgt-V11-03-00)
- G4VSplitableHadron - added G4HadronicException header.
## 2022-11-11 Alberto Ribon (hadr-partonstring-mgt-V11-00-03)
- G4VPartonStringModel : added debugging information on the number of lambdas
for residual projectile hypernuclei.
@@ -37,9 +37,10 @@
#include "G4VSplitableHadron.hh"
#include "G4Nucleon.hh"
#include "G4VKineticNucleon.hh"
#include "G4HadronicException.hh"
G4VSplitableHadron::G4VSplitableHadron()
: theDefinition(NULL), TimeOfCreation(0.), theCollisionCount(0), curStatus(0), isSplit(false)
: theDefinition(nullptr), TimeOfCreation(0.), theCollisionCount(0), curStatus(0), isSplit(false)
{
}
@@ -6,6 +6,10 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-23 Vladimir Ivanchenko (hadr-qgsm-V11-03-00)
- G4GammaParticipants, G4QGSParticipants, G4QGSMSplitableHadron - added
G4HadronicException header.
## 2023-03-09 Vladimir Ivanchenko (hadr-qgsm-V11-01-01)
- G4BaryonSplitter, G4MesonSplitter, G4QGSMSplittableHadron, G4SPBaryon -
attempt make code more uniform in order to reduce probability of warnings
@@ -27,6 +27,7 @@
#include "G4GammaParticipants.hh"
#include "G4LorentzVector.hh"
#include "G4V3DNucleus.hh"
#include "G4HadronicException.hh"
#include <utility>
// Class G4GammaParticipants
@@ -33,6 +33,7 @@
#include "G4PionZero.hh"
#include "G4KaonPlus.hh"
#include "G4KaonMinus.hh"
#include "G4HadronicException.hh"
#include "G4Log.hh"
#include "G4Pow.hh"
@@ -33,6 +33,7 @@
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4PhysicalConstants.hh"
#include "G4HadronicException.hh"
#include "G4Exp.hh"
#include "G4Log.hh"
@@ -1,8 +1,13 @@
# Category had-theo-HE History
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-23 Vladimir Ivanchenko (had-theo-HE-V11-03-01)
- G4TheoFSGenerator : added G4HadronicException header.
## 2025-08-14 Alberto Ribon (had-theo-HE-V11-03-00)
- G4TheoFSGenerator : introduced the ID model identification for FTF inelastic
@@ -38,7 +38,7 @@
#include "G4HadronicParameters.hh"
#include "G4CRCoalescence.hh"
#include "G4HadronicInteractionRegistry.hh"
#include "G4HadronicException.hh"
G4TheoFSGenerator::G4TheoFSGenerator( const G4String& name )
: G4HadronicInteraction( name )
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-12-23 Vladimir Ivanchenko (hadr-stopping-V11-03-02)
- G4HadronStoppingProcess, G4MuonicAtomDecay: added G4HadronicException header.
## 2025-09-22 Jean-Christophe David (hadr-stopping-V11-03-01)
- G4HadronicAbsorptionINCLXX: the energy max is different for antiproton and antineutron in INCLXX.
@@ -1,9 +1,15 @@
# Category channeling History
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top). It must **not**
be used as a substitute for writing good git commit messages!
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-04 Gabriele Cosmo (channeling-V11-03-00)
- In G4ChannelingMaterialData, fixed reported Coverity defects for
string parameters copying. Use consistently G4 types and minor
code formatting.
## 2024-07-17 Vladimir Ivanchenko (channeling-V11-02-00)
- G4ChannelingOptrMultiParticleChangeCrossSection,
@@ -25,8 +25,8 @@
//
//
#ifndef G4ChannelingMaterialData_h
#define G4ChannelingMaterialData_h 1
#ifndef G4CHANNELINGMATERIALDATA_HH
#define G4CHANNELINGMATERIALDATA_HH
#include "G4ios.hh"
#include "globals.hh"
@@ -38,69 +38,53 @@
#include <unordered_map>
#include "G4PhysicsLinearVector.hh"
class G4ChannelingMaterialData : public G4VMaterialExtension{
public:
class G4ChannelingMaterialData : public G4VMaterialExtension
{
public:
G4ChannelingMaterialData(const G4String&);
virtual ~G4ChannelingMaterialData();
public:
void Print() const {G4cout << "Channeling Material Data" << G4endl;};
void Print() const { G4cout << "Channeling Material Data" << G4endl; }
void SetFilename(const G4String&);
void SetFilenameElement(const G4String&,std::string);
void SetFilenameElement(const G4String&, const G4String&);
public:
G4ChannelingECHARM* GetPot() {return fPotential;};
G4ChannelingECHARM* GetEFX() {return fElectricFieldX;};
G4ChannelingECHARM* GetEFY() {return fElectricFieldY;};
G4ChannelingECHARM* GetNuD() {return fNucleiDensity;};
G4ChannelingECHARM* GetElD() {return fElectronDensity;};
G4ChannelingECHARM* GetPot() { return fPotential; }
G4ChannelingECHARM* GetEFX() { return fElectricFieldX; }
G4ChannelingECHARM* GetEFY() { return fElectricFieldY; }
G4ChannelingECHARM* GetNuD() { return fNucleiDensity; }
G4ChannelingECHARM* GetElD() { return fElectronDensity; }
private:
G4ChannelingECHARM* fPotential;
G4ChannelingECHARM* fElectricFieldX;
G4ChannelingECHARM* fElectricFieldY;
G4ChannelingECHARM* fNucleiDensity;
G4ChannelingECHARM* fElectronDensity;
G4ChannelingECHARM* GetPotEl(const G4String& name) { return fPotentialElement[name]; }
G4ChannelingECHARM* GetEFXEl(const G4String& name) { return fElectricFieldXElement[name]; }
G4ChannelingECHARM* GetEFYEl(const G4String& name) { return fElectricFieldYElement[name]; }
G4ChannelingECHARM* GetNuDEl(const G4String& name) { return fNucleiDensityElement[name]; }
G4ChannelingECHARM* GetElDEl(const G4String& name) { return fElectronDensityElement[name]; }
public:
G4ChannelingECHARM* GetPotEl(std::string name) {return fPotentialElement[name];};
G4ChannelingECHARM* GetEFXEl(std::string name) {return fElectricFieldXElement[name];};
G4ChannelingECHARM* GetEFYEl(std::string name) {return fElectricFieldYElement[name];};
G4ChannelingECHARM* GetNuDEl(std::string name) {return fNucleiDensityElement[name];};
G4ChannelingECHARM* GetElDEl(std::string name) {return fElectronDensityElement[name];};
virtual G4bool IsBent() { return bIsBent; }
private:
std::unordered_map<std::string,G4ChannelingECHARM*> fPotentialElement;
std::unordered_map<std::string,G4ChannelingECHARM*> fElectricFieldXElement;
std::unordered_map<std::string,G4ChannelingECHARM*> fElectricFieldYElement;
std::unordered_map<std::string,G4ChannelingECHARM*> fNucleiDensityElement;
std::unordered_map<std::string,G4ChannelingECHARM*> fElectronDensityElement;
public:
virtual G4bool IsBent() {
return bIsBent;
};
virtual G4ThreeVector GetBR(G4ThreeVector& v3) {
return G4ThreeVector(fVectorR->Value(v3.z()),0.,0.);
};
virtual G4ThreeVector GetBR(const G4ThreeVector& v3) { return G4ThreeVector(fVectorR->Value(v3.z()),0.,0.); }
virtual void SetBR(const G4String&);
virtual void SetBR(G4double);
protected:
G4PhysicsVector* fVectorR;
G4bool bIsBent;
protected:
G4PhysicsVector* fVectorR = nullptr;
G4bool bIsBent = false;
private:
G4ChannelingECHARM* fPotential = nullptr;
G4ChannelingECHARM* fElectricFieldX = nullptr;
G4ChannelingECHARM* fElectricFieldY = nullptr;
G4ChannelingECHARM* fNucleiDensity = nullptr;
G4ChannelingECHARM* fElectronDensity = nullptr;
std::unordered_map<std::string, G4ChannelingECHARM*> fPotentialElement;
std::unordered_map<std::string, G4ChannelingECHARM*> fElectricFieldXElement;
std::unordered_map<std::string, G4ChannelingECHARM*> fElectricFieldYElement;
std::unordered_map<std::string, G4ChannelingECHARM*> fNucleiDensityElement;
std::unordered_map<std::string, G4ChannelingECHARM*> fElectronDensityElement;
};
#endif
@@ -33,19 +33,15 @@
#include "G4LogicalCrystalVolume.hh"
#include "G4TouchableHistory.hh"
G4ChannelingMaterialData::G4ChannelingMaterialData(const G4String& name):
G4VMaterialExtension(name),
fPotential(0),
fElectricFieldX(0),
fElectricFieldY(0),
fNucleiDensity(0),
fElectronDensity(0),
fVectorR(0),
bIsBent(false){;}
G4ChannelingMaterialData::G4ChannelingMaterialData(const G4String& name)
: G4VMaterialExtension(name)
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ChannelingMaterialData::SetFilename(const G4String& fileName){
void G4ChannelingMaterialData::SetFilename(const G4String& fileName)
{
G4String filePot = fileName + "_pot.txt";
G4String fileEFX = fileName + "_efx.txt";
G4String fileEFY = fileName + "_efy.txt";
@@ -67,7 +63,8 @@ void G4ChannelingMaterialData::SetFilename(const G4String& fileName){
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ChannelingMaterialData::SetFilenameElement(const G4String& fileName,std::string elementName){
void G4ChannelingMaterialData::SetFilenameElement(const G4String& fileName, const G4String& elementName)
{
G4String filePot = fileName + "_pot.txt";
G4String fileEFX = fileName + "_efx.txt";
G4String fileEFY = fileName + "_efy.txt";
@@ -90,7 +87,8 @@ void G4ChannelingMaterialData::SetFilenameElement(const G4String& fileName,std::
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ChannelingMaterialData::SetBR(G4double val){
void G4ChannelingMaterialData::SetBR(G4double val)
{
fVectorR = new G4PhysicsLinearVector(0,DBL_MAX,2);
fVectorR->PutValue(0,val);
fVectorR->PutValue(1,val);
@@ -99,17 +97,18 @@ void G4ChannelingMaterialData::SetBR(G4double val){
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ChannelingMaterialData::SetBR(const G4String& filename){
void G4ChannelingMaterialData::SetBR(const G4String& filename)
{
std::ifstream vFileIn;
int points;
float maximum;
G4int points;
G4float maximum;
vFileIn.open(filename);
vFileIn >> points >> maximum;
fVectorR = new G4PhysicsLinearVector(0,maximum * CLHEP::millimeter,points);
double vTempX;
double maximumY = -DBL_MAX;
double minimumY = +DBL_MAX;
G4double vTempX;
G4double maximumY = -DBL_MAX;
G4double minimumY = +DBL_MAX;
for(G4int i0=0;i0<points; i0++){
vFileIn >> vTempX;
if(vTempX>maximumY) maximumY = vTempX;
+23
View File
@@ -5,6 +5,29 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-03-06 Makoto Asai (run-V11-03-07)
- Fixing the material scanner
- G4MaterialScanner.cc
Delete G4Event object at the end of each event.
Make sure geometry is optimized before starting the scan, cooping with
multithreaded geometry optimization.
- G4MSSteppingAction.cc
Fix average A and average Z taking number of atoms into account.
- G4RunManager.cc
Material scanner is instantiated only for the master thread.
- G4MatScanMessenger.cc
Prevent material scanner UI commands from broadcasting to worker threads.
Material scanner is centrally managed by the master thread.
## 2026-01-22 Igor Semeniouk
- Introducing UI command to force geometry optimization
- G4RunManager, G4MTRunManager, G4WorkerRunManager : add GeometryOptimisation method
- G4RunMessenger : the /run/undertakeOptimisation command added
## 2026-01-16 Alvaro Tolosa-Delgado
- Re-enable automatic instantiation of G4MaterialScanner in G4RunManager.
## 2025-11-06 Laurent Desorgher (run-V11-03-06)
- G4AdjointPrimaryGeneratorAction :
Remove pointer attribute on G4AdjointPrimaryGenerator and call it by G4AdjointPrimaryGenerator::GetInstance()
+5 -2
View File
@@ -35,8 +35,8 @@
// Original authors: X.Dong, A.Dotti - February 2013
// --------------------------------------------------------------------
#ifndef G4MTRunManager_hh
#define G4MTRunManager_hh 1
#ifndef G4MTRUNMANAGER_HH
#define G4MTRUNMANAGER_HH
#include "G4MTBarrier.hh"
#include "G4RNGHelper.hh"
@@ -77,6 +77,9 @@ class G4MTRunManager : public G4RunManager
G4int n_select = -1) override;
virtual void InitializeThreadPool() {}
// Start parallel optimization
void GeometryOptimisation() override;
// The following do not do anything for this runmanager
void TerminateOneEvent() override;
void ProcessOneEvent(G4int i_event) override;
+4 -4
View File
@@ -32,8 +32,8 @@
// Author: M.Asai, May 2006
// --------------------------------------------------------------------
#ifndef G4MaterialScanner_hh
#define G4MaterialScanner_hh 1
#ifndef G4MATERIALSCANNER_HH
#define G4MATERIALSCANNER_HH
#include "G4ThreeVector.hh"
#include "globals.hh"
@@ -104,10 +104,10 @@ class G4MaterialScanner
G4MSSteppingAction* theMatScannerSteppingAction = nullptr;
G4ThreeVector eyePosition;
G4int nTheta = 91;
G4int nTheta = 1;
G4double thetaMin = 0.0;
G4double thetaSpan = 0.0;
G4int nPhi = 37;
G4int nPhi = 1;
G4double phiMin = 0.0;
G4double phiSpan = 0.0;
+5 -3
View File
@@ -98,8 +98,8 @@
// Original author: M.Asai, 1996
// --------------------------------------------------------------------
#ifndef G4RunManager_hh
#define G4RunManager_hh 1
#ifndef G4RUNMANAGER_HH
#define G4RUNMANAGER_HH
#include "G4Event.hh"
#include "G4EventManager.hh"
@@ -133,6 +133,7 @@ class G4DCtable;
class G4Run;
class G4PrimaryTransformer;
class G4RunManagerFactory;
class G4MaterialScanner;
class G4RunManager
{
@@ -207,6 +208,7 @@ class G4RunManager
// InitializeGeometry() and the G4VUserPhysicsList class will be accessed
// from the method InitializePhysics().
virtual void InitializeGeometry();
virtual void GeometryOptimisation();
virtual void InitializePhysics();
// These four methods are invoked from the BeamOn() method and they're
@@ -673,7 +675,7 @@ class G4RunManager
static G4ThreadLocal G4RunManager* fRunManager;
G4RunMessenger* runMessenger = nullptr;
G4MaterialScanner* materialScanner = nullptr;
};
#endif
+3 -2
View File
@@ -36,8 +36,8 @@
// Original authors: X.Dong, A.Dotti - 2013
// --------------------------------------------------------------------
#ifndef G4WorkerRunManager_hh
#define G4WorkerRunManager_hh 1
#ifndef G4WORKERRUNMANAGER_HH
#define G4WORKERRUNMANAGER_HH
#include "G4RNGHelper.hh"
#include "G4RunManager.hh"
@@ -55,6 +55,7 @@ class G4WorkerRunManager : public G4RunManager
~G4WorkerRunManager() override;
void InitializeGeometry() override;
void GeometryOptimisation() override;
void RunInitialization() override;
void DoEventLoop(G4int n_event, const char* macroFile = nullptr, G4int n_select = -1) override;
void ProcessOneEvent(G4int i_event) override;
+3 -2
View File
@@ -47,8 +47,8 @@
// Original author: M.Asai, 1997
// --------------------------------------------------------------------
#ifndef G4RunMessenger_hh
#define G4RunMessenger_hh 1
#ifndef G4RUNMESSENGER_HH
#define G4RUNMESSENGER_HH
#include "G4UImessenger.hh"
#include "globals.hh"
@@ -92,6 +92,7 @@ class G4RunMessenger : public G4UImessenger
G4UIcmdWithoutParameter* initCmd = nullptr;
G4UIcmdWithoutParameter* geomCmd = nullptr;
G4UIcmdWithABool* geomRebCmd = nullptr;
G4UIcmdWithoutParameter* undertakeOptCmd = nullptr;
G4UIcmdWithoutParameter* physCmd = nullptr;
G4UIcmdWithAnInteger* randEvtCmd = nullptr;
G4UIcommand* procUICmds = nullptr;
+8 -5
View File
@@ -72,13 +72,16 @@ void G4MSSteppingAction::UserSteppingAction(const G4Step* aStep)
// calculate average mass number and atomic number
{
const std::vector<const G4Element*> * ElementVector_ptr = material->GetElementVector();
for( auto & element : *ElementVector_ptr)
const G4int* AtomsVector = material->GetAtomsVector();
G4int nAtoms = 0;
for( size_t i = 0; i < ElementVector_ptr->size(); i++)
{
thisMaterialInfo.aveA += element->GetA();
thisMaterialInfo.aveZ += element->GetZ();
thisMaterialInfo.aveA += (*ElementVector_ptr)[i]->GetA() * AtomsVector[i];
thisMaterialInfo.aveZ += (*ElementVector_ptr)[i]->GetZ() * AtomsVector[i];
nAtoms += AtomsVector[i];
}
thisMaterialInfo.aveA /= ElementVector_ptr->size();
thisMaterialInfo.aveZ /= ElementVector_ptr->size();
thisMaterialInfo.aveA /= nAtoms;
thisMaterialInfo.aveZ /= nAtoms;
}
thisMaterialInfo.density = material->GetDensity();
thisMaterialInfo.radiation_length = material->GetRadlen();
+15
View File
@@ -32,6 +32,7 @@
#include "G4AutoLock.hh"
#include "G4CopyRandomState.hh"
#include "G4GeometryManager.hh"
#include "G4MTRunManagerKernel.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Run.hh"
@@ -422,6 +423,20 @@ void G4MTRunManager::InitializeEventLoop(G4int n_event, const char* macroFile, G
WaitForReadyWorkers();
}
// --------------------------------------------------------------------
void G4MTRunManager::GeometryOptimisation()
{
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
// G4bool configred = geomManager->IsParallelOptimisationConfigured();
// G4bool finished = geomManager->IsParallelOptimisationFinished();
geomManager->OpenGeometry();
geomManager->CloseGeometry(true, true);
// Force workers to execute UI command
RequestWorkersProcessCommandsStack();
}
// --------------------------------------------------------------------
void G4MTRunManager::RefillSeeds()
{
+9
View File
@@ -57,6 +57,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
scanCmd->SetGuidance("Scanning range should be defined with");
scanCmd->SetGuidance("/control/matScan/theta and /control/matSca/phi commands.");
scanCmd->AvailableForStates(G4State_Idle);
scanCmd->SetToBeBroadcasted(false);
thetaCmd = new G4UIcommand("/control/matScan/theta", this);
thetaCmd->SetGuidance("Define theta range.");
@@ -76,6 +77,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
par->SetDefaultValue("deg");
par->SetParameterCandidates(thetaCmd->UnitsList(thetaCmd->CategoryOf("deg")));
thetaCmd->SetParameter(par);
thetaCmd->SetToBeBroadcasted(false);
phiCmd = new G4UIcommand("/control/matScan/phi", this);
phiCmd->SetGuidance("Define phi range.");
@@ -97,6 +99,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
par->SetDefaultValue("deg");
par->SetParameterCandidates(phiCmd->UnitsList(phiCmd->CategoryOf("deg")));
phiCmd->SetParameter(par);
phiCmd->SetToBeBroadcasted(false);
singleCmd = new G4UIcommand("/control/matScan/singleMeasure", this);
singleCmd->SetGuidance("Measure thickness for one particular direction.");
@@ -114,16 +117,19 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
par->SetDefaultValue("deg");
par->SetParameterCandidates(singleCmd->UnitsList(singleCmd->CategoryOf("deg")));
singleCmd->SetParameter(par);
singleCmd->SetToBeBroadcasted(false);
single2Cmd = new G4UIcmdWith3Vector("/control/matScan/singleTo", this);
single2Cmd->SetGuidance("Measure thickness for one direction defined by a unit vector.");
single2Cmd->SetParameterName("X", "Y", "Z", false);
single2Cmd->SetToBeBroadcasted(false);
eyePosCmd = new G4UIcmdWith3VectorAndUnit("/control/matScan/eyePosition", this);
eyePosCmd->SetGuidance("Define the eye position.");
eyePosCmd->SetParameterName("X", "Y", "Z", true);
eyePosCmd->SetDefaultValue(G4ThreeVector(0., 0., 0.));
eyePosCmd->SetDefaultUnit("m");
eyePosCmd->SetToBeBroadcasted(false);
regSenseCmd = new G4UIcmdWithABool("/control/matScan/regionSensitive", this);
regSenseCmd->SetGuidance("Set region sensitivity.");
@@ -131,6 +137,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
regSenseCmd->SetGuidance(" if /control/matScan/region command is issued.");
regSenseCmd->SetParameterName("senseFlag", true);
regSenseCmd->SetDefaultValue(false);
regSenseCmd->SetToBeBroadcasted(false);
regionCmd = new G4UIcmdWithAString("/control/matScan/region", this);
regionCmd->SetGuidance("Define region name to be scanned.");
@@ -138,6 +145,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
regionCmd->SetGuidance("set to TRUE with this command.");
regionCmd->SetParameterName("region", true);
regionCmd->SetDefaultValue("DefaultRegionForTheWorld");
regionCmd->SetToBeBroadcasted(false);
verboseCmd = new G4UIcmdWithAnInteger("/control/matScan/verbose", this);
verboseCmd->SetGuidance("Set verbose level of material scan");
@@ -146,6 +154,7 @@ G4MatScanMessenger::G4MatScanMessenger(G4MaterialScanner* p1)
verboseCmd->SetGuidance("2: detailed properties per material crossed");
verboseCmd->SetParameterName("verbose_level", false);
verboseCmd->SetDefaultValue(0);
verboseCmd->SetToBeBroadcasted(false);
}
// --------------------------------------------------------------------
+13 -12
View File
@@ -45,6 +45,7 @@
#include "G4StateManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4TransportationManager.hh"
#include "G4UImanager.hh"
// --------------------------------------------------------------------
G4MaterialScanner::G4MaterialScanner()
@@ -54,8 +55,12 @@ G4MaterialScanner::G4MaterialScanner()
theEventManager = G4EventManager::GetEventManager();
eyePosition = G4ThreeVector(0., 0., 0.);
thetaSpan = 90. * deg;
phiSpan = 360. * deg;
nTheta = 81;
thetaMin = -80.0 * deg;
thetaSpan = 160.0 * deg;
nPhi = 36;
phiMin = 0.0 * deg;
phiSpan = 350.0 * deg;
}
// --------------------------------------------------------------------
@@ -102,9 +107,6 @@ void G4MaterialScanner::StoreUserActions()
theSDMan->Activate("/", false);
}
G4GeometryManager* theGeomMan = G4GeometryManager::GetInstance();
theGeomMan->OpenGeometry();
theGeomMan->CloseGeometry(true);
}
// --------------------------------------------------------------------
@@ -124,20 +126,18 @@ void G4MaterialScanner::RestoreUserActions()
// --------------------------------------------------------------------
void G4MaterialScanner::DoScan()
{
// Confirm material table is updated
// Confirm geometry is optimized and material table is updated
G4UImanager::GetUIpointer()->ApplyCommand("/run/undertakeOptimisation");
G4StateManager* theStateMan = G4StateManager::GetStateManager();
theStateMan->SetNewState(G4State_Init);
G4RunManagerKernel::GetRunManagerKernel()->UpdateRegion();
// Close geometry and set the application state
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
geomManager->OpenGeometry();
geomManager->CloseGeometry(true, false);
theStateMan->SetNewState(G4State_Idle);
G4ThreeVector center(0, 0, 0);
G4Navigator* navigator =
G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
navigator->LocateGlobalPointAndSetup(center, nullptr, false);
G4StateManager* theStateMan = G4StateManager::GetStateManager();
theStateMan->SetNewState(G4State_GeomClosed);
// Event loop
@@ -176,6 +176,7 @@ void G4MaterialScanner::DoScan()
theMatScannerSteppingAction->PrintEachMaterialVerbose(G4cout);
}
G4cout << G4endl;
delete anEvent;
aveLength += length / mm;
aveX0 += x0;
aveLambda += lambda;
+16
View File
@@ -82,6 +82,7 @@
#include "G4WorkerRunManagerKernel.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4MaterialScanner.hh"
#include <sstream>
@@ -131,7 +132,9 @@ G4RunManager::G4RunManager()
randomNumberStatusForThisRun = oss.str();
randomNumberStatusForThisEvent = oss.str();
runManagerType = sequentialRM;
materialScanner = new G4MaterialScanner();
G4UImanager::GetUIpointer()->SetAlias("RunMode sequential");
}
// --------------------------------------------------------------------
@@ -157,6 +160,7 @@ G4RunManager::G4RunManager(RMType rmType)
switch (rmType) {
case masterRM:
kernel = new G4MTRunManagerKernel();
materialScanner = new G4MaterialScanner();
break;
case workerRM:
kernel = new G4WorkerRunManagerKernel();
@@ -207,6 +211,7 @@ G4RunManager::~G4RunManager()
delete timer;
delete runMessenger;
delete previousEvents;
delete materialScanner;
// The following will work for all RunManager types
// if derived class does the correct thing in the derived
@@ -633,6 +638,17 @@ void G4RunManager::Initialize()
}
}
// --------------------------------------------------------------------
void G4RunManager::GeometryOptimisation()
{
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
// G4bool configred = geomManager->IsParallelOptimisationConfigured();
// G4bool finished = geomManager->IsParallelOptimisationFinished();
geomManager->OpenGeometry();
geomManager->CloseGeometry(true, true);
}
// --------------------------------------------------------------------
void G4RunManager::InitializeGeometry()
{
+11
View File
@@ -247,6 +247,13 @@ G4RunMessenger::G4RunMessenger(G4RunManager* runMgr) : runManager(runMgr)
geomRebCmd->SetDefaultValue(false);
geomRebCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
undertakeOptCmd = new G4UIcmdWithoutParameter("/run/undertakeOptimisation", this);
undertakeOptCmd->SetGuidance("Force geometry optimisation.");
undertakeOptCmd->SetGuidance("May be used before the command which use geometry navigation");
undertakeOptCmd->SetGuidance("e.g. /vis/scene/add/magneticField command.");
undertakeOptCmd->SetToBeBroadcasted(true);
undertakeOptCmd->AvailableForStates(G4State_Idle);
physCmd = new G4UIcmdWithoutParameter("/run/physicsModified", this);
physCmd->SetGuidance("Force all physics tables recalculated again.");
physCmd->SetGuidance("This command must be applied");
@@ -400,6 +407,7 @@ G4RunMessenger::~G4RunMessenger()
delete initCmd;
delete geomCmd;
delete geomRebCmd;
delete undertakeOptCmd;
delete physCmd;
delete randEvtCmd;
delete constScoreCmd;
@@ -547,6 +555,9 @@ void G4RunMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
else if (command == geomRebCmd) {
runManager->ReinitializeGeometry(geomRebCmd->GetNewBoolValue(newValue), false);
}
else if (command == undertakeOptCmd) {
runManager->GeometryOptimisation();
}
else if (command == physCmd) {
runManager->PhysicsHasBeenModified();
}
+12 -1
View File
@@ -131,6 +131,17 @@ G4WorkerRunManager::~G4WorkerRunManager()
if (verboseLevel > 1) G4cout << "Destroying WorkerRunManager (" << this << ")" << G4endl;
}
// --------------------------------------------------------------------
void G4WorkerRunManager::GeometryOptimisation()
{
G4GeometryManager* geomManager = G4GeometryManager::GetInstance();
G4bool configred = geomManager->IsParallelOptimisationConfigured();
G4bool finished = geomManager->IsParallelOptimisationFinished();
if (configred && !finished) {
geomManager->UndertakeOptimisation();
}
}
// --------------------------------------------------------------------
void G4WorkerRunManager::InitializeGeometry()
{
@@ -153,7 +164,7 @@ void G4WorkerRunManager::InitializeGeometry()
}
// A barrier must ensure that all that all threads have finished this work.
// Currently we rely on the (later) barrier at the end of initialisation.
// Step1: Get pointer to the physiWorld (note: needs to get the "super
// pointer, i.e. the one shared by all threads"
G4RunManagerKernel* masterKernel = G4MTRunManager::GetMasterRunManagerKernel();
+13
View File
@@ -5,6 +5,19 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-01 John Allison (opengl-V11-03-10)
- G4OpenGLViewer.cc:
- Remove archaic and unnecessary 20th-century #include statements. The first
raises a warning on some platforms.
- #include "G4ios.hh"
- #include <CLHEP/Units/SystemOfUnits.h>
## 2025-12-26 John Allison
- G4OpenGLQtViewer.cc: Fix bug 2688:
- In G4OpenGLQtViewer::G4wheelEvent:
- Fix for Qt version < 5.14.
## 2025-10-31 Andrea Barresi (opengl-V11-03-09)
- G4OpenGLQtViewer
- Improved context menu behavior for picking
@@ -1556,7 +1556,11 @@ void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * evnt)
double delta = evnt->angleDelta().y();
#endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
ZoomFromMouseWheel(delta, evnt->modifiers() & Qt::ShiftModifier, evnt->pos().x(), evnt->pos().y());
#else
ZoomFromMouseWheel(delta, evnt->modifiers() & Qt::ShiftModifier, evnt->position().x(), evnt->position().y());
#endif
updateQWidget();
}
@@ -29,8 +29,6 @@
// Andrew Walkden 27th March 1996
// OpenGL view - opens window, hard copy, etc.
#include "G4ios.hh"
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4OpenGLViewer.hh"
#include "G4OpenGLSceneHandler.hh"
#include "G4OpenGLTransform3D.hh"
+12
View File
@@ -5,6 +5,18 @@ which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-01-30 John Allison (vis_toolssg-V11-03-13)
- G4ToolsSGSceneHandler.cc:
- Obtain applicable auxiliary edge flag.
## 2026-01-10 John Allison
- G4ToolsSGSceneHandler.cc:
- G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& ...
- Fix Bug #2691: Daughter of cloud-represented volume in wrong position.
- Transformation of cloud-represented volume was being accumulated with daughter's.
- Add and missing separator, prevent accumulation.
## 2025-10-24 Guy Barrand (vis_toolssg-V11-03-12)
- implementation/sources.cmake: handle "-DTOOLS_USE_GL_VERSION_3_2" in case "GEANT4_USE_VTK".
@@ -272,6 +272,9 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
auto currentNode = GetOrCreateNode();
if (!currentNode) return; // Node not available
tools::sg::separator* sep = new tools::sg::separator;
currentNode->add(sep);
// Transformation
{tools::sg::matrix* mtx = new tools::sg::matrix;
G4Transform3D& elem = fObjectTransformation;
@@ -279,7 +282,7 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
elem(1,0),elem(1,1),elem(1,2),elem(1,3),
elem(2,0),elem(2,1),elem(2,2),elem(2,3),
0, 0, 0, 1);
currentNode->add(mtx);}
sep->add(mtx);}
{const auto& colour = GetColour(a_polymarker);
tools::sg::rgba* mat = new tools::sg::rgba();
@@ -288,7 +291,7 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
float(colour.GetGreen()),
float(colour.GetBlue()),
float(colour.GetAlpha()));
currentNode->add(mat);}
sep->add(mat);}
MarkerSizeType markerSizeType;
G4double markerSize = GetMarkerSize(a_polymarker, markerSizeType);
@@ -300,14 +303,14 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
ds->style = tools::sg::draw_points;
ds->point_size = markerSize;
ds->point_smooth = fpViewer->GetViewParameters().IsDotsSmooth()?true:false;
currentNode->add(ds);
sep->add(ds);
tools::sg::vertices* vtxs = new tools::sg::vertices;
vtxs->mode = tools::gl::points();
{for (const auto& i : a_polymarker) {
vtxs->add(float(i.x()),float(i.y()),float(i.z()));
}}
currentNode->add(vtxs);
sep->add(vtxs);
}break;
case G4Polymarker::circles:{
{tools::sg::markers* markers = new tools::sg::markers;
@@ -321,7 +324,7 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
for (const auto& i : a_polymarker) {
markers->add(float(i.x()),float(i.y()),float(i.z()));
}
currentNode->add(markers);}
sep->add(markers);}
}break;
case G4Polymarker::squares:{
{tools::sg::markers* markers = new tools::sg::markers;
@@ -335,7 +338,7 @@ void G4ToolsSGSceneHandler::AddPrimitive (const G4Polymarker& a_polymarker)
for (const auto& i : a_polymarker) {
markers->add(float(i.x()),float(i.y()),float(i.z()));
}
currentNode->add(markers);}
sep->add(markers);}
}break;
}
}
@@ -467,7 +470,7 @@ void G4ToolsSGSceneHandler::AddPrimitive(const G4Polyhedron& a_polyhedron)
lines.push_back(newLine);
};
G4bool isAuxilaryEdgeVisible = fpViewer->GetViewParameters().IsAuxEdgeVisible();
G4bool isAuxilaryEdgeVisible = GetAuxEdgeVisible (fpVisAttribs);
G4bool notLastFace;
do {
G4int nEdges;
+6
View File
@@ -6,6 +6,12 @@ be used as a substitute for writing good git commit messages!
--------------------------------------------------------------------
## 2026-02-11 John Allison (vistree-V11-03-00)
- Move fVerbosityGuidance to G4ASCIITree factory.
- It was a static variable in G4ASCIITreeMessenger - static to allow access - but
it gives "AddressSanitizer: container-overflow" with "-fsanitize=address,undefined"
(as discovered by user Davide Terzani, Bug Report 2699).
## 2023-02-06 Ben Morgan (vistree-V11-01-00)
- Isolate private headers and update dependencies
@@ -35,6 +35,8 @@
#include "G4VTree.hh"
#include <vector>
class G4ASCIITreeMessenger;
class G4ASCIITree: public G4VTree {
@@ -44,12 +46,14 @@ public:
G4VSceneHandler* CreateSceneHandler (const G4String& name = "");
G4VViewer* CreateViewer (G4VSceneHandler&, const G4String& name = "");
G4int GetVerbosity() const {return fVerbosity;}
const std::vector<G4String>& GetVerbosityGuidance() const {return fVerbosityGuidance;}
G4String GetOutFileName () const {return fOutFileName;}
void SetVerbosity (G4int verbosity) {fVerbosity = verbosity;}
void SetOutFileName (const G4String& name) {fOutFileName = name;}
protected:
G4int fVerbosity;
G4ASCIITreeMessenger* fpMessenger;
std::vector<G4String> fVerbosityGuidance;
G4String fOutFileName;
};
@@ -36,8 +36,6 @@
#include "G4UImessenger.hh"
#include <vector>
class G4ASCIITree;
class G4UIcommand;
class G4UIcmdWithAnInteger;
@@ -49,7 +47,6 @@ public:
virtual ~G4ASCIITreeMessenger();
G4String GetCurrentValue (G4UIcommand* command);
void SetNewValue (G4UIcommand* command, G4String newValue);
static std::vector<G4String> fVerbosityGuidance;
private:
G4ASCIITree* fpASCIITree;
G4UIcommand* fpDirectory;
@@ -45,6 +45,57 @@ G4ASCIITree::G4ASCIITree ():
fVerbosity(1),
fOutFileName ("G4cout")
{
fVerbosityGuidance.push_back
(" < 10: notifies but does not print details of repeated volumes.");
fVerbosityGuidance.push_back
(" >= 10: prints all physical volumes (touchables).");
fVerbosityGuidance.push_back
("The level of detail is given by verbosity%10:");
fVerbosityGuidance.push_back
(" >= 0: physical volume name.");
fVerbosityGuidance.push_back
(" >= 1: logical volume name (and names of sensitive detector"
" and readout geometry, if any).");
fVerbosityGuidance.push_back
(" >= 2: solid name and type.");
fVerbosityGuidance.push_back
(" >= 3: volume and density.");
fVerbosityGuidance.push_back
(" >= 5: daughter-subtracted volume and mass.");
fVerbosityGuidance.push_back
(" >= 6: physical volume dump.");
fVerbosityGuidance.push_back
(" >= 7: polyhedron dump.");
fVerbosityGuidance.push_back
("and in the summary at the end of printing:");
fVerbosityGuidance.push_back
(" >= 4: daughter-included mass of top physical volume(s) in scene"
" to depth specified.");
fVerbosityGuidance.push_back
("Note: by default, culling is switched off so all volumes are seen.");
fVerbosityGuidance.push_back
("Note: the mass calculation takes into account daughters, which can be"
" time consuming. If you want the mass of a particular subtree try:");
fVerbosityGuidance.push_back
(" /vis/drawTree <subtree-physical-volume-name>");
fVerbosityGuidance.push_back
("Or if you want more control, for example:");
fVerbosityGuidance.push_back
(" /vis/open ATree");
fVerbosityGuidance.push_back
(" /vis/ASCIITree/verbose 14");
fVerbosityGuidance.push_back
(" /vis/scene/create");
fVerbosityGuidance.push_back
(" /vis/scene/add/volume <subtree-physical-volume-name> ! <depth>");
fVerbosityGuidance.push_back
(" /vis/sceneHandler/attach");
fVerbosityGuidance.push_back
(" /vis/viewer/flush");
fVerbosityGuidance.push_back
("Note: dumping the physical volumes produces a lot of output. It is"
" advisable to select the volume of interest, as for a sub-tree above.");
fpMessenger = new G4ASCIITreeMessenger(this);
}
@@ -38,8 +38,6 @@
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithAString.hh"
std::vector<G4String> G4ASCIITreeMessenger::fVerbosityGuidance;
G4ASCIITreeMessenger::G4ASCIITreeMessenger
(G4ASCIITree* ASCIITree):
fpASCIITree(ASCIITree) {
@@ -53,58 +51,8 @@ fpASCIITree(ASCIITree) {
fpDirectorySet -> SetGuidance ("Settings for ASCIITree control.");
fpCommandVerbose = new G4UIcmdWithAnInteger ("/vis/ASCIITree/verbose", this);
fVerbosityGuidance.push_back
(" < 10: notifies but does not print details of repeated volumes.");
fVerbosityGuidance.push_back
(" >= 10: prints all physical volumes (touchables).");
fVerbosityGuidance.push_back
("The level of detail is given by verbosity%10:");
fVerbosityGuidance.push_back
(" >= 0: physical volume name.");
fVerbosityGuidance.push_back
(" >= 1: logical volume name (and names of sensitive detector"
" and readout geometry, if any).");
fVerbosityGuidance.push_back
(" >= 2: solid name and type.");
fVerbosityGuidance.push_back
(" >= 3: volume and density.");
fVerbosityGuidance.push_back
(" >= 5: daughter-subtracted volume and mass.");
fVerbosityGuidance.push_back
(" >= 6: physical volume dump.");
fVerbosityGuidance.push_back
(" >= 7: polyhedron dump.");
fVerbosityGuidance.push_back
("and in the summary at the end of printing:");
fVerbosityGuidance.push_back
(" >= 4: daughter-included mass of top physical volume(s) in scene"
" to depth specified.");
fVerbosityGuidance.push_back
("Note: by default, culling is switched off so all volumes are seen.");
fVerbosityGuidance.push_back
("Note: the mass calculation takes into account daughters, which can be"
" time consuming. If you want the mass of a particular subtree try:");
fVerbosityGuidance.push_back
(" /vis/drawTree <subtree-physical-volume-name>");
fVerbosityGuidance.push_back
("Or if you want more control, for example:");
fVerbosityGuidance.push_back
(" /vis/open ATree");
fVerbosityGuidance.push_back
(" /vis/ASCIITree/verbose 14");
fVerbosityGuidance.push_back
(" /vis/scene/create");
fVerbosityGuidance.push_back
(" /vis/scene/add/volume <subtree-physical-volume-name> ! <depth>");
fVerbosityGuidance.push_back
(" /vis/sceneHandler/attach");
fVerbosityGuidance.push_back
(" /vis/viewer/flush");
fVerbosityGuidance.push_back
("Note: dumping the physical volumes produces a lot of output. It is"
" advisable to select the volume of interest, as for a sub-tree above.");
for (size_t i = 0; i < fVerbosityGuidance.size(); ++i) {
fpCommandVerbose -> SetGuidance(fVerbosityGuidance[i]);
for (size_t i = 0; i < fpASCIITree->GetVerbosityGuidance().size(); ++i) {
fpCommandVerbose -> SetGuidance(fpASCIITree->GetVerbosityGuidance()[i]);
}
fpCommandVerbose -> SetParameterName ("verbosity",omitable = true);
fpCommandVerbose -> SetDefaultValue(1);
@@ -86,11 +86,12 @@ void G4ASCIITreeSceneHandler::BeginModeling () {
G4cout << "file \"" << outFileName << "\"";
}
G4cout << G4endl;
WriteHeader (G4cout); G4cout << G4endl;
}
if (outFileName != "G4cout") {
if (outFileName == "G4cout") {
WriteHeader (G4cout); G4cout << G4endl;
} else {
G4cout << "Writing to output file \"" << outFileName << "\"" << G4endl;
WriteHeader (fOutFile); fOutFile << std::endl;
}
}
@@ -101,9 +102,13 @@ void G4ASCIITreeSceneHandler::WriteHeader (std::ostream& os)
const G4int verbosity = pSystem->GetVerbosity();
const G4int detail = verbosity % 10;
os << "# Set verbosity with \"/vis/ASCIITree/verbose <verbosity>\":";
for (size_t i = 0;
i < G4ASCIITreeMessenger::fVerbosityGuidance.size(); ++i) {
os << "\n# " << G4ASCIITreeMessenger::fVerbosityGuidance[i];
static G4bool firstTime = true;
if (firstTime) {
firstTime = false;
for (size_t i = 0;
i < pSystem->GetVerbosityGuidance().size(); ++i) {
os << "\n# " << pSystem->GetVerbosityGuidance()[i];
}
}
os << "\n# Now printing with verbosity " << verbosity;
os << "\n# Format is: PV:n";
+3
View File
@@ -6,6 +6,9 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-02-19 Gabriele Cosmo (gMocren-V11-03-00)
- Fixed reported Coverity defect for unnecessary string copy in G4GMocrenIO.
## 2024-09-29 John Allison (gMocren-V11-02-02)
- More Coverity fixes
@@ -80,7 +80,7 @@ public:
T * getImage(int _z); // get image of each layer
void setCenterPosition(float _center[3]);
void getCenterPosition(float _center[3]);
void setName(std::string & _name);
void setName(const std::string & _name);
std::string getName();
};
@@ -373,7 +373,7 @@ public:
// get & get name of calculated dose distribution
std::string getDoseDistName(int _num = 0);
void setDoseDistName(std::string _name, int _num = 0);
void setDoseDistName(const std::string& _name, int _num = 0);
// copy dose distributions
void copyDoseDist(std::vector<class GMocrenDataPrimitive<double> > & _dose);
@@ -234,7 +234,7 @@ void GMocrenDataPrimitive<T>::getCenterPosition(float _center[3]) {
for(int i = 0; i < 3; i++) _center[i] = kCenter[i];
}
template <typename T>
void GMocrenDataPrimitive<T>::setName(std::string & _name) {
void GMocrenDataPrimitive<T>::setName(const std::string & _name) {
kDataName = _name;
}
template <typename T>
@@ -3659,7 +3659,7 @@ void G4GMocrenIO::getDoseDistCenterPosition(float _center[3], int _num) {
kDose[_num].getCenterPosition(_center);
}
// set & get name of dose distribution
void G4GMocrenIO::setDoseDistName(std::string _name, int _num) {
void G4GMocrenIO::setDoseDistName(const std::string& _name, int _num) {
kDose[_num].setName(_name);
}
+11
View File
@@ -6,6 +6,17 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2026-03-05 John Allison (modeling-V11-03-09)
- G4PhysicalVolumeModel:
- Build and maintain a private G4NavigationHistory.
- Create a temporary G4TouchableHistory from it when required (i.e., when
calling nested parameterisation ComputeMaterial()).
## 2026-03-03 John Apostolakis
- G4PhysicalVolumeModel.cc:
- Replace helper class G4PhysicalVolumeModelTouchable with temporary
G4TouchableHistory object (when calling nested parameterisation.)
## 2025-04-13 John Allison (modeling-V11-03-08)
- G4PhysicalVolumeModel.cc:
- Fix typo in ModelType.
@@ -64,7 +64,7 @@
#include "G4VModel.hh"
#include "G4ModelingParameters.hh"
#include "G4VTouchable.hh"
#include "G4NavigationHistory.hh"
#include "G4Transform3D.hh"
#include "G4Plane3D.hh"
#include <iostream>
@@ -124,21 +124,6 @@ public: // With description
G4bool fDrawn;
};
// Nested class for handling nested parameterisations.
class G4PhysicalVolumeModelTouchable: public G4VTouchable {
public:
G4PhysicalVolumeModelTouchable
(const std::vector<G4PhysicalVolumeNodeID>& fullPVPath);
const G4ThreeVector& GetTranslation(G4int depth) const;
const G4RotationMatrix* GetRotation(G4int depth) const;
G4VPhysicalVolume* GetVolume(G4int depth) const;
G4VSolid* GetSolid(G4int depth) const;
G4int GetReplicaNumber(G4int depth) const;
G4int GetHistoryDepth() const {return G4int(fFullPVPath.size());}
private:
const std::vector<G4PhysicalVolumeNodeID>& fFullPVPath;
};
// Nested struct for encapsulating touchable properties
struct TouchableProperties {
TouchableProperties(): fpTouchablePV(nullptr), fCopyNo(0) {}
@@ -319,6 +304,7 @@ protected:
std::vector<G4PhysicalVolumeNodeID> fBaseFullPVPath; // Base. May be empty.
std::vector<G4PhysicalVolumeNodeID> fFullPVPath; // Starts from base.
std::vector<G4PhysicalVolumeNodeID> fDrawnPVPath; // Omits culled volumes.
G4NavigationHistory fNavigationHistory; // Starts from top PV.
mutable G4bool fAbort; // Abort all further traversing.
mutable G4bool fCurtailDescent;// Can be set to curtail descent.
G4VSolid* fpClippingSolid;
@@ -39,10 +39,10 @@
#include "G4VSolid.hh"
#include "G4SubtractionSolid.hh"
#include "G4IntersectionSolid.hh"
#include "G4TouchableHistory.hh"
#include "G4Material.hh"
#include "G4VisAttributes.hh"
#include "G4BoundingExtentScene.hh"
#include "G4TransportationManager.hh"
#include "G4Polyhedron.hh"
#include "HepPolyhedronProcessor.h"
#include "G4AttDefStore.hh"
@@ -114,6 +114,7 @@ G4PhysicalVolumeModel::G4PhysicalVolumeModel
<< " BasePath:" << fBaseFullPVPath;
fGlobalTag = oss.str();
fGlobalDescription = "G4PhysicalVolumeModel " + fGlobalTag;
fNavigationHistory.SetFirstEntry(fpTopPV);
CalculateExtent ();
}
}
@@ -252,6 +253,7 @@ void G4PhysicalVolumeModel::DescribeYourselfTo
fpCurrentMaterial = fpCurrentLV? fpCurrentLV->GetMaterial(): 0;
fFullPVPath = fBaseFullPVPath;
fDrawnPVPath.clear();
fNavigationHistory.Reset(); // Keeps top PV
fAbort = false;
fCurtailDescent = false;
}
@@ -323,7 +325,7 @@ void G4PhysicalVolumeModel::VisitGeometryAndGetVisReps
// Create a touchable of current parent for ComputeMaterial.
// fFullPVPath has not been updated yet so at this point it
// corresponds to the parent.
G4PhysicalVolumeModelTouchable parentTouchable(fFullPVPath);
G4TouchableHistory parentTouchable(fNavigationHistory);
pMaterial = pP -> ComputeMaterial (n, pVPV, &parentTouchable);
DescribeAndDescend (pVPV, requestedDepth, pLV, pSol, pMaterial,
theAT, sceneHandler);
@@ -442,6 +444,8 @@ void G4PhysicalVolumeModel::DescribeAndDescend
// Update full path of physical volumes...
fFullPVPath.push_back(nodeID);
// ...and navigation history (kNormal is OK for our purposes)
fNavigationHistory.NewLevel(fpCurrentPV, kNormal, copyNo);
const G4RotationMatrix objectRotation = pVPV -> GetObjectRotationValue ();
const G4ThreeVector& translation = pVPV -> GetTranslation ();
@@ -471,7 +475,7 @@ void G4PhysicalVolumeModel::DescribeAndDescend
if (fpMP->GetCBDAlgorithmNumber() == 1) {
// Algorithm 1: 3 parameters: Simple rainbow mapping.
if (fpMP->GetCBDParameters().size() != 3) {
G4Exception("G4PhysicalVolumeModelTouchable::DescribeAndDescend",
G4Exception("G4PhysicalVolumeModel::DescribeAndDescend",
"modeling0014",
FatalErrorInArgument,
"Algorithm-parameter mismatch for Colour By Density");
@@ -822,6 +826,7 @@ void G4PhysicalVolumeModel::DescribeAndDescend
if (thisToBeDrawn) {
fDrawnPVPath.pop_back();
}
fNavigationHistory.BackLevel();
}
namespace
@@ -1160,71 +1165,3 @@ std::ostream& operator<<
}
return os;
}
G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::G4PhysicalVolumeModelTouchable
(const std::vector<G4PhysicalVolumeNodeID>& fullPVPath):
fFullPVPath(fullPVPath) {}
const G4ThreeVector& G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::GetTranslation(G4int depth) const
{
size_t i = fFullPVPath.size() - depth - 1;
if (i >= fFullPVPath.size()) {
G4Exception("G4PhysicalVolumeModelTouchable::GetTranslation",
"modeling0005",
FatalErrorInArgument,
"Index out of range. Asking for non-existent depth");
}
static G4ThreeVector tempTranslation;
tempTranslation = fFullPVPath[i].GetTransform().getTranslation();
return tempTranslation;
}
const G4RotationMatrix* G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::GetRotation(G4int depth) const
{
size_t i = fFullPVPath.size() - depth - 1;
if (i >= fFullPVPath.size()) {
G4Exception("G4PhysicalVolumeModelTouchable::GetRotation",
"modeling0006",
FatalErrorInArgument,
"Index out of range. Asking for non-existent depth");
}
static G4RotationMatrix tempRotation;
tempRotation = fFullPVPath[i].GetTransform().getRotation();
return &tempRotation;
}
G4VPhysicalVolume* G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::GetVolume(G4int depth) const
{
size_t i = fFullPVPath.size() - depth - 1;
if (i >= fFullPVPath.size()) {
G4Exception("G4PhysicalVolumeModelTouchable::GetVolume",
"modeling0007",
FatalErrorInArgument,
"Index out of range. Asking for non-existent depth");
}
return fFullPVPath[i].GetPhysicalVolume();
}
G4VSolid* G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::GetSolid(G4int depth) const
{
size_t i = fFullPVPath.size() - depth - 1;
if (i >= fFullPVPath.size()) {
G4Exception("G4PhysicalVolumeModelTouchable::GetSolid",
"modeling0008",
FatalErrorInArgument,
"Index out of range. Asking for non-existent depth");
}
return fFullPVPath[i].GetPhysicalVolume()->GetLogicalVolume()->GetSolid();
}
G4int G4PhysicalVolumeModel::G4PhysicalVolumeModelTouchable::GetReplicaNumber(G4int depth) const
{
size_t i = fFullPVPath.size() - depth - 1;
if (i >= fFullPVPath.size()) {
G4Exception("G4PhysicalVolumeModelTouchable::GetReplicaNumber",
"modeling0009",
FatalErrorInArgument,
"Index out of range. Asking for non-existent depth");
}
return fFullPVPath[i].GetCopyNo();
}