39{
40
41 std::map< std::string, std::vector<std::vector<std::string>* > > decayMap;
44 while (getline(decayFile,line)) {
45 std::istringstream is(line);
46 std::vector<std::string>* txtvec = new std::vector<std::string>(std::istream_iterator<std::string>(is),std::istream_iterator<std::string>());
47 const std::string
name = (*txtvec)[0];
48 try {
49 decayMap.at(name).push_back(txtvec);
50 }
51 catch (const::std::out_of_range& e) {
52 std::vector<std::vector<std::string>* >
decays;
54 decayMap[
name] = std::move(decays);
55 }
56 }
58
59
60 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
61
62 std::set<G4ParticleDefinition *>
particles;
63
65 G4String pType="custom";
66 G4String pSubType="";
67 G4double spectatormass = 0;
68 G4ParticleDefinition* spectator = 0;
71 int pdgCode;
73 G4double lifetime{-1.0};
76
77
78 while (getline(configFile,line)) {
79 G4cout << "-------------------------------------------------" << G4endl;
80 std::string::size_type beg_idx,end_idx;
81
82 beg_idx =
line.find_first_not_of(
"\t #");
83 if (beg_idx > 0 && line[beg_idx-1] == '#') continue;
84 end_idx =
line.find_first_of(
"\t ", beg_idx);
85 if (end_idx == std::string::npos) continue;
86 char *endptr;
87 const std::string pdgCodeString =
line.substr( beg_idx, end_idx - beg_idx );
88 pdgCode = strtol(pdgCodeString.c_str(), &endptr, 0);
89 if (endptr[0] != '\0') {
90 throw std::invalid_argument(
"Could not convert string to int: " +
line.substr( beg_idx, end_idx - beg_idx ));
91 }
92
93 beg_idx =
line.find_first_not_of(
"\t ",end_idx);
94 end_idx =
line.find_first_of(
"\t #", beg_idx);
95 if (end_idx == std::string::npos) continue;
96 mass =
atof(
line.substr( beg_idx, end_idx - beg_idx ).c_str());
97
98 beg_idx =
line.find_first_not_of(
"\t# ",end_idx);
99 end_idx =
line.length();
100 if (beg_idx==std::string::npos) beg_idx = end_idx;
101 name =
line.substr( beg_idx, end_idx - beg_idx );
102 while (
name.c_str()[0] ==
' ') {
name.erase(0,1); }
103 while (name[
name.size()-1] ==
' ') {
name.erase(
name.size()-1,1); }
104
105 if (abs(pdgCode) / 1000000 == 0){
106 G4cout << "Pdg code too low " << pdgCode << " "<<abs(pdgCode) / 1000000 << std::endl;
107 continue;
108 }
109
112
113 pType="custom";
116
117 G4cout<<"pType: "<<pType<<G4endl;
119
120 G4ParticleDefinition* previousDefinition = theParticleTable->FindParticle(pdgCode);
121
122 if (previousDefinition) {
123 G4cout <<
"Found an existing G4ParticleDefinition for " <<
name <<
"(" << pdgCode <<
") in G4ParticleTable. Assuming that we want the new definition, so removing previous definition! May cause issues elsewhere though..." << G4endl;
124 previousDefinition->DumpTable();
125 theParticleTable->Remove(previousDefinition);
126 delete previousDefinition;
127 }
128
129
130
131
132
133
134
135 CustomParticle *
particle =
new CustomParticle(
136 name, mass * CLHEP::GeV , 0.0*CLHEP::MeV, CLHEP::eplus *
MC::charge(pdgCode),
138 0, 0, 0,
139 pType, 0, +1, pdgCode,
140 stable, lifetime, nullptr );
141 if (pType=="custom") {
142 spectatormass =
mass;
144 }
145 if (first) {
147 spectatormass =
mass;
149 } else {
150 G4String cloudname =
name+
"cloud";
151 G4String cloudtype = pType+"cloud";
152 G4double cloudmass =
mass-spectatormass;
153 const bool cloudstable = !(
parameters->DoDecays() == 1 || decayMap.contains(cloudname));
154 const G4double cloudlifetime = cloudstable ? -1.0 :
parameters->Lifetime();
155
156 std::unique_ptr<G4ParticleDefinition> tmpParticle = std::unique_ptr<CustomParticle>( new CustomParticle(
157 cloudname, cloudmass * CLHEP::GeV , 0.0*CLHEP::MeV, 0 ,
158 0, +1, 0,
159 0, 0, 0,
160 cloudtype, 0, +1, 0,
161 cloudstable, cloudlifetime, nullptr ) );
164
165 G4cout <<
name <<
" being assigned cloud " <<
particle->GetCloud()->GetParticleName() <<
" and spectator " <<
particle->GetSpectator()->GetParticleName() << G4endl;
166 G4cout << "Masses: "
167 <<
particle->GetPDGMass()/CLHEP::GeV <<
" Gev, "
168 <<
particle->GetCloud()->GetPDGMass()/CLHEP::GeV <<
" GeV and "
169 <<
particle->GetSpectator()->GetPDGMass()/CLHEP::GeV <<
" GeV."
170 << G4endl;
171 }
172
174 }
176 G4cout << "-------------------------------------------------" << G4endl;
177
178
179 for (G4ParticleDefinition *part : particles) {
181 if ( decayMap.contains(name) ) {
182 std::vector<std::vector<std::string>* >& mydecays = decayMap.at(name);
183
184 if (mydecays.empty()) { continue; }
185 int ndec=mydecays.size();
186 G4DecayTable*
table =
new G4DecayTable();
187 G4VDecayChannel**
mode =
new G4VDecayChannel*[ndec]{};
188 for (
int i=0;
i!=ndec;
i++) {
189 std::vector<std::string> thisdec=*(mydecays[
i]);
190 if (thisdec.empty()) continue;
191 const double branch = std::stod(thisdec.back());
192 thisdec.pop_back();
193 for (const auto & thisString:thisdec) G4cout<<thisString<<G4endl;
194 if (thisdec.size()==3) {
195 mode[
i] =
new G4PhaseSpaceDecayChannel(thisdec[0],branch,2,thisdec[1],thisdec[2]);
196 } else if (thisdec.size()==4) {
197 mode[
i] =
new G4PhaseSpaceDecayChannel(thisdec[0],branch,3,thisdec[1],thisdec[2],thisdec[3]);
198 } else {
199 G4cout<<"Decay chain invalid!!!"<<std::endl;
200 }
201 }
202 for (G4int index=0;
index <ndec;
index++ ) {
table->Insert(mode[index]); }
204 part->SetDecayTable(table);
205 }
206 else { continue; }
207 }
209}
static const PhysicsConfigurationHelper * Instance()
double atof(std::string_view str)
Converts a string into a double / float.
bool isSlepton(const T &p)
bool isRHadron(const T &p)
double charge(const T &p)
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses