Source code for tardis.scripts.cmfgen2tardis

import os
import sys
import argparse
import numpy as np
import pandas as pd

from tardis.io.atom_data import AtomData

# The from_hdf() method requires an argument, so the line below doesn't work
# atomic_dataset = AtomData.from_hdf()


[docs] def get_atomic_number(element): index = -1 for atomic_no, row in atomic_dataset.atom_data.iterrows(): if element in row["name"]: index = atomic_no break return index
[docs] def extract_file_block(f): qty = [] for line in f: items = line.split() if items: qty.extend(np.array(items).astype(np.float64)) else: break qty = np.array(qty) # Convention in CMFGEN files is different from TARDIS files. # CMFGEN stores velocity values in decreasing order, while # TARDIS stores it in ascending order, so alongwith # velocity, all columns will be reversed. return qty[::-1]
[docs] def convert_format(file_path): quantities_row = [] prop_list = ["Velocity", "Density", "Electron density", "Temperature"] with open(file_path, "r") as f: for line in f: items = line.replace("(", "").replace(")", "").split() n = len(items) if "data points" in line: abundances_df = pd.DataFrame( columns=np.arange(int(items[n - 1])), index=pd.Index([], name="element"), dtype=np.float64, ) if any(prop in line for prop in prop_list): quantities_row.append(items[n - 1].replace("gm", "g")) if "Time" in line: time_of_model = float(items[n - 1]) if "Velocity" in line: velocity = extract_file_block(f) if "Density" in line: density = extract_file_block(f) if "Electron density" in line: electron_density = extract_file_block(f) if "Temperature" in line: temperature = extract_file_block(f) if "mass fraction\n" in line: element_string = items[0] atomic_no = get_atomic_number(element_string.capitalize()) element_symbol = atomic_dataset.atom_data.loc[atomic_no][ "symbol" ] # Its a Isotope if n == 4: element_symbol += items[1] abundances = extract_file_block(f) abundances_df.loc[element_symbol] = abundances density_df = pd.DataFrame.from_records( [velocity, temperature * 10**4, density, electron_density] ).transpose() density_df.columns = [ "velocity", "temperature", "densities", "electron_densities", ] quantities_row += abundances_df.shape[0] * [1] return ( abundances_df.transpose(), density_df, time_of_model, quantities_row, )
[docs] def parse_file(args): abundances_df, density_df, time_of_model, quantities_row = convert_format( args.input_path ) filename = os.path.splitext(os.path.basename(args.input_path))[0] save_fname = ".".join((filename, "csv")) resultant_df = pd.concat([density_df, abundances_df], axis=1) resultant_df.columns = pd.MultiIndex.from_tuples( zip(resultant_df.columns, quantities_row) ) save_file_path = os.path.join(args.output_path, save_fname) with open(save_file_path, "w") as f: f.write(" ".join(("t0:", str(time_of_model), "day"))) f.write("\n") resultant_df.to_csv(save_file_path, index=False, sep=" ", mode="a")
[docs] def main(): parser = argparse.ArgumentParser() parser.add_argument("input_path", help="Path to a CMFGEN file") parser.add_argument( "output_path", help="Path to store converted TARDIS format files" ) args = parser.parse_args() parse_file(args)