def test_cgmsurvey_from_fields_sightlines(): # Instantiate fields and add galaxies field1 = ('PG1407+265', 212.349634 * u.deg, 26.3058650 * u.deg) fieldobj1 = IgmGalaxyField((field1[1], field1[2]), name=field1[0], verbose=False) field2 = ('PG1148+549', 177.83526042 * u.deg, 54.625855 * u.deg) fieldobj2 = IgmGalaxyField((field2[1], field2[2]), name=field2[0], verbose=False) f1ras = [212.33310891, 212.329875] * u.deg f1decs = [26.3722716934, 26.3084391667] * u.deg f1zs = [0.974413514137, 0.22016787529] f1gals = Table([f1ras, f1decs, f1zs], names=['RA', 'DEC', 'Z']) f2ras = [177.835229336, 178.536958333] * u.deg f2decs = [54.625851084, 54.6176108333] * u.deg f2zs = [0.0595485754311, 0.00385531364009] f2gals = Table([f2ras, f2decs, f2zs], names=['RA', 'DEC', 'Z']) fieldobj1.galaxies = f1gals fieldobj2.galaxies = f2gals fields = [fieldobj1, fieldobj2] # Instantiate sightlines sl1coord = SkyCoord(field1[1], field1[2], unit='deg') sl2coord = SkyCoord(field2[1], field2[2], unit='deg') comp11 = AbsComponent(sl1coord, (8, 6), 0.9743, [-200, 200] * u.km / u.s) comp12 = AbsComponent(sl1coord, (1, 1), 0.9743, [-200, 200] * u.km / u.s) al11 = AbsLine('OVI 1031') al11.attrib['coord'] = sl1coord al11.analy['spec'] = 'files/J0042-1037.358_9.fits.gz' al12 = AbsLine('HI 1215') al12.attrib['coord'] = sl1coord al12.analy['spec'] = 'files/J0042-1037.358_9.fits.gz' comp11.add_absline(al11, chk_sep=False, chk_vel=False) comp12.add_absline(al12, chk_sep=False, chk_vel=False) sys1 = IGMSystem.from_components([comp11, comp12]) sl1 = IGMSightline.from_systems([sys1]) comp21 = AbsComponent(sl2coord, (6, 4), 0.0037, [-200, 200] * u.km / u.s) comp22 = AbsComponent(sl2coord, (1, 1), 0.0037, [-200, 200] * u.km / u.s) al21 = AbsLine('CIV 1548') al21.attrib['coord'] = sl1coord al21.analy['spec'] = 'files/J0042-1037.358_9.fits.gz' al22 = AbsLine('HI 1215') al22.attrib['coord'] = sl1coord al22.analy['spec'] = 'files/J0042-1037.358_9.fits.gz' comp21.add_absline(al21, chk_sep=False, chk_vel=False) comp22.add_absline(al22, chk_sep=False, chk_vel=False) sys2 = IGMSystem.from_components([comp21, comp22]) sl2 = IGMSightline.from_systems([sys2]) sightlines = [sl1, sl2] # Run function csurvey = cgmsurvey_from_sightlines_fields(fields, sightlines) assert isinstance(csurvey, CGMAbsSurvey)
def __init__(self, radec, zabs, vlim, NHI, **kwargs): """Standard init NHI keyword is required """ # NHI if NHI < 20.3: raise ValueError("This is not a DLA! Try an LLS (or SLLS)") # vlim if vlim is None: vlim = [-500., 500.]*u.km/u.s # Generate with type IGMSystem.__init__(self, radec, zabs, vlim, NHI=NHI, abs_type='DLA', **kwargs)
def __init__(self, radec, zabs, vlim, **kwargs): """Standard init NHI keyword is required Parameters ---------- radec : tuple or coordinate RA/Dec of the sightline or astropy.coordinate zabs : float Absorption redshift vlim : Quantity array (2) Velocity limits of the system Defaulted to +/- 500 km/s if None (see Prochaska et al. 2016 HDLLS) NHI= : float, required despite being a keyword log10 of HI column density **kwargs : keywords passed to IGMSystem.__init__ """ # NHI try: NHI = kwargs['NHI'] except KeyError: raise ValueError("NHI must be specified for LLSSystem") else: kwargs.pop('NHI') # vlim if vlim is None: vlim = [-500., 500.] * u.km / u.s # Generate with type IGMSystem.__init__(self, radec, zabs, vlim, NHI=NHI, abs_type='LLS', **kwargs) # Set tau_LL self.tau_LL = (10.**self.NHI) * ltaa.photo_cross( 1, 1, 1 * u.Ry).to('cm**2').value # Other self.zpeak = None # Optical depth weighted redshift self.ZH = 0. self.metallicity = None # MetallicityPDF class usually # Subsystems self.nsub = 0 self.subsys = {}
def from_dict(cls, idict, use_angrho=False, **kwargs): """ Generate a CGMAbsSys object from a dict Parameters ---------- idict : dict use_angrho : bool, optional Use ang_sep and rho if in idict and cosmo is too """ # Galaxy object galaxy = Galaxy.from_dict(idict['galaxy']) # IGM system igm_sys = IGMSystem.from_dict(idict['igm_sys'], **kwargs) # Keywords kwargs2 = kwargs.copy() kwargs2['name'] = idict['Name'] if 'cosmo' in idict.keys(): kwargs2['cosmo'] = getattr(cosmology, idict['cosmo']) if use_angrho: kwargs2['ang_sep'] = idict['ang_sep']*u.arcsec kwargs2['rho'] = idict['rho']*u.kpc # Instantiate slf = cls(galaxy, igm_sys, **kwargs2) # Return return slf
def from_dict(cls, idict, use_angrho=False, **kwargs): """ Generate a CGMAbsSys object from a dict Parameters ---------- idict : dict use_angrho : bool, optional Use ang_sep and rho if in idict and cosmo is too """ # Galaxy object galaxy = Galaxy.from_dict(idict['galaxy']) # IGM system igm_sys = IGMSystem.from_dict(idict['igm_sys'], **kwargs) # Keywords kwargs2 = kwargs.copy() kwargs2['name'] = idict['Name'] if 'cosmo' in idict.keys(): kwargs2['cosmo'] = getattr(cosmology, idict['cosmo']) if use_angrho: kwargs2['ang_sep'] = idict['ang_sep'] * u.arcsec kwargs2['rho'] = idict['rho'] * u.kpc # Instantiate slf = cls(galaxy, igm_sys, **kwargs2) # Extras for key in ['ebv']: if key in idict.keys(): setattr(slf, key, idict[key]) # Return return slf
def main(args=None): from astropy.coordinates import SkyCoord from astropy import units as u from linetools import utils as ltu from pyigm.abssys.dla import DLASystem from pyigm.abssys.lls import LLSSystem from pyigm.abssys.igmsys import MgIISystem, IGMSystem if args is None: pargs = parser() else: pargs = args # Coordinates if pargs.jcoord is not None: coord = ltu.radec_to_coord(pargs.jcoord) else: coord = SkyCoord(ra=0., dec=0., unit='deg') # vlim if pargs.vlim is not None: vlims = [float(vlim) for vlim in pargs.vlim.split(',')] * u.km / u.s else: vlims = None # go if pargs.itype.lower() == 'dla': isys = DLASystem(coord, pargs.zabs, vlims, pargs.NHI, zem=pargs.zem, sig_NHI=pargs.sigNHI) elif pargs.itype.lower() == 'lls': isys = LLSSystem(coord, pargs.zabs, vlims, NHI=pargs.NHI, zem=pargs.zem, sig_NHI=pargs.sigNHI) elif pargs.itype.lower() == 'mgii': isys = MgIISystem(coord, pargs.zabs, vlims, NHI=pargs.NHI, zem=pargs.zem, sig_NHI=pargs.sigNHI) elif pargs.itype.lower() == 'igm': isys = IGMSystem(coord, pargs.zabs, vlims, NHI=pargs.NHI, zem=pargs.zem, sig_NHI=pargs.sigNHI) else: raise IOError("Not prepared for this type of IGMSystem") # Write isys.write_json(pargs.outfile)
def test_init(): # Simple properties radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) igmsys = IGMSystem(radec, 1.244, [-500,500]*u.km/u.s, NHI=16., abs_type='MgII') # Test np.testing.assert_allclose(igmsys.zabs,1.244) # hisys = HISystem(radec, 1.244, [-500,500]*u.km/u.s, NHI=15.) np.testing.assert_allclose(hisys.NHI, 15.) np.testing.assert_allclose(hisys.vlim[0].value, -500.)
def simple_cgmabssys(): radec = (125.0 * u.deg, 45.2 * u.deg) gal = Galaxy(radec, z=0.3) radec_qso = (125.0 * u.deg, 45.203 * u.deg) igmsys = IGMSystem(radec_qso, gal.z, [-500, 500] * u.km / u.s, abs_type='CGM') # Instantiate cgmabs = CGMAbsSys(gal, igmsys, cosmo=cosmo) return cgmabs
def __init__(self, radec, zabs, vlim, NHI, **kwargs): """Standard init NHI keyword is required """ # NHI if NHI < 20.3: raise ValueError("This is not a DLA! Try an LLS (or SLLS)") # vlim if vlim is None: vlim = [-500., 500.] * u.km / u.s # Generate with type IGMSystem.__init__(self, radec, zabs, vlim, NHI=NHI, abs_type='DLA', **kwargs)
def __init__(self, radec, zabs, vlim, **kwargs): """Standard init NHI keyword is required Parameters ---------- radec : tuple or coordinate RA/Dec of the sightline or astropy.coordinate zabs : float Absorption redshift vlim : Quantity array (2) Velocity limits of the system Defaulted to +/- 500 km/s if None (see Prochaska et al. 2016 HDLLS) NHI= : float, required despite being a keyword log10 of HI column density **kwargs : keywords passed to IGMSystem.__init__ """ # NHI try: NHI = kwargs['NHI'] except KeyError: raise ValueError("NHI must be specified for LLSSystem") else: kwargs.pop('NHI') # vlim if vlim is None: vlim = [-500.,500.]*u.km/u.s # Generate with type IGMSystem.__init__(self, 'LLS', radec, zabs, vlim, NHI=NHI, **kwargs) # Set tau_LL self.tau_LL = (10.**self.NHI)*ltaa.photo_cross(1, 1, 1*u.Ry).to('cm**2').value # Other self.zpeak = None # Optical depth weighted redshift self.ZH = 0. self.metallicity = None # MetallicityPDF class usually # Subsystems self.nsub = 0 self.subsys = {}
def test_calcrho(): # Dummy galaxy = Galaxy((100., 50.), 0.2) igmsys = IGMSystem((100., 50.001), 1.2, None) # Calc rho, angle = calc_cgm_rho(galaxy, igmsys, cosmo) # Test assert np.isclose(rho.value, 12.2587523534) assert rho.unit == astropy.units.kpc assert isinstance(angle, astropy.coordinates.Angle)
def test_calcrho(): # Dummy galaxy = Galaxy((100., 50.), 0.2) igmsys = IGMSystem((100., 50.001), 1.2, None) # Calc rho, angle = calc_rho(galaxy, igmsys, cosmo) # Test assert np.isclose(rho.value, 12.2587523534) assert rho.unit == astropy.units.kpc assert isinstance(angle, astropy.coordinates.Angle) # Galactic milkyway = Galaxy((0., 0.), 0.) igmsys.coord = SkyCoord(l=0. * u.deg, b=0. * u.deg, frame='galactic') rho2, angle2 = calc_rho(galaxy, igmsys, None, Galactic=True) assert np.isclose(rho2.value, 0.) assert np.isclose(angle2.value, 0.) igmsys.coord = SkyCoord(l=45. * u.deg, b=45. * u.deg, frame='galactic') rho3, angle3 = calc_rho(galaxy, igmsys, None, Galactic=True) assert np.isclose(rho3.value, 6.928203230275509)
def test_generic(): # Start gensurvey = GenericIGMSurvey() # Systems coord = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) gensys1 = IGMSystem("Generic", coord, 1.244, [-300, 300.0] * u.km / u.s, NHI=16.0) gensys1.name = "Sys1" # coord2 = SkyCoord(ra=223.1143 * u.deg, dec=42.4321 * u.deg) gensys2 = IGMSystem("Generic", coord2, 1.744, [-300, 300.0] * u.km / u.s, NHI=17.0) gensys2.name = "Sys2" # Combine gensurvey.add_abs_sys(gensys1) gensurvey.add_abs_sys(gensys2) assert gensurvey.nsys == 2 # Attribute aNHI = gensurvey.NHI np.testing.assert_allclose(aNHI, np.array([16.0, 17.0]))
def test_init_cgmabssys(): radec = (125 * u.deg, 45.2 * u.deg) gal = Galaxy(radec, z=0.3) radec_qso = (125 * u.deg, 45.203 * u.deg) igmsys = IGMSystem(radec_qso, gal.z, [-500, 500] * u.km / u.s, abs_type='CGM') # Instantiate cgmabs = CGMAbsSys(gal, igmsys) # Test np.testing.assert_allclose(cgmabs.rho.value, 48.72077748027017)
def test_to_dict(): from linetools import utils as ltu radec = (125 * u.deg, 45.2 * u.deg) gal = Galaxy(radec, z=0.3) radec_qso = (125 * u.deg, 45.203 * u.deg) igmsys = IGMSystem(radec_qso, gal.z, [-500, 500] * u.km / u.s, abs_type='CGM') # Instantiate cgmabs = CGMAbsSys(gal, igmsys) # Test cdict = cgmabs.to_dict() ltu.savejson('tmp.json', cdict, overwrite=True)
def test_to_dict(): radec = (125 * u.deg, 45.2 * u.deg) gal = Galaxy(radec, z=0.3) radec_qso = (125 * u.deg, 45.203 * u.deg) igmsys = IGMSystem(radec_qso, gal.z, [-500, 500] * u.km / u.s, abs_type='CGM') # Instantiate cgmabs = CGMAbsSys(gal, igmsys) # Test cdict = cgmabs.to_dict() with io.open('tmp.json', 'w', encoding='utf-8') as f: f.write( unicode( json.dumps(cdict, sort_keys=True, indent=4, separators=(',', ': '))))
def ingest_johnson15(): """ Ingest Johnson+15 """ # Dict for QSO coords qsos = {} qsos['1ES1028+511'] = ltu.radec_to_coord('J103118.52517+505335.8193') qsos['FBQS1010+3003'] = ltu.radec_to_coord((152.5029167, 30.056111)) qsos['HE0226-4110'] = ltu.radec_to_coord('J022815.252-405714.62') qsos['HS1102+3441'] = ltu.radec_to_coord('J110539.8189+342534.672') qsos['LBQS1435-0134'] = ltu.radec_to_coord((219.451183, -1.786328)) qsos['PG0832+251'] = ltu.radec_to_coord('J083535.8048+245940.146') qsos['PG1522+101'] = ltu.radec_to_coord((231.1023075, 9.9749372)) qsos['PKS0405-123'] = ltu.radec_to_coord('J040748.4376-121136.662') qsos['SBS1108+560'] = ltu.radec_to_coord((167.8841667, 55.790556)) qsos['SBS1122+594'] = ltu.radec_to_coord((171.4741250, 59.172667)) qsos['Ton236'] = ltu.radec_to_coord((232.1691746, 28.424928)) # Virial matching j15_file = resource_filename('pyigm', 'data/CGM/z0/johnson2015_table1.fits') j15_tbl = Table.read(j15_file) # Clip COS-Halos keep = j15_tbl['Survey'] != 'COS-Halos' j15_tbl = j15_tbl[keep] # CGM Survey j15 = CGMAbsSurvey(survey='J15', ref='Johnson+15') # Linelist llist = LineList('ISM') for row in j15_tbl: # RA, DEC # Galaxy gal = Galaxy((row['RAJ2000'], row['DEJ2000']), z=float(row['zgal'])) gal.Class = row['Class'] gal.Mstar = row['logM_'] gal.field = row['Name'] gal.Env = row['Env'] gal.d_Rh = row['d_Rh'] # igmsys = IGMSystem(qsos[row['Name']], float(row['zgal']), (-400., 400.) * u.km / u.s) # HI if np.isnan(row['logNHI']): pass else: # HI component if row['l_logNHI'] == '<': flagN = 3 sigNHI = 99. elif np.isnan(row['e_logNHI']): flagN = 2 sigNHI = 99. else: flagN = 1 sigNHI = row['e_logNHI'] HIcomp = AbsComponent(qsos[row['Name']], (1, 1), float(row['zgal']), (-400, 400) * u.km / u.s, Ntup=(flagN, row['logNHI'], sigNHI)) igmsys._components.append(HIcomp) # NHI igmsys.NHI = HIcomp.logN igmsys.flag_NHI = HIcomp.flag_N igmsys.sig_NHI = HIcomp.sig_N # OVI if np.isnan(row['logNHOVI']): pass else: # OVI component if row['l_logNHOVI'] == '<': flagN = 3 sigNHOVI = 99. elif np.isnan(row['e_logNHOVI']): flagN = 2 sigNHOVI = 99. else: flagN = 1 sigNHOVI = row['e_logNHOVI'] OVIcomp = AbsComponent(qsos[row['Name']], (8, 6), float(row['zgal']), (-400, 400) * u.km / u.s, Ntup=(flagN, row['logNHOVI'], sigNHOVI)) igmsys._components.append(OVIcomp) # CGM cgmabs = CGMAbsSys(gal, igmsys, chk_lowz=False) j15.cgm_abs.append(cgmabs) # Write tarball out_file = resource_filename('pyigm', '/data/CGM/z0/J15_sys.tar') j15.to_json_tarball(out_file)
def ingest_burchett16(smthd='vir'): """ Ingest Burchett+16 """ # Virial matching if smthd == 'vir': b16_file = resource_filename( 'pyigm', 'data/CGM/z0/Burchett2016_CIV_HI_virselect.fits') else: b16_file = resource_filename( 'pyigm', 'data/CGM/z0/Burchett2016_CIV_HI_kpcselect.fits') b16_tbl = Table.read(b16_file) # CGM Survey b16 = CGMAbsSurvey(survey='B16', ref='Burchett+16') # Linelist llist = LineList('ISM') for row in b16_tbl: # RA, DEC # Galaxy gal = Galaxy((row['ra_gal'], row['dec_gal']), z=row['zgal']) gal.SFR = row['SFR'] gal.sig_SFR = row['SFR_err'] gal.Mstar = row['mstars'] gal.field = row['field'] gal.RRvir = row['rrvir'] gal.NSAidx = row['NSAidx'] # igmsys = IGMSystem((row['ra_qso'], row['dec_qso']), row['zgal'], (-400., 400.) * u.km / u.s) # HI if row['flag_h1'] > 0: # Lya lya = AbsLine(1215.67 * u.AA, z=row['zgal'], linelist=llist) lya.attrib['EW'] = row['EW_h1'] * u.AA lya.attrib['logN'] = row['col_h1'] lya.attrib['N'] = 10**row['col_h1'] * u.cm**-2 if row['flag_h1'] == 3: lya.attrib['flag_EW'] = 3 lya.attrib['flag_N'] = 3 lya.attrib['sig_N'] = (10**(row['col_h1'])) / 3. * u.cm**-2 elif row['flag_h1'] == 2: lya.attrib['flag_EW'] = 1 lya.attrib['flag_N'] = 2 else: lya.attrib['flag_EW'] = 1 lya.attrib['flag_N'] = 1 lya.attrib['sig_N'] = (10**(row['col_h1'] + row['colsig_h1']) - 10**row['col_h1']) * u.cm**-2 lya.attrib['sig_EW'] = row['EWsig_h1'] * u.AA # Ref lya.attrib['Ref'] = 'Burchett+16' # HI component if row['colsig_h1'] >= 99.: flagN = 2 elif row['colsig_h1'] <= 0.: flagN = 3 else: flagN = 1 HIcomp = AbsComponent( (row['ra_qso'], row['dec_qso']), (1, 1), row['zgal'], (-400, 400) * u.km / u.s, Ntup=(flagN, row['col_h1'], row['colsig_h1'])) HIcomp._abslines.append(lya) igmsys._components.append(HIcomp) # NHI igmsys.NHI = HIcomp.logN igmsys.flag_NHI = HIcomp.flag_N igmsys.sig_NHI = HIcomp.sig_N # CIV if row['flag_c4'] > 0: # CIV 1548 civ1548 = AbsLine(1548.195 * u.AA, z=row['zgal'], linelist=llist) civ1548.attrib['EW'] = row['EW_c4'] * u.AA civ1548.attrib['logN'] = row['col_c4'] civ1548.attrib['N'] = 10**row['col_c4'] * u.cm**-2 if row['flag_c4'] == 3: civ1548.attrib['flag_EW'] = 3 civ1548.attrib['flag_N'] = 3 civ1548.attrib['sig_N'] = (10**(row['col_c4'])) / 3. * u.cm**-2 elif row['flag_c4'] == 2: civ1548.attrib['flag_EW'] = 1 civ1548.attrib['flag_N'] = 2 else: civ1548.attrib['flag_EW'] = 1 civ1548.attrib['flag_N'] = 1 civ1548.attrib['sig_N'] = (10** (row['col_c4'] + row['colsig_c4']) - 10**row['col_c4']) * u.cm**-2 civ1548.attrib['sig_EW'] = row['EWsig_c4'] * u.AA # Ref civ1548.attrib['Ref'] = 'Burchett+16' # CIV component if row['colsig_c4'] >= 99.: flagN = 2 elif row['colsig_c4'] <= 0.: flagN = 3 else: flagN = 1 CIVcomp = AbsComponent( (row['ra_qso'], row['dec_qso']), (6, 4), row['zgal'], (-400, 400) * u.km / u.s, Ntup=(flagN, row['col_c4'], row['colsig_c4'])) CIVcomp._abslines.append(civ1548) igmsys._components.append(CIVcomp) # CGM cgmabs = CGMAbsSys(gal, igmsys, correct_lowz=False) b16.cgm_abs.append(cgmabs) # Write tarball if smthd == 'vir': out_file = resource_filename('pyigm', '/data/CGM/z0/B16_vir_sys.tar') else: out_file = resource_filename('pyigm', '/data/CGM/z0/B16_kpc_sys.tar') b16.to_json_tarball(out_file)
def load_data(self, **kwargs): # if self.from_dict: q5file = self.data_file qpq5dict = CGMAbsSurvey.from_json(q5file) ism = LineList('ISM') qpq5dict.build_systems_from_dict(llist=ism) self.survey_data = qpq5dict #self.cgm_abs = qpq5dict.cgm_abs else: qpqdata = load_qpq(5) nmax = len(qpqdata) # max number of QSOs for i in range(nmax): # Instantiate the galaxy gal = Galaxy((qpqdata['RAD'][i], qpqdata['DECD'][i]), z=qpqdata['Z_FG'][i]) gal.L_BOL = qpqdata['L_BOL'][i] gal.L_912 = qpqdata['L_912'][i] gal.G_UV = qpqdata['G_UV'][i] gal.flg_BOSS = qpqdata['FLG_BOSS'][i] gal.zsig = qpqdata['Z_FSIG'][i] * u.km / u.s # Instantiate the IGM System igm_sys = IGMSystem( (qpqdata['RAD_BG'][i], qpqdata['DECD_BG'][i]), qpqdata['Z_FG'][i], [-5500, 5500.] * u.km / u.s, abs_type='CGM') igm_sys.zem = qpqdata['Z_BG'][i] igm_sys.NHI = qpqdata['NHI'][i] igm_sys.sig_NHI = qpqdata['SIG_NHI'][i] igm_sys.flag_NHI = qpqdata['FLG_NHI'][i] igm_sys.s2n_lya = qpqdata['S2N_LYA'][i] igm_sys.flg_othick = qpqdata['FLG_OTHICK'][i] igm_sys.z_lya = qpqdata['Z_LYA'][i] iname = qpqdata['QSO'][i] # Instantiate rho = qpqdata['R_PHYS'][i] * u.kpc cgabs = CGMAbsSys(gal, igm_sys, name=iname, rho=rho, **kwargs) aline = AbsLine(1215.67 * u.AA, closest=True, z=igm_sys.zabs, linelist=ism) aline.attrib['EW'] = qpqdata['EWLYA'][i] * u.AA # Rest EW aline.attrib['sig_EW'] = qpqdata['SIG_EWLYA'][i] * u.AA if aline.attrib['EW'] > 3. * aline.attrib['sig_EW']: aline.attrib['flag_EW'] = 1 else: aline.attrib['flag_EW'] = 3 aline.attrib['coord'] = igm_sys.coord #aline.limits._wvlim = qpqdata['WVMNX'][i]*u.AA ## (no data in QPQ7 file) #dv = ltu.rel_vel(aline.limits._wvlim, aline.wrest * (1 + qpqdata['Z_FG'][i])) #aline.limits._vlim = dv abslines = [] abslines.append(aline) comp = AbsComponent.from_abslines(abslines, chk_vel=False) cgabs.igm_sys.add_component(comp) # add metal lines for j in range(100): if qpqdata[i]['FLG_METAL_EW'][j] > 0: wave0 = qpqdata[i]['METAL_WREST'][j] iline = AbsLine(wave0 * u.AA, closest=True, z=igm_sys.zabs, linelist=ism) iline.attrib[ 'EW'] = qpqdata['METAL_EW'][i][j] * u.AA # Rest EW iline.attrib[ 'sig_EW'] = qpqdata['METAL_SIGEW'][i][j] * u.AA iline.attrib['flag_EW'] = qpqdata['FLG_METAL_EW'][i][j] iline.analy['flg_eye'] = qpqdata['FLG_METAL_EYE'][i][j] iline.attrib['coord'] = igm_sys.coord abslines = [] abslines.append(iline) comp = AbsComponent.from_abslines(abslines, chk_vel=False) cgabs.igm_sys.add_component(comp) # add ang_sep qsocoord = SkyCoord(ra=qpqdata['RAD'][i], dec=qpqdata['DECD'][i], unit='deg') bgcoord = SkyCoord(ra=qpqdata['RAD_BG'][i], dec=qpqdata['DECD_BG'][i], unit='deg') cgabs.ang_sep = qsocoord.separation(bgcoord).to('arcsec') self.cgm_abs.append(cgabs)
def load_single_fits(self, inp, skip_ions=False, verbose=True, **kwargs): """ Load a single COS-Halos sightline Appends to cgm_abs list Parameters ---------- inp : tuple or str if tuple -- (field,gal_id) field: str Name of field (e.g. 'J0226+0015') gal_id: str Name of galaxy (e.g. '268_22') skip_ions : bool, optional Avoid loading the ions (not recommended) verbose : bool, optional """ # Parse input if isinstance(inp, basestring): fil = inp elif isinstance(inp, tuple): field, gal_id = inp tmp = self.fits_path+'/'+field+'.'+gal_id+'.fits.gz' fils = glob.glob(tmp) if len(fils) != 1: raise IOError('Bad field, gal_id: {:s}'.format(tmp)) fil = fils[0] else: raise IOError('Bad input to load_single') # Read COS-Halos file if verbose: print('cos_halos: Reading {:s}'.format(fil)) hdu = fits.open(fil) summ = Table(hdu[1].data) galx = Table(hdu[2].data) # Instantiate the galaxy gal = Galaxy((galx['RA'][0], galx['DEC'][0]), z=summ['ZFINAL'][0]) gal.field = galx['FIELD'][0] gal.gal_id = galx['GALID'][0] # Galaxy properties gal.halo_mass = summ['LOGMHALO'][0] gal.stellar_mass = summ['LOGMFINAL'][0] gal.rvir = galx['RVIR'][0] gal.MH = galx['ABUN'][0] gal.flag_MH = galx['ABUN_FLAG'][0] gal.sdss_phot = [galx[key][0] for key in ['SDSSU','SDSSG','SDSSR','SDSSI','SDSSZ']] gal.sdss_phot_sig = [galx[key][0] for key in ['SDSSU_ERR','SDSSG_ERR','SDSSR_ERR','SDSSI_ERR','SDSSZ_ERR']] gal.sfr = (galx['SFR_UPLIM'][0], galx['SFR'][0], galx['SFR_FLAG'][0]) # FLAG actually gives method used gal.ssfr = galx['SSFR'][0] # Instantiate the IGM System igm_sys = IGMSystem((galx['QSORA'][0], galx['QSODEC'][0]), summ['ZFINAL'][0], [-600, 600.]*u.km/u.s, abs_type='CGM') igm_sys.zqso = galx['ZQSO'][0] # Instantiate cgabs = CGMAbsSys(gal, igm_sys, name=gal.field+'_'+gal.gal_id, **kwargs) # EBV cgabs.ebv = galx['EBV'][0] # Ions if skip_ions is True: # NHI dat_tab = Table(hdu[3].data) #if dat_tab['Z'] != 1: # raise ValueError("Uh oh") cgabs.igm_sys.NHI = dat_tab['CLM'][0] cgabs.igm_sys.sig_NHI = dat_tab['SIG_CLM'][0] cgabs.igm_sys.flag_NHI = dat_tab['FLG_CLM'][0] self.cgm_abs.append(cgabs) return all_Z = [] all_ion = [] for jj in range(summ['NION'][0]): iont = hdu[3+jj].data if jj == 0: # Generate new Table dat_tab = Table(iont) else: try: dat_tab.add_row(Table(iont)[0]) except: pdb.set_trace() all_Z.append(iont['ZION'][0][0]) all_ion.append(iont['ZION'][0][1]) # AbsLines abslines = [] ntrans = len(np.where(iont['LAMBDA'][0] > 1.)[0]) for kk in range(ntrans): flg = iont['FLG'][0][kk] # Fill in aline = AbsLine(iont['LAMBDA'][0][kk]*u.AA, closest=True) aline.attrib['flag_origCH'] = int(flg) aline.attrib['EW'] = iont['WOBS'][0][kk]*u.AA/1e3 # Observed aline.attrib['sig_EW'] = iont['SIGWOBS'][0][kk]*u.AA/1e3 if aline.attrib['EW'] > 3.*aline.attrib['sig_EW']: aline.attrib['flag_EW'] = 1 else: aline.attrib['flag_EW'] = 3 # Force an upper limit (i.e. from a blend) if (flg == 2) or (flg == 4) or (flg == 6): aline.attrib['flag_EW'] = 3 # aline.analy['vlim'] = [iont['VMIN'][0][kk],iont['VMAX'][0][kk]]*u.km/u.s aline.attrib['z'] = igm_sys.zabs aline.attrib['coord'] = igm_sys.coord # Check f if (np.abs(aline.data['f']-iont['FVAL'][0][kk])/aline.data['f']) > 0.001: Nscl = iont['FVAL'][0][kk] / aline.data['f'] flag_f = True else: Nscl = 1. flag_f = False # Colm if ((flg % 2) == 0) or (flg == 15) or (flg == 13): flgN = 0 print('Skipping column contribution from {:g} as NG for a line; flg={:d}'.format(iont['LAMBDA'][0][kk],flg)) elif (flg == 1) or (flg == 3): flgN = 1 elif (flg == 5) or (flg == 7): flgN = 3 elif (flg == 9) or (flg == 11): flgN = 2 else: pdb.set_trace() raise ValueError("Bad flag!") if flgN == 3: aline.attrib['logN'] = iont['LOGN2SIG'][0][kk] + np.log10(Nscl) aline.attrib['sig_logN'] = 9. elif flgN == 0: # Not for N measurement pass else: aline.attrib['logN'] = iont['LOGN'][0][kk] + np.log10(Nscl) aline.attrib['sig_logN'] = iont['SIGLOGN'][0][kk] aline.attrib['flag_N'] = int(flgN) #pdb.set_trace() if flgN != 0: _,_ = ltaa.linear_clm(aline.attrib) # Append abslines.append(aline) # Component if len(abslines) == 0: comp = AbsComponent(cgabs.igm_sys.coord, (iont['ZION'][0][0],iont['ZION'][0][1]), igm_sys.zabs, igm_sys.vlim) else: comp = AbsComponent.from_abslines(abslines, chk_vel=False) if comp.Zion != (1,1): comp.synthesize_colm() # Combine the abs lines if np.abs(comp.logN - float(iont['CLM'][0])) > 0.15: print("New colm for ({:d},{:d}) and sys {:s} is {:g} different from old".format( comp.Zion[0], comp.Zion[1], cgabs.name, comp.logN - float(iont['CLM'][0]))) if comp.flag_N != iont['FLG_CLM'][0]: if comp.flag_N == 0: pass else: print("New flag for ({:d},{:d}) and sys {:s} is different from old".format( comp.Zion[0], comp.Zion[1], cgabs.name)) pdb.set_trace() #_,_ = ltaa.linear_clm(comp) cgabs.igm_sys.add_component(comp) self.cgm_abs.append(cgabs) # Add Z,ion dat_tab.add_column(Column(all_Z,name='Z')) dat_tab.add_column(Column(all_ion,name='ion')) # Rename dat_tab.rename_column('LOGN','indiv_logN') dat_tab.rename_column('SIGLOGN','indiv_sig_logN') dat_tab.rename_column('CLM','logN') dat_tab.rename_column('SIG_CLM','sig_logN') dat_tab.rename_column('FLG_CLM','flag_N') # Set self.cgm_abs[-1].igm_sys._ionN = dat_tab # NHI HI = (dat_tab['Z'] == 1) & (dat_tab['ion'] == 1) if np.sum(HI) > 0: self.cgm_abs[-1].igm_sys.NHI = dat_tab[HI]['logN'][0] self.cgm_abs[-1].igm_sys.sig_NHI = dat_tab[HI]['sig_logN'][0] self.cgm_abs[-1].igm_sys.flag_NHI = dat_tab[HI]['flag_N'][0] else: warnings.warn("No HI measurement for {}".format(self.cgm_abs[-1])) self.cgm_abs[-1].igm_sys.flag_NHI = 0
def cgm_from_galaxy_igmsystems(galaxy, igmsystems, rho_max=300 * u.kpc, dv_max=400 * u.km / u.s, cosmo=None, dummysys=False, dummyspec=None, verbose=True, **kwargs): """ Generate a list of CGMAbsSys objects given an input galaxy and a list of IGMSystems Parameters ---------- galaxy : Galaxy igmsystems : list list of IGMSystems rho_max : Quantity Maximum projected separation from sightline to galaxy dv_max Maximum velocity offset between system and galaxy dummysys: bool, optional If True, instantiate CGMAbsSys even if no match is found in igmsystems dummyspec : XSpectrum1D, optional Spectrum object to attach to dummy AbsLine/AbsComponent objects when adding IGMSystems if dummysys is True. Returns ------- cgm_list : list list of CGM objects generated """ from pyigm.cgm.cgm import CGMAbsSys # Cosmology if cosmo is None: cosmo = cosmology.Planck15 if dummysys is True: if dummyspec is None: dummyspec = igmsystems[0]._components[0]._abslines[0].analy['spec'] dummycoords = igmsystems[0].coord # R -- speed things up rho, angles = calc_cgm_rho(galaxy, igmsystems, cosmo, **kwargs) if len(igmsystems) == 1: # Kludge rho = u.Quantity([rho]) angles = u.Quantity([angles]) # dv igm_z = np.array([igmsystem.zabs for igmsystem in igmsystems]) dv = ltu.dv_from_z(igm_z, galaxy.z) # Rules match = np.where((rho < rho_max) & (np.abs(dv) < dv_max))[0] ### If none, see if some system has a component that's actually within dv_max if (len(match) == 0) & (rho[0] < rho_max): zcomps = [] sysidxs = [] for i, csys in enumerate(igmsystems): thesezs = [comp.zcomp for comp in csys._components] sysidxs.extend([i] * len(thesezs)) zcomps.extend(thesezs) zcomps = np.array(zcomps) sysidxs = np.array(sysidxs) dv_comps = ltu.dv_from_z(zcomps, galaxy.z) match = np.unique(sysidxs[np.where(np.abs(dv_comps) < dv_max)[0]]) if len(match) == 0: if dummysys is False: print( "No IGMSystem paired to this galaxy. CGM object not created.") return [] else: if verbose: print("No IGMSystem match found. Attaching dummy IGMSystem.") dummysystem = IGMSystem(dummycoords, galaxy.z, vlim=None) dummycomp = AbsComponent(dummycoords, (1, 1), galaxy.z, [-100., 100.] * u.km / u.s) dummycomp.flag_N = 3 dummyline = AbsLine( 'HI 1215', **kwargs) # Need an actual transition for comp check dummyline.analy['spec'] = dummyspec dummyline.attrib['coord'] = dummycoords dummycomp.add_absline(dummyline, chk_vel=False, chk_sep=False) dummysystem.add_component(dummycomp, chk_vel=False, chk_sep=False) cgm = CGMAbsSys(galaxy, dummysystem, cosmo=cosmo, **kwargs) cgm_list = [cgm] else: # Loop to generate cgm_list = [] for imatch in match: # Instantiate new IGMSystem # Otherwise, updates to the IGMSystem cross-pollinate other CGMs sysmatch = igmsystems[imatch] newisys = sysmatch.copy() # Handle z limits zlim = ltu.z_from_dv((-dv_max.value, dv_max.value) * u.km / u.s, galaxy.z) newlims = zLimits(galaxy.z, zlim.tolist()) newisys.limits = newlims # Allow for components extending beyond dv_max newisys.update_vlim() newisys.update_component_vel() # Finish cgm = CGMAbsSys(galaxy, newisys, cosmo=cosmo, rho=rho[imatch], ang_sep=angles[imatch], **kwargs) cgm_list.append(cgm) # Return return cgm_list
def load_hotgas(self): """ Load data on hot gas (e.g. OVII, OVIII) Fang+15 """ from linetools.lists.linelist import LineList from linetools.analysis.absline import linear_clm llist = LineList('EUV',use_ISM_table=False) ovii = AbsLine('OVII 21', linelist=llist) # Fang+15 Table 1 [OVII] self.fang15 = Table.read(pyigm.__path__[0]+'/data/CGM/Galaxy/fang15_table1.dat', format='cds') print('Loading Fang+15 for OVII') # Reference if len(self.refs) > 0: self.refs += ',' self.refs += 'Fang+15' # Generate the systems # # (should check to see if low-ion ones exist already) for row in self.fang15: # Coordinates gc = SkyCoord(l=row['GLON']*u.degree, b=row['GLAT']*u.degree, frame='galactic') # Limits # OVII line aline = ovii.copy() aline.attrib['coord'] = gc z = row['Vel']/c_kms try: aline.setz(z) except IOError: z = 0. vlim = np.array([-300,300]) * u.km/u.s aline.attrib['flag_EW'] = 3 aline.attrib['flag_N'] = 0 # Might be able to set an upper limit aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA aline.attrib['sig_EW'] = 99. * u.AA else: aline.attrib['b'] = row['b'] * u.km / u.s aline.attrib['flag_EW'] = 1 aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA aline.attrib['sig_EW'] = row['e_EW1'] / 1e3 * u.AA vlim = np.array([-1,1]) * (2 * row['b'] + 2 * row['E_b']) * u.km/u.s # N_OVII aline.attrib['flag_N'] = 1 aline.attrib['logN'] = row['logNO'] aline.attrib['sig_logN'] = np.array([row['e_logNO'], row['E_logNO']]) # Fill linear _,_ = linear_clm(aline.attrib) # OVII aline.limits.set(vlim) # Generate component and add comp = AbsComponent.from_abslines([aline]) comp.synthesize_colm() # Instantiate abssys = IGMSystem(gc, z, vlim, name=row['Name']+'_z0', zem=row['z']) abssys.add_component(comp, chk_sep=False) # CGM Abs cgmabs = CGMAbsSys(self.galaxy, abssys, Galactic=True) # Add to cgm_abs self.abs.cgm_abs.append(cgmabs) scoord = self.abs.scoord # Sightline coordiantes # Savage+03 Table 2 [OVI] -- Thick disk/halo only?? print('Loading Savage+03 for OVI') self.savage03 = Table.read(pyigm.__path__[0] + '/data/CGM/Galaxy/savage03_table2.fits') # Reference if len(self.refs) > 0: self.refs += ',' self.refs += 'Savage+03' # Generate the systems # # (should check to see if low-ion ones exist already) for row in self.savage03: # Coordinates coord = SkyCoord(ra=row['_RA']*u.deg, dec=row['_DE']*u.deg, frame='fk5') gc = coord.transform_to('galactic') # Build the component vlim = np.array([row['V-'],row['V_']])*u.km/u.s comp = AbsComponent(gc, (8,6), 0., vlim) # Add attributes if row['b'] > 0.: comp.attrib['vcen'] = row['__v_obs']*u.km/u.s comp.attrib['sig_vcen'] = row['e__v_obs']*u.km/u.s comp.attrib['b'] = row['b']*u.km/u.s comp.attrib['sig_b'] = row['e_b']*u.km/u.s # Column comp.flag_N = 1 comp.logN = row['logN_OVI_'] comp.sig_logN = np.sqrt(row['e_sc']**2 + row['e_sys']**2) else: # Upper limit comp.flag_N = 3 comp.logN = row['logN_OVI_'] comp.sig_logN = 99. # Check for existing system minsep = np.min(comp.coord.separation(scoord).to('arcsec')) if minsep < 30*u.arcsec: idx = np.argmin(comp.coord.separation(scoord).to('arcsec')) self.abs.cgm_abs[idx].igm_sys.add_component(comp, chk_sep=False, debug=True) else: # New if row['RV'] > 0: zem = row['RV']/c_kms else: zem = row['z'] abssys = IGMSystem(gc, comp.zcomp, vlim, name=row['Name']+'_z0', zem=zem) abssys.add_component(comp, chk_sep=False, debug=True) # CGM Abs cgmabs = CGMAbsSys(self.galaxy, abssys, Galactic=True) # Add to cgm_abs self.abs.cgm_abs.append(cgmabs)
def p11(): """ Ingest Prochaska et al. 2011 CGM survey """ # Low z OVI summary ovi_file = pyigm.__path__[0] + '/data/CGM/P11/lowovidat.fits' ovidat = Table.read(ovi_file) qso_radec = SkyCoord(ra=ovidat['QSO_RA'], dec=ovidat['QSO_DEC'], unit=(u.hourangle, u.deg)) qso_nms = np.array([row['QSO'].strip() for row in ovidat]) # CGM Survey p11 = CGMAbsSurvey(survey='P11', ref='Prochaska+11') # Dwarfs cgm_dwarf_file = pyigm.__path__[0] + '/data/CGM/P11/dwarf_galabs_strct.fits' cgm_dwarfs = Table.read(cgm_dwarf_file) # sub L* cgm_subls_file = pyigm.__path__[0] + '/data/CGM/P11/subls_galabs_strct.fits' cgm_subls = Table.read(cgm_subls_file) # L* cgm_lstar_file = pyigm.__path__[0] + '/data/CGM/P11/lstar_galabs_strct.fits' cgm_lstar = Table.read(cgm_lstar_file) # Loop on subsets for subset in [cgm_dwarfs, cgm_subls, cgm_lstar]: for row in subset: # RA, DEC # Galaxy gal = Galaxy((row['RA'], row['DEC']), z=row['Z']) gal.Lstar = row['DDEC'] gal.type = row['GAL_TYPE'] # IGMSys mtqso = np.where(qso_nms == row['FIELD'].strip())[0] if len(mtqso) != 1: pdb.set_trace() raise ValueError("No Field match") igmsys = IGMSystem(qso_radec[mtqso[0]], row['Z'], (-400., 400.) * u.km / u.s) # HI if row['MAG'][2] > 0.: # Lya lya = AbsLine(1215.67 * u.AA, z=float(row['MAG'][3])) lya.attrib['EW'] = row['MAG'][4] / 1e3 * u.AA if row['MAG'][5] >= 99.: lya.attrib['flag_EW'] = 3 else: lya.attrib['flag_EW'] = 1 lya.attrib['sig_EW'] = row['MAG'][5] / 1e3 * u.AA # Ref lya.attrib['Ref'] = int(row['MAG'][2]) # HI component if row['MAG'][9] <= 0.: flagN = 3 elif row['MAG'][9] > 9.: flagN = 2 else: flagN = 1 HIcomp = AbsComponent(qso_radec[mtqso[0]], (1, 1), float(row['MAG'][3]), (-400, 400) * u.km / u.s, Ntup=(flagN, row['MAG'][8], row['MAG'][9])) HIcomp._abslines.append(lya) igmsys._components.append(HIcomp) # NHI igmsys.NHI = HIcomp.logN igmsys.flag_NHI = HIcomp.flag_N igmsys.sig_NHI = HIcomp.sig_N # OVI if row['MAGERR'][2] > 0.: # OVI 1031 ovi1031 = None if row['MAGERR'][4] > 0.: ovi1031 = AbsLine(1031.9261 * u.AA, z=float(row['MAGERR'][3])) if row['MAGERR'][5] >= 99.: ovi1031.attrib['flag_EW'] = 3 else: ovi1031.attrib['flag_EW'] = 1 ovi1031.attrib['EW'] = row['MAGERR'][4] / 1e3 * u.AA ovi1031.attrib['sig_EW'] = row['MAGERR'][5] / 1e3 * u.AA # OVI component if row['MAGERR'][9] <= 0.: flagN = 3 elif row['MAGERR'][9] > 9.: flagN = 2 else: flagN = 1 OVIcomp = AbsComponent(qso_radec[mtqso[0]], (8, 6), float(row['MAGERR'][3]), (-400, 400) * u.km / u.s, Ntup=(flagN, row['MAGERR'][8], row['MAGERR'][9])) if ovi1031 is not None: OVIcomp._abslines.append(ovi1031) # Ref OVIcomp.Ref = int(row['MAG'][2]) igmsys._components.append(OVIcomp) # CGM cgmabs = CGMAbsSys(gal, igmsys, chk_lowz=False) p11.cgm_abs.append(cgmabs) # Write tarball out_file = pyigm.__path__[0] + '/data/CGM/P11/P11_sys.tar' p11.to_json_tarball(out_file)
def load_single_fits(self, inp, skip_ions=False, verbose=True, **kwargs): """ Load a single COS-Halos sightline Appends to cgm_abs list Parameters ---------- inp : tuple or str if tuple -- (field,gal_id) field: str Name of field (e.g. 'J0226+0015') gal_id: str Name of galaxy (e.g. '268_22') skip_ions : bool, optional Avoid loading the ions (not recommended) verbose : bool, optional """ # Parse input if isinstance(inp, basestring): fil = inp elif isinstance(inp, tuple): field, gal_id = inp tmp = self.fits_path + '/' + field + '.' + gal_id + '.fits.gz' fils = glob.glob(tmp) if len(fils) != 1: raise IOError('Bad field, gal_id: {:s}'.format(tmp)) fil = fils[0] else: raise IOError('Bad input to load_single') # Read COS-Halos file if verbose: print('cos_halos: Reading {:s}'.format(fil)) hdu = fits.open(fil) summ = Table(hdu[1].data) galx = Table(hdu[2].data) # Instantiate the galaxy gal = Galaxy((galx['RA'][0], galx['DEC'][0]), z=summ['ZFINAL'][0]) gal.field = galx['FIELD'][0] gal.gal_id = galx['GALID'][0] # Galaxy properties gal.halo_mass = summ['LOGMHALO'][0] gal.stellar_mass = summ['LOGMFINAL'][0] gal.rvir = galx['RVIR'][0] gal.MH = galx['ABUN'][0] gal.flag_MH = galx['ABUN_FLAG'][0] gal.sdss_phot = [ galx[key][0] for key in ['SDSSU', 'SDSSG', 'SDSSR', 'SDSSI', 'SDSSZ'] ] gal.sdss_phot_sig = [ galx[key][0] for key in ['SDSSU_ERR', 'SDSSG_ERR', 'SDSSR_ERR', 'SDSSI_ERR', 'SDSSZ_ERR'] ] gal.sfr = (galx['SFR_UPLIM'][0], galx['SFR'][0], galx['SFR_FLAG'][0] ) # FLAG actually gives method used gal.ssfr = galx['SSFR'][0] # Instantiate the IGM System igm_sys = IGMSystem((galx['QSORA'][0], galx['QSODEC'][0]), summ['ZFINAL'][0], [-600, 600.] * u.km / u.s, abs_type='CGM') igm_sys.zqso = galx['ZQSO'][0] # Instantiate cgabs = CGMAbsSys(gal, igm_sys, name=gal.field + '_' + gal.gal_id, **kwargs) # EBV cgabs.ebv = galx['EBV'][0] # Ions if skip_ions is True: # NHI dat_tab = Table(hdu[3].data) #if dat_tab['Z'] != 1: # raise ValueError("Uh oh") cgabs.igm_sys.NHI = dat_tab['CLM'][0] cgabs.igm_sys.sig_NHI = dat_tab['SIG_CLM'][0] cgabs.igm_sys.flag_NHI = dat_tab['FLG_CLM'][0] self.cgm_abs.append(cgabs) return all_Z = [] all_ion = [] for jj in range(summ['NION'][0]): iont = hdu[3 + jj].data if jj == 0: # Generate new Table dat_tab = Table(iont) else: try: dat_tab.add_row(Table(iont)[0]) except: pdb.set_trace() all_Z.append(iont['ZION'][0][0]) all_ion.append(iont['ZION'][0][1]) # AbsLines abslines = [] ntrans = len(np.where(iont['LAMBDA'][0] > 1.)[0]) for kk in range(ntrans): flg = iont['FLG'][0][kk] # Fill in aline = AbsLine(iont['LAMBDA'][0][kk] * u.AA, closest=True) aline.attrib['flag_origCH'] = int(flg) aline.attrib[ 'EW'] = iont['WOBS'][0][kk] * u.AA / 1e3 # Observed aline.attrib['sig_EW'] = iont['SIGWOBS'][0][kk] * u.AA / 1e3 if aline.attrib['EW'] > 3. * aline.attrib['sig_EW']: aline.attrib['flag_EW'] = 1 else: aline.attrib['flag_EW'] = 3 # Force an upper limit (i.e. from a blend) if (flg == 2) or (flg == 4) or (flg == 6): aline.attrib['flag_EW'] = 3 # aline.analy['vlim'] = [ iont['VMIN'][0][kk], iont['VMAX'][0][kk] ] * u.km / u.s aline.attrib['z'] = igm_sys.zabs aline.attrib['coord'] = igm_sys.coord # Check f if (np.abs(aline.data['f'] - iont['FVAL'][0][kk]) / aline.data['f']) > 0.001: Nscl = iont['FVAL'][0][kk] / aline.data['f'] flag_f = True else: Nscl = 1. flag_f = False # Colm if ((flg % 2) == 0) or (flg == 15) or (flg == 13): flgN = 0 print( 'Skipping column contribution from {:g} as NG for a line; flg={:d}' .format(iont['LAMBDA'][0][kk], flg)) elif (flg == 1) or (flg == 3): flgN = 1 elif (flg == 5) or (flg == 7): flgN = 3 elif (flg == 9) or (flg == 11): flgN = 2 else: pdb.set_trace() raise ValueError("Bad flag!") if flgN == 3: aline.attrib['logN'] = iont['LOGN2SIG'][0][kk] + np.log10( Nscl) aline.attrib['sig_logN'] = 9. elif flgN == 0: # Not for N measurement pass else: aline.attrib['logN'] = iont['LOGN'][0][kk] + np.log10(Nscl) aline.attrib['sig_logN'] = iont['SIGLOGN'][0][kk] aline.attrib['flag_N'] = int(flgN) #pdb.set_trace() if flgN != 0: _, _ = ltaa.linear_clm(aline.attrib) # Append abslines.append(aline) # Component if len(abslines) == 0: comp = AbsComponent(cgabs.igm_sys.coord, (iont['ZION'][0][0], iont['ZION'][0][1]), igm_sys.zabs, igm_sys.vlim) else: comp = AbsComponent.from_abslines(abslines, chk_vel=False) if comp.Zion != (1, 1): comp.synthesize_colm() # Combine the abs lines if np.abs(comp.logN - float(iont['CLM'][0])) > 0.15: print( "New colm for ({:d},{:d}) and sys {:s} is {:g} different from old" .format(comp.Zion[0], comp.Zion[1], cgabs.name, comp.logN - float(iont['CLM'][0]))) if comp.flag_N != iont['FLG_CLM'][0]: if comp.flag_N == 0: pass else: print( "New flag for ({:d},{:d}) and sys {:s} is different from old" .format(comp.Zion[0], comp.Zion[1], cgabs.name)) pdb.set_trace() #_,_ = ltaa.linear_clm(comp) cgabs.igm_sys.add_component(comp) self.cgm_abs.append(cgabs) # Add Z,ion dat_tab.add_column(Column(all_Z, name='Z')) dat_tab.add_column(Column(all_ion, name='ion')) # Rename dat_tab.rename_column('LOGN', 'indiv_logN') dat_tab.rename_column('SIGLOGN', 'indiv_sig_logN') dat_tab.rename_column('CLM', 'logN') dat_tab.rename_column('SIG_CLM', 'sig_logN') dat_tab.rename_column('FLG_CLM', 'flag_N') # Set self.cgm_abs[-1].igm_sys._ionN = dat_tab # NHI HI = (dat_tab['Z'] == 1) & (dat_tab['ion'] == 1) if np.sum(HI) > 0: self.cgm_abs[-1].igm_sys.NHI = dat_tab[HI]['logN'][0] self.cgm_abs[-1].igm_sys.sig_NHI = dat_tab[HI]['sig_logN'][0] self.cgm_abs[-1].igm_sys.flag_NHI = dat_tab[HI]['flag_N'][0] else: warnings.warn("No HI measurement for {}".format(self.cgm_abs[-1])) self.cgm_abs[-1].igm_sys.flag_NHI = 0
def load_data(self, **kwargs): # q6file = self.data_file if self.from_dict: qpq6dict = CGMAbsSurvey.from_json(q6file) ism = LineList('ISM') qpq6dict.build_systems_from_dict(llist=ism) self.survey_data = qpq6dict #self.cgm_abs = qpq6dict.cgm_abs else: qpqdata = Table.read(q6file) if self.nmax is not None: nmax = self.nmax else: nmax = len(qpqdata) for i in range(nmax): # Instantiate the galaxy gal = Galaxy((qpqdata['RAD'][i], qpqdata['DECD'][i]), z=qpqdata['Z_FG'][i]) gal.L_BOL = qpqdata['L_BOL'][i] gal.L_912 = qpqdata['L_912'][i] gal.G_UV = qpqdata['G_UV'][i] gal.flg_BOSS = qpqdata['FLG_BOSS'][i] gal.zsig = qpqdata['Z_FSIG'][i] * u.km / u.s # Instantiate the IGM System igm_sys = IGMSystem( (qpqdata['RAD_BG'][i], qpqdata['DECD_BG'][i]), qpqdata['Z_FG'][i], [-5500, 5500.] * u.km / u.s, abs_type='CGM' ) ## if velocity range lower - does not load all abslines igm_sys.zem = qpqdata['Z_BG'][i] igm_sys.NHI = qpqdata['NHI'][i] igm_sys.sig_NHI = qpqdata['SIG_NHI'][i] igm_sys.flag_NHI = qpqdata['FLG_NHI'][i] igm_sys.s2n_lya = qpqdata['S2N_LYA'][i] igm_sys.flg_othick = qpqdata['FLG_OTHICK'][i] igm_sys.z_lya = qpqdata['Z_LYA'][i] iname = qpqdata['QSO'][i] # Instantiate rho = qpqdata['R_PHYS'][i] * u.kpc cgabs = CGMAbsSys(gal, igm_sys, name=iname, rho=rho, **kwargs) aline = AbsLine(1215.67 * u.AA, closest=True, z=igm_sys.zabs) aline.attrib['EW'] = qpqdata['EWLYA'][i] * u.AA # Rest EW aline.attrib['sig_EW'] = qpqdata['SIG_EWLYA'][i] * u.AA if aline.attrib['EW'] > 3. * aline.attrib['sig_EW']: aline.attrib['flag_EW'] = 1 else: aline.attrib['flag_EW'] = 3 aline.attrib['coord'] = igm_sys.coord aline.limits._wvlim = qpqdata['WVMNX'][i] * u.AA dv = ltu.rel_vel(aline.limits._wvlim, aline.wrest * (1 + qpqdata['Z_FG'][i])) aline.limits._vlim = dv abslines = [] abslines.append(aline) ### comp = AbsComponent.from_abslines(abslines, chk_vel=False) # add ang_sep qsocoord = SkyCoord(ra=qpqdata['RAD'][i], dec=qpqdata['DECD'][i], unit='deg') bgcoord = SkyCoord(ra=qpqdata['RAD_BG'][i], dec=qpqdata['DECD_BG'][i], unit='deg') cgabs.ang_sep = qsocoord.separation(bgcoord).to('arcsec') cgabs.igm_sys.add_component(comp) self.cgm_abs.append(cgabs)
def load_coolgas(self): """ Load data on cool gas (CII, CIV, SiII, SiIII) Richter+17 """ llist = LineList('ISM') # Ricther+17 print('Loading Richter+17 for CII, CIV, SiII, SiIII') r17_a1_file = resource_filename('pyigm', '/data/CGM/Galaxy/richter17_A1.fits') r17_a1 = Table.read(r17_a1_file) r17_a2_file = resource_filename('pyigm', '/data/CGM/Galaxy/richter17_A2.fits') r17_a2 = Table.read(r17_a2_file) # Coords coords = SkyCoord(ra=r17_a1['_RAJ2000'], dec=r17_a1['_DEJ2000'], unit='deg') gc = coords.transform_to('galactic') ra = np.zeros((len(r17_a2))) dec = np.zeros((len(r17_a2))) # Loop on Sightlines for kk, row in enumerate(r17_a1): if self.debug and (kk == 5): break a2_idx = np.where(r17_a2['Name'] == row['Name'])[0] if len(a2_idx) == 0: continue ra[a2_idx] = row['_RAJ2000'] dec[a2_idx] = row['_DEJ2000'] # Generate the components icoord = gc[kk] alines = [] for jj, idx in enumerate(a2_idx): # Transition trans = '{:s} {:d}'.format(r17_a2['Ion'][idx].strip(), int(r17_a2['lambda0'][idx])) try: aline = AbsLine(trans, linelist=llist) except ValueError: pdb.set_trace() aline.attrib['coord'] = icoord # Skip EW=0 lines if r17_a2['e_W'][idx] == 0: continue # Velocity z = 0. aline.setz(z) vlim = np.array([r17_a2['vmin'][idx], r17_a2['vmax'][idx] ]) * u.km / u.s aline.limits.set(vlim) # These are v_LSR # EW aline.attrib['flag_EW'] = 1 aline.attrib['EW'] = r17_a2['W'][idx] / 1e3 * u.AA aline.attrib['sig_EW'] = r17_a2['e_W'][idx] / 1e3 * u.AA # Column if np.isnan( r17_a2['logN'] [idx]): # Odd that some lines had an error but no value aline.attrib['flag_N'] = 0 elif r17_a2['l_logN'][idx] == '>': aline.attrib['flag_N'] = 2 aline.attrib['sig_logN'] = 99.99 else: aline.attrib['flag_N'] = 1 aline.attrib['sig_logN'] = r17_a2['e_logN'][idx] aline.attrib['logN'] = r17_a2['logN'][idx] # Fill linear _, _ = linear_clm(aline.attrib) alines.append(aline) # Generate components from abslines comps = ltiu.build_components_from_abslines(alines, chk_sep=False, chk_vel=False) # Limits vmin = np.min([icomp.limits.vmin.value for icomp in comps]) vmax = np.max([icomp.limits.vmax.value for icomp in comps]) # Instantiate s_kwargs = dict(name=row['Name'] + '_z0') c_kwargs = dict(chk_sep=False, chk_z=False) abssys = IGMSystem.from_components(comps, vlim=[vmin, vmax] * u.km / u.s, s_kwargs=s_kwargs, c_kwargs=c_kwargs) # CGM Abs rho, ang_sep = calc_Galactic_rho(abssys.coord) cgmabs = CGMAbsSys(self.galaxy, abssys, rho=rho, ang_sep=ang_sep, cosmo=self.cosmo) # Add to cgm_abs self.abs.cgm_abs.append(cgmabs) # Finish r17_a2['RA'] = ra r17_a2['DEC'] = dec self.richter17 = r17_a2 # Reference if len(self.refs) > 0: self.refs += ',' self.refs += 'Richter+17'
def load_hotgas(self): """ Load data on hot gas (e.g. OVII, OVIII) Fang+15 """ # Init llist = LineList('EUV') ovii = AbsLine('OVII 21', linelist=llist) scoord = self.abs.scoord # Sightline coordiantes # Fang+15 Table 1 [OVII] fang15_file = resource_filename('pyigm', '/data/CGM/Galaxy/fang15_table1.dat') self.fang15 = Table.read(fang15_file, format='cds') print('Loading Fang+15 for OVII') # Reference if len(self.refs) > 0: self.refs += ',' self.refs += 'Fang+15' # Generate the systems # # (should check to see if low-ion ones exist already) for row in self.fang15: # Coordinates gc = SkyCoord(l=row['GLON'] * u.degree, b=row['GLAT'] * u.degree, frame='galactic') # Limits # OVII line aline = ovii.copy() aline.attrib['coord'] = gc z = row['Vel'] / c_kms try: aline.setz(z) except IOError: z = 0. vlim = np.array([-300, 300]) * u.km / u.s aline.attrib['flag_EW'] = 3 aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA aline.attrib['sig_EW'] = 99. * u.AA # aline.attrib[ 'flag_N'] = 0 # Might be able to set an upper limit else: aline.attrib['b'] = row['b'] * u.km / u.s aline.attrib['flag_EW'] = 1 aline.attrib['EW'] = row['EW1'] / 1e3 * u.AA aline.attrib['sig_EW'] = row['e_EW1'] / 1e3 * u.AA vlim = np.array( [-1, 1]) * (2 * row['b'] + 2 * row['E_b']) * u.km / u.s # N_OVII aline.attrib['flag_N'] = 1 aline.attrib['logN'] = row['logNO'] aline.attrib['sig_logN'] = np.array( [row['e_logNO'], row['E_logNO']]) # Fill linear _, _ = linear_clm(aline.attrib) # OVII aline.limits.set(vlim) # Generate component and add comp = AbsComponent.from_abslines([aline]) if aline.attrib['flag_N'] == 0: # Hack to merge later comp.attrib['sig_logN'] = np.array([0., 0.]) else: pass # Check for existing system minsep = np.min(comp.coord.separation(scoord).to('arcsec')) if minsep < 30 * u.arcsec: # Add component to existing system idx = np.argmin(comp.coord.separation(scoord).to('arcsec')) if self.verbose: print("Adding OVII system to {}".format( self.abs.cgm_abs[idx].igm_sys)) self.abs.cgm_abs[idx].igm_sys.add_component(comp, chk_sep=False, debug=True) else: # Instantiate abssys = IGMSystem(gc, z, vlim, name=row['Name'] + '_z0', zem=row['z']) abssys.add_component(comp, chk_sep=False) # CGM Abs rho, ang_sep = calc_Galactic_rho(abssys.coord) cgmabs = CGMAbsSys(self.galaxy, abssys, rho=rho, ang_sep=ang_sep, cosmo=self.cosmo) # Add to cgm_abs self.abs.cgm_abs.append(cgmabs) scoord = self.abs.scoord # Sightline coordiantes # Savage+03 Table 2 [OVI] -- Thick disk/halo only?? print('Loading Savage+03 for OVI') savage03_file = resource_filename( 'pyigm', '/data/CGM/Galaxy/savage03_table2.fits') self.savage03 = Table.read(savage03_file) # Reference if len(self.refs) > 0: self.refs += ',' self.refs += 'Savage+03' # Generate the systems # # (should check to see if low-ion ones exist already) for row in self.savage03: # Coordinates coord = SkyCoord(ra=row['_RA'] * u.deg, dec=row['_DE'] * u.deg, frame='icrs') gc = coord.transform_to('galactic') # Build the component vlim = np.array([row['V-'], row['V_']]) * u.km / u.s comp = AbsComponent(gc, (8, 6), 0., vlim) # Add attributes if row['b'] > 0.: comp.attrib['vcen'] = row['__v_obs'] * u.km / u.s comp.attrib['sig_vcen'] = row['e__v_obs'] * u.km / u.s comp.attrib['b'] = row['b'] * u.km / u.s comp.attrib['sig_b'] = row['e_b'] * u.km / u.s # Column comp.attrib['flag_N'] = 1 comp.attrib['logN'] = row['logN_OVI_'] comp.attrib['sig_logN'] = np.array( [np.sqrt(row['e_sc']**2 + row['e_sys']**2)] * 2) else: # Upper limit comp.attrib['flag_N'] = 3 comp.attrib['logN'] = row['logN_OVI_'] comp.attrib['sig_logN'] = np.array([99.] * 2) # Set linear quantities _, _ = linear_clm(comp.attrib) # Check for existing system minsep = np.min(comp.coord.separation(scoord).to('arcsec')) if minsep < 30 * u.arcsec: idx = np.argmin(comp.coord.separation(scoord).to('arcsec')) self.abs.cgm_abs[idx].igm_sys.add_component(comp, chk_sep=False, debug=True, update_vlim=True) else: # New if row['RV'] > 0: zem = row['RV'] / c_kms else: zem = row['z'] abssys = IGMSystem(gc, comp.zcomp, vlim, name=row['Name'] + '_z0', zem=zem) abssys.add_component(comp, chk_sep=False, debug=True) # CGM Abs rho, ang_sep = calc_Galactic_rho(abssys.coord) cgmabs = CGMAbsSys(self.galaxy, abssys, rho=rho, ang_sep=ang_sep, cosmo=self.cosmo) # Add to cgm_abs self.abs.cgm_abs.append(cgmabs)
def load_data(self, **kwargs): # #q8file = resource_filename('pyigm', 'data/CGM/QPQ/qpq8_all_measured.dat') q8file = self.data_file if self.from_dict: q8file = self.data_file qpq8dict = CGMAbsSurvey.from_json(q8file) ism = LineList('ISM') qpq8dict.build_systems_from_dict(llist=ism) self.survey_data = qpq8dict #self.cgm_abs = qpq8dict.cgm_abs else: qpqdata = Table.read(q8file, format='ascii') #nmax = len(qpqdata) # max number of QSOs q8filecoord = resource_filename('pyigm', 'data/CGM/QPQ/qpq8_pairs.fits') qpqdatacoord = Table.read(q8filecoord) if self.nmax is not None: nmax = self.nmax else: nmax = len(qpqdatacoord) #(qpqdata) # match names with qpqdatacoord qnames = [] for i in range(len(qpqdatacoord)): qname = qpqdatacoord['QSO'][i].strip() qnames.append(qname[-10:]) qnames2 = [] for i in range(len(qpqdata)): qname = qpqdata['Pair'][i] qnames2.append(qname) for j in range(nmax): # i,j # match names with qpqdatacoord i = np.where(np.asarray(qnames2) == qnames[j])[0] # Instantiate the galaxy gal = Galaxy((qpqdatacoord['RAD'][j], qpqdatacoord['DECD'][j]), z=qpqdatacoord['Z_FG'][j]) gal.L_BOL = qpqdatacoord['L_BOL'][j] gal.L_912 = qpqdatacoord['L_912'][j] gal.G_UV = qpqdatacoord['G_UV'][j] gal.zsig = qpqdatacoord['Z_FSIG'][j] * u.km / u.s # Instantiate the IGM System igm_sys = IGMSystem( (qpqdatacoord['RAD_BG'][j], qpqdatacoord['DECD_BG'][j]), qpqdatacoord['Z_FG'][j], [-5500, 5500.] * u.km / u.s, abs_type='CGM') # Redshifts: QSO emission redshifts igm_sys.zem = qpqdatacoord['Z_BG'][j] igm_sys.NHI = qpqdata['HIcol'][i] igm_sys.sig_NHI = [ qpqdata['HIcolhierr'][i], qpqdata['HIcolloerr'][i] ] igm_sys.s2n_lya = qpqdatacoord['S2N_LYA'][j] iname = qpqdata['Pair'][i][0] #+'_'+qpqdata['subsys'][i] # Instantiate rho = qpqdatacoord['R_PHYS'][j] * u.kpc cgabs = CGMAbsSys(gal, igm_sys, name=iname, rho=rho, **kwargs) ### add metal lines ### not included CII*, SiII* lines = [ ['CII 1334'], ## ['CII* 1335'], ['CIV 1548', 'CIV 1550'], ['NI 1134', 'NI 1199'], ['NII 1083'], ['NV 1238', 'NV 1242'], ['OI 1302'], ['OVI 1037'], ['MgI 2852'], ['MgII 2796', 'MgII 2803'], ['AlII 1670'], ['AlIII 1854', 'AlIII 1862'], [ 'SiII 1190', 'SiII 1193', 'SiII 1304', 'SiII 1260', 'SiII 1526', 'SiII 1808' ], ## ['SiII* 1264'], ['SiIII 1206'], ['SiIV 1393', 'SiIV 1402'], [ 'FeII 1608', 'FeII 2344', 'FeII 2374', 'FeII 2382', 'FeII 2586', 'FeII 2600' ], ['FeIII 1122'] ] for kk in i: for icmp in range(len(lines)): abslines = [] for ii in range(len(lines[icmp])): wave0 = float(lines[icmp][ii].split(' ')[1]) ewstr = str(lines[icmp][ii].split(' ')[1]) + 'EW' ewerrstr = str( lines[icmp][ii].split(' ')[1]) + 'EWerr' if ewstr == '1808EW': ewstr = '1808E' if ewerrstr == '1122EWerr': ewerrstr = '122EWerr' if qpqdata[ewstr][kk] != '/': # find z v0 = 0.5 * ( qpqdata['v_lobound'][kk] + qpqdata['v_upbound'][kk]) * u.km / u.s dv = v0 zref = igm_sys.zabs z_cmp = ltu.z_from_dv(dv, zref) ## vlim v1 = qpqdata['v_lobound'][kk] * u.km / u.s z1 = ltu.z_from_dv(v1, zref) v1_cmp = ltu.dv_from_z(z1, z_cmp) v2 = qpqdata['v_upbound'][kk] * u.km / u.s z2 = ltu.z_from_dv(v2, zref) v2_cmp = ltu.dv_from_z(z2, z_cmp) # iline iline = AbsLine(wave0 * u.AA, closest=True, z=z_cmp) iline.attrib['coord'] = igm_sys.coord ## EW iline.attrib['EW'] = float( qpqdata[ewstr][kk]) * u.AA # Rest EW iline.attrib['sig_EW'] = float( qpqdata[ewerrstr][kk]) * u.AA flgew = 1 if iline.attrib[ 'EW'] < 3. * iline.attrib['sig_EW']: flgew = 3 iline.attrib['flag_EW'] = flgew ## column densities colstr = str( lines[icmp][ii].split(' ')[0]) + 'col' colerrstr = str( lines[icmp][ii].split(' ')[0]) + 'colerr' iline.attrib['logN'] = qpqdata[colstr][kk] iline.attrib['sig_logN'] = qpqdata[colerrstr][ kk] abslines.append(iline) if len(abslines) > 0: comp = AbsComponent.from_abslines(abslines, chk_vel=False) comp.limits._vlim = [v1_cmp.value, v2_cmp.value ] * u.km / u.s cgabs.igm_sys.add_component(comp) # add ang_sep qsocoord = SkyCoord(ra=qpqdatacoord['RAD'][j], dec=qpqdatacoord['DECD'][j], unit='deg') bgcoord = SkyCoord(ra=qpqdatacoord['RAD_BG'][j], dec=qpqdatacoord['DECD_BG'][j], unit='deg') cgabs.ang_sep = qsocoord.separation(bgcoord).to('arcsec') self.cgm_abs.append(cgabs)