Skip to content

Commit 6a31750

Browse files
Add and apply RadfordImpurityDensity in SSD extension
1 parent 7c834db commit 6a31750

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

Project.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
1111
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1212
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
1313
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
14+
LsqFit = "2fda8390-95c7-5789-9bda-21331edee243"
1415
MIMEs = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
1516
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
1617
Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
@@ -30,8 +31,8 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
3031
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
3132

3233
[weakdeps]
33-
LegendHDF5IO = "c9265ca6-b027-5446-b1a4-febfa8dd10b0"
3434
LegendDataTypes = "99e09c13-5545-5ee2-bfa2-77f358fb75d8"
35+
LegendHDF5IO = "c9265ca6-b027-5446-b1a4-febfa8dd10b0"
3536
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
3637
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
3738
SolidStateDetectors = "71e43887-2bd9-5f77-aebd-47f656f0a3f0"
@@ -48,10 +49,11 @@ Format = "1.2"
4849
Glob = "1.3"
4950
IntervalSets = "0.6, 0.7"
5051
JSON = "0.21.2, 1"
52+
LRUCache = "1.5"
53+
LsqFit = "0.13, 0.14, 0.15"
5154
LegendDataTypes = "0.1.13"
5255
LegendHDF5IO = "0.1.14"
5356
LinearAlgebra = "<0.0.1, 1"
54-
LRUCache = "1.5"
5557
MIMEs = "0.1"
5658
Markdown = "<0.0.1, 1"
5759
Measurements = "2.2.1"

ext/LegendDataManagementSolidStateDetectorsExt.jl

+48-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,36 @@ using SolidStateDetectors
66
using LegendDataManagement
77
using Unitful
88
using PropDicts
9+
using LsqFit
910

1011
const _SSDDefaultNumtype = Float32
1112

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+
1239

1340
"""
1441
SolidStateDetector[{T<:AbstractFloat}](data::LegendData, detector::DetectorIdLike)
@@ -527,11 +554,27 @@ function create_SSD_config_dict_from_LEGEND_metadata(meta::PropDict, xtal_meta::
527554
mantle_contact_parts
528555
end
529556

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
535578

536579
# evaluate "include" statements - needed for the charge drift model
537580
SolidStateDetectors.scan_and_merge_included_json_files!(config_dict, "")

0 commit comments

Comments
 (0)