def test_missing_required_property(csvy_missing_fname): yaml_dict, csv = csvy.load_csvy(csvy_missing_fname) with pytest.raises(Exception): vy = validate_dict(yaml_dict, schemapath=os.path.join(tardis.__path__[0], 'io', 'schemas', 'csvy_model.yml'))
def from_config_dict(cls, config_dict, validate=True, config_dirname=''): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : ~dict dictionary of a raw unvalidated config file validate: ~bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict validated_config_dict['config_dirname'] = config_dirname montecarlo_section = validated_config_dict['montecarlo'] montecarlo_section['convergence_strategy'] = ( parse_convergence_section( montecarlo_section['convergence_strategy'])) return cls(validated_config_dict)
def from_config_dict(cls, config_dict, validate=True, config_dirname=""): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : dict dictionary of a raw unvalidated config file validate : bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict validated_config_dict["config_dirname"] = config_dirname montecarlo_section = validated_config_dict["montecarlo"] if montecarlo_section["convergence_strategy"]["type"] == "damped": montecarlo_section[ "convergence_strategy" ] = parse_convergence_section( montecarlo_section["convergence_strategy"] ) elif montecarlo_section["convergence_strategy"]["type"] == "custom": raise NotImplementedError( 'convergence_strategy is set to "custom"; ' "you need to implement your specific convergence treatment" ) else: raise ValueError( 'convergence_strategy is not "damped" ' 'or "custom"' ) enable_full_relativity = montecarlo_section["enable_full_relativity"] spectrum_integrated = ( validated_config_dict["spectrum"]["method"] == "integrated" ) if enable_full_relativity and spectrum_integrated: raise NotImplementedError( "The spectrum method is set to 'integrated' and " "enable_full_relativity to 'True'.\n" "The FormalIntegrator is not yet implemented for the full " "relativity mode. " ) return cls(validated_config_dict)
def from_config_dict(cls, config_dict): """ Validating a config file. Parameters ---------- config_dict : dict dictionary of a raw unvalidated config file Returns ------- `tardis.config_reader.Configuration` """ return cls(config_validator.validate_dict(config_dict))
def from_config_dict(cls, config_dict, validate=True, config_dirname=''): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : ~dict dictionary of a raw unvalidated config file validate: ~bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict validated_config_dict['config_dirname'] = config_dirname montecarlo_section = validated_config_dict['montecarlo'] if montecarlo_section['convergence_strategy']['type'] == "damped": montecarlo_section['convergence_strategy'] = ( parse_convergence_section( montecarlo_section['convergence_strategy'])) elif montecarlo_section['convergence_strategy']['type'] == "custom": raise NotImplementedError( 'convergence_strategy is set to "custom"; ' 'you need to implement your specific convergence treatment') else: raise ValueError('convergence_strategy is not "damped" ' 'or "custom"') return cls(validated_config_dict)
def from_config_dict(cls, config_dict): """ Validating a config file. Parameters ---------- config_dict : ~dict dictionary of a raw unvalidated config file Returns ------- `tardis.config_reader.Configuration` """ return cls(config_validator.validate_dict(config_dict))
def from_config_dict(cls, config_dict, atom_data=None, test_parser=False, validate=True, config_dirname=''): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : ~dict dictionary of a raw unvalidated config file atom_data: ~tardis.atomic.AtomData atom data object. if `None` will be tried to be read from atom data file path in the config_dict [default=None] test_parser: ~bool switch on to ignore a working atom_data, mainly useful for testing this reader validate: ~bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict #First let's see if we can find an atom_db anywhere: if test_parser: atom_data = None elif 'atom_data' in validated_config_dict.keys(): if os.path.isabs(validated_config_dict['atom_data']): atom_data_fname = validated_config_dict['atom_data'] else: atom_data_fname = os.path.join( config_dirname, validated_config_dict['atom_data']) validated_config_dict['atom_data_fname'] = atom_data_fname else: raise ConfigurationError( 'No atom_data key found in config or command line') if atom_data is None and not test_parser: logger.info('Reading Atomic Data from %s', atom_data_fname) atom_data = atomic.AtomData.from_hdf5(atom_data_fname) else: atom_data = atom_data #Parsing supernova dictionary validated_config_dict['supernova']['luminosity_nu_start'] = \ validated_config_dict['supernova']['luminosity_wavelength_end'].to( u.Hz, u.spectral()) try: validated_config_dict['supernova']['luminosity_nu_end'] = \ (validated_config_dict['supernova'] ['luminosity_wavelength_start'].to(u.Hz, u.spectral())) except ZeroDivisionError: validated_config_dict['supernova']['luminosity_nu_end'] = (np.inf * u.Hz) validated_config_dict['supernova']['time_explosion'] = ( validated_config_dict['supernova']['time_explosion'].cgs) validated_config_dict['supernova']['luminosity_requested'] = ( validated_config_dict['supernova']['luminosity_requested'].cgs) #Parsing the model section model_section = validated_config_dict['model'] v_inner = None v_outer = None mean_densities = None abundances = None structure_section = model_section['structure'] if structure_section['type'] == 'specific': velocity = model_section['structure']['velocity'] start, stop, num = velocity['start'], velocity['stop'], \ velocity['num'] num += 1 velocities = quantity_linspace(start, stop, num) v_inner, v_outer = velocities[:-1], velocities[1:] mean_densities = parse_density_section( model_section['structure']['density'], v_inner, v_outer, validated_config_dict['supernova']['time_explosion']).cgs elif structure_section['type'] == 'file': if os.path.isabs(structure_section['filename']): structure_fname = structure_section['filename'] else: structure_fname = os.path.join(config_dirname, structure_section['filename']) v_inner, v_outer, mean_densities, inner_boundary_index, \ outer_boundary_index = read_density_file( structure_fname, structure_section['filetype'], validated_config_dict['supernova']['time_explosion'], structure_section['v_inner_boundary'], structure_section['v_outer_boundary']) r_inner = validated_config_dict['supernova']['time_explosion'] * v_inner r_outer = validated_config_dict['supernova']['time_explosion'] * v_outer r_middle = 0.5 * (r_inner + r_outer) structure_section['v_inner'] = v_inner.cgs structure_section['v_outer'] = v_outer.cgs structure_section['mean_densities'] = mean_densities.cgs no_of_shells = len(v_inner) structure_section['no_of_shells'] = no_of_shells structure_section['r_inner'] = r_inner.cgs structure_section['r_outer'] = r_outer.cgs structure_section['r_middle'] = r_middle.cgs structure_section['volumes'] = ((4. / 3) * np.pi * \ (r_outer ** 3 - r_inner ** 3)).cgs #### TODO the following is legacy code and should be removed validated_config_dict['structure'] = \ validated_config_dict['model']['structure'] # ^^^^^^^^^^^^^^^^ abundances_section = model_section['abundances'] if abundances_section['type'] == 'uniform': abundances = pd.DataFrame(columns=np.arange(no_of_shells), index=pd.Index(np.arange(1, 120), name='atomic_number'), dtype=np.float64) for element_symbol_string in abundances_section: if element_symbol_string == 'type': continue z = element_symbol2atomic_number(element_symbol_string) abundances.ix[z] = float( abundances_section[element_symbol_string]) elif abundances_section['type'] == 'file': if os.path.isabs(abundances_section['filename']): abundances_fname = abundances_section['filename'] else: abundances_fname = os.path.join(config_dirname, abundances_section['filename']) index, abundances = read_abundances_file( abundances_fname, abundances_section['filetype'], inner_boundary_index, outer_boundary_index) if len(index) != no_of_shells: raise ConfigurationError( 'The abundance file specified has not the same number of cells' 'as the specified density profile') abundances = abundances.replace(np.nan, 0.0) abundances = abundances[abundances.sum(axis=1) > 0] norm_factor = abundances.sum(axis=0) if np.any(np.abs(norm_factor - 1) > 1e-12): logger.warning( "Abundances have not been normalized to 1. - normalizing") abundances /= norm_factor validated_config_dict['abundances'] = abundances ########### DOING PLASMA SECTION ############### plasma_section = validated_config_dict['plasma'] if plasma_section['initial_t_inner'] < 0.0 * u.K: luminosity_requested = validated_config_dict['supernova'][ 'luminosity_requested'] plasma_section['t_inner'] = (( luminosity_requested / (4 * np.pi * r_inner[0]**2 * constants.sigma_sb))**.25).to('K') logger.info( '"initial_t_inner" is not specified in the plasma ' 'section - initializing to %s with given luminosity', plasma_section['t_inner']) else: plasma_section['t_inner'] = plasma_section['initial_t_inner'] if plasma_section['initial_t_rad'] > 0 * u.K: plasma_section['t_rads'] = np.ones(no_of_shells) * \ plasma_section['initial_t_rad'] else: plasma_section['t_rads'] = None if plasma_section['disable_electron_scattering'] is False: logger.debug("Electron scattering switched on") validated_config_dict['montecarlo'][ 'sigma_thomson'] = 6.652486e-25 / (u.cm**2) else: logger.warn('Disabling electron scattering - this is not physical') validated_config_dict['montecarlo']['sigma_thomson'] = 1e-200 / ( u.cm**2) if plasma_section['helium_treatment'] == 'recomb-nlte': validated_config_dict['plasma'][ 'helium_treatment'] == 'recomb-nlte' else: validated_config_dict['plasma']['helium_treatment'] == 'dilute-lte' ##### NLTE subsection of Plasma start nlte_validated_config_dict = {} nlte_species = [] nlte_section = plasma_section['nlte'] nlte_species_list = nlte_section.pop('species') for species_string in nlte_species_list: nlte_species.append(species_string_to_tuple(species_string)) nlte_validated_config_dict['species'] = nlte_species nlte_validated_config_dict['species_string'] = nlte_species_list nlte_validated_config_dict.update(nlte_section) if 'coronal_approximation' not in nlte_section: logger.debug( 'NLTE "coronal_approximation" not specified in NLTE section - defaulting to False' ) nlte_validated_config_dict['coronal_approximation'] = False if 'classical_nebular' not in nlte_section: logger.debug( 'NLTE "classical_nebular" not specified in NLTE section - defaulting to False' ) nlte_validated_config_dict['classical_nebular'] = False elif nlte_section: #checks that the dictionary is not empty logger.warn( 'No "species" given - ignoring other NLTE options given:\n%s', pp.pformat(nlte_section)) if not nlte_validated_config_dict: nlte_validated_config_dict['species'] = [] plasma_section['nlte'] = nlte_validated_config_dict #^^^^^^^^^^^^^^ End of Plasma Section ##### Monte Carlo Section montecarlo_section = validated_config_dict['montecarlo'] montecarlo_section['no_of_packets'] = \ int(montecarlo_section['no_of_packets']) montecarlo_section['last_no_of_packets'] = \ int(montecarlo_section['last_no_of_packets']) if montecarlo_section['last_no_of_packets'] < 0: montecarlo_section['last_no_of_packets'] = \ montecarlo_section['no_of_packets'] montecarlo_section['convergence_strategy'] = ( parse_convergence_section( montecarlo_section['convergence_strategy'])) black_body_section = montecarlo_section['black_body_sampling'] montecarlo_section['black_body_sampling'] = {} montecarlo_section['black_body_sampling']['start'] = \ black_body_section['start'] montecarlo_section['black_body_sampling']['end'] = \ black_body_section['stop'] montecarlo_section['black_body_sampling']['samples'] = \ black_body_section['num'] virtual_spectrum_section = montecarlo_section['virtual_spectrum_range'] montecarlo_section['virtual_spectrum_range'] = {} montecarlo_section['virtual_spectrum_range']['start'] = \ virtual_spectrum_section['start'] montecarlo_section['virtual_spectrum_range']['end'] = \ virtual_spectrum_section['stop'] montecarlo_section['virtual_spectrum_range']['samples'] = \ virtual_spectrum_section['num'] ###### END of convergence section reading validated_config_dict['spectrum'] = parse_spectrum_list2dict( validated_config_dict['spectrum']) return cls(validated_config_dict, atom_data)
def from_csvy(cls, config): """ Create a new Radial1DModel instance from a Configuration object. Parameters ---------- config : tardis.io.config_reader.Configuration Returns ------- Radial1DModel """ if os.path.isabs(config.csvy_model): csvy_model_fname = config.csvy_model else: csvy_model_fname = os.path.join(config.config_dirname, config.csvy_model) csvy_model_config, csvy_model_data = load_csvy(csvy_model_fname) base_dir = os.path.abspath(os.path.dirname(__file__)) schema_dir = os.path.join(base_dir, '..', 'io', 'schemas') csvy_schema_file = os.path.join(schema_dir, 'csvy_model.yml') csvy_model_config = Configuration( validate_dict(csvy_model_config, schemapath=csvy_schema_file)) time_explosion = config.supernova.time_explosion.cgs electron_densities = None temperature = None if hasattr(csvy_model_config, 'v_inner_boundary'): v_boundary_inner = csvy_model_config.v_inner_boundary else: v_boundary_inner = None if hasattr(csvy_model_config, 'v_outer_boundary'): v_boundary_outer = csvy_model_config.v_outer_boundary else: v_boundary_outer = None if hasattr(csvy_model_config, 'velocity'): velocity = quantity_linspace(csvy_model_config.velocity.start, csvy_model_config.velocity.stop, csvy_model_config.velocity.num + 1).cgs else: velocity_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('velocity') velocity_unit = u.Unit( csvy_model_config.datatype.fields[velocity_field_index] ['unit']) velocity = csvy_model_data['velocity'].values * velocity_unit velocity = velocity.to('cm/s') if hasattr(csvy_model_config, 'density'): homologous_density = HomologousDensity.from_csvy( config, csvy_model_config) else: time_0 = csvy_model_config.model_density_time_0 density_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('density') density_unit = u.Unit( csvy_model_config.datatype.fields[density_field_index]['unit']) density_0 = csvy_model_data['density'].values * density_unit density_0 = density_0.to('g/cm^3')[1:] density_0 = density_0.insert(0, 0) homologous_density = HomologousDensity(density_0, time_0) no_of_shells = len(velocity) - 1 # TODO -- implement t_radiative #t_radiative = None if temperature: t_radiative = temperature elif hasattr(csvy_model_data, 'columns'): if 't_rad' in csvy_model_data.columns: t_rad_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('t_rad') t_rad_unit = u.Unit( csvy_model_config.datatype.fields[t_rad_field_index] ['unit']) t_radiative = csvy_model_data['t_rad'].iloc[ 0:].values * t_rad_unit else: t_radiative = None dilution_factor = None if hasattr(csvy_model_data, 'columns'): if 'w' in csvy_model_data.columns: dilution_factor = csvy_model_data['w'].iloc[0:].to_numpy() elif config.plasma.initial_t_rad > 0 * u.K: t_radiative = np.ones(no_of_shells) * config.plasma.initial_t_rad else: t_radiative = None if config.plasma.initial_t_inner < 0.0 * u.K: luminosity_requested = config.supernova.luminosity_requested t_inner = None else: luminosity_requested = None t_inner = config.plasma.initial_t_inner if hasattr(csvy_model_config, 'abundance'): abundances_section = csvy_model_config.abundance abundance, isotope_abundance = read_uniform_abundances( abundances_section, no_of_shells) else: index, abundance, isotope_abundance = parse_csv_abundances( csvy_model_data) abundance = abundance.replace(np.nan, 0.0) abundance = abundance[abundance.sum(axis=1) > 0] norm_factor = abundance.sum(axis=0) + isotope_abundance.sum(axis=0) if np.any(np.abs(norm_factor - 1) > 1e-12): logger.warning("Abundances have not been normalized to 1." " - normalizing") abundance /= norm_factor isotope_abundance /= norm_factor #isotope_abundance = IsotopeAbundances(isotope_abundance) isotope_abundance = IsotopeAbundances( isotope_abundance, time_0=csvy_model_config.model_isotope_time_0) #isotope_abundance.time_0 = csvy_model_config.model_isotope_time_0 return cls(velocity=velocity, homologous_density=homologous_density, abundance=abundance, isotope_abundance=isotope_abundance, time_explosion=time_explosion, t_radiative=t_radiative, t_inner=t_inner, luminosity_requested=luminosity_requested, dilution_factor=dilution_factor, v_boundary_inner=v_boundary_inner, v_boundary_outer=v_boundary_outer, electron_densities=electron_densities)
def from_csvy(cls, config): """ Create a new Radial1DModel instance from a Configuration object. Parameters ---------- config : tardis.io.config_reader.Configuration Returns ------- Radial1DModel """ CSVY_SUPPORTED_COLUMNS = { 'velocity', 'density', 't_rad', 'dilution_factor' } if os.path.isabs(config.csvy_model): csvy_model_fname = config.csvy_model else: csvy_model_fname = os.path.join(config.config_dirname, config.csvy_model) csvy_model_config, csvy_model_data = load_csvy(csvy_model_fname) base_dir = os.path.abspath(os.path.dirname(__file__)) schema_dir = os.path.join(base_dir, '..', 'io', 'schemas') csvy_schema_file = os.path.join(schema_dir, 'csvy_model.yml') csvy_model_config = Configuration( validate_dict(csvy_model_config, schemapath=csvy_schema_file)) if hasattr(csvy_model_data, 'columns'): abund_names = set([ name for name in csvy_model_data.columns if nucname.iselement(name) or nucname.isnuclide(name) ]) unsupported_columns = set( csvy_model_data.columns) - abund_names - CSVY_SUPPORTED_COLUMNS field_names = set( [field['name'] for field in csvy_model_config.datatype.fields]) assert set(csvy_model_data.columns) - field_names == set(),\ 'CSVY columns exist without field descriptions' assert field_names - set(csvy_model_data.columns) == set(),\ 'CSVY field descriptions exist without corresponding csv data' if unsupported_columns != set(): logger.warning( "The following columns are specified in the csvy" "model file, but are IGNORED by TARDIS: %s" % (str(unsupported_columns))) time_explosion = config.supernova.time_explosion.cgs electron_densities = None temperature = None #if hasattr(csvy_model_config, 'v_inner_boundary'): # v_boundary_inner = csvy_model_config.v_inner_boundary #else: # v_boundary_inner = None #if hasattr(csvy_model_config, 'v_outer_boundary'): # v_boundary_outer = csvy_model_config.v_outer_boundary #else: # v_boundary_outer = None if hasattr(config, 'model'): if hasattr(config.model, 'v_inner_boundary'): v_boundary_inner = config.model.v_inner_boundary else: v_boundary_inner = None if hasattr(config.model, 'v_outer_boundary'): v_boundary_outer = config.model.v_outer_boundary else: v_boundary_outer = None else: v_boundary_inner = None v_boundary_outer = None if hasattr(csvy_model_config, 'velocity'): velocity = quantity_linspace(csvy_model_config.velocity.start, csvy_model_config.velocity.stop, csvy_model_config.velocity.num + 1).cgs else: velocity_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('velocity') velocity_unit = u.Unit( csvy_model_config.datatype.fields[velocity_field_index] ['unit']) velocity = csvy_model_data['velocity'].values * velocity_unit velocity = velocity.to('cm/s') if hasattr(csvy_model_config, 'density'): homologous_density = HomologousDensity.from_csvy( config, csvy_model_config) else: time_0 = csvy_model_config.model_density_time_0 density_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('density') density_unit = u.Unit( csvy_model_config.datatype.fields[density_field_index]['unit']) density_0 = csvy_model_data['density'].values * density_unit density_0 = density_0.to('g/cm^3')[1:] density_0 = density_0.insert(0, 0) homologous_density = HomologousDensity(density_0, time_0) no_of_shells = len(velocity) - 1 # TODO -- implement t_radiative #t_radiative = None if temperature: t_radiative = temperature elif hasattr(csvy_model_data, 'columns'): if 't_rad' in csvy_model_data.columns: t_rad_field_index = [ field['name'] for field in csvy_model_config.datatype.fields ].index('t_rad') t_rad_unit = u.Unit( csvy_model_config.datatype.fields[t_rad_field_index] ['unit']) t_radiative = csvy_model_data['t_rad'].iloc[ 0:].values * t_rad_unit else: t_radiative = None dilution_factor = None if hasattr(csvy_model_data, 'columns'): if 'dilution_factor' in csvy_model_data.columns: dilution_factor = csvy_model_data['dilution_factor'].iloc[ 0:].to_numpy() elif config.plasma.initial_t_rad > 0 * u.K: t_radiative = np.ones(no_of_shells) * config.plasma.initial_t_rad else: t_radiative = None if config.plasma.initial_t_inner < 0.0 * u.K: luminosity_requested = config.supernova.luminosity_requested t_inner = None else: luminosity_requested = None t_inner = config.plasma.initial_t_inner if hasattr(csvy_model_config, 'abundance'): abundances_section = csvy_model_config.abundance abundance, isotope_abundance = read_uniform_abundances( abundances_section, no_of_shells) else: index, abundance, isotope_abundance = parse_csv_abundances( csvy_model_data) abundance = abundance.replace(np.nan, 0.0) abundance = abundance[abundance.sum(axis=1) > 0] abundance = abundance.loc[:, 1:] abundance.columns = np.arange(abundance.shape[1]) norm_factor = abundance.sum(axis=0) + isotope_abundance.sum(axis=0) if np.any(np.abs(norm_factor - 1) > 1e-12): logger.warning("Abundances have not been normalized to 1." " - normalizing") abundance /= norm_factor isotope_abundance /= norm_factor #isotope_abundance = IsotopeAbundances(isotope_abundance) isotope_abundance = IsotopeAbundances( isotope_abundance, time_0=csvy_model_config.model_isotope_time_0) #isotope_abundance.time_0 = csvy_model_config.model_isotope_time_0 return cls(velocity=velocity, homologous_density=homologous_density, abundance=abundance, isotope_abundance=isotope_abundance, time_explosion=time_explosion, t_radiative=t_radiative, t_inner=t_inner, luminosity_requested=luminosity_requested, dilution_factor=dilution_factor, v_boundary_inner=v_boundary_inner, v_boundary_outer=v_boundary_outer, electron_densities=electron_densities)
def from_config_dict(cls, config_dict, validate=True, config_dirname=""): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : dict dictionary of a raw unvalidated config file validate : bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict validated_config_dict["config_dirname"] = config_dirname # Montecarlo Section Implementation montecarlo_section = validated_config_dict["montecarlo"] if montecarlo_section["convergence_strategy"]["type"] == "damped": montecarlo_section[ "convergence_strategy" ] = parse_convergence_section( montecarlo_section["convergence_strategy"] ) elif montecarlo_section["convergence_strategy"]["type"] == "custom": raise NotImplementedError( 'convergence_strategy is set to "custom"; ' "you need to implement your specific convergence treatment" ) else: raise ValueError( 'convergence_strategy is not "damped" ' 'or "custom"' ) enable_full_relativity = montecarlo_section["enable_full_relativity"] spectrum_integrated = ( validated_config_dict["spectrum"]["method"] == "integrated" ) if enable_full_relativity and spectrum_integrated: raise NotImplementedError( "The spectrum method is set to 'integrated' and " "enable_full_relativity to 'True'.\n" "The FormalIntegrator is not yet implemented for the full " "relativity mode. " ) if "csvy_model" in validated_config_dict.keys(): pass elif "model" in validated_config_dict.keys(): # Model Section Validation model_section = validated_config_dict["model"] if model_section["structure"]["type"] == "specific": start_velocity = model_section["structure"]["velocity"]["start"] stop_velocity = model_section["structure"]["velocity"]["stop"] if stop_velocity.value < start_velocity.value: raise ValueError( "Stop Velocity Cannot Be Less than Start Velocity. \n" f"Start Velocity = {start_velocity} \n" f"Stop Velocity = {stop_velocity}" ) elif model_section["structure"]["type"] == "file": v_inner_boundary = model_section["structure"][ "v_inner_boundary" ] v_outer_boundary = model_section["structure"][ "v_outer_boundary" ] if v_outer_boundary.value < v_inner_boundary.value: raise ValueError( "Outer Boundary Velocity Cannot Be Less than Inner Boundary Velocity. \n" f"Inner Boundary Velocity = {v_inner_boundary} \n" f"Outer Boundary Velocity = {v_outer_boundary}" ) if "density" in model_section["structure"].keys(): if ( model_section["structure"]["density"]["type"] == "exponential" ): rho_0 = model_section["structure"]["density"]["rho_0"] v_0 = model_section["structure"]["density"]["v_0"] if not rho_0.value > 0: raise ValueError( f"Density Specified is Invalid, {rho_0}" ) if not v_0.value > 0: raise ValueError( f"Velocity Specified is Invalid, {v_0}" ) if "time_0" in model_section["structure"]["density"].keys(): time_0 = model_section["structure"]["density"]["time_0"] if not time_0.value > 0: raise ValueError( f"Time Specified is Invalid, {time_0}" ) elif ( model_section["structure"]["density"]["type"] == "power_law" ): rho_0 = model_section["structure"]["density"]["rho_0"] v_0 = model_section["structure"]["density"]["v_0"] if not rho_0.value > 0: raise ValueError( f"Density Specified is Invalid, {rho_0}" ) if not v_0.value > 0: raise ValueError( f"Velocity Specified is Invalid, {v_0}" ) if "time_0" in model_section["structure"]["density"].keys(): time_0 = model_section["structure"]["density"]["time_0"] if not time_0.value > 0: raise ValueError( f"Time Specified is Invalid, {time_0}" ) elif model_section["structure"]["density"]["type"] == "uniform": value = model_section["structure"]["density"]["value"] if not value.value > 0: raise ValueError( f"Density Value Specified is Invalid, {value}" ) if "time_0" in model_section["structure"]["density"].keys(): time_0 = model_section["structure"]["density"]["time_0"] if not time_0.value > 0: raise ValueError( f"Time Specified is Invalid, {time_0}" ) # SuperNova Section Validation supernova_section = validated_config_dict["supernova"] time_explosion = supernova_section["time_explosion"] luminosity_wavelength_start = supernova_section[ "luminosity_wavelength_start" ] luminosity_wavelength_end = supernova_section[ "luminosity_wavelength_end" ] if not time_explosion.value > 0: raise ValueError( f"Time Of Explosion is Invalid, {time_explosion}" ) if ( luminosity_wavelength_start.value > luminosity_wavelength_end.value ): raise ValueError( "Integral Limits for Luminosity Wavelength are Invalid, Start Limit > End Limit \n" f"Luminosity Wavelength Start : {luminosity_wavelength_start} \n" f"Luminosity Wavelength End : {luminosity_wavelength_end}" ) # Plasma Section Validation plasma_section = validated_config_dict["plasma"] initial_t_inner = plasma_section["initial_t_inner"] initial_t_rad = plasma_section["initial_t_rad"] if not initial_t_inner.value >= -1: raise ValueError( f"Initial Temperature of Inner Boundary Black Body is Invalid, {initial_t_inner}" ) if not initial_t_rad.value >= -1: raise ValueError( f"Initial Radiative Temperature is Invalid, {initial_t_inner}" ) # Spectrum Section Validation spectrum_section = validated_config_dict["spectrum"] start = spectrum_section["start"] stop = spectrum_section["stop"] if start.value > stop.value: raise ValueError( "Start Value of Spectrum Cannot be Greater than Stop Value. \n" f"Start : {start} \n" f"Stop : {stop}" ) return cls(validated_config_dict)
def from_config_dict(cls, config_dict, atom_data=None, test_parser=False, validate=True, config_dirname=''): """ Validating and subsequently parsing a config file. Parameters ---------- config_dict : ~dict dictionary of a raw unvalidated config file atom_data: ~tardis.atomic.AtomData atom data object. if `None` will be tried to be read from atom data file path in the config_dict [default=None] test_parser: ~bool switch on to ignore a working atom_data, mainly useful for testing this reader validate: ~bool Turn validation on or off. Returns ------- `tardis.config_reader.Configuration` """ if validate: validated_config_dict = config_validator.validate_dict(config_dict) else: validated_config_dict = config_dict #First let's see if we can find an atom_db anywhere: if test_parser: atom_data = None elif 'atom_data' in validated_config_dict.keys(): if os.path.isabs(validated_config_dict['atom_data']): atom_data_fname = validated_config_dict['atom_data'] else: atom_data_fname = os.path.join(config_dirname, validated_config_dict['atom_data']) validated_config_dict['atom_data_fname'] = atom_data_fname else: raise ConfigurationError('No atom_data key found in config or command line') if atom_data is None and not test_parser: logger.info('Reading Atomic Data from %s', atom_data_fname) atom_data = atomic.AtomData.from_hdf5(atom_data_fname) else: atom_data = atom_data #Parsing supernova dictionary validated_config_dict['supernova']['luminosity_nu_start'] = \ validated_config_dict['supernova']['luminosity_wavelength_end'].to( u.Hz, u.spectral()) try: validated_config_dict['supernova']['luminosity_nu_end'] = \ (validated_config_dict['supernova'] ['luminosity_wavelength_start'].to(u.Hz, u.spectral())) except ZeroDivisionError: validated_config_dict['supernova']['luminosity_nu_end'] = ( np.inf * u.Hz) validated_config_dict['supernova']['time_explosion'] = ( validated_config_dict['supernova']['time_explosion'].cgs) validated_config_dict['supernova']['luminosity_requested'] = ( validated_config_dict['supernova']['luminosity_requested'].cgs) #Parsing the model section model_section = validated_config_dict['model'] v_inner = None v_outer = None mean_densities = None abundances = None structure_section = model_section['structure'] if structure_section['type'] == 'specific': velocity = model_section['structure']['velocity'] start, stop, num = velocity['start'], velocity['stop'], \ velocity['num'] num += 1 velocities = quantity_linspace(start, stop, num) v_inner, v_outer = velocities[:-1], velocities[1:] mean_densities = parse_density_section( model_section['structure']['density'], v_inner, v_outer, validated_config_dict['supernova']['time_explosion']).cgs elif structure_section['type'] == 'file': if os.path.isabs(structure_section['filename']): structure_fname = structure_section['filename'] else: structure_fname = os.path.join(config_dirname, structure_section['filename']) v_inner, v_outer, mean_densities, inner_boundary_index, \ outer_boundary_index = read_density_file( structure_fname, structure_section['filetype'], validated_config_dict['supernova']['time_explosion'], structure_section['v_inner_boundary'], structure_section['v_outer_boundary']) r_inner = validated_config_dict['supernova']['time_explosion'] * v_inner r_outer = validated_config_dict['supernova']['time_explosion'] * v_outer r_middle = 0.5 * (r_inner + r_outer) structure_section['v_inner'] = v_inner.cgs structure_section['v_outer'] = v_outer.cgs structure_section['mean_densities'] = mean_densities.cgs no_of_shells = len(v_inner) structure_section['no_of_shells'] = no_of_shells structure_section['r_inner'] = r_inner.cgs structure_section['r_outer'] = r_outer.cgs structure_section['r_middle'] = r_middle.cgs structure_section['volumes'] = ((4. / 3) * np.pi * \ (r_outer ** 3 - r_inner ** 3)).cgs #### TODO the following is legacy code and should be removed validated_config_dict['structure'] = \ validated_config_dict['model']['structure'] # ^^^^^^^^^^^^^^^^ abundances_section = model_section['abundances'] if abundances_section['type'] == 'uniform': abundances = pd.DataFrame(columns=np.arange(no_of_shells), index=pd.Index(np.arange(1, 120), name='atomic_number'), dtype=np.float64) for element_symbol_string in abundances_section: if element_symbol_string == 'type': continue z = element_symbol2atomic_number(element_symbol_string) abundances.ix[z] = float(abundances_section[element_symbol_string]) elif abundances_section['type'] == 'file': if os.path.isabs(abundances_section['filename']): abundances_fname = abundances_section['filename'] else: abundances_fname = os.path.join(config_dirname, abundances_section['filename']) index, abundances = read_abundances_file(abundances_fname, abundances_section['filetype'], inner_boundary_index, outer_boundary_index) if len(index) != no_of_shells: raise ConfigurationError('The abundance file specified has not the same number of cells' 'as the specified density profile') abundances = abundances.replace(np.nan, 0.0) abundances = abundances[abundances.sum(axis=1) > 0] norm_factor = abundances.sum(axis=0) if np.any(np.abs(norm_factor - 1) > 1e-12): logger.warning("Abundances have not been normalized to 1. - normalizing") abundances /= norm_factor validated_config_dict['abundances'] = abundances ########### DOING PLASMA SECTION ############### plasma_section = validated_config_dict['plasma'] if plasma_section['initial_t_inner'] < 0.0 * u.K: luminosity_requested = validated_config_dict['supernova']['luminosity_requested'] plasma_section['t_inner'] = ((luminosity_requested / (4 * np.pi * r_inner[0] ** 2 * constants.sigma_sb)) ** .25).to('K') logger.info('"initial_t_inner" is not specified in the plasma ' 'section - initializing to %s with given luminosity', plasma_section['t_inner']) else: plasma_section['t_inner'] = plasma_section['initial_t_inner'] if plasma_section['initial_t_rad'] > 0 * u.K: plasma_section['t_rads'] = np.ones(no_of_shells) * \ plasma_section['initial_t_rad'] else: plasma_section['t_rads'] = None if plasma_section['disable_electron_scattering'] is False: logger.debug("Electron scattering switched on") validated_config_dict['montecarlo']['sigma_thomson'] = 6.652486e-25 / (u.cm ** 2) else: logger.warn('Disabling electron scattering - this is not physical') validated_config_dict['montecarlo']['sigma_thomson'] = 1e-200 / (u.cm ** 2) if plasma_section['helium_treatment'] == 'recomb-nlte': validated_config_dict['plasma']['helium_treatment'] == 'recomb-nlte' else: validated_config_dict['plasma']['helium_treatment'] == 'dilute-lte' ##### NLTE subsection of Plasma start nlte_validated_config_dict = {} nlte_species = [] nlte_section = plasma_section['nlte'] nlte_species_list = nlte_section.pop('species') for species_string in nlte_species_list: nlte_species.append(species_string_to_tuple(species_string)) nlte_validated_config_dict['species'] = nlte_species nlte_validated_config_dict['species_string'] = nlte_species_list nlte_validated_config_dict.update(nlte_section) if 'coronal_approximation' not in nlte_section: logger.debug('NLTE "coronal_approximation" not specified in NLTE section - defaulting to False') nlte_validated_config_dict['coronal_approximation'] = False if 'classical_nebular' not in nlte_section: logger.debug('NLTE "classical_nebular" not specified in NLTE section - defaulting to False') nlte_validated_config_dict['classical_nebular'] = False elif nlte_section: #checks that the dictionary is not empty logger.warn('No "species" given - ignoring other NLTE options given:\n%s', pp.pformat(nlte_section)) if not nlte_validated_config_dict: nlte_validated_config_dict['species'] = [] plasma_section['nlte'] = nlte_validated_config_dict #^^^^^^^^^^^^^^ End of Plasma Section ##### Monte Carlo Section montecarlo_section = validated_config_dict['montecarlo'] montecarlo_section['no_of_packets'] = \ int(montecarlo_section['no_of_packets']) montecarlo_section['last_no_of_packets'] = \ int(montecarlo_section['last_no_of_packets']) if montecarlo_section['last_no_of_packets'] < 0: montecarlo_section['last_no_of_packets'] = \ montecarlo_section['no_of_packets'] montecarlo_section['convergence_strategy'] = ( parse_convergence_section( montecarlo_section['convergence_strategy'])) black_body_section = montecarlo_section['black_body_sampling'] montecarlo_section['black_body_sampling'] = {} montecarlo_section['black_body_sampling']['start'] = \ black_body_section['start'] montecarlo_section['black_body_sampling']['end'] = \ black_body_section['stop'] montecarlo_section['black_body_sampling']['samples'] = \ black_body_section['num'] virtual_spectrum_section = montecarlo_section['virtual_spectrum_range'] montecarlo_section['virtual_spectrum_range'] = {} montecarlo_section['virtual_spectrum_range']['start'] = \ virtual_spectrum_section['start'] montecarlo_section['virtual_spectrum_range']['end'] = \ virtual_spectrum_section['stop'] montecarlo_section['virtual_spectrum_range']['samples'] = \ virtual_spectrum_section['num'] ###### END of convergence section reading validated_config_dict['spectrum'] = parse_spectrum_list2dict( validated_config_dict['spectrum']) return cls(validated_config_dict, atom_data)
def from_csvy(cls, config): """ Create a new Radial1DModel instance from a Configuration object. Parameters ---------- config : tardis.io.config_reader.Configuration Returns ------- Radial1DModel """ CSVY_SUPPORTED_COLUMNS = { "velocity", "density", "t_rad", "dilution_factor", } if os.path.isabs(config.csvy_model): csvy_model_fname = config.csvy_model else: csvy_model_fname = os.path.join( config.config_dirname, config.csvy_model ) csvy_model_config, csvy_model_data = load_csvy(csvy_model_fname) base_dir = os.path.abspath(os.path.dirname(__file__)) schema_dir = os.path.join(base_dir, "..", "io", "schemas") csvy_schema_file = os.path.join(schema_dir, "csvy_model.yml") csvy_model_config = Configuration( validate_dict(csvy_model_config, schemapath=csvy_schema_file) ) if hasattr(csvy_model_data, "columns"): abund_names = set( [ name for name in csvy_model_data.columns if is_valid_nuclide_or_elem(name) ] ) unsupported_columns = ( set(csvy_model_data.columns) - abund_names - CSVY_SUPPORTED_COLUMNS ) field_names = set( [field["name"] for field in csvy_model_config.datatype.fields] ) assert ( set(csvy_model_data.columns) - field_names == set() ), "CSVY columns exist without field descriptions" assert ( field_names - set(csvy_model_data.columns) == set() ), "CSVY field descriptions exist without corresponding csv data" if unsupported_columns != set(): logger.warning( "The following columns are " "specified in the csvy model file," f" but are IGNORED by TARDIS: {str(unsupported_columns)}" ) time_explosion = config.supernova.time_explosion.cgs electron_densities = None temperature = None # if hasattr(csvy_model_config, 'v_inner_boundary'): # v_boundary_inner = csvy_model_config.v_inner_boundary # else: # v_boundary_inner = None # if hasattr(csvy_model_config, 'v_outer_boundary'): # v_boundary_outer = csvy_model_config.v_outer_boundary # else: # v_boundary_outer = None if hasattr(config, "model"): if hasattr(config.model, "v_inner_boundary"): v_boundary_inner = config.model.v_inner_boundary else: v_boundary_inner = None if hasattr(config.model, "v_outer_boundary"): v_boundary_outer = config.model.v_outer_boundary else: v_boundary_outer = None else: v_boundary_inner = None v_boundary_outer = None if hasattr(csvy_model_config, "velocity"): velocity = quantity_linspace( csvy_model_config.velocity.start, csvy_model_config.velocity.stop, csvy_model_config.velocity.num + 1, ).cgs else: velocity_field_index = [ field["name"] for field in csvy_model_config.datatype.fields ].index("velocity") velocity_unit = u.Unit( csvy_model_config.datatype.fields[velocity_field_index]["unit"] ) velocity = csvy_model_data["velocity"].values * velocity_unit velocity = velocity.to("cm/s") if hasattr(csvy_model_config, "density"): homologous_density = HomologousDensity.from_csvy( config, csvy_model_config ) else: time_0 = csvy_model_config.model_density_time_0 density_field_index = [ field["name"] for field in csvy_model_config.datatype.fields ].index("density") density_unit = u.Unit( csvy_model_config.datatype.fields[density_field_index]["unit"] ) density_0 = csvy_model_data["density"].values * density_unit density_0 = density_0.to("g/cm^3")[1:] density_0 = density_0.insert(0, 0) homologous_density = HomologousDensity(density_0, time_0) no_of_shells = len(velocity) - 1 # TODO -- implement t_radiative # t_radiative = None if temperature: t_radiative = temperature elif hasattr(csvy_model_data, "columns"): if "t_rad" in csvy_model_data.columns: t_rad_field_index = [ field["name"] for field in csvy_model_config.datatype.fields ].index("t_rad") t_rad_unit = u.Unit( csvy_model_config.datatype.fields[t_rad_field_index]["unit"] ) t_radiative = ( csvy_model_data["t_rad"].iloc[0:].values * t_rad_unit ) else: t_radiative = None dilution_factor = None if hasattr(csvy_model_data, "columns"): if "dilution_factor" in csvy_model_data.columns: dilution_factor = ( csvy_model_data["dilution_factor"].iloc[0:].to_numpy() ) elif config.plasma.initial_t_rad > 0 * u.K: t_radiative = np.ones(no_of_shells) * config.plasma.initial_t_rad else: t_radiative = None if config.plasma.initial_t_inner < 0.0 * u.K: luminosity_requested = config.supernova.luminosity_requested t_inner = None else: luminosity_requested = None t_inner = config.plasma.initial_t_inner if hasattr(csvy_model_config, "abundance"): abundances_section = csvy_model_config.abundance abundance, isotope_abundance = read_uniform_abundances( abundances_section, no_of_shells ) else: index, abundance, isotope_abundance = parse_csv_abundances( csvy_model_data ) abundance = abundance.loc[:, 1:] abundance.columns = np.arange(abundance.shape[1]) isotope_abundance = isotope_abundance.loc[:, 1:] isotope_abundance.columns = np.arange(isotope_abundance.shape[1]) abundance = abundance.replace(np.nan, 0.0) abundance = abundance[abundance.sum(axis=1) > 0] isotope_abundance = isotope_abundance.replace(np.nan, 0.0) isotope_abundance = isotope_abundance[isotope_abundance.sum(axis=1) > 0] norm_factor = abundance.sum(axis=0) + isotope_abundance.sum(axis=0) if np.any(np.abs(norm_factor - 1) > 1e-12): logger.warning( "Abundances have not been normalized to 1." " - normalizing" ) abundance /= norm_factor isotope_abundance /= norm_factor # isotope_abundance = IsotopeAbundances(isotope_abundance) isotope_abundance = IsotopeAbundances( isotope_abundance, time_0=csvy_model_config.model_isotope_time_0 ) # isotope_abundance.time_0 = csvy_model_config.model_isotope_time_0 return cls( velocity=velocity, homologous_density=homologous_density, abundance=abundance, isotope_abundance=isotope_abundance, time_explosion=time_explosion, t_radiative=t_radiative, t_inner=t_inner, luminosity_requested=luminosity_requested, dilution_factor=dilution_factor, v_boundary_inner=v_boundary_inner, v_boundary_outer=v_boundary_outer, electron_densities=electron_densities, )