def get_flux(self, model_param: Dict[str, float], synphot=None): """ Function for calculating the average flux density for the ``filter_name``. Parameters ---------- model_param : dict Model parameters and values. synphot : species.analysis.photometry.SyntheticPhotometry, None Synthetic photometry object. The object is created if set to None. Returns ------- float Average flux (W m-2 um-1). float, None Uncertainty (W m-2 um-1), which is set to ``None``. """ for key in self.get_parameters(): if key not in model_param.keys(): raise ValueError(f'The \'{key}\' parameter is required by \'{self.model}\'. ' f'The mandatory parameters are {self.get_parameters()}.') if self.spectrum_interp is None: self.interpolate_model() spectrum = self.get_model(model_param) if synphot is None: synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_flux(spectrum.wavelength, spectrum.flux)
def get_magnitude(self, model_param: Dict[str, Union[float, List[float]]], synphot=None) -> Tuple[Tuple[float, None], Tuple[float, None]]: """ Function for calculating the magnitude for the ``filter_name``. Parameters ---------- model_param : dict Dictionary with the 'teff' (K), 'radius' (Rjup), and 'distance' (pc). synphot : species.analysis.photometry.SyntheticPhotometry, None Synthetic photometry object. The object is created if set to None. Returns ------- float Apparent magnitude (mag). float Absolute magnitude (mag) """ if 'teff' in model_param and isinstance(model_param['teff'], list): model_param = self.update_parameters(model_param) spectrum = self.get_spectrum(model_param, 100.) if synphot is None: synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_magnitude(spectrum.wavelength, spectrum.flux, distance=(model_param['distance'], None))
def get_flux( self, model_param: Optional[Dict[str, float]] = None) -> Tuple[float, float]: """ Function for calculating the average flux for the ``filter_name``. Parameters ---------- model_param : dict, None Model parameters. Should contain the 'scaling' value. Not used if set to ``None``. Returns ------- Returns ------- float Average flux (W m-2 um-1). float Uncertainty (W m-2 um-1). """ specbox = self.get_spectrum(model_param=model_param, apply_mask=True) synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_flux(specbox.wavelength, specbox.flux, error=specbox.flux)
def get_magnitude( self, model_param: Optional[Dict[str, float]] = None, distance: Optional[Tuple[float, float]] = None ) -> Tuple[Tuple[float, float], Tuple[Optional[float], Optional[float]]]: """ Function for calculating the apparent magnitude for the ``filter_name``. Parameters ---------- model_param : dict, None Model parameters. Should contain the 'scaling' value. Not used if set to ``None``. distance : tuple(float, float), None Distance and uncertainty to the calibration object (pc). Not used if set to ``None``, in which case the returned absolute magnitude is ``(None, None)``. Returns ------- tuple(float, float) Apparent magnitude and uncertainty. tuple(float, float), tuple(None, None) Absolute magnitude and uncertainty. """ specbox = self.get_spectrum(model_param=model_param) synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_magnitude(specbox.wavelength, specbox.flux, error=specbox.error, distance=distance)
def get_magnitude(self, model_par): """ Parameters ---------- model_par : dict Model parameter values. Returns ------- float Apparent magnitude (mag). float Absolute magnitude (mag). """ if self.spectrum_interp is None: self.interpolate() spectrum = self.get_model(model_par, None) synphot = photometry.SyntheticPhotometry(self.filter_name) if 'distance' in model_par: app_mag, abs_mag = synphot.spectrum_to_magnitude( spectrum.wavelength, spectrum.flux, model_par['distance']) else: app_mag, abs_mag = synphot.spectrum_to_magnitude( spectrum.wavelength, spectrum.flux, None) return app_mag, abs_mag
def get_photometry(self, model_par, synphot=None): """ Parameters ---------- model_par : dict Model parameter values. synphot : species.analysis.photometry.SyntheticPhotometry Synthetic photometry object. Returns ------- float Average flux density (W m-2 micron-1). """ if self.spectrum_interp is None: self.interpolate() spectrum = self.get_model(model_par, None) if not synphot: synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_photometry(spectrum.wavelength, spectrum.flux)
def get_flux(self, model_param: Dict[str, Union[float, List[float]]], synphot=None) -> Tuple[float, None]: """ Function for calculating the average flux density for the ``filter_name``. Parameters ---------- model_param : dict Dictionary with the 'teff' (K), 'radius' (Rjup), and 'distance' (pc). synphot : species.analysis.photometry.SyntheticPhotometry, None Synthetic photometry object. The object is created if set to None. Returns ------- float Average flux density (W m-2 um-1). NoneType None """ if 'teff' in model_param and isinstance(model_param['teff'], list): model_param = self.update_parameters(model_param) spectrum = self.get_spectrum(model_param, 100.) if synphot is None: synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_flux(spectrum.wavelength, spectrum.flux)
def multi_photometry(datatype: str, spectrum: str, filters: List[str], parameters: Dict[str, float]) -> box.SynphotBox: """ Parameters ---------- datatype : str Data type ('model' or 'calibration'). spectrum : str Spectrum name (e.g., 'drift-phoenix', 'planck', 'powerlaw'). filters : list(str, ) List with the filter names. parameters : dict Dictionary with the model parameters. Returns ------- species.core.box.SynphotBox Box with synthetic photometry. """ print('Calculating synthetic photometry...', end='', flush=True) flux = {} if datatype == 'model': for item in filters: if spectrum == 'planck': readmodel = read_planck.ReadPlanck(filter_name=item) elif spectrum == 'powerlaw': synphot = photometry.SyntheticPhotometry(item) synphot.zero_point() # Set the wavel_range attribute powerl_box = read_util.powerlaw_spectrum(synphot.wavel_range, parameters) flux[item] = synphot.spectrum_to_flux(powerl_box.wavelength, powerl_box.flux)[0] else: readmodel = read_model.ReadModel(spectrum, filter_name=item) try: flux[item] = readmodel.get_flux(parameters)[0] except IndexError: flux[item] = np.nan warnings.warn(f'The wavelength range of the {item} filter does not match with ' f'the wavelength range of {spectrum}. The flux is set to NaN.') elif datatype == 'calibration': for item in filters: readcalib = read_calibration.ReadCalibration(spectrum, filter_name=item) flux[item] = readcalib.get_flux(parameters)[0] print(' [DONE]') return box.create_box('synphot', name='synphot', flux=flux)
def get_magnitude( self, model_param: Dict[str, float]) -> Tuple[float, Optional[float]]: """ Function for calculating the apparent and absolute magnitudes for the ``filter_name``. Parameters ---------- model_param : dict Model parameters and values. Returns ------- float Apparent magnitude. float, None Absolute magnitude. A ``None`` is returned if the ``model_param`` do not contain a ``radius`` and ``distance``. """ for key in self.get_parameters(): if key not in model_param.keys(): raise ValueError( f'The \'{key}\' parameter is required by \'{self.model}\'. ' f'The mandatory parameters are {self.get_parameters()}.') if self.spectrum_interp is None: self.interpolate_model() try: spectrum = self.get_model(model_param) except ValueError: warnings.warn( f'The set of model parameters {model_param} is outside the grid range ' f'{self.get_bounds()} so returning a NaN.') return np.nan, np.nan if spectrum.wavelength.size == 0: app_mag = np.nan abs_mag = np.nan else: synphot = photometry.SyntheticPhotometry(self.filter_name) if 'distance' in model_param: app_mag, abs_mag = synphot.spectrum_to_magnitude( spectrum.wavelength, spectrum.flux, distance=(model_param['distance'], None)) else: app_mag, abs_mag = synphot.spectrum_to_magnitude( spectrum.wavelength, spectrum.flux, distance=None) return app_mag[0], abs_mag[0]
def __init__( self, object_name: str, filters: Optional[List[str]], spectrum: str, bounds: Dict[str, Tuple[float, float]], ) -> None: """ Parameters ---------- object_name : str Object name in the database. filters : list(str) Filter names for which the photometry is selected. All available photometry of the object is selected if set to ``None``. spectrum : str Calibration spectrum as labelled in the database. The calibration spectrum can be stored in the database with :func:`~species.data.database.Database.add_calibration`. bounds : dict Boundaries of the scaling parameter, as ``{'scaling':(min, max)}``. Returns ------- NoneType None """ self.object = read_object.ReadObject(object_name) self.spectrum = spectrum self.bounds = bounds self.objphot = [] self.specphot = [] if filters is None: species_db = database.Database() objectbox = species_db.get_object(object_name, inc_phot=True, inc_spec=False) filters = objectbox.filters for item in filters: readcalib = read_calibration.ReadCalibration(self.spectrum, item) calibspec = readcalib.get_spectrum() synphot = photometry.SyntheticPhotometry(item) spec_phot = synphot.spectrum_to_flux(calibspec.wavelength, calibspec.flux) self.specphot.append(spec_phot[0]) obj_phot = self.object.get_photometry(item) self.objphot.append(np.array([obj_phot[2], obj_phot[3]])) self.modelpar = ["scaling"]
def get_magnitude(self, sptypes: List[str] = None) -> box.PhotometryBox: """ Function for calculating the apparent magnitude for the ``filter_name``. Parameters ---------- sptypes : list(str) Spectral types to select from a library. The spectral types should be indicated with two characters (e.g. 'M5', 'L2', 'T3'). All spectra are selected if set to ``None``. Returns ------- species.core.box.PhotometryBox Box with the synthetic photometry. """ specbox = self.get_spectrum(sptypes=sptypes, exclude_nan=True) n_spectra = len(specbox.wavelength) filter_profile = read_filter.ReadFilter(filter_name=self.filter_name) mean_wavel = filter_profile.mean_wavelength() wavelengths = np.full(n_spectra, mean_wavel) filters = np.full(n_spectra, self.filter_name) synphot = photometry.SyntheticPhotometry(filter_name=self.filter_name) app_mag = [] abs_mag = [] for i in range(n_spectra): if np.isnan(specbox.distance[i][0]): app_tmp = (np.nan, np.nan) abs_tmp = (np.nan, np.nan) else: app_tmp, abs_tmp = synphot.spectrum_to_magnitude( specbox.wavelength[i], specbox.flux[i], error=specbox.error[i], distance=(float(specbox.distance[i][0]), float(specbox.distance[i][1]))) app_mag.append(app_tmp) abs_mag.append(abs_tmp) return box.create_box(boxtype='photometry', name=specbox.name, sptype=specbox.sptype, wavelength=wavelengths, flux=None, app_mag=np.asarray(app_mag), abs_mag=np.asarray(abs_mag), filter_name=filters)
def synthetic_photometry( self, filter_name: Union[str, List[str]]) -> PhotometryBox: """ Method for calculating synthetic photometry from the model spectrum that is stored in the ``ModelBox``. Parameters ---------- filter_name : str, list(str) Single filter name or a list of filter names for which synthetic photometry will be calculated. Returns ------- species.core.box.PhotometryBox Box with the synthetic photometry. """ if isinstance(filter_name, str): filter_name = [filter_name] list_wavel = [] list_flux = [] list_app_mag = [] list_abs_mag = [] for item in filter_name: syn_phot = photometry.SyntheticPhotometry(filter_name=item) syn_flux = syn_phot.spectrum_to_flux(wavelength=self.wavelength, flux=self.flux) syn_mag = syn_phot.spectrum_to_magnitude( wavelength=self.wavelength, flux=self.flux) list_flux.append(syn_flux) list_app_mag.append(syn_mag[0]) list_abs_mag.append(syn_mag[1]) filter_profile = read_filter.ReadFilter(filter_name=item) list_wavel.append(filter_profile.mean_wavelength()) phot_box = create_box( boxtype="photometry", name=None, sptype=None, wavelength=list_wavel, flux=list_flux, app_mag=list_app_mag, abs_mag=list_abs_mag, filter_name=filter_name, ) return phot_box
def get_flux(self, sptypes: List[str] = None) -> box.PhotometryBox: """ Function for calculating the average flux density for the ``filter_name``. Parameters ---------- sptypes : list(str), None Spectral types to select from a library. The spectral types should be indicated with two characters (e.g. 'M5', 'L2', 'T3'). All spectra are selected if set to ``None``. Returns ------- species.core.box.PhotometryBox Box with the synthetic photometry. """ specbox = self.get_spectrum(sptypes=sptypes, exclude_nan=True) n_spectra = len(specbox.wavelength) filter_profile = read_filter.ReadFilter(filter_name=self.filter_name) mean_wavel = filter_profile.mean_wavelength() wavelengths = np.full(n_spectra, mean_wavel) filters = np.full(n_spectra, self.filter_name) synphot = photometry.SyntheticPhotometry(filter_name=self.filter_name) phot_flux = [] for i in range(n_spectra): flux = synphot.spectrum_to_flux( wavelength=specbox.wavelength[i], flux=specbox.flux[i], error=specbox.error[i], ) phot_flux.append(flux) phot_flux = np.asarray(phot_flux) return box.create_box( boxtype="photometry", name=specbox.name, sptype=specbox.sptype, wavelength=wavelengths, flux=phot_flux, app_mag=None, abs_mag=None, filter_name=filters, )
def __init__(self, objname, filters, spectrum, bounds): """ Parameters ---------- objname : str Object name in the database. filters : tuple(str, ) Filter IDs for which the photometry is selected. All available photometry of the object is selected if set to None. spectrum : str Calibration spectrum. bounds : dict Boundaries of the scaling parameter, as {'scaling':(min, max)}. Returns ------- None """ self.object = read_object.ReadObject(objname) self.spectrum = spectrum self.bounds = bounds self.objphot = [] self.specphot = [] if filters is None: species_db = database.Database() objectbox = species_db.get_object(objname, None) filters = objectbox.filter for item in filters: readcalib = read_calibration.ReadCalibration(self.spectrum, item) calibspec = readcalib.get_spectrum() synphot = photometry.SyntheticPhotometry(item) spec_phot = synphot.spectrum_to_photometry(calibspec.wavelength, calibspec.flux) self.specphot.append(spec_phot) obj_phot = self.object.get_photometry(item) self.objphot.append((obj_phot[2], obj_phot[3])) self.modelpar = ['scaling']
def get_photometry(self, parameters=None, synphot=None): """ Parameters ---------- parameters : dict, None Model parameter values. Not used if set to None. synphot Returns ------- float Average flux density (W m-2 micron-1). """ specbox = self.get_spectrum(parameters, ) synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_photometry(specbox.wavelength, specbox.flux)
def get_magnitude(self, parameters=None, synphot=None): """ Parameters ---------- parameters : dict, None Model parameter values. Not used if set to None. synphot Returns ------- float Apparent magnitude (mag). """ specbox = self.get_spectrum(parameters, ) synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_magnitude(specbox.wavelength, specbox.flux, distance=None)
def get_flux(self, model_param: Dict[str, float]) -> Tuple[float, None]: """ Function for calculating the average flux density for the ``filter_name``. Parameters ---------- model_param : dict Dictionary with the model parameters and values. Returns ------- float Flux (W m-2 um-1). NoneType Error (W m-2 um-1). Always set to ``None``. """ spectrum = self.get_model(model_param) synphot = photometry.SyntheticPhotometry(self.filter_name) return synphot.spectrum_to_flux(spectrum.wavelength, spectrum.flux)
def add_spex(input_path, database): """ Function for adding the SpeX Prism Spectral Library to the database. Parameters ---------- input_path : str Path of the data folder. database : h5py._hl.files.File The HDF5 database. Returns ------- NoneType None """ distance_url = 'https://people.phys.ethz.ch/~stolkert/species/distance.dat' distance_file = os.path.join(input_path, 'distance.dat') if not os.path.isfile(distance_file): urllib.request.urlretrieve(distance_url, distance_file) distance_data = pd.pandas.read_csv( distance_file, usecols=[0, 3, 4], names=['object', 'distance', 'distance_error'], delimiter=',', dtype={ 'object': str, 'distance': float, 'distance_error': float }) database.create_group('spectra/spex') data_path = os.path.join(input_path, 'spex') if not os.path.exists(data_path): os.makedirs(data_path) url_all = 'http://svo2.cab.inta-csic.es/vocats/v2/spex/' \ 'cs.php?RA=180.000000&DEC=0.000000&SR=180.000000&VERB=2' xml_file_spex = os.path.join(data_path, 'spex.xml') if not os.path.isfile(xml_file_spex): urllib.request.urlretrieve(url_all, xml_file_spex) table = parse_single_table(xml_file_spex) # name = table.array['name'] twomass = table.array['name2m'] url = table.array['access_url'] unique_id = [] for i, item in enumerate(url): if twomass[i] not in unique_id: xml_file_1 = os.path.join(data_path, twomass[i].decode('utf-8') + '.xml') if not os.path.isfile(xml_file_1): urllib.request.urlretrieve(item.decode('utf-8'), xml_file_1) table = parse_single_table(xml_file_1) name = table.array['ID'] name = name[0].decode('utf-8') url = table.array['access_url'] print_message = f'Downloading SpeX Prism Spectral Library... {name}' print(f'\r{print_message:<72}', end='') xml_file_2 = os.path.join(data_path, f'spex_{name}.xml') if not os.path.isfile(xml_file_2): urllib.request.urlretrieve(url[0].decode('utf-8'), xml_file_2) unique_id.append(twomass[i]) print_message = 'Downloading SpeX Prism Spectral Library... [DONE]' print(f'\r{print_message:<72}') h_twomass = photometry.SyntheticPhotometry('2MASS/2MASS.H') # 2MASS H band zero point for 0 mag (Cogen et al. 2003) h_zp = 1.133e-9 # (W m-2 um-1) for votable in os.listdir(data_path): if votable.startswith('spex_') and votable.endswith('.xml'): xml_file = os.path.join(data_path, votable) table = parse_single_table(xml_file) wavelength = table.array['wavelength'] # (Angstrom) flux = table.array['flux'] # Normalized units wavelength = np.array(wavelength * 1e-4) # (um) flux = np.array(flux) # (a.u.) error = np.full(flux.size, np.nan) # 2MASS magnitudes j_mag = table.get_field_by_id('jmag').value h_mag = table.get_field_by_id('hmag').value ks_mag = table.get_field_by_id('ksmag').value j_mag = j_mag.decode('utf-8') h_mag = h_mag.decode('utf-8') ks_mag = ks_mag.decode('utf-8') if j_mag == '': j_mag = np.nan else: j_mag = float(j_mag) if h_mag == '': h_mag = np.nan else: h_mag = float(h_mag) if ks_mag == '': ks_mag = np.nan else: ks_mag = float(ks_mag) name = table.get_field_by_id('name').value name = name.decode('utf-8') twomass_id = table.get_field_by_id('name2m').value twomass_id = twomass_id.decode('utf-8') try: sptype = table.get_field_by_id('nirspty').value sptype = sptype.decode('utf-8') except KeyError: try: sptype = table.get_field_by_id('optspty').value sptype = sptype.decode('utf-8') except KeyError: sptype = 'None' sptype = data_util.update_sptype(np.array([sptype]))[0].strip() h_flux, _ = h_twomass.magnitude_to_flux(h_mag, error=None, zp_flux=h_zp) phot = h_twomass.spectrum_to_flux(wavelength, flux) # Normalized units flux *= h_flux / phot[0] # (W m-2 um-1) spdata = np.vstack([wavelength, flux, error]) # simbad_id, distance = query_util.get_distance(f'2MASS {twomass_id}') simbad_id = query_util.get_simbad(f'2MASS {twomass_id}') if simbad_id is not None: simbad_id = simbad_id.decode('utf-8') dist_select = distance_data.loc[distance_data['object'] == simbad_id] if not dist_select.empty: distance = (dist_select['distance'], dist_select['distance_error']) else: distance = (np.nan, np.nan) else: distance = (np.nan, np.nan) if sptype[0] in ['M', 'L', 'T'] and len(sptype) == 2: print_message = f'Adding SpeX Prism Spectral Library... {name}' print(f'\r{print_message:<72}', end='') dset = database.create_dataset(f'spectra/spex/{name}', data=spdata) dset.attrs['name'] = str(name).encode() dset.attrs['sptype'] = str(sptype).encode() dset.attrs['simbad'] = str(simbad_id).encode() dset.attrs['2MASS/2MASS.J'] = j_mag dset.attrs['2MASS/2MASS.H'] = h_mag dset.attrs['2MASS/2MASS.Ks'] = ks_mag dset.attrs['distance'] = distance[0] # (pc) dset.attrs['distance_error'] = distance[1] # (pc) print_message = 'Adding SpeX Prism Spectral Library... [DONE]' print(f'\r{print_message:<72}') database.close()
def add_spex(input_path: str, database: h5py._hl.files.File) -> None: """ Function for adding the SpeX Prism Spectral Library to the database. Parameters ---------- input_path : str Path of the data folder. database : h5py._hl.files.File The HDF5 database. Returns ------- NoneType None """ parallax_url = "https://home.strw.leidenuniv.nl/~stolker/species/parallax.dat" parallax_file = os.path.join(input_path, "parallax.dat") if not os.path.isfile(parallax_file): urllib.request.urlretrieve(parallax_url, parallax_file) parallax_data = pd.pandas.read_csv( parallax_file, usecols=[0, 1, 2], names=["object", "parallax", "parallax_error"], delimiter=",", dtype={"object": str, "parallax": float, "parallax_error": float}, ) database.create_group("spectra/spex") data_path = os.path.join(input_path, "spex") if not os.path.exists(data_path): os.makedirs(data_path) url_all = "http://svo2.cab.inta-csic.es/vocats/v2/spex/cs.php?" \ "RA=180.000000&DEC=0.000000&SR=180.000000&VERB=2" xml_file_spex = os.path.join(data_path, "spex.xml") if not os.path.isfile(xml_file_spex): urllib.request.urlretrieve(url_all, xml_file_spex) table = parse_single_table(xml_file_spex) # name = table.array['name'] twomass = table.array["name2m"] url = table.array["access_url"] unique_id = [] print_message = "" for i, item in enumerate(url): if twomass[i] not in unique_id: if isinstance(twomass[i], str): xml_file_1 = os.path.join(data_path, twomass[i] + ".xml") else: # Use decode for backward compatibility xml_file_1 = os.path.join( data_path, twomass[i].decode("utf-8") + ".xml" ) if not os.path.isfile(xml_file_1): if isinstance(item, str): urllib.request.urlretrieve(item, xml_file_1) else: urllib.request.urlretrieve(item.decode("utf-8"), xml_file_1) table = parse_single_table(xml_file_1) name = table.array["ID"] url = table.array["access_url"] if isinstance(name[0], str): name = name[0] else: name = name[0].decode("utf-8") empty_message = len(print_message) * " " print(f"\r{empty_message}", end="") print_message = f"Downloading SpeX Prism Spectral Library... {name}" print(f"\r{print_message}", end="") xml_file_2 = os.path.join(data_path, f"spex_{name}.xml") if not os.path.isfile(xml_file_2): if isinstance(url[0], str): urllib.request.urlretrieve(url[0], xml_file_2) else: urllib.request.urlretrieve(url[0].decode("utf-8"), xml_file_2) unique_id.append(twomass[i]) empty_message = len(print_message) * " " print(f"\r{empty_message}", end="") print_message = "Downloading SpeX Prism Spectral Library... [DONE]" print(f"\r{print_message}") h_twomass = photometry.SyntheticPhotometry("2MASS/2MASS.H") # 2MASS H band zero point for 0 mag (Cogen et al. 2003) h_zp = 1.133e-9 # (W m-2 um-1) for votable in os.listdir(data_path): if votable.startswith("spex_") and votable.endswith(".xml"): xml_file = os.path.join(data_path, votable) table = parse_single_table(xml_file) wavelength = table.array["wavelength"] # (Angstrom) flux = table.array["flux"] # Normalized units wavelength = np.array(wavelength * 1e-4) # (um) flux = np.array(flux) # (a.u.) error = np.full(flux.size, np.nan) # 2MASS magnitudes j_mag = table.get_field_by_id("jmag").value h_mag = table.get_field_by_id("hmag").value ks_mag = table.get_field_by_id("ksmag").value if not isinstance(j_mag, str): j_mag = j_mag.decode("utf-8") if not isinstance(h_mag, str): h_mag = h_mag.decode("utf-8") if not isinstance(ks_mag, str): ks_mag = ks_mag.decode("utf-8") if j_mag == "": j_mag = np.nan else: j_mag = float(j_mag) if h_mag == "": h_mag = np.nan else: h_mag = float(h_mag) if ks_mag == "": ks_mag = np.nan else: ks_mag = float(ks_mag) name = table.get_field_by_id("name").value if not isinstance(name, str): name = name.decode("utf-8") twomass_id = table.get_field_by_id("name2m").value if not isinstance(twomass_id, str): twomass_id = twomass_id.decode("utf-8") # Optical spectral type try: sptype_opt = table.get_field_by_id("optspty").value if not isinstance(sptype_opt, str): sptype_opt = sptype_opt.decode("utf-8") sptype_opt = data_util.update_sptype(np.array([sptype_opt]))[0] except KeyError: sptype_opt = None # Near-infrared spectral type try: sptype_nir = table.get_field_by_id("nirspty").value if not isinstance(sptype_nir, str): sptype_nir = sptype_nir.decode("utf-8") sptype_nir = data_util.update_sptype(np.array([sptype_nir]))[0] except KeyError: sptype_nir = None h_flux, _ = h_twomass.magnitude_to_flux(h_mag, error=None, zp_flux=h_zp) phot = h_twomass.spectrum_to_flux(wavelength, flux) # Normalized units flux *= h_flux / phot[0] # (W m-2 um-1) spdata = np.column_stack([wavelength, flux, error]) simbad_id = query_util.get_simbad(f"2MASS {twomass_id}") if simbad_id is not None: if not isinstance(simbad_id, str): simbad_id = simbad_id.decode("utf-8") par_select = parallax_data[parallax_data["object"] == simbad_id] if not par_select.empty: parallax = ( par_select["parallax"].values[0], par_select["parallax_error"].values[0], ) else: parallax = (np.nan, np.nan) else: parallax = (np.nan, np.nan) print_message = f"Adding spectra... {name}" print(f"\r{print_message:<72}", end="") dset = database.create_dataset(f"spectra/spex/{name}", data=spdata) dset.attrs["name"] = str(name).encode() if sptype_opt is not None: dset.attrs["sptype"] = str(sptype_opt).encode() elif sptype_nir is not None: dset.attrs["sptype"] = str(sptype_nir).encode() else: dset.attrs["sptype"] = str("None").encode() dset.attrs["simbad"] = str(simbad_id).encode() dset.attrs["2MASS/2MASS.J"] = j_mag dset.attrs["2MASS/2MASS.H"] = h_mag dset.attrs["2MASS/2MASS.Ks"] = ks_mag dset.attrs["parallax"] = parallax[0] # (mas) dset.attrs["parallax_error"] = parallax[1] # (mas) print_message = "Adding spectra... [DONE]" print(f"\r{print_message:<72}") database.close()
def multi_photometry( datatype: str, spectrum: str, filters: List[str], parameters: Dict[str, float], radtrans: Optional[read_radtrans.ReadRadtrans] = None, ) -> box.SynphotBox: """ Parameters ---------- datatype : str Data type ('model' or 'calibration'). spectrum : str Spectrum name (e.g., 'drift-phoenix', 'planck', 'powerlaw', 'petitradtrans'). filters : list(str) List with the filter names. parameters : dict Dictionary with the model parameters. radtrans : read_radtrans.ReadRadtrans, None Instance of :class:`~species.read.read_radtrans.ReadRadtrans`. Only required with ``spectrum='petitradtrans'`. Make sure that the ``wavel_range`` of the ``ReadRadtrans`` instance is sufficiently broad to cover all the ``filters``. Not used if set to `None`. Returns ------- species.core.box.SynphotBox Box with synthetic photometry. """ print("Calculating synthetic photometry...", end="", flush=True) flux = {} if datatype == "model": if spectrum == "petitradtrans": # Calculate the petitRADTRANS spectrum only once radtrans_box = radtrans.get_model(parameters) for item in filters: if spectrum == "petitradtrans": # Use an instance of SyntheticPhotometry instead # of get_flux from ReadRadtrans in order to not # recalculate the spectrum syn_phot = photometry.SyntheticPhotometry(item) flux[item], _ = syn_phot.spectrum_to_flux( radtrans_box.wavelength, radtrans_box.flux) elif spectrum == "powerlaw": synphot = photometry.SyntheticPhotometry(item) # Set the wavel_range attribute synphot.zero_point() powerl_box = read_util.powerlaw_spectrum( synphot.wavel_range, parameters) flux[item] = synphot.spectrum_to_flux(powerl_box.wavelength, powerl_box.flux)[0] else: if spectrum == "planck": readmodel = read_planck.ReadPlanck(filter_name=item) else: readmodel = read_model.ReadModel(spectrum, filter_name=item) try: if "teff_0" in parameters and "teff_1" in parameters: # Binary system param_0 = read_util.binary_to_single(parameters, 0) model_flux_0 = readmodel.get_flux(param_0)[0] param_1 = read_util.binary_to_single(parameters, 1) model_flux_1 = readmodel.get_flux(param_1)[0] flux[item] = ( parameters["spec_weight"] * model_flux_0 + (1.0 - parameters["spec_weight"]) * model_flux_1) else: # Single object flux[item] = readmodel.get_flux(parameters)[0] except IndexError: flux[item] = np.nan warnings.warn( f"The wavelength range of the {item} filter does not " f"match with the wavelength range of {spectrum}. The " f"flux is set to NaN.") elif datatype == "calibration": for item in filters: readcalib = read_calibration.ReadCalibration(spectrum, filter_name=item) flux[item] = readcalib.get_flux(parameters)[0] print(" [DONE]") return box.create_box("synphot", name="synphot", flux=flux)
def add_spex(input_path, database): """ Function for adding the SpeX Prism Spectral Library to the database. Parameters ---------- input_path : str Path of the data folder. database : h5py._hl.files.File Database. Returns ------- NoneType None """ database.create_group('spectra/spex') data_path = os.path.join(input_path, 'spex') if not os.path.exists(data_path): os.makedirs(data_path) url_all = 'http://svo2.cab.inta-csic.es/vocats/v2/spex/' \ 'cs.php?RA=180.000000&DEC=0.000000&SR=180.000000&VERB=2' xml_file = os.path.join(data_path, 'spex.xml') urlretrieve(url_all, xml_file) table = parse_single_table(xml_file) name = table.array['name'] twomass = table.array['name2m'] url = table.array['access_url'] os.remove(xml_file) for i, item in enumerate(url): xml_file = os.path.join(data_path, twomass[i].decode('utf-8') + '.xml') urlretrieve(item.decode('utf-8'), xml_file) table = parse_single_table(xml_file) name = table.array['ID'] name = name[0].decode('utf-8') url = table.array['access_url'] sys.stdout.write('\rDownloading SpeX Prism Spectral Library... ' + '{:<40}'.format(name)) sys.stdout.flush() os.remove(xml_file) xml_file = os.path.join(data_path, name + '.xml') urlretrieve(url[0].decode('utf-8'), xml_file) sys.stdout.write('\rDownloading SpeX Prism Spectral Library... ' + '{:<40}'.format('[DONE]') + '\n') sys.stdout.flush() h_twomass = photometry.SyntheticPhotometry('2MASS/2MASS.H') transmission = read_filter.ReadFilter('2MASS/2MASS.H') transmission.get_filter() # 2MASS H band zero point for 0 mag (Cogen et al. 2003) h_zp = 1.133e-9 # [W m-2 micron-1] for votable in os.listdir(data_path): if votable.endswith('.xml'): xml_file = os.path.join(data_path, votable) table = parse_single_table(xml_file) wavelength = table.array['wavelength'] # [Angstrom] flux = table.array['flux'] # Normalized units wavelength = np.array(wavelength * 1e-4) # [micron] flux = np.array(flux) # 2MASS magnitudes j_mag = table.get_field_by_id('jmag').value h_mag = table.get_field_by_id('hmag').value ks_mag = table.get_field_by_id('ksmag').value if j_mag == b'': j_mag = np.nan else: j_mag = float(j_mag) if h_mag == b'': h_mag = np.nan else: h_mag = float(h_mag) if ks_mag == b'': ks_mag = np.nan else: ks_mag = float(ks_mag) name = table.get_field_by_id('name').value name = name.decode('utf-8') twomass_id = table.get_field_by_id('name2m').value sys.stdout.write('\rAdding SpeX Prism Spectral Library... ' + '{:<40}'.format(name)) sys.stdout.flush() try: sptype = table.get_field_by_id('nirspty').value sptype = sptype.decode('utf-8') except KeyError: try: sptype = table.get_field_by_id('optspty').value sptype = sptype.decode('utf-8') except KeyError: sptype = 'None' sptype = data_util.update_sptype(np.array([sptype]))[0] h_flux, _ = h_twomass.magnitude_to_flux(h_mag, None, h_zp) phot = h_twomass.spectrum_to_photometry(wavelength, flux) # Normalized units flux *= h_flux / phot # [W m-2 micron-1] spdata = np.vstack((wavelength, flux)) simbad_id, distance = queries.get_distance( '2MASS ' + twomass_id.decode('utf-8')) # [pc] dset = database.create_dataset('spectra/spex/' + name, data=spdata) dset.attrs['name'] = str(name) dset.attrs['sptype'] = str(sptype) dset.attrs['simbad'] = str(simbad_id) dset.attrs['2MASS/2MASS.J'] = j_mag dset.attrs['2MASS/2MASS.H'] = h_mag dset.attrs['2MASS/2MASS.Ks'] = ks_mag dset.attrs['distance'] = distance # [pc] sys.stdout.write('\rAdding SpeX Prism Spectral Library... ' + '{:<40}'.format('[DONE]') + '\n') sys.stdout.flush() database.close()
def __init__(self, object_name: str, model: str, bounds: Dict[str, Union[Tuple[float, float], Tuple[Optional[Tuple[float, float]], Optional[Tuple[float, float]]], List[Tuple[float, float]]]], inc_phot: Union[bool, List[str]] = True, inc_spec: Union[bool, List[str]] = True, fit_corr: Optional[List[str]] = None) -> None: """ The grid of spectra is linearly interpolated for each photometric point and spectrum while taking into account the filter profile, spectral resolution, and wavelength sampling. Therefore, when fitting spectra from a model grid, the computation time of the interpolation will depend on the wavelength range, spectral resolution, and parameter space of the spectra that are stored in the database. Parameters ---------- object_name : str Object name as stored in the database with :func:`~species.data.database.Database.add_object` or :func:`~species.data.database.Database.add_companion`. model : str Atmospheric model (e.g. 'bt-settl', 'exo-rem', or 'planck'). bounds : dict(str, tuple(float, float)), None The boundaries that are used for the uniform priors. Atmospheric model parameters (e.g. ``model='bt-settl'``): - Boundaries are provided as tuple of two floats. For example, ``bounds={'teff': (1000, 1500.), 'logg': (3.5, 5.), 'radius': (0.8, 1.2)}``. - The grid boundaries are used if set to ``None``. For example, ``bounds={'teff': None, 'logg': None}``. The radius range is set to 0.8-1.5 Rjup if the boundary is set to None. Blackbody emission parameters (``model='planck'``): - Parameter boundaries have to be provided for 'teff' and 'radius'. - For a single blackbody component, the values are provided as a tuple with two floats. For example, ``bounds={'teff': (1000., 2000.), 'radius': (0.8, 1.2)}``. - For multiple blackbody component, the values are provided as a list with tuples. For example, ``bounds={'teff': [(1000., 1400.), (1200., 1600.)], 'radius': [(0.8, 1.5), (1.2, 2.)]}``. - When fitting multiple blackbody components, a prior is used which restricts the temperatures and radii to decreasing and increasing values, respectively, in the order as provided in ``bounds``. Calibration parameters: - For each spectrum/instrument, two optional parameters can be fitted to account for biases in the calibration: a scaling of the flux and a constant inflation of the uncertainties. - For example, ``bounds={'SPHERE': ((0.8, 1.2), (-18., -14.))}`` if the scaling is fitted between 0.8 and 1.2, and the error is inflated with a value between 1e-18 and 1e-14 W m-2 um-1. - The dictionary key should be equal to the database tag of the spectrum. For example, ``{'SPHERE': ((0.8, 1.2), (-18., -14.))}`` if the spectrum is stored as ``'SPHERE'`` with :func:`~species.data.database.Database.add_object`. - Each of the two calibration parameters can be set to ``None`` in which case the parameter is not used. For example, ``bounds={'SPHERE': ((0.8, 1.2), None)}``. - No calibration parameters are fitted if the spectrum name is not included in ``bounds``. ISM extinction parameters: - There are three approaches for fitting extinction. The first is with the empirical relation from Cardelli et al. (1989) for ISM extinction. - The extinction is parametrized by the V band extinction, A_V (``ism_ext``), and the reddening, R_V (``ism_red``). - The prior boundaries of ``ism_ext`` and ``ext_red`` should be provided in the ``bounds`` dictionary, for example ``bounds={'ism_ext': (0., 10.), 'ism_red': (0., 20.)}``. - Only supported by ``run_multinest``. Log-normal size distribution: - The second approach is fitting the extinction of a log-normal size distribution of grains with a crystalline MgSiO3 composition, and a homogeneous, spherical structure. - The size distribution is parameterized with a mean geometric radius (``lognorm_radius`` in um) and a geometric standard deviation (``lognorm_sigma``, dimensionless). - The extinction (``lognorm_ext``) is fitted in the V band (A_V in mag) and the wavelength-dependent extinction cross sections are interpolated from a pre-tabulated grid. - The prior boundaries of ``lognorm_radius``, ``lognorm_sigma``, and ``lognorm_ext`` should be provided in the ``bounds`` dictionary, for example ``bounds={'lognorm_radius': (0.01, 10.), 'lognorm_sigma': (1.2, 10.), 'lognorm_ext': (0., 5.)}``. - A uniform prior is used for ``lognorm_sigma`` and ``lognorm_ext``, and a log-uniform prior for ``lognorm_radius``. - Only supported by ``run_multinest``. Power-law size distribution: - The third approach is fitting the extinction of a power-law size distribution of grains, again with a crystalline MgSiO3 composition, and a homogeneous, spherical structure. - The size distribution is parameterized with a maximum radius (``powerlaw_max`` in um) and a power-law exponent (``powerlaw_exp``, dimensionless). The minimum radius is fixed to 1 nm. - The extinction (``powerlaw_ext``) is fitted in the V band (A_V in mag) and the wavelength-dependent extinction cross sections are interpolated from a pre-tabulated grid. - The prior boundaries of ``powerlaw_max``, ``powerlaw_exp``, and ``powerlaw_ext`` should be provided in the ``bounds`` dictionary, for example ``'powerlaw_max': (0.5, 10.), 'powerlaw_exp': (-5., 5.), 'powerlaw_ext': (0., 5.)}``. - A uniform prior is used for ``powerlaw_exp`` and ``powerlaw_ext``, and a log-uniform prior for ``powerlaw_max``. - Only supported by ``run_multinest``. inc_phot : bool, list(str) Include photometric data in the fit. If a boolean, either all (``True``) or none (``False``) of the data are selected. If a list, a subset of filter names (as stored in the database) can be provided. inc_spec : bool, list(str) Include spectroscopic data in the fit. If a boolean, either all (``True``) or none (``False``) of the data are selected. If a list, a subset of spectrum names (as stored in the database with :func:`~species.data.database.Database.add_object`) can be provided. fit_corr : list(str), None List with spectrum names for which the correlation length and fractional amplitude are fitted (see Wang et al. 2020). Returns ------- NoneType None """ if not inc_phot and not inc_spec: raise ValueError( 'No photometric or spectroscopic data has been selected.') if model == 'planck' and 'teff' not in bounds or 'radius' not in bounds: raise ValueError( 'The \'bounds\' dictionary should contain \'teff\' and \'radius\'.' ) self.object = read_object.ReadObject(object_name) self.distance = self.object.get_distance() if fit_corr is None: self.fit_corr = [] else: self.fit_corr = fit_corr self.model = model self.bounds = bounds if self.model == 'planck': # Fitting blackbody radiation if isinstance(bounds['teff'], list) and isinstance( bounds['radius'], list): # Update temperature and radius parameters in case of multiple blackbody components self.n_planck = len(bounds['teff']) self.modelpar = [] self.bounds = {} for i, item in enumerate(bounds['teff']): self.modelpar.append(f'teff_{i}') self.modelpar.append(f'radius_{i}') self.bounds[f'teff_{i}'] = bounds['teff'][i] self.bounds[f'radius_{i}'] = bounds['radius'][i] else: # Fitting a single blackbody compoentn self.n_planck = 1 self.modelpar = ['teff', 'radius'] self.bounds = bounds else: # Fitting self-consistent atmospheric models if self.bounds is not None: readmodel = read_model.ReadModel(self.model) bounds_grid = readmodel.get_bounds() for item in bounds_grid: if item not in self.bounds: # Set the parameter boundaries to the grid boundaries if set to None self.bounds[item] = bounds_grid[item] else: # Set all parameter boundaries to the grid boundaries readmodel = read_model.ReadModel(self.model, None, None) self.bounds = readmodel.get_bounds() if 'radius' not in self.bounds: self.bounds['radius'] = (0.8, 1.5) self.n_planck = 0 self.modelpar = readmodel.get_parameters() self.modelpar.append('radius') # Select filters and spectra if isinstance(inc_phot, bool): if inc_phot: # Select all filters if True species_db = database.Database() objectbox = species_db.get_object(object_name) inc_phot = objectbox.filters else: inc_phot = [] if isinstance(inc_spec, bool): if inc_spec: # Select all filters if True species_db = database.Database() objectbox = species_db.get_object(object_name) inc_spec = list(objectbox.spectrum.keys()) else: inc_spec = [] # Include photometric data self.objphot = [] self.modelphot = [] for item in inc_phot: if self.model == 'planck': # Create SyntheticPhotometry objects when fitting a Planck function print(f'Creating synthetic photometry: {item}...', end='', flush=True) self.modelphot.append(photometry.SyntheticPhotometry(item)) else: # Or interpolate the model grid for each filter print(f'Interpolating {item}...', end='', flush=True) readmodel = read_model.ReadModel(self.model, filter_name=item) readmodel.interpolate_grid(wavel_resample=None, smooth=False, spec_res=None) self.modelphot.append(readmodel) print(' [DONE]') # Store the flux and uncertainty for each filter obj_phot = self.object.get_photometry(item) self.objphot.append(np.array([obj_phot[2], obj_phot[3]])) # Include spectroscopic data if inc_spec: # Select all spectra self.spectrum = self.object.get_spectrum() # Select the spectrum names that are not in inc_spec spec_remove = [] for item in self.spectrum: if item not in inc_spec: spec_remove.append(item) # Remove the spectra that are not included in inc_spec for item in spec_remove: del self.spectrum[item] self.n_corr_par = 0 for item in self.spectrum: if item in self.fit_corr: self.modelpar.append(f'corr_len_{item}') self.modelpar.append(f'corr_amp_{item}') self.bounds[f'corr_len_{item}'] = ( -3., 0.) # log10(corr_len) (um) self.bounds[f'corr_amp_{item}'] = (0., 1.) self.n_corr_par += 2 self.modelspec = [] if self.model != 'planck': for key, value in self.spectrum.items(): print(f'\rInterpolating {key}...', end='', flush=True) wavel_range = (0.9 * value[0][0, 0], 1.1 * value[0][-1, 0]) readmodel = read_model.ReadModel(self.model, wavel_range=wavel_range) readmodel.interpolate_grid( wavel_resample=self.spectrum[key][0][:, 0], smooth=True, spec_res=self.spectrum[key][3]) self.modelspec.append(readmodel) print(' [DONE]') else: self.spectrum = {} self.modelspec = None self.n_corr_par = 0 for item in self.spectrum: if item in bounds: if bounds[item][0] is not None: # Add the flux scaling parameter self.modelpar.append(f'scaling_{item}') self.bounds[f'scaling_{item}'] = (bounds[item][0][0], bounds[item][0][1]) if bounds[item][1] is not None: # Add the error offset parameters self.modelpar.append(f'error_{item}') self.bounds[f'error_{item}'] = (bounds[item][1][0], bounds[item][1][1]) if item in self.bounds: del self.bounds[item] if 'lognorm_radius' in self.bounds and 'lognorm_sigma' in self.bounds and \ 'lognorm_ext' in self.bounds: self.cross_sections, _, _ = dust_util.interp_lognorm( inc_phot, inc_spec, self.spectrum) self.modelpar.append('lognorm_radius') self.modelpar.append('lognorm_sigma') self.modelpar.append('lognorm_ext') self.bounds['lognorm_radius'] = ( np.log10(self.bounds['lognorm_radius'][0]), np.log10(self.bounds['lognorm_radius'][1])) elif 'powerlaw_max' in self.bounds and 'powerlaw_exp' in self.bounds and \ 'powerlaw_ext' in self.bounds: self.cross_sections, _, _ = dust_util.interp_powerlaw( inc_phot, inc_spec, self.spectrum) self.modelpar.append('powerlaw_max') self.modelpar.append('powerlaw_exp') self.modelpar.append('powerlaw_ext') self.bounds['powerlaw_max'] = (np.log10( self.bounds['powerlaw_max'][0]), np.log10( self.bounds['powerlaw_max'][1])) else: self.cross_sections = None if 'ism_ext' in self.bounds and 'ism_red' in self.bounds: self.modelpar.append('ism_ext') self.modelpar.append('ism_red') print(f'Fitting {len(self.modelpar)} parameters:') for item in self.modelpar: print(f' - {item}') print('Prior boundaries:') for key, value in self.bounds.items(): print(f' - {key} = {value}')
def __init__(self, objname, filters, model, bounds, inc_phot=True, inc_spec=True): """ Parameters ---------- objname : str Object name in the database. filters : tuple(str, ) Filter IDs for which the photometry is selected. All available photometry of the object is selected if set to None. model : str Atmospheric model. bounds : dict Parameter boundaries. Full parameter range is used if set to None or not specified. The radius parameter range is set to 0-5 Rjup if not specified. inc_phot : bool Include photometry data with the fit. inc_spec : bool Include spectral data with the fit. Returns ------- NoneType None """ self.object = read_object.ReadObject(objname) self.distance = self.object.get_distance() self.model = model self.bounds = bounds if not inc_phot and not inc_spec: raise ValueError('No photometric or spectral data has been selected.') if self.bounds is not None and 'teff' in self.bounds: teff_bound = self.bounds['teff'] else: teff_bound = None if self.bounds is not None: readmodel = read_model.ReadModel(self.model, None, teff_bound) bounds_grid = readmodel.get_bounds() for item in bounds_grid: if item not in self.bounds: self.bounds[item] = bounds_grid[item] else: readmodel = read_model.ReadModel(self.model, None, None) self.bounds = readmodel.get_bounds() if 'radius' not in self.bounds: self.bounds['radius'] = (0., 5.) if inc_phot: self.objphot = [] self.modelphot = [] self.synphot = [] if not filters: species_db = database.Database() objectbox = species_db.get_object(objname, None) filters = objectbox.filter for item in filters: readmodel = read_model.ReadModel(self.model, item, teff_bound) readmodel.interpolate() self.modelphot.append(readmodel) sphot = photometry.SyntheticPhotometry(item) self.synphot.append(sphot) obj_phot = self.object.get_photometry(item) self.objphot.append((obj_phot[2], obj_phot[3])) else: self.objphot = None self.modelphot = None self.synphot = None if inc_spec: self.spectrum = self.object.get_spectrum() self.instrument = self.object.get_instrument() self.modelspec = read_model.ReadModel(self.model, (0.9, 2.5), teff_bound) else: self.spectrum = None self.instrument = None self.modelspec = None self.modelpar = readmodel.get_parameters() self.modelpar.append('radius')
def add_object(self, object_name, distance=None, app_mag=None, spectrum=None, instrument=None): """ Parameters ---------- object_name: str Object name. distance : float Distance (pc). Not written if set to None. app_mag : dict Apparent magnitudes. Not written if set to None. spectrum : str Spectrum filename. The first three columns should contain the wavelength (micron), flux density (W m-2 micron-1), and the error (W m-2 micron-1). Not written if set to None. instrument : str Instrument that was used for the spectrum (currently only 'gpi' possible). Not used if set to None. Returns ------- NoneType None """ h5_file = h5py.File(self.database, 'a') if 'objects' not in h5_file: h5_file.create_group('objects') if 'objects/' + object_name not in h5_file: h5_file.create_group('objects/' + object_name) if distance: if 'objects/' + object_name + '/distance' in h5_file: del h5_file['objects/' + object_name + '/distance'] h5_file.create_dataset('objects/' + object_name + '/distance', data=distance, dtype='f') # [pc] if app_mag: flux = {} error = {} for item in app_mag: synphot = photometry.SyntheticPhotometry(item) flux[item], error[item] = synphot.magnitude_to_flux( app_mag[item][0], app_mag[item][1]) for item in app_mag: if 'objects/' + object_name + '/' + item in h5_file: del h5_file['objects/' + object_name + '/' + item] data = np.asarray([ app_mag[item][0], app_mag[item][1], flux[item], error[item] ]) # [mag], [mag], [W m-2 micron-1], [W m-2 micron-1] h5_file.create_dataset('objects/' + object_name + '/' + item, data=data, dtype='f') sys.stdout.write('Adding object: ' + object_name + '...') sys.stdout.flush() if spectrum: if 'objects/' + object_name + '/spectrum' in h5_file: del h5_file['objects/' + object_name + '/spectrum'] data = np.loadtxt(spectrum) dset = h5_file.create_dataset('objects/' + object_name + '/spectrum', data=data[:, 0:3], dtype='f') dset.attrs['instrument'] = str(instrument) sys.stdout.write(' [DONE]\n') sys.stdout.flush() h5_file.close()