Skip to content

Instantly share code, notes, and snippets.

@brittonsmith
Created June 25, 2020 15:16
Show Gist options
  • Save brittonsmith/9ac6ce00d402bda888f95ee5bb6b7a17 to your computer and use it in GitHub Desktop.
Save brittonsmith/9ac6ce00d402bda888f95ee5bb6b7a17 to your computer and use it in GitHub Desktop.
Provide path to tree_0_0_0.dat file and it will print out units for all fields.
import functools
import re
import sys
from unyt import \
unyt_array, \
unyt_quantity
from unyt.dimensions import \
dimensionless, \
length
from unyt.unit_registry import \
UnitRegistry
from unyt.exceptions import \
UnitParseError
_unit_registry = UnitRegistry()
_unit_registry.add('h', 0.7, dimensionless)
for my_unit in ["m", "pc", "AU"]:
new_unit = "%scm" % my_unit
_unit_registry.add(
new_unit, _unit_registry.lut[my_unit][0],
length, _unit_registry.lut[my_unit][3])
quan = functools.partial(unyt_quantity,
registry=_unit_registry)
def get_ctrees_units(filename):
fields = []
fi = {}
fdb = {}
rems = ["%s%s%s" % (s[0], t, s[1])
for s in [("(", ")"), ("", "")]
for t in ["physical, peculiar",
"comoving", "physical"]]
f = open(filename, "r")
# Read the first line as a list of all fields.
# Do some footwork to remove awkard characters.
rfl = f.readline()[1:].strip().split()
reg = re.compile(r"\(\d+\)$")
for pf in rfl:
match = reg.search(pf)
if match is None:
fields.append(pf)
else:
fields.append(pf[:match.start()])
# Now grab a bunch of things from the header.
while True:
line = f.readline()
if line is None:
raise IOError(
"Encountered enexpected EOF reading %s." %
filename)
elif not line.startswith("#"):
_ntrees = int(line.strip())
_hoffset = f.tell()
break
# cosmological parameters
if "Omega_M" in line:
pars = line[1:].split(";")
for j, par in enumerate(["omega_matter",
"omega_lambda",
"hubble_constant"]):
v = float(pars[j].split(" = ")[1])
print ("%s: %s." % (par, v))
# box size
elif "Full box size" in line:
pars = line.split("=")[1].strip().split()
box = pars
print ("Box size: %s." % box)
# These are lines describing the various fields.
# Pull them apart and look for units.
elif ":" in line:
tfields, desc = line[1:].strip().split(":", 1)
# Units are enclosed in parentheses.
# Pull out what's enclosed and remove things like
# "comoving" and "physical".
if "(" in line and ")" in line:
punits = desc[desc.find("(")+1:desc.rfind(")")]
for rem in rems:
while rem in punits:
pre, mid, pos = punits.partition(rem)
punits = pre + pos
try:
quan(1, punits)
except UnitParseError:
punits = ""
punits = punits.strip()
else:
punits = ""
# Multiple fields together on the same line.
for sep in ["/", ","]:
if sep in tfields:
tfields = tfields.split(sep)
break
if not isinstance(tfields, list):
tfields = [tfields]
# Assign units and description.
for tfield in tfields:
fdb[tfield.lower()] = {"description": desc.strip(),
"units": punits}
f.close()
# Fill the field info with the units found above.
for i, field in enumerate(fields):
if "(" in field and ")" in field:
cfield = field[:field.find("(")]
else:
cfield = field
fi[field] = fdb.get(cfield.lower(),
{"description": "",
"units": ""})
fi[field]["column"] = i
return fi
if __name__ == "__main__":
fn = sys.argv[1]
fi = get_ctrees_units(fn)
### can also get "description" from each entry
for field, entry in fi.items():
print ("%s: \"%s\"" % (field, entry.get("units", "")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment