1from operator
import xor
3import lalsimulation
as lalsim
5from astropy
import units
as u
7from .
import parameter_conventions
as pc
12 Read and return a value
from LALDict
16 val : `lal.DictValues` value
17 Output
from a lal.DictValues
23 ltype = lal.ValueGetType(val)
24 if ltype == lal.CHAR_TYPE_CODE:
25 size = lal.ValueGetSize(val)
27 return lal.ValueGetCHAR(val)
29 return lal.ValueGetString(val)
30 if ltype == lal.I2_TYPE_CODE:
31 return lal.ValueGetINT2(val)
32 if ltype == lal.I4_TYPE_CODE:
33 return lal.ValueGetINT4(val)
34 if ltype == lal.I8_TYPE_CODE:
35 return lal.ValueGetINT8(val)
36 if ltype == lal.U2_TYPE_CODE:
37 return lal.ValueGetUINT2(val)
38 if ltype == lal.U4_TYPE_CODE:
39 return lal.ValueGetUINT4(val)
40 if ltype == lal.U8_TYPE_CODE:
41 return lal.ValueGetUINT8(val)
42 if ltype == lal.S_TYPE_CODE:
43 return lal.ValueGetREAL4(val)
44 if ltype == lal.D_TYPE_CODE:
45 return lal.ValueGetREAL8(val)
46 if ltype == lal.C_TYPE_CODE:
47 return lal.ValueGetCOMPLEX8(val)
48 if ltype == lal.Z_TYPE_CODE:
49 return lal.ValueGetCOMPLEX16(val)
51 raise TypeError(
'invalid lal typecode %d' % ltype)
55 Convert Python dictionary to LALDict object readble by LAL
60 Python dictionary of input parameters
65 LALDict object readable by LAL
69 ldict = lal.CreateDict()
70 for k, v
in d.items():
72 lalsim.SimInspiralWaveformParamsInsertModeArrayFromModeString(ldict, v)
73 elif k ==
'ModeArrayJframe':
74 lalsim.SimInspiralWaveformParamsInsertModeArrayJframeFromModeString(ldict, v)
76 if isinstance(v, np.generic):
78 elif type(v)
is u.quantity.Quantity:
80 lal.DictInsertREAL8Value(ldict, k, v_val)
82 if type(v)
is float
or lalsim.SimInspiralCheckKnownREAL8Key(k):
83 lal.DictInsertREAL8Value(ldict, k, v)
85 lal.DictInsertINT4Value(ldict, k, v)
87 lal.DictInsertStringValue(ldict, k, v)
95 Convert LALDict object to a Python dictionary
110 keys = lal.DictKeys(ldict)
111 vals = lal.DictValues(ldict)
112 size = lal.ListSize(keys)
113 for i
in range(size):
114 key = lal.ListItemGetStringValue(lal.ListPop(keys))
115 lal_item = lal.ListPop(vals)
118 if 'ModeArray' in key:
119 val = lalsim.SimInspiralModeArrayToModeString(lal.ListItemGetValue(lal_item))
129 """Checks the parameters used in the waveform generation routine.
133 waveform_dict (dict): The dictionary of parameters used to generate the template.
135 generic_param_dict (dict,optional): Dictionary of extra parameter names to be accepted in order to generate
136 non-standard waveforms. It should
not include standard waveform parameters
as they will
137 be ignored. The form should be parameter_name:parameter_units
and the values should be just
138 added
in the waveform_dict.
141 AssertionError: If a parameter has the wrong units.
142 TypeError: If a parameter
is not available to use
or a dimensional parameter
143 is passed
as dimensionless.
151 default_unit_sys =
'S.I.'
155 if generic_param_dict
is not None: full_parameter_list = np.concatenate([pc.full_parameter_list,list(generic_param_dict.keys())])
156 else : full_parameter_list = pc.full_parameter_list
159 for k
in waveform_dict.keys():
161 if k
not in full_parameter_list:
162 raise(TypeError( (
"Parameter %s not in accepted list of parameters"%(k))))
164 elif k
in pc.units_dict[default_unit_sys].keys():
165 try : waveform_dict[k].unit
166 except: raise(TypeError( (
"Parameter {} does not have units, please pass a parameter with astropy units equivalent to u.[{}]".format(k,pc.units_dict[default_unit_sys][k]))))
167 assert waveform_dict[k].unit.is_equivalent(pc.units_dict[default_unit_sys][k]),
"Parameter {} does not have proper units, units should be equivalent to u.[{}]".format(k,pc.units_dict[default_unit_sys][k])
169 if int(waveform_dict[k])==0
or int(waveform_dict[k])==1:
172 raise(TypeError(
"Condition should only be 0 or 1"))
174 if waveform_dict[k]<0:
175 raise(ValueError(
"lmax must be >=0"))
177 elif generic_param_dict
is not None:
178 try : waveform_dict[k].unit
179 except: raise(TypeError( (
"Parameter {} does not have units, please pass a parameter with astropy units equivalent to u.[{}]".format(k,generic_param_dict[k]))))
180 assert waveform_dict[k].unit.is_equivalent(generic_param_dict[k]),
"Parameter {} does not have proper units, units should be equivalent to u.[{}]".format(k,generic_param_dict[k])
185def add_params_units(waveform_dict,units_sys='S.I.',generic_param_dict=None):
186 """Add units or convert to desired units system to the waveform parameters dictionary
190 waveform_dict (dict): The dictionary of parameters used to generate the template.
191 units_sys (:obj:`str`, optional): System of units chosen for the given parameters.
192 Defaults to
None. If a unit system
is given,
try to convert
and provide
193 units to the parameters
in `waveform_dict`. If default checks the parameters
in `waveform_dict`
194 have the appropriate units.
195 generic_param_dict (dict,optional): Dictionary of extra parameter names to be accepted
in order to generate
196 non-standard waveforms. It should
not include standard waveform parameters
as they will
197 be ignored. The form should be parameter_name:parameter_units
and the values should be just
198 added
in the waveform_dict.
201 A dict the corresponding conversions to the
202 specified `units_sys` system.
206 AssertionError: If a parameter has wrong units
212 if units_sys
in pc.units_dict.keys():
213 dict_tmp = {key:u.Quantity(value,pc.units_dict[units_sys][key])
for (key,value)
in waveform_dict.items()
if key
in pc.units_dict[units_sys].keys()}
215 raise(TypeError(
'The units system specified is not available. Available systems are {}'.format([key
for key
in pc.units_dict.keys()])))
219 if generic_param_dict
is not None:
220 dict_tmp = {**dict_tmp, **{key:u.Quantity(value,generic_param_dict[key])
for (key,value)
in waveform_dict.items()
if key
in generic_param_dict.keys()}}
223 dict_tmp = {**waveform_dict,**dict_tmp}
226 for par
in pc.mass_params_[0:4]:
227 if par
in dict_tmp.keys():
228 if dict_tmp[par]>=2*10**30*u.solMass:
229 warn_string =
"Are you sure you want to have a {} of {} Solar Masses?".format(par,u.Quantity(dict_tmp[par],u.solMass).value)
230 warnings.warn(warn_string)
231 if 'mass_ratio' in dict_tmp.keys():
232 if (dict_tmp[
'mass_ratio']<0.001)
or (dict_tmp[
'mass_ratio']>1000.0):
233 warn_string =
"Are you sure you want to have a q of {}?".format(dict_tmp[
'mass_ratio'])
234 warnings.warn(warn_string)
244 """Check mass parameters are consistent and enough to fully characterize the binary masses
248 waveform_dict (dict): The dictionary of parameters used to generate the template.
252 TypeError: whenever mass parameters are over or underspecified
261 dimensionless_masses = [
"mass_ratio",
"sym_mass_ratio"]
262 dimensionful_masses = [
"mass1",
"mass2",
"total_mass",
"chirp_mass",
"mass_difference",
"reduced_mass"]
263 symetric_masses = [
"mass1",
"mass2",
"total_mass",
"chirp_mass",
"sym_mass_ratio",
"reduced_mass"]
266 for param
in dimensionful_masses:
267 if param
in waveform_dict.keys(): dim_number += 1
268 for param
in dimensionless_masses:
269 if param
in waveform_dict.keys(): nodim_number += 1
270 for param
in symetric_masses:
271 if param
in waveform_dict.keys(): sym_number += 1
272 if (
"mass1" in waveform_dict.keys()) & (
"mass2" in waveform_dict.keys()): sym_number = 0
274 if ((dim_number == 2
and nodim_number == 0)
or (dim_number == 1
and nodim_number == 1)):
276 warn_string =
"The larger object cannot be determined, assuming m1 >= m2."
277 warnings.warn(warn_string)
278 elif ((dim_number == 1
and nodim_number == 0)
or dim_number == 0):
279 raise(TypeError(
"Mass parameters are underspecified. Please include" \
280 " one dimensionless and one dimensionful mass parameters, or two dimensionful masses."))
282 raise(TypeError(
"Mass parameters are overspecified. Please include" \
283 " one dimensionless and one dimensionful mass parameters, or two dimensionful masses."))
286 """Check spin parameters are consistent and enough to fully characterize the binary spins
290 waveform_dict (dict): The dictionary of parameters used to generate the template.
294 TypeError: whenever spin parameters are over or underspecified
or system of coordinates
is mixed
308 cartesian = [
'x',
'y',
'z']
309 spherical = [
'_norm',
'_tilt',
'_phi']
311 for sfx
in cartesian:
312 if 'spin1'+sfx
in waveform_dict.keys(): spin1_number += 1
313 if 'spin2'+sfx
in waveform_dict.keys(): spin2_number += 1
315 if spin1_number >0: cartesian_1=
True
316 if spin2_number >0: cartesian_2=
True
321 for sfx
in spherical:
322 if 'spin1'+sfx
in waveform_dict.keys(): spin1_number += 1
323 if 'spin2'+sfx
in waveform_dict.keys(): spin2_number += 1
325 if spin1_number >0: spherical_1=
True
326 if spin2_number >0: spherical_2=
True
328 if not(xor(cartesian_1,spherical_1))
or not(xor(cartesian_2,spherical_2)):
329 raise(TypeError(
"Please specify the 3 spin parameters in either spherical or cartesian coordinates."))
def check_dict_parameters(waveform_dict, generic_param_dict=None)
Checks the parameters used in the waveform generation routine.
def CheckDeterminationOfSpins(waveform_dict)
Check spin parameters are consistent and enough to fully characterize the binary spins.
def from_lal_dict(ldict)
Convert LALDict object to a Python dictionary.
def add_params_units(waveform_dict, units_sys='S.I.', generic_param_dict=None)
Add units or convert to desired units system to the waveform parameters dictionary.
def CheckDeterminationOfMasses(waveform_dict)
Check mass parameters are consistent and enough to fully characterize the binary masses.
def from_lal_value(val)
Read and return a value from LALDict.
def to_lal_dict(d)
Convert Python dictionary to LALDict object readble by LAL.