BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSIonDefinition.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSDebug.hh"
19#include "BDSException.hh"
20#include "BDSIonDefinition.hh"
21
22#include "globals.hh"
23
24#include "CLHEP/Units/SystemOfUnits.h"
25
26#include <exception>
27#include <ostream>
28#include <regex>
29#include <stdexcept>
30
31BDSIonDefinition::BDSIonDefinition(const G4String& definition):
32 a(1),
33 z(1),
34 charge(1),
35 energy(0),
36 overrideCharge(false),
37 nElectrons(0)
38{
39 Parse(definition);
40
41 if (a < z)
42 {
43 G4String message("Invalid ion definition: \"" + definition + "\" -> A is less than Z");
44 throw BDSException(__METHOD_NAME__, message);
45 }
46 if (charge < 0)
47 {G4cout << __METHOD_NAME__ << "Using ion with -ve charge -> implies at least 1 extra electron." << G4endl;}
48}
49
51 G4int zIn,
52 G4double qIn):
53 a(aIn),
54 z(zIn),
55 charge(qIn),
56 energy(0),
57 overrideCharge(false),
58 nElectrons(0)
59{
60 if (a < z)
61 {
62 G4String message("Invalid ion definition: A is less than Z");
63 throw BDSException(__METHOD_NAME__, message);
64 }
65 if (charge > z)
66 {
67 G4String message("Invalid ion definition: Charge is greater than Z");
68 throw BDSException(__METHOD_NAME__, message);
69 }
70 if (z != charge)
71 {
72 nElectrons = z - (G4int)charge;
73 G4cout << __METHOD_NAME__ << nElectrons << " bound electrons to ion inferred from charge, A and Z." << G4endl;
74 }
75 if (charge < 0)
76 {G4cout << __METHOD_NAME__ << "Using ion with -ve charge -> implies at least 1 extra electron." << G4endl;}
77}
78
79std::ostream& operator<< (std::ostream& out, BDSIonDefinition const& io)
80{
81 out << "A: " << io.a << " Z: " << io.z << " Q: " << io.charge << " E: "
82 << io.energy << G4endl;
83 return out;
84}
85
86void BDSIonDefinition::Parse(const G4String& definition)
87{
88 std::regex wspace("\\s+"); // any whitespace
89
90 // A Z Q E
91 G4int counter = 0;
92 std::vector<G4int*> vals = {&a, &z};
93 // split on whitespace - "-1" here means split on the gap, not the token, ie the word not the whitespace
94 std::sregex_token_iterator wordsBegin(definition.begin(), definition.end(), wspace, -1);
95 std::sregex_token_iterator wordsEnd;
96 for (auto i = wordsBegin; i != wordsEnd; ++i, ++counter)
97 {
98 if (counter == 0)
99 {continue;}// the first 'word' is expected to be "ion"
100 std::string word = (*i).str();
101 if (counter == 3) // ie > 2
102 {overrideCharge = true;} // charge is specified
103 try
104 {
105 if (counter > 2)
106 {// Q or E are doubles
107 G4double value = std::stod(word);
108 if (counter == 4)
109 {energy = value*CLHEP::keV;}
110 else
111 {charge = value*CLHEP::eplus;}
112 }
113 else
114 {// A and Z are integers
115 // check for decimal point -> should not be a floating point number
116 if (word.find('.') != std::string::npos)
117 {throw BDSException(__METHOD_NAME__, "value in beam ion definition \"" + word + "\" must be an integer");}
118 (*vals[counter-1]) = std::stoi(word);
119 if (counter == 2) // by default copy Z as value of Q
120 {charge = (G4double)*vals[counter-1] * CLHEP::eplus;}
121 }
122 }
123 catch (const std::invalid_argument&) // if stod/i can't convert number to double / int
124 {throw BDSException(__METHOD_NAME__, "Invalid ion definition " + definition );}
125 }
126
127 if (z != charge)
128 {
129 nElectrons = z - (G4int)charge;
130 G4cout << __METHOD_NAME__ << nElectrons << " bound electrons to ion inferred from charge, A and Z." << G4endl;
131 }
132 if (charge > z)
133 {
134 G4String message("Invalid ion definition: Charge is greater than Z");
135 throw BDSException(__METHOD_NAME__, message);
136 }
137}
General exception with possible name of object and message.
Class to parse an ion particle definition.
G4int nElectrons
Inferred number of bound electrons if any.
G4bool overrideCharge
Whether to specify the charge.
G4double energy
Excitation energy. G4units.
void Parse(const G4String &definition)
Parse the definition.
BDSIonDefinition()=delete
No default constructor.
G4double charge
In units of eplus.