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 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