Source code for gavo.base.spectral

"""
Spectral-related functions.
"""

from gavo.base import unitconv
from gavo.base import osinter
from gavo.utils import excs


######################## specconv

[docs]def toStdSpecUnit(fromUnit): """returns a pair of (standard unit, factor) to turn fromUnit into one of J, Hz, or m. Unconvertable units raise a UfuncError. """ for stdUnit in ["J", "Hz", "m"]: try: factor = unitconv.computeConversionFactor(fromUnit, stdUnit) except unitconv.IncompatibleUnits: continue return stdUnit, factor raise unitconv.IncompatibleUnits( f"{fromUnit} is not a spectral unit understood here")
SPEC_CONVERSION = { ("J", "m"): "h*c/(({expr})*{f})", ("J", "Hz"): "({expr})*{f}/h", ("J", "J"): "({expr})*{f}", ("Hz", "m"): "c/({expr})/{f}", ("Hz", "Hz"): "{f}*({expr})", ("Hz", "J"): "h*{f}*({expr})", ("m", "m"): "{f}*({expr})", ("m", "Hz"): "c/({expr})/{f}", ("m", "J"): "h*c/({expr})/{f}",}
[docs]def getSpecExpr(fromUnit, toUnit): """returns an expression that turns a value in fromUnit to one in toUnit. The value in fromUnit is represented by a {} so you can just .format the expression it is in into the resulting string. """ fromStd, fromFactor = toStdSpecUnit(fromUnit) toStd, toFactor = toStdSpecUnit(toUnit) convExpr = SPEC_CONVERSION[fromStd, toStd ].replace("h", str(unitconv.PLANCK_H) ).replace("c", str(unitconv.LIGHT_C)) return "{}/{}".format( convExpr.format(f=fromFactor, expr="{}"), toFactor)
[docs]def getSpecConverter(fromUnit, toUnit): """Returns a function converting spectral values in fromUnit to toUnit. """ return eval("lambda x: "+getSpecExpr(fromUnit, toUnit).format("x"))
########### our filter library NM = 1e-9
[docs]def getFilterMap(): """returns a pair for filter_def, aliases mapping. This parses from the built-in data/filters.txt; filter_def maps filter names to tuples of lower, central, long wavelength in metres. (we may add further fields later, so it's safer to [:3] these results). Aliases just maps common filter names to our canontical names for these filters. """ filterMap, aliases = {}, {} with osinter.openDistFile("data/filters.txt", encoding="utf-8") as f: for index, line in enumerate(f): if not line: break line = line.strip() if line.startswith("#"): continue parts = line.split("\t") primary = parts[0].strip() if primary.startswith("="): primary = primary[1:].strip() for p in parts[1:]: aliases[p.strip()] = primary else: try: filterMap[primary] = ( float(parts[1])*NM, float(parts[2])*NM, float(parts[3])*NM) except IndexError: raise excs.ReportableError("Bad filtermap: filters.txt," " line %d."%(index+1)) return filterMap, aliases