32void ClearBank(std::vector<Heed::gparticle*>& bank) {
34 std::vector<Heed::gparticle*>::iterator it;
35 std::vector<Heed::gparticle*>::const_iterator end = bank.end();
36 for (it = bank.begin(); it != end; ++it)
if (*it)
delete *it;
52 1000. * Heed::CLHEP::cm,
53 0.1 * Heed::CLHEP::rad,
54 0.2 * Heed::CLHEP::rad);
62 m_hasActiveTrack(false),
65 m_usePhotonReabsorption(true),
66 m_usePacsOutput(false),
67 m_doDeltaTransport(true),
75 m_nEnergyIntervals(200),
91 m_conductionElectrons.reserve(1000);
92 m_conductionIons.reserve(1000);
97 if (m_matter)
delete m_matter;
98 if (m_gas)
delete m_gas;
99 if (m_material)
delete m_material;
100 if (m_atPacs)
delete m_atPacs;
101 if (m_molPacs)
delete m_molPacs;
102 if (m_energyMesh)
delete m_energyMesh;
103 if (m_transferCs)
delete m_transferCs;
104 if (m_elScat)
delete m_elScat;
105 if (m_lowSigma)
delete m_lowSigma;
106 if (m_pairProd)
delete m_pairProd;
107 if (m_deltaCs)
delete m_deltaCs;
108 if (m_chamber)
delete m_chamber;
112 const double t0,
const double dx0,
const double dy0,
115 m_hasActiveTrack =
false;
121 <<
" Sensor is not defined.\n";
126 double xmin = 0., ymin = 0., zmin = 0.;
127 double xmax = 0., ymax = 0., zmax = 0.;
130 <<
" Drift area is not set.\n";
134 const double lx = fabs(xmax - xmin);
135 const double ly = fabs(ymax - ymin);
136 const double lz = fabs(zmax - zmin);
139 <<
" Bounding box dimensions:\n"
140 <<
" x: " << lx <<
" cm\n"
141 <<
" y: " << ly <<
" cm\n"
142 <<
" z: " << lz <<
" cm\n";
144 if (fabs(lx - m_lX) > Small || fabs(ly - m_lY) > Small || fabs(lz - m_lZ) > Small) {
151 if (std::isinf(xmin) || std::isinf(xmax)) {
154 m_cX = 0.5 * (xmin + xmax);
156 if (std::isinf(ymin) || std::isinf(ymax)) {
159 m_cY = 0.5 * (ymin + ymax);
161 if (std::isinf(zmin) || std::isinf(zmax)) {
164 m_cZ = 0.5 * (zmin + zmax);
168 <<
" Center of bounding box:\n"
169 <<
" x: " << m_cX <<
" cm\n"
170 <<
" y: " << m_cY <<
" cm\n"
171 <<
" z: " << m_cZ <<
" cm\n";
181 <<
" No medium at initial position.\n";
185 <<
" Medium at initial position is not ionisable.\n";
190 if (medium->
GetName() != m_mediumName ||
198 if (!Setup(medium))
return false;
200 m_mediumName = medium->
GetName();
206 m_deltaElectrons.clear();
207 m_conductionElectrons.clear();
208 m_conductionIons.clear();
211 double dx = dx0, dy = dy0, dz = dz0;
212 const double d = sqrt(dx * dx + dy * dy + dz * dz);
216 <<
" Direction vector has zero norm.\n"
217 <<
" Initial direction is randomized.\n";
228 velocity = velocity * Heed::CLHEP::c_light *
GetBeta();
231 std::cout <<
m_className <<
"::NewTrack:\n Track starts at ("
232 << x0 <<
", " << y0 <<
", " << z0 <<
") at time " << t0 <<
"\n"
233 <<
" Direction: (" << dx <<
", " << dy <<
", " << dz <<
")\n";
238 Heed::point p0((x0 - m_cX) * 10., (y0 - m_cY) * 10., (z0 - m_cZ) * 10.);
281 particleType, &m_fieldMap);
283 particle.
fly(m_particleBank);
284 m_bankIterator = m_particleBank.begin();
285 m_hasActiveTrack =
true;
296 std::cerr <<
m_className <<
"::GetClusterDensity:\n"
297 <<
" Track has not been initialized.\n";
302 std::cerr <<
m_className <<
"::GetClusterDensity:\n"
303 <<
" Ionisation cross-section is not available.\n";
307 return m_transferCs->
quanC;
313 std::cerr <<
m_className <<
"::GetStoppingPower:\n"
314 <<
" Track has not been initialized.\n";
319 std::cerr <<
m_className <<
"::GetStoppingPower:\n"
320 <<
" Ionisation cross-section is not available.\n";
324 return m_transferCs->
meanC1 * 1.e6;
328 double& tcls,
int& n,
double& e,
double& extra) {
331 return GetCluster(xcls, ycls, zcls, tcls, n, ni, e, extra);
335 double& tcls,
int& ne,
int& ni,
double& e,
339 xcls = ycls = zcls = tcls = 0.;
344 m_deltaElectrons.clear();
345 m_conductionElectrons.clear();
346 m_conductionIons.clear();
351 <<
" Track has not been initialized. Call NewTrack first.\n";
355 std::vector<Heed::gparticle*>::const_iterator end = m_particleBank.end();
356 if (m_bankIterator == end) {
358 <<
" There are no more clusters on this track.\n";
364 for (; m_bankIterator != end; ++m_bankIterator) {
367 if (!virtualPhoton) {
369 <<
" Particle is not a virtual photon. Program bug!\n";
381 if (!IsInside(xcls, ycls, zcls))
continue;
383 m_conductionIons.push_back(
390 if (m_bankIterator == end || !virtualPhoton)
return false;
394 std::vector<Heed::gparticle*> secondaries;
396 virtualPhoton->
fly(secondaries);
398 e = virtualPhoton->
energy * 1.e6;
400 while (!secondaries.empty()) {
401 std::vector<Heed::gparticle*> newSecondaries;
403 std::vector<Heed::gparticle*>::iterator it;
404 std::vector<Heed::gparticle*>::const_iterator send = secondaries.end();
405 for (it = secondaries.begin(); it != send; ++it) {
410 const double x = delta->
currpos.
pt.
v.
x * 0.1 + m_cX;
411 const double y = delta->
currpos.
pt.
v.
y * 0.1 + m_cY;
412 const double z = delta->
currpos.
pt.
v.
z * 0.1 + m_cZ;
413 if (!IsInside(x, y, z))
continue;
414 if (m_doDeltaTransport) {
416 delta->
fly(newSecondaries);
418 m_conductionElectrons.insert(m_conductionElectrons.end(),
421 m_conductionIons.insert(m_conductionIons.end(),
426 deltaElectron newDeltaElectron;
427 newDeltaElectron.x = delta->
currpos.
pt.
v.
x * 0.1 + m_cX;
428 newDeltaElectron.y = delta->
currpos.
pt.
v.
y * 0.1 + m_cY;
429 newDeltaElectron.z = delta->
currpos.
pt.
v.
z * 0.1 + m_cZ;
435 m_deltaElectrons.push_back(newDeltaElectron);
443 <<
" Particle is neither an electron nor a photon.\n";
445 extra += photon->
energy * 1.e6;
446 const double x = photon->
currpos.
pt.
v.
x * 0.1 + m_cX;
447 const double y = photon->
currpos.
pt.
v.
y * 0.1 + m_cY;
448 const double z = photon->
currpos.
pt.
v.
z * 0.1 + m_cZ;
449 if (!IsInside(x, y, z))
continue;
451 if (m_usePhotonReabsorption) photon->
fly(newSecondaries);
453 for (it = secondaries.begin(); it != secondaries.end(); ++it) {
457 secondaries.swap(newSecondaries);
460 ne = m_doDeltaTransport ? m_conductionElectrons.size() : m_deltaElectrons.size();
461 ni = m_conductionIons.size();
466 double& x,
double& y,
double& z,
double& t,
467 double& e,
double& dx,
double& dy,
double& dz) {
472 <<
" Track has not been initialized. Call NewTrack first.\n";
476 if (m_doDeltaTransport) {
478 if (i >= m_conductionElectrons.size()) {
479 std::cerr <<
m_className <<
"::GetElectron: Index out of range.\n";
483 x = m_conductionElectrons[i].ptloc.v.x * 0.1 + m_cX;
484 y = m_conductionElectrons[i].ptloc.v.y * 0.1 + m_cY;
485 z = m_conductionElectrons[i].ptloc.v.z * 0.1 + m_cZ;
486 t = m_conductionElectrons[i].time;
492 if (i >= m_deltaElectrons.size()) {
494 <<
" Delta electron number out of range.\n";
498 x = m_deltaElectrons[i].x;
499 y = m_deltaElectrons[i].y;
500 z = m_deltaElectrons[i].z;
501 t = m_deltaElectrons[i].t;
502 e = m_deltaElectrons[i].e;
503 dx = m_deltaElectrons[i].dx;
504 dy = m_deltaElectrons[i].dy;
505 dz = m_deltaElectrons[i].dz;
511 double& x,
double& y,
double& z,
double& t)
const {
514 if (i >= m_conductionIons.size()) {
515 std::cerr <<
m_className <<
"::GetIon: Index out of range.\n";
519 x = m_conductionIons[i].ptloc.v.x * 0.1 + m_cX;
520 y = m_conductionIons[i].ptloc.v.y * 0.1 + m_cY;
521 z = m_conductionIons[i].ptloc.v.z * 0.1 + m_cZ;
522 t = m_conductionIons[i].time;
527 const double z0,
const double t0,
528 const double e0,
const double dx0,
529 const double dy0,
const double dz0,
536 const double z0,
const double t0,
537 const double e0,
const double dx0,
538 const double dy0,
const double dz0,
545 if (!m_doDeltaTransport) {
546 std::cerr <<
m_className <<
"::TransportDeltaElectron:\n"
547 <<
" Delta electron transport has been switched off.\n";
554 std::cerr <<
m_className <<
"::TransportDeltaElectron:\n"
555 <<
" Sensor is not defined.\n";
561 double xmin, ymin, zmin;
562 double xmax, ymax, zmax;
564 std::cerr <<
m_className <<
"::TransportDeltaElectron:\n"
565 <<
" Drift area is not set.\n";
571 const double lx = fabs(xmax - xmin);
572 const double ly = fabs(ymax - ymin);
573 const double lz = fabs(zmax - zmin);
574 if (fabs(lx - m_lX) > Small || fabs(ly - m_lY) > Small || fabs(lz - m_lZ) > Small) {
580 m_hasActiveTrack =
false;
583 m_cX = 0.5 * (xmin + xmax);
584 m_cY = 0.5 * (ymin + ymax);
585 m_cZ = 0.5 * (zmin + zmax);
593 std::cerr <<
m_className <<
"::TransportDeltaElectron:\n"
594 <<
" No medium at initial position.\n";
597 std::cerr <<
"TrackHeed:TransportDeltaElectron:\n"
598 <<
" Medium at initial position is not ionisable.\n";
604 if (medium->
GetName() != m_mediumName ||
609 m_hasActiveTrack =
false;
614 if (!Setup(medium))
return;
616 m_mediumName = medium->
GetName();
620 m_deltaElectrons.clear();
621 m_conductionElectrons.clear();
622 m_conductionIons.clear();
626 Heed::point p0((x0 - m_cX) * 10., (y0 - m_cY) * 10., (z0 - m_cZ) * 10.);
637 double dx = dx0, dy = dy0, dz = dz0;
638 const double d = sqrt(dx * dx + dy * dy + dz * dz);
651 const double gamma = 1. + e0 / ElectronMass;
652 const double beta = sqrt(1. - 1. / (gamma * gamma));
653 double speed = Heed::CLHEP::c_light * beta;
654 velocity = velocity * speed;
657 std::vector<Heed::gparticle*> secondaries;
659 delta.
fly(secondaries);
660 ClearBank(secondaries);
664 nel = m_conductionElectrons.size();
665 ni = m_conductionIons.size();
669 const double z0,
const double t0,
670 const double e0,
const double dx0,
671 const double dy0,
const double dz0,
int& nel) {
677 const double z0,
const double t0,
678 const double e0,
const double dx0,
679 const double dy0,
const double dz0,
688 <<
" Photon energy must be positive.\n";
695 <<
" Sensor is not defined.\n";
701 double xmin, ymin, zmin;
702 double xmax, ymax, zmax;
705 <<
" Drift area is not set.\n";
711 const double lx = fabs(xmax - xmin);
712 const double ly = fabs(ymax - ymin);
713 const double lz = fabs(zmax - zmin);
714 if (fabs(lx - m_lX) > Small || fabs(ly - m_lY) > Small || fabs(lz - m_lZ) > Small) {
720 m_hasActiveTrack =
false;
723 m_cX = 0.5 * (xmin + xmax);
724 m_cY = 0.5 * (ymin + ymax);
725 m_cZ = 0.5 * (zmin + zmax);
734 <<
" No medium at initial position.\n";
737 std::cerr <<
"TrackHeed:TransportPhoton:\n"
738 <<
" Medium at initial position is not ionisable.\n";
744 if (medium->
GetName() != m_mediumName ||
753 if (!Setup(medium))
return;
755 m_mediumName = medium->
GetName();
761 m_hasActiveTrack =
false;
763 m_deltaElectrons.clear();
764 m_conductionElectrons.clear();
765 m_conductionIons.clear();
768 double dx = dx0, dy = dy0, dz = dz0;
769 const double d = sqrt(dx * dx + dy * dy + dz * dz);
780 velocity = velocity * Heed::CLHEP::c_light;
784 Heed::point p0((x0 - m_cX) * 10., (y0 - m_cY) * 10., (z0 - m_cZ) * 10.);
790 std::vector<Heed::gparticle*> secondaries;
791 photon.
fly(secondaries);
793 while (!secondaries.empty()) {
794 std::vector<Heed::gparticle*> newSecondaries;
796 std::vector<Heed::gparticle*>::iterator it;
797 for (it = secondaries.begin(); it != secondaries.end(); ++it) {
801 if (m_doDeltaTransport) {
803 delta->
fly(newSecondaries);
805 m_conductionElectrons.insert(m_conductionElectrons.end(),
808 m_conductionIons.insert(m_conductionIons.end(),
813 deltaElectron newDeltaElectron;
814 newDeltaElectron.x = delta->
currpos.
pt.
v.
x * 0.1 + m_cX;
815 newDeltaElectron.y = delta->
currpos.
pt.
v.
y * 0.1 + m_cY;
816 newDeltaElectron.z = delta->
currpos.
pt.
v.
z * 0.1 + m_cZ;
822 m_deltaElectrons.push_back(newDeltaElectron);
828 if (!fluorescencePhoton) {
830 <<
" Unknown secondary particle.\n";
831 ClearBank(secondaries);
832 ClearBank(newSecondaries);
835 fluorescencePhoton->
fly(newSecondaries);
837 secondaries.swap(newSecondaries);
838 ClearBank(newSecondaries);
842 nel = m_doDeltaTransport ? m_conductionElectrons.size() :
843 m_deltaElectrons.size();
844 ni = m_conductionIons.size();
855 if (fabs(e1 - e0) < Small) {
857 std::cerr <<
" Invalid energy range:\n";
858 std::cerr <<
" " << e0 <<
" < E [eV] < " << e1 <<
"\n";
864 std::cerr <<
" Number of intervals must be > 0.\n";
868 m_emin = std::min(e0, e1);
869 m_emax = std::max(e0, e1);
872 m_nEnergyIntervals = nsteps;
877 if (fabs(z) < Small) {
879 <<
" Particle cannot have zero charge.\n";
884 <<
" Particle mass must be greater than zero.\n";
893bool TrackHeed::Setup(
Medium* medium) {
896 std::string databasePath;
897 char* dbPath = std::getenv(
"HEED_DATABASE");
898 if (dbPath == NULL) {
900 dbPath = std::getenv(
"GARFIELD_HOME");
901 if (dbPath == NULL) {
902 std::cerr <<
m_className <<
"::Setup:\n Cannot retrieve database path "
903 <<
"(environment variables HEED_DATABASE and GARFIELD_HOME "
904 <<
"are not defined).\n Cannot proceed.\n";
907 databasePath = std::string(dbPath) +
"/Heed/heed++/database";
909 databasePath = dbPath;
911 if (databasePath[databasePath.size() - 1] !=
'/') {
912 databasePath.append(
"/");
917 std::cerr <<
m_className <<
"::Setup: Null pointer.\n";
928 if (medium->
IsGas()) {
929 if (!SetupGas(medium))
return false;
931 if (!SetupMaterial(medium))
return false;
946 if (!SetupDelta(databasePath))
return false;
949 const double nc = m_transferCs->
quanC;
950 const double dedx = m_transferCs->
meanC * 1.e3;
951 const double dedx1 = m_transferCs->
meanC1 * 1.e3;
952 const double w = m_matter->
W * 1.e6;
953 const double f = m_matter->
F;
956 std::cout <<
" Cluster density: " << nc <<
" cm-1\n";
957 std::cout <<
" Stopping power (restricted): " << dedx <<
" keV/cm\n";
958 std::cout <<
" Stopping power (incl. tail): " << dedx1 <<
" keV/cm\n";
959 std::cout <<
" W value: " << w <<
" eV\n";
960 std::cout <<
" Fano factor: " << f <<
"\n";
961 std::cout <<
" Min. ionization potential: " << minI <<
" eV\n";
970 m_chamber =
new HeedChamber(primSys, m_lX, m_lY, m_lZ,
971 *m_transferCs, *m_deltaCs);
976bool TrackHeed::SetupGas(Medium* medium) {
979 double pressure = medium->GetPressure();
980 pressure = (pressure / AtmosphericPressure) * Heed::CLHEP::atmosphere;
981 double temperature = medium->GetTemperature();
983 const int nComponents = medium->GetNumberOfComponents();
984 if (nComponents < 1) {
986 std::cerr <<
" Gas " << medium->GetName() <<
" has zero constituents.\n";
995 std::vector<std::string> notations;
996 std::vector<double> fractions;
998 for (
int i = 0; i < nComponents; ++i) {
1001 medium->GetComponent(i, gasname, frac);
1003 if (gasname ==
"He-3") gasname =
"He";
1004 if (gasname ==
"CD4") gasname =
"CH4";
1005 if (gasname ==
"iC4H10" || gasname ==
"nC4H10") gasname =
"C4H10";
1006 if (gasname ==
"neoC5H12" || gasname ==
"nC5H12") gasname =
"C5H12";
1007 if (gasname ==
"H2O") gasname =
"Water";
1008 if (gasname ==
"D2") gasname =
"H2";
1009 if (gasname ==
"cC3H6") gasname =
"C3H6";
1011 if (gasname ==
"CF4")
1013 else if (gasname ==
"Ar")
1015 else if (gasname ==
"He")
1017 else if (gasname ==
"Ne")
1019 else if (gasname ==
"Kr")
1021 else if (gasname ==
"Xe")
1023 else if (gasname ==
"CH4")
1025 else if (gasname ==
"C2H6")
1027 else if (gasname ==
"C3H8")
1029 else if (gasname ==
"C4H10")
1031 else if (gasname ==
"CO2")
1033 else if (gasname ==
"C5H12")
1035 else if (gasname ==
"Water")
1037 else if (gasname ==
"O2")
1039 else if (gasname ==
"N2" || gasname ==
"N2 (Phelps)")
1041 else if (gasname ==
"NO")
1043 else if (gasname ==
"N2O")
1045 else if (gasname ==
"C2H4")
1047 else if (gasname ==
"C2H2")
1049 else if (gasname ==
"H2")
1051 else if (gasname ==
"CO")
1053 else if (gasname ==
"Methylal")
1055 else if (gasname ==
"DME")
1057 else if (gasname ==
"C2F6")
1059 else if (gasname ==
"SF6")
1061 else if (gasname ==
"NH3")
1063 else if (gasname ==
"C3H6")
1065 else if (gasname ==
"CH3OH")
1067 else if (gasname ==
"C2H5OH")
1069 else if (gasname ==
"C3H7OH")
1071 else if (gasname ==
"Cs")
1073 else if (gasname ==
"F2")
1075 else if (gasname ==
"CS2")
1077 else if (gasname ==
"COS")
1079 else if (gasname ==
"CD4")
1081 else if (gasname ==
"BF3")
1083 else if (gasname ==
"C2HF5")
1085 else if (gasname ==
"C2H2F4")
1087 else if (gasname ==
"CHF3")
1089 else if (gasname ==
"CF3Br")
1091 else if (gasname ==
"C3F8")
1093 else if (gasname ==
"O3")
1095 else if (gasname ==
"Hg")
1097 else if (gasname ==
"H2S")
1099 else if (gasname ==
"GeH4")
1101 else if (gasname ==
"SiH4")
1104 std::cerr <<
m_className <<
"::SetupGas:\n Photoabsorption "
1105 <<
"cross-section for " << gasname <<
" not available.\n";
1108 notations.push_back(gasname);
1109 fractions.push_back(frac);
1111 if (m_usePacsOutput) {
1112 std::ofstream pacsfile;
1113 pacsfile.open(
"heed_pacs.txt", std::ios::out);
1114 const int nValues = m_energyMesh->
get_q();
1116 for (
int i = 0; i < nValues; ++i) {
1117 double e = m_energyMesh->
get_e(i);
1118 pacsfile << 1.e6 * e <<
" ";
1119 for (
int j = 0; j < nComponents; ++j) {
1120 pacsfile << m_molPacs[j]->
get_ACS(e) <<
" "
1121 << m_molPacs[j]->
get_ICS(e) <<
" ";
1129 const std::string gasname = FindUnusedMaterialName(medium->GetName());
1135 m_gas =
new Heed::GasDef(gasname, gasname, nComponents, notations, fractions,
1136 pressure, temperature, -1.);
1138 const double w = std::max(medium->GetW() * 1.e-6, 0.);
1139 double f = medium->GetFanoFactor();
1151bool TrackHeed::SetupMaterial(Medium* medium) {
1154 double temperature = medium->GetTemperature();
1155 const double density = medium->GetMassDensity() * Heed::CLHEP::gram /
1158 const int nComponents = medium->GetNumberOfComponents();
1165 std::vector<std::string> notations;
1166 std::vector<double> fractions;
1167 for (
int i = 0; i < nComponents; ++i) {
1168 std::string materialName;
1170 medium->GetComponent(i, materialName, frac);
1171 if (materialName ==
"C")
1173 else if (materialName ==
"Si")
1176 else if (materialName ==
"Ga")
1178 else if (materialName ==
"Ge")
1180 else if (materialName ==
"As")
1182 else if (materialName ==
"Cd")
1184 else if (materialName ==
"Te")
1188 std::cerr <<
" Photoabsorption cross-section data for " << materialName
1189 <<
" are not implemented.\n";
1192 notations.push_back(materialName);
1193 fractions.push_back(frac);
1195 if (m_usePacsOutput) {
1196 std::ofstream pacsfile;
1197 pacsfile.open(
"heed_pacs.txt", std::ios::out);
1198 const int nValues = m_energyMesh->
get_q();
1200 for (
int i = 0; i < nValues; ++i) {
1201 double e = m_energyMesh->
get_e(i);
1202 pacsfile << 1.e6 * e <<
" ";
1203 for (
int j = 0; j < nComponents; ++j) {
1204 pacsfile << m_atPacs[j]->
get_ACS(e) <<
" " << m_atPacs[j]->
get_ICS(e)
1216 const std::string materialName = FindUnusedMaterialName(medium->GetName());
1217 m_material =
new Heed::MatterDef(materialName, materialName, nComponents,
1218 notations, fractions, density, temperature);
1220 double w = medium->GetW() * 1.e-6;
1222 double f = medium->GetFanoFactor();
1234bool TrackHeed::SetupDelta(
const std::string& databasePath) {
1237 std::string filename = databasePath +
"cbdel.dat";
1244 filename = databasePath +
"elastic_disp.dat";
1253 const double w = m_matter->
W * 1.e6;
1254 const double f = m_matter->
F;
1255 filename = databasePath +
"delta_path.dat";
1273std::string TrackHeed::FindUnusedMaterialName(
const std::string& namein) {
1275 std::string nameout = namein;
1276 unsigned int counter = 0;
1278 std::stringstream ss;
1279 ss << namein <<
"_" << counter;
1287void TrackHeed::ClearParticleBank() {
1290 ClearBank(m_particleBank);
1291 m_bankIterator = m_particleBank.end();
1294bool TrackHeed::IsInside(
const double x,
const double y,
const double z) {
1299 Medium* medium = NULL;
1302 if (medium->GetName() != m_mediumName ||
1303 fabs(medium->GetMassDensity() - m_mediumDensity) > 1.e-9 ||
1304 !medium->IsIonisable()) {
Abstract base class for media.
virtual double GetMassDensity() const
const std::string & GetName() const
virtual bool IsGas() const
bool IsInArea(const double x, const double y, const double z)
Check if a point is inside the user area.
bool GetMedium(const double x, const double y, const double z, Medium *&medium)
Get the medium at (x, y, z).
bool GetArea(double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Return the current user area.
void EnableMagneticField()
void SetEnergyMesh(const double e0, const double e1, const int nsteps)
virtual bool GetCluster(double &xcls, double &ycls, double &zcls, double &tcls, int &n, double &e, double &extra)
void EnableElectricField()
void DisableMagneticField()
void TransportPhoton(const double x0, const double y0, const double z0, const double t0, const double e0, const double dx0, const double dy0, const double dz0, int &nel, int &ni)
double GetFanoFactor() const
void TransportDeltaElectron(const double x0, const double y0, const double z0, const double t0, const double e0, const double dx0, const double dy0, const double dz0, int &nel, int &ni)
virtual double GetClusterDensity()
bool GetElectron(const unsigned int i, double &x, double &y, double &z, double &t, double &e, double &dx, double &dy, double &dz)
bool GetIon(const unsigned int i, double &x, double &y, double &z, double &t) const
virtual ~TrackHeed()
Destructor.
virtual bool NewTrack(const double x0, const double y0, const double z0, const double t0, const double dx0, const double dy0, const double dz0)
void SetParticleUser(const double m, const double z)
void DisableElectricField()
virtual double GetStoppingPower()
Get the stopping power (mean energy loss [eV] per cm).
std::string m_particleName
void PlotCluster(const double x0, const double y0, const double z0)
void PlotNewTrack(const double x0, const double y0, const double z0)
Atomic photoabsorption cross-section abstract base class.
virtual double get_ACS(double energy) const =0
virtual double get_ICS(double energy) const =0
double quanC
Integrated (ionization) cross-section.
long get_q() const
Return number of bins.
double get_e(long n) const
Return left side of a given bin.
std::vector< HeedCondElectron > conduction_electrons
std::vector< HeedCondElectron > conduction_ions
void SetSensor(Garfield::Sensor *sensor)
void SetCentre(const double x, const double y, const double z)
void UseEfield(const bool flag)
void UseBfield(const bool flag)
double W
Mean work per pair production, MeV.
double energy
Photon energy [MeV].
static MatterDef * get_MatterDef(const std::string &fnotation)
virtual double get_ACS(double energy) const
Photo-absorption cross-section [Mbarn] at a given energy [MeV].
virtual double get_ICS(double energy) const
Photo-ionization cross-section [Mbarn] at a given energy [MeV].
virtual void fly(std::vector< gparticle * > &secondaries)
Transport the particle.
void set_mass(const double m)
void set_charge(const double z)
vec dir
Unit vector, in the first system in the tree.
point pt
Coordinates in the first system in the tree.
void RndmDirection(double &dx, double &dy, double &dz, const double length=1.)
Draw a random (isotropic) direction vector.
MolecPhotoAbsCS Cs_MPACS(Caesium_PACS, 1)
particle_def pi_minus_meson_def("pi_minus_meson", "pi-", 139.56755 *MeV/c_squared, -eplus, 0, 0, 0.0, spin_def(1.0, -1.0))
particle_def pi_plus_meson_def("pi_plus_meson", "pi+", 139.56755 *MeV/c_squared, eplus, 0, 0, 0.0, spin_def(1.0, 1.0))
ExAtomPhotoAbsCS Tellurium_PACS(49, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"Te.dat")
MolecPhotoAbsCS CF3Br_MPACS(Carbon_for_CF4_PACS, 1, Fluorine_PACS, 3, Bromine_PACS, 1)
MolecPhotoAbsCS N2_MPACS(Nitrogen_PACS, 2, 34.8e-6)
ExAtomPhotoAbsCS Silicon_crystal_PACS(14, shelllist_dir_name+"shelllist_solid.dat", pacs_table_dir_name+"Si.dat", "Si_crystal")
particle_def muon_minus_def("muon_minus", "mu-", 105.658367 *MeV/c_squared, electron_charge, 1, 0, 0.5, spin_def(0.0, 0.0))
MolecPhotoAbsCS Ne_MPACS(Neon_PACS, 1, 35.4e-6)
MolecPhotoAbsCS C5H12_MPACS(Carbon_for_C4H10_PACS, 5, Hydrogen_for_H2_PACS, 12, 23.2e-6)
MolecPhotoAbsCS CO_MPACS(Carbon_for_CO2_PACS, 1, Oxygen_PACS, 1)
long last_particle_number
particle_def alpha_particle_def("alpha_particle", "alpha", 3727.417 *MeV/c_squared, 2 *eplus, 0, 4, 0.0, spin_def(0.0, 0.0))
particle_def anti_proton_def("", "p-", proton_def)
MolecPhotoAbsCS Hg_MPACS(Mercury_PACS, 1)
MolecPhotoAbsCS SiH4_MPACS(Silicon_PACS, 1, Hydrogen_for_H2_PACS, 4)
MolecPhotoAbsCS CS2_MPACS(Carbon_for_CO2_PACS, 1, Sulfur_PACS, 2)
MolecPhotoAbsCS COS_MPACS(Carbon_for_CO2_PACS, 1, Oxygen_PACS, 1, Sulfur_PACS, 1)
particle_def deuteron_def("deuteron", "dtr", 1875.613 *MeV/c_squared, eplus, 0, 2, 0.0, spin_def(0.0, 0.0))
MolecPhotoAbsCS DME_MPACS(Carbon_for_Methylal_PACS, 2, Hydrogen_for_H2_PACS, 6, Oxygen_PACS, 1)
MolecPhotoAbsCS Xe_MPACS(Xenon_PACS, 1, 22.1e-6)
particle_def proton_def("proton", "p+", proton_mass_c2/c_squared, eplus, 0, 1, 0.5, spin_def(0.5, 0.5))
MolecPhotoAbsCS H2S_MPACS(Hydrogen_for_H2_PACS, 2, Sulfur_PACS, 1)
ExAtomPhotoAbsCS Cadmium_PACS(48, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"Cd.dat")
MolecPhotoAbsCS F2_MPACS(Fluorine_PACS, 2)
MolecPhotoAbsCS C3H8_MPACS(Carbon_for_CH4_PACS, 3, Hydrogen_for_H2_PACS, 8, 24.0e-6)
ExAtomPhotoAbsCS Arsenic_PACS(33, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"As.dat")
particle_def K_minus_meson_def("K_minus_meson_def", "K-", K_plus_meson_def)
const double standard_factor_Fano
MolecPhotoAbsCS C2H5OH_MPACS(Carbon_for_C2H6_PACS, 2, Hydrogen_for_H2_PACS, 6, Oxygen_PACS, 1, 24.8e-6)
MolecPhotoAbsCS O2_MPACS(Oxygen_PACS, 2, 30.8e-6)
MolecPhotoAbsCS C2H2_MPACS(Carbon_for_CH4_PACS, 2, Hydrogen_for_H2_PACS, 2, 25.8e-6)
MolecPhotoAbsCS C2H4_MPACS(Carbon_for_C2H4_PACS, 2, Hydrogen_for_H2_PACS, 4, 25.8e-6)
particle_def K_plus_meson_def("K_plus_meson_def", "K+", 493.677 *MeV/c_squared, 1, 0, 0, 0.0, spin_def(0.5, -0.5))
MolecPhotoAbsCS Ar_MPACS(Argon_PACS, 1, 26.4e-6)
MolecPhotoAbsCS CHF3_MPACS(Carbon_for_CF4_PACS, 1, Hydrogen_for_H2_PACS, 1, Fluorine_PACS, 3)
MolecPhotoAbsCS NH3_MPACS(Nitrogen_PACS, 1, Hydrogen_for_NH4_PACS, 3, 26.6e-6)
MolecPhotoAbsCS CH3OH_MPACS(Carbon_for_C2H6_PACS, 1, Hydrogen_for_H2_PACS, 4, Oxygen_PACS, 1, 24.7e-6)
MolecPhotoAbsCS C2HF5_MPACS(Carbon_for_C2H6_PACS, 2, Hydrogen_for_H2_PACS, 1, Fluorine_PACS, 5)
MolecPhotoAbsCS C4H10_MPACS(Carbon_for_C4H10_PACS, 4, Hydrogen_for_H2_PACS, 10, 23.4e-6)
MolecPhotoAbsCS CH4_MPACS(Carbon_for_CH4_PACS, 1, Hydrogen_for_CH4_PACS, 4, 27.3e-6)
MolecPhotoAbsCS SF6_MPACS(Sulfur_PACS, 1, Fluorine_PACS, 6)
particle_def user_particle_def("user_particle", "X", 139.56755 *MeV/c_squared, eplus, 0, 0, 0.0, spin_def(0.0, 0.0))
MolecPhotoAbsCS C2H2F4_MPACS(Carbon_for_C2H6_PACS, 2, Fluorine_PACS, 4, Hydrogen_for_H2_PACS, 2)
MolecPhotoAbsCS BF3_MPACS(Boron_PACS, 1, Fluorine_PACS, 3)
ExAtomPhotoAbsCS Germanium_PACS(32, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"Ge.dat")
MolecPhotoAbsCS Kr_MPACS(Krypton_PACS, 1, 24.4e-6)
DoubleAc fabs(const DoubleAc &f)
MolecPhotoAbsCS C2F6_MPACS(Carbon_for_C2H6_PACS, 2, Fluorine_PACS, 6)
MolecPhotoAbsCS C3H7OH_MPACS(Carbon_for_C2H6_PACS, 3, Hydrogen_for_H2_PACS, 8, Oxygen_PACS, 1)
MolecPhotoAbsCS CO2_MPACS(Carbon_for_CO2_PACS, 1, Oxygen_for_CO2_PACS, 2, 33.0e-6)
MolecPhotoAbsCS C2H6_MPACS(Carbon_for_C2H6_PACS, 2, Hydrogen_for_H2_PACS, 6, 25.0e-6)
MolecPhotoAbsCS He_MPACS(Helium_PACS, 1, 41.3e-6)
particle_def muon_plus_def("muon_plus", "mu+", muon_minus_def)
particle_def positron_def("positron", "e+", electron_def)
particle_def electron_def("electron", "e-", electron_mass_c2/c_squared, electron_charge, 1, 0, 0.5, spin_def(0.0, 0.0))
MolecPhotoAbsCS H2_MPACS(Hydrogen_for_H2_PACS, 2)
ExAtomPhotoAbsCS Gallium_PACS(31, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"Ga.dat")
ExAtomPhotoAbsCS Carbon_PACS(6, shelllist_dir_name+"shelllist.dat", pacs_table_dir_name+"C.dat")
MolecPhotoAbsCS NO_MPACS(Nitrogen_PACS, 1, Oxygen_PACS, 1)
MolecPhotoAbsCS O3_MPACS(Oxygen_PACS, 3)
MolecPhotoAbsCS GeH4_MPACS(Germanium_PACS, 1, Hydrogen_for_H2_PACS, 4)
MolecPhotoAbsCS C3F8_MPACS(Carbon_for_CF4_PACS, 3, Fluorine_PACS, 8)
MolecPhotoAbsCS Methylal_MPACS(Oxygen_PACS, 2, Carbon_for_Methylal_PACS, 3, Hydrogen_for_H2_PACS, 8, 10.0e-6 *23.4/10.55)
MolecPhotoAbsCS H2O_MPACS(Hydrogen_for_H2_PACS, 2, Oxygen_PACS, 1, 29.6e-6)
MolecPhotoAbsCS CF4_MPACS(Carbon_for_CF4_PACS, 1, Fluorine_PACS, 4)
MolecPhotoAbsCS N2O_MPACS(Nitrogen_PACS, 2, Oxygen_PACS, 1, 34.8e-6)
MolecPhotoAbsCS C3H6_MPACS(Carbon_for_C2H6_PACS, 3, Hydrogen_for_H2_PACS, 6)