Skip to content

Commit f8a04a6

Browse files
committed
Handle energy spread units in source generation
1 parent 47a8a19 commit f8a04a6

9 files changed

Lines changed: 157 additions & 7 deletions

File tree

Intern/rayx-core/src/Beamline/StringConversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ const std::map<std::string, ElectronEnergyOrientation> StringToElectronEnergyOri
3939
{"Clockwise", ElectronEnergyOrientation::Clockwise}, {"Counterclockwise", ElectronEnergyOrientation::Counterclockwise}};
4040

4141
// EnergySpreadUnit conversion
42-
const std::map<EnergySpreadUnit, std::string> EnergySpreadUnitToString = {{EnergySpreadUnit::EU_PERCENT, "Percent"}, {EnergySpreadUnit::EU_eV, "eV"}};
43-
const std::map<std::string, EnergySpreadUnit> StringToEnergySpreadUnit = {{"Percent", EnergySpreadUnit::EU_PERCENT}, {"eV", EnergySpreadUnit::EU_eV}};
42+
const std::map<EnergySpreadUnit, std::string> EnergySpreadUnitToString = {{EnergySpreadUnit::EU_eV, "eV"}, {EnergySpreadUnit::EU_PERCENT, "Percent"}};
43+
const std::map<std::string, EnergySpreadUnit> StringToEnergySpreadUnit = {{"eV", EnergySpreadUnit::EU_eV}, {"Percent", EnergySpreadUnit::EU_PERCENT}};
4444

4545
// RZPType conversion
4646
const std::map<RZPType, std::string> RZPTypeToString = {{RZPType::Elliptical, "Elliptical"}, {RZPType::Meriodional, "Meriodional"}};

Intern/rayx-core/src/Design/DesignSource.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,22 @@ void DesignSource::setEnergySpread(double value) { m_elementParameters["energySp
184184
double DesignSource::getEnergySpread() const { return m_elementParameters["energySpread"].as_double(); }
185185

186186
void DesignSource::setEnergySpreadUnit(EnergySpreadUnit value) { m_elementParameters["energySpreadUnit"] = value; }
187-
EnergySpreadUnit DesignSource::getEnergySpreadUnit() const { return m_elementParameters["energySpreadUnit"].as_energySpreadUnit(); }
187+
EnergySpreadUnit DesignSource::getEnergySpreadUnit() const {
188+
if (!m_elementParameters.hasKey("energySpreadUnit")) {
189+
return EnergySpreadUnit::EU_eV;
190+
}
191+
192+
return m_elementParameters["energySpreadUnit"].as_energySpreadUnit();
193+
}
194+
195+
double DesignSource::getEnergySpreadInEv() const {
196+
const double energySpread = getEnergySpread();
197+
if (getEnergySpreadUnit() == EnergySpreadUnit::EU_PERCENT) {
198+
return getEnergy() * energySpread / 100.0;
199+
}
200+
201+
return energySpread;
202+
}
188203

189204
void DesignSource::setEnergyDistributionType(EnergyDistributionType value) { m_elementParameters["energyDistributionType"] = value; }
190205
EnergyDistributionType DesignSource::getEnergyDistributionType() const {
@@ -217,7 +232,7 @@ EnergyDistributionVariant DesignSource::getEnergyDistribution() const {
217232
en = EnergyDistributionVariant(df);
218233
} else if (energyDistributionType == EnergyDistributionType::Values) {
219234
double photonEnergy = m_elementParameters["energy"].as_double();
220-
double energySpread = m_elementParameters["energySpread"].as_double();
235+
double energySpread = getEnergySpreadInEv();
221236

222237
if (spreadType == SpreadType::SoftEdge) {
223238
if (energySpread == 0) { energySpread = 1; }

Intern/rayx-core/src/Design/DesignSource.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class RAYX_API DesignSource : public BeamlineNode {
8383

8484
void setEnergySpreadUnit(EnergySpreadUnit value);
8585
EnergySpreadUnit getEnergySpreadUnit() const;
86+
double getEnergySpreadInEv() const;
8687

8788
void setElectronEnergy(double value);
8889
double getElectronEnergy() const;

Intern/rayx-core/src/Rml/DesignSourceWriter.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111

1212
namespace rayx {
1313

14+
namespace {
15+
EnergySpreadUnit parseEnergySpreadUnitOrDefault(xml::Parser parser) {
16+
int energySpreadUnit = 0;
17+
if (!xml::paramInt(parser.node, "energySpreadUnit", &energySpreadUnit)) {
18+
return EnergySpreadUnit::EU_eV;
19+
}
20+
21+
return static_cast<EnergySpreadUnit>(energySpreadUnit);
22+
}
23+
} // unnamed namespace
24+
1425
void setAllMandatory(xml::Parser parser, DesignSource* ds) {
1526
ds->setName(parser.name());
1627
ds->setType(parser.type());
@@ -28,6 +39,7 @@ void setDefaultEnergy(xml::Parser parser, DesignSource* ds) {
2839
} else {
2940
ds->setEnergy(parser.parsePhotonEnergy());
3041
ds->setEnergySpread(parser.parseEnergySpread());
42+
ds->setEnergySpreadUnit(parseEnergySpreadUnitOrDefault(parser));
3143
if (ds->getEnergySpreadType() == SpreadType::SeparateEnergies) ds->setNumberOfSeparateEnergies(parser.parseNumberOfSeparateEnergies());
3244
}
3345
}
@@ -84,7 +96,7 @@ void setDipoleSource(xml::Parser parser, DesignSource* ds) {
8496
ds->setSourceWidth(parser.parseSourceWidth());
8597
ds->setVerEBeamDivergence(parser.parseVerEbeamDivergence());
8698
ds->setEnergy(parser.parsePhotonEnergy());
87-
ds->setEnergySpreadUnit(parser.parseEnergySpreadUnit());
99+
ds->setEnergySpreadUnit(parseEnergySpreadUnitOrDefault(parser));
88100
ds->setEnergyDistributionType(parser.parseEnergyDistributionType());
89101
ds->setHorDivergence(parser.parseHorDiv());
90102
}

Intern/rayx-core/src/Shader/LightSources/DipoleSource.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ DipoleSource::DipoleSource(const DesignSource& dSource)
374374
m_verEbeamDivergence(dSource.getVerEBeamDivergence()),
375375
// m_bandwidth(1.0e-3),
376376
// m_photonWaveLength(hvlam(m_photonEnergy)),
377-
m_energySpread(dSource.getEnergySpread()),
377+
m_energySpread(dSource.getEnergySpreadInEv()),
378378
m_horDivergence(dSource.getHorDivergence()) {
379379
auto rand = Rand(randomUint());
380380
m_gamma = calcGamma(m_electronEnergy);

Intern/rayx-core/src/Shader/LightSources/LightSource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace rayx {
1515

1616
enum class SourceDist { Uniform, Gaussian, Thirds, Circle }; // SourceDist::Thirds represents PixelSource Footprint
1717
enum class ElectronEnergyOrientation { Clockwise, Counterclockwise };
18-
enum class EnergySpreadUnit { EU_PERCENT, EU_eV };
18+
enum class EnergySpreadUnit { EU_eV, EU_PERCENT };
1919
enum class SigmaType { ST_STANDARD, ST_ACCURATE };
2020
enum class SourcePulseType { None };
2121

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<lab>
3+
<version>1.12</version>
4+
<beamline>
5+
6+
<object name="Point Source" type="Point Source">
7+
<param id="numberRays" enabled="T">200</param>
8+
<param id="sourceWidthDistribution" comment="hard edge" enabled="T">0</param>
9+
<param id="sourceWidth" enabled="T">0.065</param>
10+
<param id="sourceHeightDistribution" comment="gaussian (sigma)" enabled="T">1</param>
11+
<param id="sourceHeight" enabled="T">0.04</param>
12+
<param id="sourceDepth" enabled="T">1</param>
13+
<param id="horDivDistribution" comment="gaussian (sigma)" enabled="T">1</param>
14+
<param id="horDiv" enabled="T">1</param>
15+
<param id="verDivDistribution" comment="gaussian (sigma)" enabled="T">1</param>
16+
<param id="verDiv" enabled="T">1</param>
17+
<param id="alignmentError" comment="No" enabled="T">1</param>
18+
<param id="translationXerror" enabled="F">0</param>
19+
<param id="translationYerror" enabled="F">0</param>
20+
<param id="rotationXerror" enabled="F">0</param>
21+
<param id="rotationYerror" enabled="F">0</param>
22+
<param id="energyDistributionType" comment="Values" enabled="T">1</param>
23+
<param id="photonEnergyDistributionFile" absolute="" enabled="F"></param>
24+
<param id="photonEnergy" enabled="T">100</param>
25+
<param id="energySpreadType" comment="white band" enabled="T">0</param>
26+
<param id="energySpreadUnit" comment="%" enabled="T">1</param>
27+
<param id="energySpread" enabled="T">10</param>
28+
<param id="linearPol_0" enabled="T">1</param>
29+
<param id="linearPol_45" enabled="T">0</param>
30+
<param id="circularPol" enabled="T">0</param>
31+
<param id="sourcePulseType" comment="all rays start simultaneously" enabled="T">0</param>
32+
<param id="sourcePulseLength" enabled="F">0</param>
33+
<param id="worldPosition" enabled="F">
34+
<x>0</x>
35+
<y>0</y>
36+
<z>0</z>
37+
</param>
38+
<param id="worldXdirection" enabled="F">
39+
<x>1</x>
40+
<y>0</y>
41+
<z>0</z>
42+
</param>
43+
<param id="worldYdirection" enabled="F">
44+
<x>0</x>
45+
<y>1</y>
46+
<z>0</z>
47+
</param>
48+
<param id="worldZdirection" enabled="F">
49+
<x>0</x>
50+
<y>0</y>
51+
<z>1</z>
52+
</param>
53+
</object>
54+
55+
</beamline>
56+
57+
<ExtraData>
58+
</ExtraData>
59+
</lab>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<lab>
3+
<version>1.13</version>
4+
<beamline>
5+
<object name="Dipole Source" type="Dipole Source">
6+
<param id="numberRays" enabled="T">200</param>
7+
<param id="sourceWidth" enabled="T">0.065</param>
8+
<param id="sourceHeight" enabled="T">0.04</param>
9+
<param id="verEbeamDiv" enabled="T">1</param>
10+
<param id="horDiv" enabled="T">100</param>
11+
<param id="electronEnergy" enabled="T">1.7</param>
12+
<param id="electronEnergyOrientation" comment="clockwise" enabled="T">0</param>
13+
<param id="bendingRadius" enabled="T">4.35</param>
14+
<param id="alignmentError" comment="No" enabled="T">1</param>
15+
<param id="translationXerror" enabled="F">0</param>
16+
<param id="translationYerror" enabled="F">0</param>
17+
<param id="rotationXerror" enabled="F">0</param>
18+
<param id="rotationYerror" enabled="F">0</param>
19+
<param id="worldPosition" enabled="F">
20+
<x>0.0000000000000000</x>
21+
<y>0.0000000000000000</y>
22+
<z>0.0000000000000000</z>
23+
</param>
24+
<param id="worldXdirection" enabled="F">
25+
<x>1.0000000000000000</x>
26+
<y>0.0000000000000000</y>
27+
<z>0.0000000000000000</z>
28+
</param>
29+
<param id="worldYdirection" enabled="F">
30+
<x>0.0000000000000000</x>
31+
<y>1.0000000000000000</y>
32+
<z>0.0000000000000000</z>
33+
</param>
34+
<param id="worldZdirection" enabled="F">
35+
<x>0.0000000000000000</x>
36+
<y>0.0000000000000000</y>
37+
<z>1.0000000000000000</z>
38+
</param>
39+
<param id="energyDistributionType" comment="Values" enabled="T">1</param>
40+
<param id="photonEnergyDistributionFile" absolute="" enabled="F"></param>
41+
<param id="photonEnergy" enabled="T">1000</param>
42+
<param id="energySpreadType" comment="white band" enabled="T">0</param>
43+
<param id="energySpreadUnit" comment="%" enabled="T">1</param>
44+
<param id="energySpread" enabled="T">10</param>
45+
<param id="sourcePulseType" comment="all rays start simultaneously" enabled="T">0</param>
46+
<param id="sourcePulseLength" enabled="F">0</param>
47+
<param id="photonFlux" enabled="T">2.76089e+12</param>
48+
</object>
49+
</beamline>
50+
</lab>

Intern/rayx-core/tests/testSources.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ void checkEnergyDistribution(const Rays& rays, double photonEnergy, double energ
88
for (const auto energy : rays.energy) { CHECK_IN(energy, photonEnergy - energySpread, photonEnergy + energySpread); }
99
}
1010

11+
void checkEnergyDistributionWindow(const Rays& rays, double minEnergy, double maxEnergy) {
12+
CHECK(rays.energy.size() > 0);
13+
for (const auto energy : rays.energy) { CHECK_IN(energy, minEnergy, maxEnergy); }
14+
}
15+
1116
void checkZDistribution(const Rays& rays, double center, double spread) {
1217
CHECK(rays.position_z.size() > 0);
1318
for (const auto position_z : rays.position_z) { CHECK_IN(position_z, center - spread, center + spread); }
@@ -51,6 +56,10 @@ TEST_F(TestSuite, MatrixSourceTracedRayUI) {
5156

5257
TEST_F(TestSuite, PointSourceHardEdge) { checkEnergyDistribution(traceRml("PointSourceHardEdge", RayAttrMask::Energy), 120.97, 12.1); }
5358

59+
TEST_F(TestSuite, PointSourceHardEdgePercentUnit) {
60+
checkEnergyDistributionWindow(traceRml("PointSourceHardEdgePercent", RayAttrMask::Energy), 95.0, 105.0);
61+
}
62+
5463
TEST_F(TestSuite, PointSourceSoftEdge) { checkEnergyDistribution(traceRml("PointSourceSoftEdge", RayAttrMask::Energy), 151, 6); }
5564

5665
TEST_F(TestSuite, MatrixSourceEnergyDistribution) { checkEnergyDistribution(traceRml("PointSourceSoftEdge", RayAttrMask::Energy), 151, 6); }
@@ -61,6 +70,10 @@ TEST_F(TestSuite, DipoleSourcePosition) {
6170

6271
TEST_F(TestSuite, DipoleEnergyDistribution) { checkEnergyDistribution(traceRml("dipole_energySpread", RayAttrMask::Energy), 1000, 23000); }
6372

73+
TEST_F(TestSuite, DipoleEnergyDistributionPercentUnit) {
74+
checkEnergyDistributionWindow(traceRml("dipole_energySpread_percent", RayAttrMask::Energy), 950.0, 1050.0);
75+
}
76+
6477
TEST_F(TestSuite, PixelPositionTest) {
6578
const auto [beamline, rays] =
6679
loadBeamlineAndTrace("PixelSource", RayAttrMask::PositionX | RayAttrMask::PositionY | RayAttrMask::DirectionX | RayAttrMask::DirectionZ);

0 commit comments

Comments
 (0)