ATLAS Offline Software
CustomMonopoleFactory.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // class header
7 // package headers
8 #include "CustomMonopole.h"
9 // CLHEP headers
10 #include "CLHEP/Units/PhysicalConstants.h"
11 #include "CLHEP/Units/SystemOfUnits.h"
12 // STL headers
13 #include <fstream>
14 #include <iomanip>
15 #include <iostream>
16 #include <stdexcept>
17 #include <sstream>
18 #include <iterator>
19 #include <set>
20 
21 
23 {
24  static const CustomMonopoleFactory factory;
25  return factory;
26 }
27 
29 {
30  return (particle && m_particles.find(particle)!=m_particles.end());
31 }
32 
34 {
36 }
37 
39 {
40  std::ifstream configFile("particles.txt");
41  // std::ifstream configFile("stophadrons.txt");
42  G4String pType="custom";
43  G4String pSubType="";
44  // bool first = true;
45  int pdgCode;
46  double mass;
47  double elCharge;
48  double magCharge;
49  std::string name,line;
50  // This should be compatible IMO to SLHA
51  while(getline(configFile,line))
52  {
53  std::string::size_type beg_idx,end_idx;
54  bool isQball = false;
55  bool isFCP = false; // Wendy Taylor: fractionally charged particle
56 
57  beg_idx = line.find_first_not_of("\t #");
58  if(beg_idx > 0 && line[beg_idx-1] == '#') continue;
59  end_idx = line.find_first_of( "\t ", beg_idx);
60  if (end_idx == std::string::npos) continue;
61  char *endptr;
62  pdgCode = strtol(line.substr( beg_idx, end_idx - beg_idx ).c_str(), &endptr, 0);
63  if (endptr[0] != '\0') {
64  throw std::invalid_argument("CustomMonopoleFactory::loadCustomMonopoles: Could not convert string to int: " + line.substr( beg_idx, end_idx - beg_idx ));
65  }
66 
67  G4cout << "CustomMonopoleFactory: pdgCode = " << pdgCode << G4endl;
68 
69  beg_idx = line.find_first_not_of("\t ",end_idx);
70  end_idx = line.find_first_of( "\t #", beg_idx);
71  if (end_idx == std::string::npos) continue;
72 
73  mass = atof(line.substr( beg_idx, end_idx - beg_idx ).c_str());
74 
75  beg_idx = line.find_first_not_of("\t ",end_idx);
76  end_idx = line.find_first_of( "\t #", beg_idx);
77  if (end_idx == std::string::npos) continue;
78 
79  elCharge = atof(line.substr( beg_idx, end_idx - beg_idx ).c_str());
80 
81  beg_idx = line.find_first_not_of("\t ",end_idx);
82  end_idx = line.find_first_of( "\t #", beg_idx);
83 
84  if (end_idx == std::string::npos) continue;
85  magCharge = atof(line.substr( beg_idx, end_idx - beg_idx ).c_str());
86 
87  beg_idx = line.find_first_not_of("\t# ",end_idx);
88  end_idx = line.length();
89  name = line.substr( beg_idx, end_idx - beg_idx );
90  while(name.c_str()[0] == ' ') name.erase(0,1);
91  while(name[name.size()-1] == ' ') name.erase(name.size()-1,1);
92  std::string lowerCaseName(name);
93  for(unsigned int il=0; il < lowerCaseName.length(); ++il) lowerCaseName[il] = std::tolower(lowerCaseName[il]);
94  isQball = (lowerCaseName.find("qball") != std::string::npos) ? true : false;
95 
96  isFCP = (lowerCaseName.find("fcp") != std::string::npos) ? true : false;
97 
98  G4cout << "CustomMonopoleFactory: name = " << name << G4endl;
99 
100  if(abs(pdgCode) / 1000000 == 0)
101  {
102  G4cout << "CustomMonopoleFactory: pdgCode too low: " << pdgCode << " " << abs(pdgCode) / 1000000 << G4endl;
103  continue;
104  }
105  else
106  {
107 
108  double elChargeFromPDGcode = (isQball) ? (pdgCode/10)%10000/10. : (pdgCode/10)%1000/1. ;
109 
110  if (isFCP)
111  {
112  // pdgCode charge encoding scheme developed by quanyin.li@cern.ch
113  float XX, YY; // XX = numerator, YY = denominator
114  XX = (abs(pdgCode)/1000)%100;
115  YY = (abs(pdgCode)/10)%100;
116  G4cout << "CustomMonopoleFactory: XX = " << XX << ", YY = " << YY << G4endl;
117 
118  elChargeFromPDGcode = (pdgCode>0) ? round(100.*XX/YY)/100. : -round(100.*XX/YY)/100.;
119  G4cout << "CustomMonopoleFactory: elChargeFromPDGcode = " << elChargeFromPDGcode << G4endl;
120  }
121 
122  if (!isQball && !isFCP && abs((int)(pdgCode/10000)) == 412) elChargeFromPDGcode = -elChargeFromPDGcode;
123 
124 
125  if (elChargeFromPDGcode != elCharge) {
126  G4cout << "CustomMonopoleFactory: El. charges for "<< name <<" from PDGcode and 3d col. of particles.txt file do not agree: " << elChargeFromPDGcode << " / " << elCharge << G4endl;
127  G4Exception("CustomMonopoleFactory::loadCustomMonopoles","WrongElCharges",FatalException,"El charge from PDGcode and 3d col. of particles.txt file do not agree");
128  }
129  if (elCharge == 0.0 && magCharge == 0.0) {
130  G4cout << "CustomMonopoleFactory: Both electric and magnetic charges are ZEROs. Skip the particle. " << G4endl;
131  continue;
132  }
133 
134  }
135 
136  G4cout << "CustomMonopoleFactory: pType is " << pType << G4endl;
137  G4cout << "CustomMonopoleFactory: PDGcode of " << name << " is " << pdgCode << G4endl;
138  G4cout << "CustomMonopoleFactory: Mass of " << name << " is " << mass << G4endl;
139  G4cout << "CustomMonopoleFactory: Electrical Charge of " << name << " is "<< elCharge << G4endl;
140  G4cout << "CustomMonopoleFactory: Magnetic Charge of " << name << " is "<< magCharge << G4endl;
141 
142  // CustomMonopole *particle = CustomMonopole::MonopoleDefinition(
144  name, mass * CLHEP::GeV , 0.0*CLHEP::MeV, CLHEP::eplus*elCharge,
145  0, +1, 0,
146  0, 0, 0,
147  pType, 0, +1, pdgCode,
148  true, -1.0, NULL);
149  // magCharge);
150 
151  particle->SetMagneticCharge(magCharge);
152  particle->PrintMonopoleInfo();
153  m_particles.insert(particle);
154  }
155 
156  configFile.close();
157 
158  if (m_particles.empty()) {
159  G4cout << "CustomMonopoleFactory: No particles have been loaded." << G4endl;
160  G4Exception("CustomMonopoleFactory::loadCustomMonopoles","NoParticlesLoaded",FatalException,"No particles have been loaded");
161  }
162  return;
163 }
PlotCalibFromCool.il
il
Definition: PlotCalibFromCool.py:381
checkFileSG.line
line
Definition: checkFileSG.py:75
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
taskman.configFile
configFile
Definition: taskman.py:311
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
CustomMonopoleFactory::isCustomMonopole
bool isCustomMonopole(CustomMonopole *particle) const
Definition: CustomMonopoleFactory.cxx:28
CustomMonopoleFactory::m_particles
std::set< CustomMonopole * > m_particles
Definition: CustomMonopoleFactory.h:27
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
CustomMonopoleFactory::instance
static const CustomMonopoleFactory & instance()
Definition: CustomMonopoleFactory.cxx:22
CustomMonopoleFactory::CustomMonopoleFactory
CustomMonopoleFactory()
Definition: CustomMonopoleFactory.cxx:33
CustomMonopoleFactory
Definition: CustomMonopoleFactory.h:19
CustomMonopoleFactory::loadCustomMonopoles
void loadCustomMonopoles()
Definition: CustomMonopoleFactory.cxx:38
tolower
void tolower(std::string &s)
Definition: AthenaSummarySvc.cxx:113
CxxUtils::atof
double atof(std::string_view str)
Converts a string into a double / float.
Definition: Control/CxxUtils/Root/StringUtils.cxx:91
CustomMonopoleFactory.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CustomMonopole.h
python.SystemOfUnits.eplus
int eplus
Definition: SystemOfUnits.py:137
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
CustomMonopole
Definition: CustomMonopole.h:34