Skip to content

Commit 749bf91

Browse files
committed
CS_FluorShell*: add unittests
1 parent 761d681 commit 749bf91

File tree

8 files changed

+511
-21
lines changed

8 files changed

+511
-21
lines changed

java/Xraylib.java

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ public static double PM5_full_cascade_kissel(int Z, double E, double PK, double
18701870
}
18711871

18721872
/**
1873-
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
1873+
* For a given atomic number, line, and excitation energy, returns the corresponding XRF production cross section.
18741874
*
18751875
* This method is an alias for #CS_FluorLine_Kissel_Cascade, meaning that the cascade effect will be taken into account.
18761876
*
@@ -1885,6 +1885,22 @@ public static double CS_FluorLine_Kissel(int Z, int line, double E) {
18851885
return CS_FluorLine_Kissel_Cascade(Z, line, E);
18861886
}
18871887

1888+
/**
1889+
* For a given atomic number, line and excitation energy, returns the corresponding XRF production cross section.
1890+
*
1891+
* This method is an alias for #CSb_FluorLine_Kissel_Cascade, meaning that the cascade effect will be taken into account.
1892+
*
1893+
* This method used the Kissel database to calculate the photoionization cross section.
1894+
*
1895+
* @param Z The atomic number
1896+
* @param line A macro identifying the line, such as #KL3_LINE or #LA1_LINE.
1897+
* @param E The energy of the photon, expressed in keV.
1898+
* @return The XRF production cross section, expressed in barn/atom.
1899+
*/
1900+
public static double CSb_FluorLine_Kissel(int Z, int line, double E) {
1901+
return CSb_FluorLine_Kissel_Cascade(Z, line, E);
1902+
}
1903+
18881904
private static class LineMapping {
18891905

18901906
public final int line_lower;
@@ -1899,7 +1915,7 @@ public LineMapping(final int line_lower, final int line_upper, final int shell)
18991915
}
19001916

19011917
private static final LineMapping[] line_mappings = new LineMapping[]{
1902-
new LineMapping(Xraylib.KN5_LINE, Xraylib.KB_LINE, Xraylib.K_SHELL),
1918+
new LineMapping(Xraylib.KP5_LINE, Xraylib.KB_LINE, Xraylib.K_SHELL),
19031919
new LineMapping(Xraylib.L1P5_LINE, Xraylib.L1L2_LINE, Xraylib.L1_SHELL),
19041920
new LineMapping(Xraylib.L2Q1_LINE, Xraylib.L2L3_LINE, Xraylib.L2_SHELL),
19051921
new LineMapping(Xraylib.L3Q1_LINE, Xraylib.L3M1_LINE, Xraylib.L3_SHELL),
@@ -2162,7 +2178,7 @@ else if (shell == M5_SHELL) {
21622178
return FluorYield(Z, M5_SHELL) * PM5_pure_kissel(Z, E, PM1, PM2, PM3, PM4);
21632179
}
21642180
else {
2165-
throw new IllegalArgumentException(INVALID_LINE);
2181+
throw new IllegalArgumentException(INVALID_SHELL);
21662182
}
21672183
}
21682184

@@ -2177,28 +2193,26 @@ public final double execute(int Z, int shell, double E) {
21772193
throw new IllegalArgumentException(NEGATIVE_ENERGY);
21782194
}
21792195

2180-
double yield = FluorYield(Z, shell);
2181-
21822196
if (shell == K_SHELL) {
21832197
/*
21842198
* K lines -> never cascade effect!
21852199
*/
2186-
return yield * CS_Photo_Partial(Z, K_SHELL, E);
2200+
return FluorYield(Z, shell) * CS_Photo_Partial(Z, K_SHELL, E);
21872201
}
21882202
else if (shell == L1_SHELL) {
21892203
/*
21902204
* L1 lines
21912205
*/
21922206
double PK = CS_Photo_Partial_catch(Z, K_SHELL, E);
2193-
return PL1_cascade_kissel(Z, E, PK) * yield;
2207+
return FluorYield(Z, shell)* PL1_cascade_kissel(Z, E, PK);
21942208
}
21952209
else if (shell == L2_SHELL) {
21962210
/*
21972211
* L2 lines
21982212
*/
21992213
double PK = CS_Photo_Partial_catch(Z, K_SHELL, E);
22002214
double PL1 = PL1_cascade_kissel_catch(Z, E, PK);
2201-
return PL2_cascade_kissel(Z, E, PK, PL1) * yield;
2215+
return FluorYield(Z, shell) * PL2_cascade_kissel(Z, E, PK, PL1);
22022216
}
22032217
else if (shell == L3_SHELL) {
22042218
/*
@@ -2207,7 +2221,7 @@ else if (shell == L3_SHELL) {
22072221
double PK = CS_Photo_Partial_catch(Z, K_SHELL, E);
22082222
double PL1 = PL1_cascade_kissel_catch(Z, E, PK);
22092223
double PL2 = PL2_cascade_kissel_catch(Z, E, PK, PL1);
2210-
return yield * PL3_cascade_kissel(Z, E, PK, PL1, PL2);
2224+
return FluorYield(Z, shell) * PL3_cascade_kissel(Z, E, PK, PL1, PL2);
22112225
}
22122226
else if (shell == M1_SHELL) {
22132227
/*
@@ -2217,7 +2231,7 @@ else if (shell == M1_SHELL) {
22172231
double PL1 = PL1_cascade_kissel_catch(Z, E, PK);
22182232
double PL2 = PL2_cascade_kissel_catch(Z, E, PK, PL1);
22192233
double PL3 = PL3_cascade_kissel_catch(Z, E, PK, PL1, PL2);
2220-
return yield * PM1_cascade_kissel(Z, E, PK, PL1, PL2, PL3);
2234+
return FluorYield(Z, shell) * PM1_cascade_kissel(Z, E, PK, PL1, PL2, PL3);
22212235
}
22222236
else if (shell == M2_SHELL) {
22232237
/*
@@ -2228,7 +2242,7 @@ else if (shell == M2_SHELL) {
22282242
double PL2 = PL2_cascade_kissel_catch(Z, E, PK, PL1);
22292243
double PL3 = PL3_cascade_kissel_catch(Z, E, PK, PL1, PL2);
22302244
double PM1 = PM1_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3);
2231-
return yield * PM2_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1);
2245+
return FluorYield(Z, shell) * PM2_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1);
22322246
}
22332247
else if (shell == M3_SHELL) {
22342248
/*
@@ -2240,7 +2254,7 @@ else if (shell == M3_SHELL) {
22402254
double PL3 = PL3_cascade_kissel_catch(Z, E, PK, PL1, PL2);
22412255
double PM1 = PM1_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3);
22422256
double PM2 = PM2_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1);
2243-
return yield * PM3_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2);
2257+
return FluorYield(Z, shell) * PM3_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2);
22442258
}
22452259
else if (shell == M4_SHELL) {
22462260
/*
@@ -2253,7 +2267,7 @@ else if (shell == M4_SHELL) {
22532267
double PM1 = PM1_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3);
22542268
double PM2 = PM2_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1);
22552269
double PM3 = PM3_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1, PM2);
2256-
return yield * PM4_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2, PM3);
2270+
return FluorYield(Z, shell) * PM4_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2, PM3);
22572271
}
22582272
else if (shell == M5_SHELL) {
22592273
/*
@@ -2267,10 +2281,10 @@ else if (shell == M5_SHELL) {
22672281
double PM2 = PM2_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1);
22682282
double PM3 = PM3_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1, PM2);
22692283
double PM4 = PM4_cascade_kissel_catch(Z, E, PK, PL1, PL2, PL3, PM1, PM2, PM3);
2270-
return yield * PM5_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2, PM3, PM4);
2284+
return FluorYield(Z, shell) * PM5_cascade_kissel(Z, E, PK, PL1, PL2, PL3, PM1, PM2, PM3, PM4);
22712285
}
22722286
else {
2273-
throw new IllegalArgumentException(INVALID_LINE);
2287+
throw new IllegalArgumentException(INVALID_SHELL);
22742288
}
22752289
}
22762290

@@ -2491,6 +2505,102 @@ public static double CS_FluorShell_Kissel_Cascade(int Z, int shell, double E) {
24912505
return CS_FLUORSHELL_KISSEL_FULL.execute(Z, shell, E);
24922506
}
24932507

2508+
/**
2509+
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
2510+
*
2511+
* This implementation includes both non-radiative and radiative cascade effect contributions!
2512+
*
2513+
* This method used the Kissel database to calculate the photoionization cross section.
2514+
*
2515+
* @param Z The atomic number
2516+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2517+
* @param E The energy of the photon, expressed in keV.
2518+
* @return The XRF production cross section, expressed in barn/atom.
2519+
*/
2520+
public static double CSb_FluorShell_Kissel_Cascade(int Z, int shell, double E) {
2521+
return CS_FluorShell_Kissel_Cascade(Z, shell, E) * AtomicWeight_arr[Z] / AVOGNUM;
2522+
}
2523+
2524+
/**
2525+
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
2526+
*
2527+
* This implementation includes the non-radiative cascade contributions but excludes the radiative cascade effect!
2528+
*
2529+
* This method used the Kissel database to calculate the photoionization cross section.
2530+
*
2531+
* @param Z The atomic number
2532+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2533+
* @param E The energy of the photon, expressed in keV.
2534+
* @return The XRF production cross section, expressed in barn/atom.
2535+
*/
2536+
public static double CSb_FluorShell_Kissel_Nonradiative_Cascade(int Z, int shell, double E) {
2537+
return CS_FluorShell_Kissel_Nonradiative_Cascade(Z, shell, E) * AtomicWeight_arr[Z] / AVOGNUM;
2538+
}
2539+
2540+
/**
2541+
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
2542+
*
2543+
* This implementation includes the radiative cascade contributions but excludes the non-radiative cascade effect!
2544+
*
2545+
* This method used the Kissel database to calculate the photoionization cross section.
2546+
*
2547+
* @param Z The atomic number
2548+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2549+
* @param E The energy of the photon, expressed in keV.
2550+
* @return The XRF production cross section, expressed in barn/atom.
2551+
*/
2552+
public static double CSb_FluorShell_Kissel_Radiative_Cascade(int Z, int shell, double E) {
2553+
return CS_FluorShell_Kissel_Radiative_Cascade(Z, shell, E) * AtomicWeight_arr[Z] / AVOGNUM;
2554+
}
2555+
2556+
/**
2557+
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
2558+
*
2559+
* This method excludes the cascade effect from the calculation!
2560+
*
2561+
* This method used the Kissel database to calculate the photoionization cross section.
2562+
*
2563+
* @param Z The atomic number
2564+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2565+
* @param E The energy of the photon, expressed in keV.
2566+
* @return The XRF production cross section, expressed in barn/atom.
2567+
*/
2568+
public static double CSb_FluorShell_Kissel_no_Cascade(int Z, int shell, double E) {
2569+
return CS_FluorShell_Kissel_no_Cascade(Z, shell, E) * AtomicWeight_arr[Z] / AVOGNUM;
2570+
}
2571+
2572+
/**
2573+
* For a given atomic number, shell, and excitation energy, returns the corresponding XRF production cross section.
2574+
*
2575+
* This method is an alias for #CS_FluorShell_Kissel_Cascade, meaning that the cascade effect will be taken into account.
2576+
*
2577+
* This method used the Kissel database to calculate the photoionization cross section.
2578+
*
2579+
* @param Z The atomic number
2580+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2581+
* @param E The energy of the photon, expressed in keV.
2582+
* @return The XRF production cross section, expressed in cm<sup>2</sup>/g.
2583+
*/
2584+
public static double CS_FluorShell_Kissel(int Z, int shell, double E) {
2585+
return CS_FluorShell_Kissel_Cascade(Z, shell, E);
2586+
}
2587+
2588+
/**
2589+
* For a given atomic number, line and excitation energy, returns the corresponding XRF production cross section.
2590+
*
2591+
* This method is an alias for #CSb_FluorShell_Kissel_Cascade, meaning that the cascade effect will be taken into account.
2592+
*
2593+
* This method used the Kissel database to calculate the photoionization cross section.
2594+
*
2595+
* @param Z The atomic number
2596+
* @param shell A macro identifying the shell, such as #K_SHELL or #L1_SHELL.
2597+
* @param E The energy of the photon, expressed in keV.
2598+
* @return The XRF production cross section, expressed in barn/atom.
2599+
*/
2600+
public static double CSb_FluorShell_Kissel(int Z, int shell, double E) {
2601+
return CSb_FluorShell_Kissel_Cascade(Z, shell, E);
2602+
}
2603+
24942604
/**
24952605
* For a given atomic number, shell and excitation energy, returns the corresponding XRF production cross section.
24962606
*
@@ -2817,7 +2927,7 @@ public static double CS_FluorLine(int Z, int line, double E) {
28172927
double Factor = 1.0;
28182928
double rr;
28192929

2820-
if (line >= KN5_LINE && line <= KB_LINE) {
2930+
if (line >= KP5_LINE && line <= KB_LINE) {
28212931
rr = RadRate(Z, line);
28222932
Factor = CS_FluorShell(Z, K_SHELL, E);
28232933
return rr * Factor;

java/tests/TestCrossSectionsFluorLine.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,66 @@ public void test_deprecated_siegbahn_macros() {
8686
}
8787
assertEquals(cs, Xraylib.CS_FluorLine(92, Xraylib.LB_LINE, 30.0), 1E-6);
8888
}
89+
90+
private static class LineMapping {
91+
92+
public final int line_lower;
93+
public final int line_upper;
94+
public final int shell;
95+
96+
public LineMapping(final int line_lower, final int line_upper, final int shell) {
97+
this.line_lower = line_lower;
98+
this.line_upper = line_upper;
99+
this.shell = shell;
100+
}
101+
}
102+
103+
private static final LineMapping[] line_mappings = new LineMapping[]{
104+
new LineMapping(Xraylib.KN5_LINE, Xraylib.KB_LINE, Xraylib.K_SHELL),
105+
new LineMapping(Xraylib.L1P5_LINE, Xraylib.L1L2_LINE, Xraylib.L1_SHELL),
106+
new LineMapping(Xraylib.L2Q1_LINE, Xraylib.L2L3_LINE, Xraylib.L2_SHELL),
107+
new LineMapping(Xraylib.L3Q1_LINE, Xraylib.L3M1_LINE, Xraylib.L3_SHELL),
108+
};
109+
110+
@Test
111+
public void test_fluor_shell_all() {
112+
for (LineMapping mapping: line_mappings) {
113+
double cs = Xraylib.CS_FluorShell(92, mapping.shell, 120.0);
114+
double cs2 = 0;
115+
double rr = 0;
116+
117+
for (int j = mapping.line_lower ; j <= mapping.line_upper ; j++) {
118+
try {
119+
rr += Xraylib.RadRate(92, j);
120+
cs2 += Xraylib.CS_FluorLine(92, j, 120.0);
121+
} catch (IllegalArgumentException e) {
122+
continue;
123+
}
124+
}
125+
assertEquals(cs2, rr * cs, 1E-6);
126+
}
127+
}
128+
129+
static Stream<Arguments> badShellValuesProvider() {
130+
return Stream.of(
131+
arguments(0, Xraylib.K_SHELL, 10.0, Xraylib.Z_OUT_OF_RANGE),
132+
arguments(Xraylib.ZMAX, Xraylib.K_SHELL, 10.0, Xraylib.INVALID_SHELL),
133+
arguments(Xraylib.ZMAX + 1, Xraylib.K_SHELL, 10.0, Xraylib.Z_OUT_OF_RANGE),
134+
arguments(1, Xraylib.K_SHELL, 10.0, Xraylib.INVALID_SHELL),
135+
arguments(92, Xraylib.M1_SHELL, 10.0, Xraylib.INVALID_SHELL),
136+
arguments(92, Xraylib.KL3_LINE, 10.0, Xraylib.INVALID_SHELL),
137+
arguments(26, Xraylib.K_SHELL, 0.0, Xraylib.NEGATIVE_ENERGY),
138+
arguments(26, Xraylib.K_SHELL, 1001.0, Xraylib.SPLINT_X_TOO_HIGH),
139+
arguments(26, Xraylib.K_SHELL, 5, Xraylib.TOO_LOW_EXCITATION_ENERGY)
140+
);
141+
}
142+
143+
@ParameterizedTest(name="test_bad_shell_values {index} -> {0} {1} {2}")
144+
@MethodSource("badShellValuesProvider")
145+
public void test_bad_shell_values(int Z, int shell, double energy, String message) {
146+
IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> {
147+
double cs = Xraylib.CS_FluorShell(Z, shell, energy);
148+
}, message);
149+
assertEquals(exc.getMessage(), message);
150+
}
89151
}

0 commit comments

Comments
 (0)