@@ -6,9 +6,36 @@ using SolidStateDetectors
6
6
using LegendDataManagement
7
7
using Unitful
8
8
using PropDicts
9
+ using LsqFit
9
10
10
11
const _SSDDefaultNumtype = Float32
11
12
13
+ struct RadfordImpurityDensity{T} <: SolidStateDetectors.AbstractImpurityDensity{T}
14
+ # a + b*z + c*exp((z-L)/tau) -> needs at least 4 points
15
+ a:: T
16
+ b:: T
17
+ c:: T
18
+ tau:: T
19
+ L:: T
20
+ det_z0:: T
21
+ end
22
+
23
+ function SolidStateDetectors. get_impurity_density (
24
+ idm:: RadfordImpurityDensity , pt:: SolidStateDetectors.AbstractCoordinatePoint{T}
25
+ ):: T where {T}
26
+ cpt = CartesianPoint (pt)
27
+ z = cpt[3 ]
28
+
29
+ # the function parameters are in crystal axis coordinates i.e. z = 0 is seed end, z = L crystal length
30
+ # -> convert to detector coordiantes where z = 0 corresponds to p+ contact i.e. z -> det_z0 - z
31
+ - (idm. a .+ idm. b * (idm. det_z0 .- z) .+ idm. c * exp .((idm. det_z0 .- z .- idm. L)/ idm. tau))
32
+
33
+ end
34
+
35
+ function SolidStateDetectors. ImpurityDensity (T:: DataType , t:: Val{:radford} , dict:: AbstractDict , input_units:: NamedTuple )
36
+ RadfordImpurityDensity {T} (dict[" parameters" ]. .. , )
37
+ end
38
+
12
39
13
40
"""
14
41
SolidStateDetector[{T<:AbstractFloat}](data::LegendData, detector::DetectorIdLike)
@@ -527,11 +554,27 @@ function create_SSD_config_dict_from_LEGEND_metadata(meta::PropDict, xtal_meta::
527
554
mantle_contact_parts
528
555
end
529
556
530
-
531
- config_dict[" detectors" ][1 ][" semiconductor" ][" impurity_density" ] = dicttype (
532
- " name" => " constant" ,
533
- " value" => " -1e9cm^-3"
534
- )
557
+
558
+ if X == PropDict
559
+
560
+ if ! haskey (xtal_meta, :impurity_measurements )
561
+ @warn " No information regarding impurity density for $(xtal_meta. name) "
562
+ end
563
+ # TODO : check units of impurity density against the values in the config file
564
+ # Fit the impurity measurement data to a Radford model
565
+ @. fit_model (z, p) = p[1 ] + p[2 ]* z + p[3 ]* exp ((z- p[5 ])/ p[4 ])
566
+ pos = xtal_meta. impurity_measurements. distance_from_seed_end_mm * 1e-3 # units: m
567
+ val = xtal_meta. impurity_measurements. value_in_1e9e_cm3 # units: e/m^-3
568
+ fit_result = curve_fit (fit_model, pos, val, ones (Float64,5 ))
569
+
570
+ config_dict[" detectors" ][1 ][" semiconductor" ][" impurity_density" ] = dicttype (
571
+ " name" => " radford" ,
572
+ " parameters" => vcat (fit_result. param... , xtal_meta. slices[Symbol (meta. name[end ])]. detector_offset_in_mm / 1000 )
573
+ )
574
+ else
575
+ @warn " No crystal metadata found for detector $(meta. name) "
576
+ # TODO : Implement a default impurity density for cases without crystal metadata
577
+ end
535
578
536
579
# evaluate "include" statements - needed for the charge drift model
537
580
SolidStateDetectors. scan_and_merge_included_json_files! (config_dict, " " )
0 commit comments