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