-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcif_dic.jl
113 lines (98 loc) · 3.84 KB
/
cif_dic.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# **CIF Dictionaries
export get_names_in_cat,AbstractCifDictionary,has_drel_methods
export convert_to_julia
export get_container_type
"""
A dictionary providing type and other information about a series
of data names.
"""
abstract type AbstractCifDictionary end
Base.length(d::AbstractCifDictionary) = begin
return length(keys(d))
end
"""
has_drel_methods(d)
Does `d` include methods written in dREL for derivation of data
values?
"""
has_drel_methods(d::AbstractCifDictionary) = true
"""
get_names_in_cat(d::AbstractCifDictionary,catname;aliases=false,only_items=true)
Return a list of all names in `catname`, as defined in `d`. If `aliases`, include any
declared aliases of the name. If `only_items` is false, return child categories as
well.
"""
get_names_in_cat(d::AbstractCifDictionary,catname;aliases=false,only_items=true) = begin
all_objs = get_objs_in_cat(d,catname)
canonical_names = [find_name(d,catname,x) for x in all_objs]
if only_items filter!(x->!is_category(d,x),canonical_names) end
if aliases
search_names = copy(canonical_names)
for n in search_names
append!(canonical_names,list_aliases(d,n))
end
end
return canonical_names
end
"""
convert_to_julia(cdic,cat,obj,value::Array)
Convert elements of array `value` to the appropriate Julia type
using information in `cdic` for given `category` and `object`, unless
value is `missing` or `nothing`, which are returned unchanged.
This only handles one level of arrays. `value` must be either an
`Array{CifValue,1}` (usually `Array{String,}`) or of the correct type
already.
"""
convert_to_julia(cdic,cat,obj,value::Array) = begin
julia_base_type,cont_type = get_julia_type_name(cdic,cat,obj)
if typeof(value) == Array{julia_base_type,1} return value end
#if !(eltype(value) <: CifValue)
# throw(error("Unable to convert values of type $(eltype(value))"))
#end
change_func = (x->x)
#println("Julia type for $cat/$obj is $julia_base_type, converting $value")
if julia_base_type == Integer
change_func = (x -> map(y->parse(Int,y),x))
elseif julia_base_type == Float64
change_func = (x -> map(y->real_from_meas(y),x))
elseif julia_base_type == Complex
change_func = (x -> map(y-> if ismissing(y) || isnothing(y) y else parse(Complex{Float64},y) end,x)) #TODO: SU on values
elseif julia_base_type in (String,AbstractString)
change_func = (x -> map(y-> if ismissing(y) || isnothing(y) y else String(y) end,x))
elseif julia_base_type == :CaselessString
change_func = (x -> map(y-> if ismissing(y) || isnothing(y) y else CaselessString(y) end,x))
end
if cont_type == "Single"
return change_func(value)
elseif cont_type in ["Array","Matrix"]
return map(change_func,value)
else error("Unsupported container type $cont_type") #we can do nothing
end
end
"""
convert_to_julia(cdic,dataname,value)
Convert String elements of array `value` to the appropriate Julia type
using information in `cdic` for `dataname`, unless value is `missing`
or `nothing`, which are returned unchanged. This only handles one
level of arrays.
"""
convert_to_julia(cdic,dataname::AbstractString,value) = begin
return convert_to_julia(cdic,find_category(cdic,dataname),find_object(cdic,dataname),value)
end
"""
real_from_meas(value::String)
Remove optionally attached su from `value` with form `dd(ee)` and return as a `Float64`.
"""
real_from_meas(value::String) = begin
#println("Getting real value from $value")
if '(' in value
#println("NB $(value[1:findfirst(isequal('('),value)])")
return parse(Float64,value[1:findfirst(isequal('('),value)-1])
end
return parse(Float64,value)
end
real_from_meas(value::Missing) = missing
Range(v::String) = begin
lower,upper = split(v,":")
parse(Int32,lower),parse(Int32,upper)
end