def supplement(self): """ Add some supplemental columns """ from ugali.utils.projector import gal2cel, gal2cel_angle kwargs = dict(usemask=False, asrecarray=True) out = copy.deepcopy(self) if ('lon' in out.names) and ('lat' in out.names): # Ignore entries that are all zero zeros = np.all(self.ndarray == 0, axis=1) ra, dec = gal2cel(out.lon, out.lat) ra[zeros] = 0 dec[zeros] = 0 out = recfuncs.append_fields(out, ['ra', 'dec'], [ra, dec], **kwargs).view(Samples) if 'position_angle' in out.names: pa = gal2cel_angle(out.lon, out.lat, out.position_angle) pa = pa - 180. * (pa > 180.) pa[zeros] = 0 out = recfuncs.append_fields(out, ['position_angle_cel'], [pa], **kwargs).view(Samples) return out
def finalizeObjects(self, objects): objs = numpy.recarray(len(objects), dtype=[('NAME','S24'), ('TS','f4'), ('GLON','f4'), ('GLAT','f4'), ('RA','f4'), ('DEC','f4'), ('MODULUS','f4'), ('DISTANCE','f4'), ('RICHNESS','f4'), ('MASS','f4'), ('NANNULUS','i4'), ('NINTERIOR','i4'), ]) objs['TS'] = self.values[objects['IDX_MAX'],objects['ZIDX_MAX']] lon,lat = objects['X_MAX'],objects['Y_MAX'] coordsys = self.config['coords']['coordsys'] if coordsys.lower() == 'gal': print("GAL coordintes") objs['GLON'],objs['GLAT'] = lon,lat objs['RA'],objs['DEC'] = gal2cel(lon,lat) else: print("CEL coordintes") objs['RA'],objs['DEC'] = lon,lat objs['GLON'],objs['GLAT'] = cel2gal(lon,lat) modulus = objects['Z_MAX'] objs['MODULUS'] = modulus objs['DISTANCE'] = mod2dist(modulus) nside = healpy.npix2nside(len(self.nannulus)) pix = ang2pix(nside,lon,lat) richness = self.richness[objects['IDX_MAX'],objects['ZIDX_MAX']] objs['RICHNESS'] = richness objs['MASS'] = richness * self.stellar[pix] objs['NANNULUS'] = self.nannulus[pix].astype(int) objs['NINTERIOR'] = self.ninterior[pix].astype(int) # Default name formatting # http://cdsarc.u-strasbg.fr/ftp/pub/iau/ # http://cds.u-strasbg.fr/vizier/Dic/iau-spec.htx fmt = "J%(hour)02i%(hmin)04.1f%(deg)+03i%(dmin)02i" for obj,_ra,_dec in zip(objs,objs['RA'],objs['DEC']): hms = dec2hms(_ra); dms = dec2dms(_dec) params = dict(hour=hms[0],hmin=hms[1]+hms[2]/60., deg=dms[0],dmin=dms[1]+dms[2]/60.) obj['NAME'] = fmt%params out = recfuncs.merge_arrays([objs,objects],usemask=False, asrecarray=True,flatten=True) return out
def submit_all(self, coords=None, queue=None, debug=False): """ Submit likelihood analyses on a set of coordinates. If coords is `None`, submit all coordinates in the footprint. Inputs: coords : Array of target locations in Galactic coordinates. queue : Overwrite submit queue. debug : Don't run. """ if coords is None: pixels = np.arange(hp.nside2npix(self.nside_likelihood)) else: coords = np.asarray(coords) if coords.ndim == 1: coords = np.array([coords]) if coords.shape[1] == 2: lon, lat = coords.T radius = np.zeros(len(lon)) elif coords.shape[1] == 3: lon, lat, radius = coords.T else: raise Exception("Unrecognized coords shape:" + str(coords.shape)) #ADW: targets is still in glon,glat if self.config['coords']['coordsys'].lower() == 'cel': lon, lat = gal2cel(lon, lat) vec = ang2vec(lon, lat) pixels = np.zeros(0, dtype=int) for v, r in zip(vec, radius): pix = query_disc(self.nside_likelihood, v, r, inclusive=True, fact=32) pixels = np.hstack([pixels, pix]) #pixels = np.unique(pixels) inside = ugali.utils.skymap.inFootprint(self.config, pixels) if inside.sum() != len(pixels): logger.warning("Ignoring pixels outside survey footprint:\n" + str(pixels[~inside])) if inside.sum() == 0: logger.warning("No pixels inside footprint.") return # Only write the configfile once outdir = mkdir(self.config['output']['likedir']) # Actually copy config instead of re-writing shutil.copy(self.config.filename, outdir) configfile = join(outdir, os.path.basename(self.config.filename)) pixels = pixels[inside] self.submit(pixels, queue=queue, debug=debug, configfile=configfile)
def finalizeObjects(self, objects): objs = numpy.recarray(len(objects), dtype=[('NAME','S24'), ('TS','f4'), ('GLON','f4'), ('GLAT','f4'), ('RA','f4'), ('DEC','f4'), ('MODULUS','f4'), ('DISTANCE','f4'), ('RICHNESS','f4'), ('MASS','f4'), ('NANNULUS','i4'), ('NINTERIOR','i4'), ]) objs['TS'] = self.values[objects['IDX_MAX'],objects['ZIDX_MAX']] glon,glat = objects['X_MAX'],objects['Y_MAX'] objs['GLON'],objs['GLAT'] = glon,glat ra,dec = gal2cel(glon,glat) objs['RA'],objs['DEC'] = ra,dec modulus = objects['Z_MAX'] objs['MODULUS'] = modulus objs['DISTANCE'] = mod2dist(modulus) #ninterior = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'NINSIDE') #nannulus = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'NANNULUS') #stellar = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'STELLAR') nside = healpy.npix2nside(len(self.nannulus)) pix = ang2pix(nside,glon,glat) richness = self.richness[objects['IDX_MAX'],objects['ZIDX_MAX']] objs['RICHNESS'] = richness objs['MASS'] = richness * self.stellar[pix] objs['NANNULUS'] = self.nannulus[pix].astype(int) objs['NINTERIOR'] = self.ninterior[pix].astype(int) # Default name formatting # http://cdsarc.u-strasbg.fr/ftp/pub/iau/ # http://cds.u-strasbg.fr/vizier/Dic/iau-spec.htx fmt = "J%(hour)02i%(hmin)04.1f%(deg)+03i%(dmin)02i" for obj,_ra,_dec in zip(objs,ra,dec): hms = dec2hms(_ra); dms = dec2dms(_dec) params = dict(hour=hms[0],hmin=hms[1]+hms[2]/60., deg=dms[0],dmin=dms[1]+dms[2]/60.) obj['NAME'] = fmt%params out = recfuncs.merge_arrays([objs,objects],usemask=False,asrecarray=True,flatten=True) # This is safer than viewing as FITS_rec return pyfits.new_table(out).data
def finalizeObjects(self, objects): objs = np.recarray(len(objects), dtype=[ ('NAME', 'S24'), ('TS', 'f4'), ('GLON', 'f4'), ('GLAT', 'f4'), ('RA', 'f4'), ('DEC', 'f4'), ('MODULUS', 'f4'), ('DISTANCE', 'f4'), ('RICHNESS', 'f4'), ('MASS', 'f4'), ('NANNULUS', 'i4'), ('NINTERIOR', 'i4'), ]) objs['TS'] = self.values[objects['IDX_MAX'], objects['ZIDX_MAX']] lon, lat = objects['X_MAX'], objects['Y_MAX'] coordsys = self.config['coords']['coordsys'] if coordsys.lower() == 'gal': print("GAL coordintes") objs['GLON'], objs['GLAT'] = lon, lat objs['RA'], objs['DEC'] = gal2cel(lon, lat) else: print("CEL coordintes") objs['RA'], objs['DEC'] = lon, lat objs['GLON'], objs['GLAT'] = cel2gal(lon, lat) modulus = objects['Z_MAX'] objs['MODULUS'] = modulus objs['DISTANCE'] = mod2dist(modulus) nside = healpy.npix2nside(len(self.nannulus)) pix = ang2pix(nside, lon, lat) richness = self.richness[objects['IDX_MAX'], objects['ZIDX_MAX']] objs['RICHNESS'] = richness objs['MASS'] = richness * self.stellar[pix] objs['NANNULUS'] = self.nannulus[pix].astype(int) objs['NINTERIOR'] = self.ninterior[pix].astype(int) objs['NAME'] = ang2iau(objs['RA'], objs['DEC'], coord='cel') out = recfuncs.merge_arrays([objs, objects], usemask=False, asrecarray=True, flatten=True) return out
def _load(self,filename): kwargs = dict(delimiter='\t',usecols=[0,1,2],dtype=['S18',float,float]) if filename is None: filename = os.path.join(self.DATADIR,"WEBDA/webda.tsv") raw = np.genfromtxt(filename,**kwargs) self.data.resize(len(raw)) self.data['name'] = numpy.char.strip(raw['f0']) self.data['glon'] = raw['f1'] self.data['glat'] = raw['f2'] ra,dec = gal2cel(self.data['glon'],self.data['glat']) self.data['ra'],self.data['dec'] = ra,dec
def _load(self,filename): kwargs = dict(delimiter=[4,18,20,8,8],usecols=[1,3,4],dtype=['S18',float,float]) if filename is None: filename = os.path.join(self.DATADIR,"J_AA_558_A53/catalog.dat") raw = np.genfromtxt(filename,**kwargs) self.data.resize(len(raw)) self.data['name'] = numpy.char.strip(raw['f0']) self.data['glon'] = raw['f1'] self.data['glat'] = raw['f2'] ra,dec = gal2cel(self.data['glon'],self.data['glat']) self.data['ra'],self.data['dec'] = ra,dec
def supplement(self, coordsys='gal'): """ Add some supplemental columns """ from ugali.utils.projector import gal2cel, gal2cel_angle from ugali.utils.projector import cel2gal, cel2gal_angle coordsys = coordsys.lower() kwargs = dict(usemask=False, asrecarray=True) out = copy.deepcopy(self) if ('lon' in out.names) and ('lat' in out.names): # Ignore entries that are all zero zeros = np.all(self.ndarray == 0, axis=1) if coordsys == 'gal': ra, dec = gal2cel(out.lon, out.lat) glon, glat = out.lon, out.lat else: ra, dec = out.lon, out.lat glon, glat = cel2gal(out.lon, out.lat) ra[zeros] = 0 dec[zeros] = 0 glon[zeros] = 0 glat[zeros] = 0 names = ['ra', 'dec', 'glon', 'glat'] arrs = [ra, dec, glon, glat] out = mlab.rec_append_fields(out, names, arrs).view(Samples) #out = recfuncs.append_fields(out,names,arrs,**kwargs).view(Samples) if 'position_angle' in out.names: if coordsys == 'gal': pa_gal = out.position_angle pa_cel = gal2cel_angle(out.lon, out.lat, out.position_angle) pa_cel = pa_cel - 180. * (pa_cel > 180.) else: pa_gal = cel2gal_angle(out.lon, out.lat, out.position_angle) pa_cel = out.position_angle pa_gal = pa_gal - 180. * (pa_gal > 180.) pa_gal[zeros] = 0 pa_cel[zeros] = 0 names = ['position_angle_gal', 'position_angle_cel'] arrs = [pa_gal, pa_cel] out = recfuncs.append_fields(out, names, arrs, **kwargs).view(Samples) return out
def write_membership2(self, filename): ra, dec = gal2cel(self.catalog.lon, self.catalog.lat) name_objid = self.config['catalog']['objid_field'] name_mag_1 = self.config['catalog']['mag_1_field'] name_mag_2 = self.config['catalog']['mag_2_field'] name_mag_err_1 = self.config['catalog']['mag_err_1_field'] name_mag_err_2 = self.config['catalog']['mag_err_2_field'] # Angular and isochrone separations sep = angsep(self.source.lon, self.source.lat, self.catalog.lon, self.catalog.lat) isosep = self.isochrone.separation(self.catalog.mag_1, self.catalog.mag_2) columns = [ pyfits.Column(name=name_objid, format='K', array=self.catalog.objid), pyfits.Column(name='GLON', format='D', array=self.catalog.lon), pyfits.Column(name='GLAT', format='D', array=self.catalog.lat), pyfits.Column(name='RA', format='D', array=ra), pyfits.Column(name='DEC', format='D', array=dec), pyfits.Column(name=name_mag_1, format='E', array=self.catalog.mag_1), pyfits.Column(name=name_mag_err_1, format='E', array=self.catalog.mag_err_1), pyfits.Column(name=name_mag_2, format='E', array=self.catalog.mag_2), pyfits.Column(name=name_mag_err_2, format='E', array=self.catalog.mag_err_2), pyfits.Column(name='COLOR', format='E', array=self.catalog.color), pyfits.Column(name='ANGSEP', format='E', array=sep), pyfits.Column(name='ISOSEP', format='E', array=isosep), pyfits.Column(name='PROB', format='E', array=self.p), ] hdu = pyfits.new_table(columns) for param, value in self.source.params.items(): # HIERARCH allows header keywords longer than 8 characters name = 'HIERARCH %s' % param.upper() hdu.header.set(name, value.value, param) name = 'HIERARCH %s' % 'TS' hdu.header.set(name, self.ts()) name = 'HIERARCH %s' % 'TIMESTAMP' hdu.header.set(name, time.asctime()) hdu.writeto(filename, clobber=True)
def supplement(self,coordsys='gal'): """ Add some supplemental columns """ from ugali.utils.projector import gal2cel, gal2cel_angle from ugali.utils.projector import cel2gal, cel2gal_angle coordsys = coordsys.lower() kwargs = dict(usemask=False, asrecarray=True) out = copy.deepcopy(self) if ('lon' in out.names) and ('lat' in out.names): # Ignore entries that are all zero zeros = np.all(self.ndarray==0,axis=1) if coordsys == 'gal': ra,dec = gal2cel(out.lon,out.lat) glon,glat = out.lon,out.lat else: ra,dec = out.lon,out.lat glon,glat = cel2gal(out.lon,out.lat) ra[zeros] = 0; dec[zeros] = 0 glon[zeros] = 0; glat[zeros] = 0 names = ['ra','dec','glon','glat'] arrs = [ra,dec,glon,glat] out = mlab.rec_append_fields(out,names,arrs).view(Samples) #out = recfuncs.append_fields(out,names,arrs,**kwargs).view(Samples) if 'position_angle' in out.names: if coordsys == 'gal': pa_gal = out.position_angle pa_cel = gal2cel_angle(out.lon,out.lat,out.position_angle) pa_cel = pa_cel - 180.*(pa_cel > 180.) else: pa_gal = cel2gal_angle(out.lon,out.lat,out.position_angle) pa_cel = out.position_angle pa_gal = pa_gal - 180.*(pa_gal > 180.) pa_gal[zeros] = 0; pa_cel[zeros] = 0 names = ['position_angle_gal','position_angle_cel'] arrs = [pa_gal,pa_cel] out = recfuncs.append_fields(out,names,arrs,**kwargs).view(Samples) return out
def write_membership(self,filename): ra,dec = gal2cel(self.catalog.lon,self.catalog.lat) name_objid = self.config['catalog']['objid_field'] name_mag_1 = self.config['catalog']['mag_1_field'] name_mag_2 = self.config['catalog']['mag_2_field'] name_mag_err_1 = self.config['catalog']['mag_err_1_field'] name_mag_err_2 = self.config['catalog']['mag_err_2_field'] # Angular and isochrone separations sep = angsep(self.source.lon,self.source.lat,self.catalog.lon,self.catalog.lat) isosep = self.isochrone.separation(self.catalog.mag_1,self.catalog.mag_2) columns = [ pyfits.Column(name=name_objid,format='K',array=self.catalog.objid), pyfits.Column(name='GLON',format='D',array=self.catalog.lon), pyfits.Column(name='GLAT',format='D',array=self.catalog.lat), pyfits.Column(name='RA',format='D',array=ra), pyfits.Column(name='DEC',format='D',array=dec), pyfits.Column(name=name_mag_1,format='E',array=self.catalog.mag_1), pyfits.Column(name=name_mag_err_1,format='E',array=self.catalog.mag_err_1), pyfits.Column(name=name_mag_2,format='E',array=self.catalog.mag_2), pyfits.Column(name=name_mag_err_2,format='E',array=self.catalog.mag_err_2), pyfits.Column(name='COLOR',format='E',array=self.catalog.color), pyfits.Column(name='ANGSEP',format='E',array=sep), pyfits.Column(name='ISOSEP',format='E',array=isosep), pyfits.Column(name='PROB',format='E',array=self.p), ] hdu = pyfits.new_table(columns) for param,value in self.source.params.items(): # HIERARCH allows header keywords longer than 8 characters name = 'HIERARCH %s'%param.upper() hdu.header.set(name,value.value,param) name = 'HIERARCH %s'%'TS' hdu.header.set(name,self.ts()) name = 'HIERARCH %s'%'TIMESTAMP' hdu.header.set(name,time.asctime()) hdu.writeto(filename,clobber=True)
def calculate(self, infile, field=1, simple=False): logger.info("Calculating magnitude limit from %s"%infile) #manglefile = self.config['mangle']['infile_%i'%field] #footfile = self.config['data']['footprint'] #try: # footprint = fitsio.read(footfile)['I'].ravel() #except: # logger.warn("Couldn't open %s; will try again."%footfile) # footprint = footfile mag_column = self.config['catalog']['mag_%i_field'%field] magerr_column = self.config['catalog']['mag_err_%i_field'%field] # For simple maglims release = self.config['data']['release'].lower() band = self.config['catalog']['mag_%i_band'%field] pixel_pix_name = 'PIX%i'%self.nside_pixel data = fitsio.read(infile,columns=[pixel_pix_name]) #mask_pixels = np.arange( hp.nside2npix(self.nside_mask), dtype='int') mask_maglims = np.zeros(hp.nside2npix(self.nside_mask)) out_pixels = np.zeros(0,dtype='int') out_maglims = np.zeros(0) # Find the objects in each pixel pixel_pix = data[pixel_pix_name] mask_pix = ugali.utils.skymap.superpixel(pixel_pix,self.nside_pixel,self.nside_mask) count = Counter(mask_pix) pixels = sorted(count.keys()) pix_digi = np.digitize(mask_pix,pixels).argsort() idx = 0 min_num = 500 signal_to_noise = 10. magerr_lim = 1/signal_to_noise for pix in pixels: # Calculate the magnitude limit in each pixel num = count[pix] objs = data[pix_digi[idx:idx+num]] idx += num if simple: # Set constant magnitude limits logger.debug("Simple magnitude limit for %s"%infile) mask_maglims[pix] = MAGLIMS[release][band] elif num < min_num: logger.info('Found <%i objects in pixel %i'%(min_num,pix)) mask_maglims[pix] = 0 else: mag = objs[mag_column] magerr = objs[magerr_column] # Estimate the magnitude limit as suggested by: # https://deswiki.cosmology.illinois.edu/confluence/display/DO/SVA1+Release+Document # (https://desweb.cosmology.illinois.edu/confluence/display/Operations/SVA1+Doc) maglim = np.median(mag[(magerr>0.9*magerr_lim)&(magerr<1.1*magerr_lim)]) # Alternative method to estimate the magnitude limit by fitting median #mag_min, mag_max = mag.min(),mag.max() #mag_bins = np.arange(mag_min,mag_max,0.1) #0.1086? #x,y = ugali.utils.binning.binnedMedian(mag,magerr,mag_bins) #x,y = x[~np.isnan(y)],y[~np.isnan(y)] #magerr_med = interp1d(x,y) #mag0 = np.median(x) #maglim = brentq(lambda a: magerr_med(a)-magerr_lim,x.min(),x.max(),disp=False) # Median from just objects near magerr cut mask_maglims[pix] = maglim logger.debug("%i (n=%i): maglim=%g"%(pix,num,mask_maglims[pix])) subpix = ugali.utils.skymap.subpixel(pix, self.nside_mask, self.nside_pixel) maglims = np.zeros(len(subpix)) + mask_maglims[pix] out_pixels = np.append(out_pixels,subpix) out_maglims = np.append(out_maglims,maglims) # Remove empty pixels logger.info("Removing empty pixels") idx = np.nonzero(out_maglims > 0)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] # Remove pixels outside the footprint if self.footfile: logger.info("Checking footprint against %s"%self.footfile) glon,glat = pix2ang(self.nside_pixel,out_pixels) ra,dec = gal2cel(glon,glat) footprint = inFootprint(self.footprint,ra,dec) idx = np.nonzero(footprint)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] logger.info("MAGLIM = %.3f +/- %.3f"%(np.mean(out_maglims),np.std(out_maglims))) return out_pixels,out_maglims
def pixelizeCatalog(infiles, config, force=False): """ Break catalog into chunks by healpix pixel. Parameters: ----------- infiles : List of input files config : Configuration file force : Overwrite existing files (depricated) Returns: -------- None """ nside_catalog = config['coords']['nside_catalog'] nside_pixel = config['coords']['nside_pixel'] coordsys = config['coords']['coordsys'].upper() outdir = mkdir(config['catalog']['dirname']) filenames = config.getFilenames() lon_field = config['catalog']['lon_field'].upper() lat_field = config['catalog']['lat_field'].upper() # ADW: It would probably be better (and more efficient) to do the # pixelizing and the new column insertion separately. for i,filename in enumerate(infiles): logger.info('(%i/%i) %s'%(i+1, len(infiles), filename)) data = fitsio.read(filename) logger.info("%i objects found"%len(data)) if not len(data): continue columns = map(str.upper,data.dtype.names) names,arrs = [],[] if (lon_field in columns) and (lat_field in columns): lon,lat = data[lon_field],data[lat_field] elif coordsys == 'GAL': msg = "Columns '%s' and '%s' not found."%(lon_field,lat_field) msg += "\nConverting from RA,DEC" logger.warning(msg) lon,lat = cel2gal(data['RA'],data['DEC']) names += [lon_field,lat_field] arrs += [lon,lat] elif coordsys == 'CEL': msg = "Columns '%s' and '%s' not found."%(lon_field,lat_field) msg += "\nConverting from GLON,GLAT" lon,lat = gal2cel(data['GLON'],data['GLAT']) names += [lon_field,lat_field] arrs += [lon,lat] cat_pix = ang2pix(nside_catalog,lon,lat) pix_pix = ang2pix(nside_pixel,lon,lat) cat_pix_name = 'PIX%i'%nside_catalog pix_pix_name = 'PIX%i'%nside_pixel try: names += [cat_pix_name,pix_pix_name] arrs += [cat_pix,pix_pix] data=mlab.rec_append_fields(data,names=names,arrs=arrs) except ValueError as e: logger.warn(str(e)+'; not adding column.') #data[cat_pix_name] = cat_pix #data[pix_pix_name] = pix_pix for pix in np.unique(cat_pix): logger.debug("Processing pixel %s"%pix) arr = data[cat_pix == pix] outfile = filenames.data['catalog'][pix] if not os.path.exists(outfile): logger.debug("Creating %s"%outfile) out=fitsio.FITS(outfile,mode='rw') out.write(arr) hdr=healpix.header_odict(nside=nside_catalog, coord=coordsys[0]) for key in ['PIXTYPE','ORDERING','NSIDE','COORDSYS']: out[1].write_key(*list(hdr[key].values())) out[1].write_key('PIX',pix,comment='HEALPIX pixel for this file') else: out=fitsio.FITS(outfile,mode='rw') out[1].append(arr) logger.debug("Writing %s"%outfile) out.close()
def ra_dec(self): return gal2cel(self.lon,self.lat) @property
def finalizeObjects(self, objects): objs = numpy.recarray(len(objects), dtype=[ ('NAME', 'S24'), ('TS', 'f4'), ('GLON', 'f4'), ('GLAT', 'f4'), ('RA', 'f4'), ('DEC', 'f4'), ('MODULUS', 'f4'), ('DISTANCE', 'f4'), ('RICHNESS', 'f4'), ('MASS', 'f4'), ('NANNULUS', 'i4'), ('NINTERIOR', 'i4'), ]) objs['TS'] = self.values[objects['IDX_MAX'], objects['ZIDX_MAX']] glon, glat = objects['X_MAX'], objects['Y_MAX'] objs['GLON'], objs['GLAT'] = glon, glat ra, dec = gal2cel(glon, glat) objs['RA'], objs['DEC'] = ra, dec modulus = objects['Z_MAX'] objs['MODULUS'] = modulus objs['DISTANCE'] = mod2dist(modulus) #ninterior = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'NINSIDE') #nannulus = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'NANNULUS') #stellar = ugali.utils.skymap.readSparseHealpixMap(self.roifile,'STELLAR') nside = healpy.npix2nside(len(self.nannulus)) pix = ang2pix(nside, glon, glat) richness = self.richness[objects['IDX_MAX'], objects['ZIDX_MAX']] objs['RICHNESS'] = richness objs['MASS'] = richness * self.stellar[pix] objs['NANNULUS'] = self.nannulus[pix].astype(int) objs['NINTERIOR'] = self.ninterior[pix].astype(int) # Default name formatting # http://cdsarc.u-strasbg.fr/ftp/pub/iau/ # http://cds.u-strasbg.fr/vizier/Dic/iau-spec.htx fmt = "J%(hour)02i%(hmin)04.1f%(deg)+03i%(dmin)02i" for obj, _ra, _dec in zip(objs, ra, dec): hms = dec2hms(_ra) dms = dec2dms(_dec) params = dict(hour=hms[0], hmin=hms[1] + hms[2] / 60., deg=dms[0], dmin=dms[1] + dms[2] / 60.) obj['NAME'] = fmt % params out = recfuncs.merge_arrays([objs, objects], usemask=False, asrecarray=True, flatten=True) # This is safer than viewing as FITS_rec return pyfits.new_table(out).data
def calculate(self, infile, field=1, simple=False): logger.info("Calculating magnitude limit from %s"%infile) #manglefile = self.config['mangle']['infile_%i'%field] footfile = self.config['data']['footprint'] mag_column = self.config['catalog']['mag_%i_field'%field] magerr_column = self.config['catalog']['mag_err_%i_field'%field] # For simple maglims release = self.config['data']['release'].lower() band = self.config['catalog']['mag_%i_band'%field] f = pyfits.open(infile) header = f[1].header data = f[1].data #mask_pixels = numpy.arange( healpy.nside2npix(self.nside_mask), dtype='int') mask_maglims = numpy.zeros( healpy.nside2npix(self.nside_mask) ) out_pixels = numpy.zeros(0,dtype='int') out_maglims = numpy.zeros(0) # Find the objects in each pixel pixel_pix = data['PIX%i'%self.nside_pixel] mask_pix = ugali.utils.skymap.superpixel(pixel_pix,self.nside_pixel,self.nside_mask) count = Counter(mask_pix) pixels = sorted(count.keys()) pix_digi = numpy.digitize(mask_pix,pixels).argsort() idx = 0 min_num = 500 signal_to_noise = 10. magerr_lim = 1/signal_to_noise for pix in pixels: # Calculate the magnitude limit in each pixel num = count[pix] objs = data[pix_digi[idx:idx+num]] idx += num if simple: # Set constant magnitude limits logger.debug("Simple magnitude limit for %s"%infile) mask_maglims[pix] = MAGLIMS[release][band] elif num < min_num: logger.info('Found <%i objects in pixel %i'%(min_num,pix)) mask_maglims[pix] = 0 else: mag = objs[mag_column] magerr = objs[magerr_column] # Estimate the magnitude limit as suggested by: # https://deswiki.cosmology.illinois.edu/confluence/display/DO/SVA1+Release+Document # (https://desweb.cosmology.illinois.edu/confluence/display/Operations/SVA1+Doc) maglim = numpy.median(mag[(magerr>0.9*magerr_lim)&(magerr<1.1*magerr_lim)]) # Alternative method to estimate the magnitude limit by fitting median #mag_min, mag_max = mag.min(),mag.max() #mag_bins = numpy.arange(mag_min,mag_max,0.1) #0.1086? #x,y = ugali.utils.binning.binnedMedian(mag,magerr,mag_bins) #x,y = x[~numpy.isnan(y)],y[~numpy.isnan(y)] #magerr_med = interp1d(x,y) #mag0 = numpy.median(x) #maglim = brentq(lambda a: magerr_med(a)-magerr_lim,x.min(),x.max(),disp=False) # Median from just objects near magerr cut mask_maglims[pix] = maglim logger.debug("%i (n=%i): maglim=%g"%(pix,num,mask_maglims[pix])) subpix = ugali.utils.skymap.subpixel(pix, self.nside_mask, self.nside_pixel) maglims = numpy.zeros(len(subpix)) + mask_maglims[pix] out_pixels = numpy.append(out_pixels,subpix) out_maglims = numpy.append(out_maglims,maglims) # Remove empty pixels logger.info("Removing empty pixels") idx = numpy.nonzero(out_maglims > 0)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] # Remove pixels outside the footprint logger.info("Checking footprint against %s"%footfile) glon,glat = pix2ang(self.nside_pixel,out_pixels) ra,dec = gal2cel(glon,glat) footprint = inFootprint(footfile,ra,dec) idx = numpy.nonzero(footprint)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] logger.info("MAGLIM = %.3f +/- %.3f"%(numpy.mean(out_maglims),numpy.std(out_maglims))) return out_pixels,out_maglims
def calculate(self, infile, field=1, simple=False): logger.info("Calculating magnitude limit from %s"%infile) #manglefile = self.config['mangle']['infile_%i'%field] #footfile = self.config['data']['footprint'] #try: # footprint = fitsio.read(footfile)['I'].ravel() #except: # logger.warn("Couldn't open %s; will try again."%footfile) # footprint = footfile mag_column = self.config['catalog']['mag_%i_field'%field] magerr_column = self.config['catalog']['mag_err_%i_field'%field] # For simple maglims release = self.config['data']['release'].lower() band = self.config['catalog']['mag_%i_band'%field] pixel_pix_name = 'PIX%i'%self.nside_pixel # If the data already has a healpix pixel assignment then use it # Otherwise recalculate... try: data = fitsio.read(infile,columns=[pixel_pix_name]) except ValueError as e: logger.info(str(e)) columns=[self.config['catalog']['lon_field'], self.config['catalog']['lat_field']] data = fitsio.read(infile,columns=columns)[columns] pix = ang2pix(self.nside_pixel,data[columns[0]],data[columns[1]]) data = recfuncs.rec_append_fields(data,pixel_pix_name,pix) #mask_pixels = np.arange( hp.nside2npix(self.nside_mask), dtype='int') mask_maglims = np.zeros(hp.nside2npix(self.nside_mask)) out_pixels = np.zeros(0,dtype='int') out_maglims = np.zeros(0) # Find the objects in each pixel pixel_pix = data[pixel_pix_name] mask_pix = ugali.utils.skymap.superpixel(pixel_pix,self.nside_pixel,self.nside_mask) count = Counter(mask_pix) pixels = sorted(count.keys()) pix_digi = np.digitize(mask_pix,pixels).argsort() idx = 0 min_num = 500 signal_to_noise = 10. magerr_lim = 1/signal_to_noise for pix in pixels: # Calculate the magnitude limit in each pixel num = count[pix] objs = data[pix_digi[idx:idx+num]] idx += num if simple: # Set constant magnitude limits logger.debug("Simple magnitude limit for %s"%infile) mask_maglims[pix] = MAGLIMS[release][band] elif num < min_num: logger.info('Found <%i objects in pixel %i'%(min_num,pix)) mask_maglims[pix] = 0 else: mag = objs[mag_column] magerr = objs[magerr_column] # Estimate the magnitude limit as suggested by: # https://deswiki.cosmology.illinois.edu/confluence/display/DO/SVA1+Release+Document # (https://desweb.cosmology.illinois.edu/confluence/display/Operations/SVA1+Doc) maglim = np.median(mag[(magerr>0.9*magerr_lim)&(magerr<1.1*magerr_lim)]) # Alternative method to estimate the magnitude limit by fitting median #mag_min, mag_max = mag.min(),mag.max() #mag_bins = np.arange(mag_min,mag_max,0.1) #0.1086? #x,y = ugali.utils.binning.binnedMedian(mag,magerr,mag_bins) #x,y = x[~np.isnan(y)],y[~np.isnan(y)] #magerr_med = interp1d(x,y) #mag0 = np.median(x) #maglim = brentq(lambda a: magerr_med(a)-magerr_lim,x.min(),x.max(),disp=False) # Median from just objects near magerr cut mask_maglims[pix] = maglim logger.debug("%i (n=%i): maglim=%g"%(pix,num,mask_maglims[pix])) subpix = ugali.utils.skymap.subpixel(pix, self.nside_mask, self.nside_pixel) maglims = np.zeros(len(subpix)) + mask_maglims[pix] out_pixels = np.append(out_pixels,subpix) out_maglims = np.append(out_maglims,maglims) # Remove empty pixels logger.info("Removing empty pixels") idx = np.nonzero(out_maglims > 0)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] # Remove pixels outside the footprint if self.footfile: logger.info("Checking footprint against %s"%self.footfile) lon,lat = pix2ang(self.nside_pixel,out_pixels) if self.config['coords']['coordsys'] == 'gal': ra,dec = gal2cel(lon,lat) else: ra,dec = lon,lat footprint = inFootprint(self.footprint,ra,dec) idx = np.nonzero(footprint)[0] out_pixels = out_pixels[idx] out_maglims = out_maglims[idx] logger.info("MAGLIM = %.3f +/- %.3f"%(np.mean(out_maglims),np.std(out_maglims))) return out_pixels,out_maglims
CATALOGS = ['McConnachie12', 'Harris96', 'Corwen04', 'Nilson73', 'Webbink85', 'Kharchenko13', 'Bica08', 'WEBDA14', 'ExtraDwarfs','ExtraClusters'] if __name__ == "__main__": import argparse description = "python script" parser = ugali.utils.parser.Parser(description=description) parser.add_coords(required=True,radius=True,targets=True) parser.add_argument('-n','--nnearest',default=1,type=int) opts = parser.parse_args() catalog = ugali.candidate.associate.SourceCatalog() for i in CATALOGS: catalog += ugali.candidate.associate.catalogFactory(i) for name,(glon,glat,radius) in zip(opts.names, opts.coords): ra,dec = gal2cel(glon,glat) iau = ang2iau(glon,glat) const = ang2const(glon,glat)[0] if radius <= 0: radius = None idx1,idx2,sep = catalog.match([glon],[glat],tol=radius,nnearest=opts.nnearest) match = catalog[idx2] if len(match) > 0: n = match[0]['name'] s = sep[0] l,b = match[0]['glon'],match[0]['glat'] r,d = match[0]['ra'],match[0]['dec'] else: n = 'NONE' s = np.nan
] if __name__ == "__main__": import argparse description = "python script" parser = ugali.utils.parser.Parser(description=description) parser.add_coords(required=True, radius=True, targets=True) parser.add_argument('-n', '--nnearest', default=1, type=int) opts = parser.parse_args() catalog = ugali.candidate.associate.SourceCatalog() for i in CATALOGS: catalog += ugali.candidate.associate.catalogFactory(i) for name, (glon, glat, radius) in zip(opts.names, opts.coords): ra, dec = gal2cel(glon, glat) iau = ang2iau(glon, glat) const = ang2const(glon, glat)[0] if radius <= 0: radius = None idx1, idx2, sep = catalog.match([glon], [glat], tol=radius, nnearest=opts.nnearest) match = catalog[idx2] if len(match) > 0: n = match[0]['name'] s = sep[0] l, b = match[0]['glon'], match[0]['glat'] r, d = match[0]['ra'], match[0]['dec'] else:
def ra_dec(self): if self.coordsys == 'cel': return self.lon, self.lat else: return gal2cel(self.lon,self.lat)
def pixelizeCatalog(infiles, config, force=False): """ Break catalog into chunks by healpix pixel. Parameters: ----------- infiles : List of input files config : Configuration file force : Overwrite existing files (depricated) Returns: -------- None """ nside_catalog = config['coords']['nside_catalog'] nside_pixel = config['coords']['nside_pixel'] coordsys = config['coords']['coordsys'].upper() outdir = mkdir(config['catalog']['dirname']) filenames = config.getFilenames() lon_field = config['catalog']['lon_field'].upper() lat_field = config['catalog']['lat_field'].upper() # ADW: It would probably be better (and more efficient) to do the # pixelizing and the new column insertion separately. for i, filename in enumerate(infiles): logger.info('(%i/%i) %s' % (i + 1, len(infiles), filename)) data = fitsio.read(filename) logger.info("%i objects found" % len(data)) if not len(data): continue columns = map(str.upper, data.dtype.names) names, arrs = [], [] if (lon_field in columns) and (lat_field in columns): lon, lat = data[lon_field], data[lat_field] elif coordsys == 'GAL': msg = "Columns '%s' and '%s' not found." % (lon_field, lat_field) msg += "\nConverting from RA,DEC" logger.warning(msg) lon, lat = cel2gal(data['RA'], data['DEC']) names += [lon_field, lat_field] arrs += [lon, lat] elif coordsys == 'CEL': msg = "Columns '%s' and '%s' not found." % (lon_field, lat_field) msg += "\nConverting from GLON,GLAT" lon, lat = gal2cel(data['GLON'], data['GLAT']) names += [lon_field, lat_field] arrs += [lon, lat] cat_pix = ang2pix(nside_catalog, lon, lat) pix_pix = ang2pix(nside_pixel, lon, lat) cat_pix_name = 'PIX%i' % nside_catalog pix_pix_name = 'PIX%i' % nside_pixel names += [cat_pix_name, pix_pix_name] arrs += [cat_pix, pix_pix] data = mlab.rec_append_fields(data, names=names, arrs=arrs) for pix in np.unique(cat_pix): logger.debug("Processing pixel %s" % pix) arr = data[cat_pix == pix] outfile = filenames.data['catalog'][pix] if not os.path.exists(outfile): logger.debug("Creating %s" % outfile) out = fitsio.FITS(outfile, mode='rw') out.write(arr) hdr = healpix.header_odict(nside=nside_catalog, coord=coordsys[0]) for key in ['PIXTYPE', 'ORDERING', 'NSIDE', 'COORDSYS']: out[1].write_key(*list(hdr[key].values())) out[1].write_key('PIX', pix, comment='HEALPIX pixel for this file') else: out = fitsio.FITS(outfile, mode='rw') out[1].append(arr) logger.debug("Writing %s" % outfile) out.close()
def write_membership(self, filename): """ Write a catalog file of the likelihood region including membership properties. Parameters: ----------- filename : output filename Returns: -------- None """ # Column names name_objid = self.config['catalog']['objid_field'] name_mag_1 = self.config['catalog']['mag_1_field'] name_mag_2 = self.config['catalog']['mag_2_field'] name_mag_err_1 = self.config['catalog']['mag_err_1_field'] name_mag_err_2 = self.config['catalog']['mag_err_2_field'] # Coordinate conversion ra, dec = gal2cel(self.catalog.lon, self.catalog.lat) # Angular and isochrone separations sep = angsep(self.source.lon, self.source.lat, self.catalog.lon, self.catalog.lat) isosep = self.isochrone.separation(self.catalog.mag_1, self.catalog.mag_2) # If size becomes an issue we can make everything float32 data = odict() data[name_objid] = self.catalog.objid data['GLON'] = self.catalog.lon data['GLAT'] = self.catalog.lat data['RA'] = ra data['DEC'] = dec data[name_mag_1] = self.catalog.mag_1 data[name_mag_err_1] = self.catalog.mag_err_1 data[name_mag_2] = self.catalog.mag_2 data[name_mag_err_2] = self.catalog.mag_err_2 data['COLOR'] = self.catalog.color data['ANGSEP'] = sep.astype(np.float32) data['ISOSEP'] = isosep.astype(np.float32) data['PROB'] = self.p.astype(np.float32) # HIERARCH allows header keywords longer than 8 characters header = [] for param, value in self.source.params.items(): card = dict(name='HIERARCH %s' % param.upper(), value=value.value, comment=param) header.append(card) card = dict(name='HIERARCH %s' % 'TS', value=self.ts(), comment='test statistic') header.append(card) card = dict(name='HIERARCH %s' % 'TIMESTAMP', value=time.asctime(), comment='creation time') header.append(card) fitsio.write(filename, data, header=header, clobber=True)
samfile = outfile # samples srcfile = outfile.replace('.npy','.yaml') # srcmdl and results memfile = outfile.replace('.npy','.fits') # membership resfile = srcfile # results file source = ugali.analysis.loglike.createSource(config,section='mcmc') source.name = opts.name if opts.srcmdl is not None: source.load(opts.srcmdl,section=opts.name) if opts.coords: lon,lat,radius = opts.coords[0] if config['coords']['coordsys'].lower() == 'gal': source.set_params(lon=lon,lat=lat) else: lon,lat = gal2cel(lon,lat) source.set_params(lon=lon,lat=lat) if config['mcmc'].get('params'): params = config['mcmc'].get('params') source.set_free_params(params) like = ugali.analysis.loglike.createLoglike(config,source) if opts.grid: grid = ugali.analysis.scan.GridSearch(config,like) grid.search() source.set_params(**grid.mle()) params = list(source.get_free_params().keys()) logger.info(source)
def get_results(self,**kwargs): kwargs.setdefault('alpha',self.alpha) kwargs.setdefault('burn',self.nburn*self.nwalkers) # Calculate best-fit parameters from MCMC chain logger.debug('Estimating parameters...') estimate = self.estimate_params(**kwargs) params = {k:v[0] for k,v in estimate.items()} results = dict(estimate) # Extra parameters from the MCMC chain logger.debug('Estimating auxiliary parameters...') try: results['ra'] = self.estimate('ra',**kwargs) results['dec'] = self.estimate('dec',**kwargs) except KeyError: logger.warn("Didn't find 'ra' or 'dec'") ra,dec = gal2cel(results['lon'][0],results['lat'][0]) results['ra'] = ugali.utils.stats.interval(ra) results['dec'] = ugali.utils.stats.interval(dec) ra,dec = results['ra'][0],results['dec'][0] glon,glat = lon,lat = results['lon'][0],results['lat'][0] results.update(gal=[float(glon),float(glat)]) results.update(cel=[float(ra),float(dec)]) try: results['position_angle_cel'] = self.estimate('position_angle_cel',**kwargs) except KeyError: results['position_angle_cel'] = ugali.utils.stats.interval(np.nan) # Update the loglike to the best-fit parameters from the chain logger.debug('Calculating TS...') ts = 2*self.loglike.value(**params) results['ts'] = ugali.utils.stats.interval(ts,np.nan,np.nan) #lon,lat = estimate['lon'][0],estimate['lat'][0] # #results.update(gal=[float(lon),float(lat)]) #ra,dec = gal2cel(lon,lat) #results.update(cel=[float(ra),float(dec)]) #results['ra'] = ugali.utils.stats.interval(ra,np.nan,np.nan) #results['dec'] = ugali.utils.stats.interval(dec,np.nan,np.nan) # Celestial position angle # Break ambiguity in direction with '% 180.' pa,pa_err = results['position_angle'] pa_cel = gal2cel_angle(lon,lat,pa) % 180. pa_cel_err = np.array(pa_err) - pa + pa_cel results['position_angle_cel'] = ugali.utils.stats.interval(pa_cel,pa_cel_err[0],pa_cel_err[1]) mod,mod_err = estimate['distance_modulus'] dist = mod2dist(mod) dist_lo,dist_hi = [mod2dist(mod_err[0]),mod2dist(mod_err[1])] results['distance'] = ugali.utils.stats.interval(dist,dist_lo,dist_hi) dist,dist_err = results['distance'] ext,ext_err = estimate['extension'] ext_sigma = np.nan_to_num(np.array(ext_err) - ext) results['extension_arcmin'] = ugali.utils.stats.interval(60*ext,60*ext_err[0],60*ext_err[1]) # Radially symmetric extension (correct for ellipticity). ell,ell_err = estimate['ellipticity'] rext,rext_err = ext*np.sqrt(1-ell),np.array(ext_err)*np.sqrt(1-ell) rext_sigma = np.nan_to_num(np.array(rext_err) - rext) results['extension_radial'] = ugali.utils.stats.interval(rext,rext_err[0],rext_err[1]) results['extension_radial_arcmin'] = ugali.utils.stats.interval(60*rext,60*rext_err[0],60*rext_err[1]) # Bayes factor for ellipticity results['ellipticity_bayes_factor'] = self.bayes_factor('ellipticity',burn=kwargs['burn']) # Physical Size (should do this with the posteriors) # Radially symmetric dist_sigma = np.nan_to_num(np.array(dist_err) - dist) size = np.arctan(np.radians(ext)) * dist size_sigma = size * np.sqrt((ext_sigma/ext)**2 + (dist_sigma/dist)**2) size_err = [size-size_sigma[0],size+size_sigma[1]] results['physical_size'] = ugali.utils.stats.interval(size,size_err[0],size_err[1]) rsize = np.arctan(np.radians(rext)) * dist rsize_sigma = rsize * np.sqrt((rext_sigma/rext)**2 + (dist_sigma/dist)**2) rsize_err = [rsize-rsize_sigma[0],rsize+rsize_sigma[1]] results['physical_size_radial'] = ugali.utils.stats.interval(rsize,rsize_err[0],rsize_err[1]) # Richness rich,rich_err = estimate['richness'] # Number of observed stars (sum of p-values) nobs = self.loglike.p.sum() nobs_lo,nobs_hi = nobs + np.sqrt(nobs)*np.array([-1,1]) results['nobs'] = ugali.utils.stats.interval(nobs,nobs_lo,nobs_hi) # Number of predicted stars (pixelization effects?) npred = self.loglike.f*rich npred_lo,npred_hi = rich_err[0]*self.loglike.f,rich_err[1]*self.loglike.f results['npred'] = ugali.utils.stats.interval(npred,npred_lo,npred_hi) # Careful, depends on the isochrone... stellar_mass = self.source.stellar_mass() mass = rich*stellar_mass mass_lo,mass_hi = rich_err[0]*stellar_mass,rich_err[1]*stellar_mass results['mass'] = ugali.utils.stats.interval(mass,mass_lo,mass_hi) stellar_luminosity = self.source.stellar_luminosity() lum = rich*stellar_luminosity lum_lo,lum_hi = rich_err[0]*stellar_luminosity,rich_err[1]*stellar_luminosity results['luminosity'] = ugali.utils.stats.interval(lum,lum_lo,lum_hi) # Absolute magnitude only calculated for DES isochrones with g,r try: Mv = self.source.absolute_magnitude(rich) Mv_lo = self.source.absolute_magnitude(rich_err[0]) Mv_hi = self.source.absolute_magnitude(rich_err[1]) results['Mv'] = ugali.utils.stats.interval(Mv,Mv_lo,Mv_hi) except ValueError as e: logger.warning("Skipping absolute magnitude") logger.warn(str(e)) results['Mv'] = np.nan # ADW: WARNING this is very fragile. # Also, this is not quite right, should cut on the CMD available space kwargs = dict(richness=rich,mag_bright=16., mag_faint=23., n_trials=5000,alpha=self.alpha, seed=0) martin = self.config['results'].get('martin') if martin: logger.info("Calculating Martin magnitude...") if martin > 1: kwargs['n_trials'] = martin Mv_martin = self.source.isochrone.absolute_magnitude_martin(**kwargs) results['Mv_martin'] = Mv_martin else: logger.warning("Skipping Martin magnitude") results['Mv_martin'] = np.nan mu = surfaceBrightness(Mv, size, dist) results['surface_brightness'] = ugali.utils.stats.interval(mu,np.nan,np.nan) try: results['constellation'] = ang2const(lon,lat,self.coordsys)[1] except: pass results['iau'] = ugali.utils.projector.ang2iau(lon,lat) coord = SkyCoord(ra*u.deg,dec*u.deg,distance=dist*u.kpc) results['ra_sex'] = str(coord.ra.to_string()) results['dec_sex'] = str(coord.dec.to_string()) # Calculate some separations from GC, LMC, SMC #NED coordinates with de Grisj distance LMC = SkyCoord(80.8939*u.deg,-69.7561*u.deg,distance=49.89*u.kpc) #NED coordinates with de Grisj distance SMC = SkyCoord(13.1866*u.deg,-72.8286*u.deg,distance=61.94*u.kpc) # GC from astropy? GC = SkyCoord(266.4168262*u.deg,-29.0077969*u.deg,distance=8.0*u.kpc) results['d_gc'] = coord.separation_3d(GC).value results['d_lmc'] = coord.separation_3d(LMC).value results['d_smc'] = coord.separation_3d(SMC).value try: results['feh'] = float(self.source.isochrone.feh) except: results['feh'] = np.nan output = dict() output['params'] = params output['results'] = results return output
def ra_dec(self): if self.coordsys == 'cel': return self.lon, self.lat else: return gal2cel(self.lon, self.lat)
def finalizeObjects(self, objects): objs = numpy.recarray(len(objects), dtype=[ ('NAME', 'S24'), ('TS', 'f4'), ('GLON', 'f4'), ('GLAT', 'f4'), ('RA', 'f4'), ('DEC', 'f4'), ('MODULUS', 'f4'), ('DISTANCE', 'f4'), ('RICHNESS', 'f4'), ('MASS', 'f4'), ('NANNULUS', 'i4'), ('NINTERIOR', 'i4'), ]) objs['TS'] = self.values[objects['IDX_MAX'], objects['ZIDX_MAX']] lon, lat = objects['X_MAX'], objects['Y_MAX'] coordsys = self.config['coords']['coordsys'] if coordsys.lower() == 'gal': print("GAL coordintes") objs['GLON'], objs['GLAT'] = lon, lat objs['RA'], objs['DEC'] = gal2cel(lon, lat) else: print("CEL coordintes") objs['RA'], objs['DEC'] = lon, lat objs['GLON'], objs['GLAT'] = cel2gal(lon, lat) modulus = objects['Z_MAX'] objs['MODULUS'] = modulus objs['DISTANCE'] = mod2dist(modulus) nside = healpy.npix2nside(len(self.nannulus)) pix = ang2pix(nside, lon, lat) richness = self.richness[objects['IDX_MAX'], objects['ZIDX_MAX']] objs['RICHNESS'] = richness objs['MASS'] = richness * self.stellar[pix] objs['NANNULUS'] = self.nannulus[pix].astype(int) objs['NINTERIOR'] = self.ninterior[pix].astype(int) # Default name formatting # http://cdsarc.u-strasbg.fr/ftp/pub/iau/ # http://cds.u-strasbg.fr/vizier/Dic/iau-spec.htx fmt = "J%(hour)02i%(hmin)04.1f%(deg)+03i%(dmin)02i" for obj, _ra, _dec in zip(objs, objs['RA'], objs['DEC']): hms = dec2hms(_ra) dms = dec2dms(_dec) params = dict(hour=hms[0], hmin=hms[1] + hms[2] / 60., deg=dms[0], dmin=dms[1] + dms[2] / 60.) obj['NAME'] = fmt % params out = recfuncs.merge_arrays([objs, objects], usemask=False, asrecarray=True, flatten=True) return out
def get_results(self, **kwargs): kwargs.setdefault('alpha', self.alpha) kwargs.setdefault('burn', self.nburn * self.nwalkers) # Calculate best-fit parameters from MCMC chain logger.debug('Estimating parameters...') estimate = self.estimate_params(**kwargs) params = {k: v[0] for k, v in estimate.items()} results = dict(estimate) # Extra parameters from the MCMC chain logger.debug('Estimating auxiliary parameters...') try: results['ra'] = self.estimate('ra', **kwargs) results['dec'] = self.estimate('dec', **kwargs) except KeyError: logger.warn("Didn't find 'ra' or 'dec'") ra, dec = gal2cel(results['lon'][0], results['lat'][0]) results['ra'] = ugali.utils.stats.interval(ra) results['dec'] = ugali.utils.stats.interval(dec) ra, dec = results['ra'][0], results['dec'][0] glon, glat = lon, lat = results['lon'][0], results['lat'][0] results.update(gal=[float(glon), float(glat)]) results.update(cel=[float(ra), float(dec)]) try: results['position_angle_cel'] = self.estimate( 'position_angle_cel', **kwargs) except KeyError: results['position_angle_cel'] = ugali.utils.stats.interval(np.nan) # Update the loglike to the best-fit parameters from the chain logger.debug('Calculating TS...') ts = 2 * self.loglike.value(**params) results['ts'] = ugali.utils.stats.interval(ts, np.nan, np.nan) #lon,lat = estimate['lon'][0],estimate['lat'][0] # #results.update(gal=[float(lon),float(lat)]) #ra,dec = gal2cel(lon,lat) #results.update(cel=[float(ra),float(dec)]) #results['ra'] = ugali.utils.stats.interval(ra,np.nan,np.nan) #results['dec'] = ugali.utils.stats.interval(dec,np.nan,np.nan) # Celestial position angle # Break ambiguity in direction with '% 180.' pa, pa_err = results['position_angle'] pa_cel = gal2cel_angle(lon, lat, pa) % 180. pa_cel_err = np.array(pa_err) - pa + pa_cel results['position_angle_cel'] = ugali.utils.stats.interval( pa_cel, pa_cel_err[0], pa_cel_err[1]) mod, mod_err = estimate['distance_modulus'] dist = mod2dist(mod) dist_lo, dist_hi = [mod2dist(mod_err[0]), mod2dist(mod_err[1])] results['distance'] = ugali.utils.stats.interval( dist, dist_lo, dist_hi) dist, dist_err = results['distance'] ext, ext_err = estimate['extension'] ext_sigma = np.nan_to_num(np.array(ext_err) - ext) results['extension_arcmin'] = ugali.utils.stats.interval( 60 * ext, 60 * ext_err[0], 60 * ext_err[1]) # Radially symmetric extension (correct for ellipticity). ell, ell_err = estimate['ellipticity'] rext, rext_err = ext * np.sqrt(1 - ell), np.array(ext_err) * np.sqrt(1 - ell) rext_sigma = np.nan_to_num(np.array(rext_err) - rext) results['extension_radial'] = ugali.utils.stats.interval( rext, rext_err[0], rext_err[1]) results['extension_radial_arcmin'] = ugali.utils.stats.interval( 60 * rext, 60 * rext_err[0], 60 * rext_err[1]) # Bayes factor for ellipticity results['ellipticity_bayes_factor'] = self.bayes_factor( 'ellipticity', burn=kwargs['burn']) # Physical Size (should do this with the posteriors) # Radially symmetric dist_sigma = np.nan_to_num(np.array(dist_err) - dist) size = np.arctan(np.radians(ext)) * dist size_sigma = size * np.sqrt((ext_sigma / ext)**2 + (dist_sigma / dist)**2) size_err = [size - size_sigma[0], size + size_sigma[1]] results['physical_size'] = ugali.utils.stats.interval( size, size_err[0], size_err[1]) rsize = np.arctan(np.radians(rext)) * dist rsize_sigma = rsize * np.sqrt((rext_sigma / rext)**2 + (dist_sigma / dist)**2) rsize_err = [rsize - rsize_sigma[0], rsize + rsize_sigma[1]] results['physical_size_radial'] = ugali.utils.stats.interval( rsize, rsize_err[0], rsize_err[1]) # Richness rich, rich_err = estimate['richness'] # Number of observed stars (sum of p-values) nobs = self.loglike.p.sum() nobs_lo, nobs_hi = nobs + np.sqrt(nobs) * np.array([-1, 1]) results['nobs'] = ugali.utils.stats.interval(nobs, nobs_lo, nobs_hi) # Number of predicted stars (pixelization effects?) npred = self.loglike.f * rich npred_lo, npred_hi = rich_err[0] * self.loglike.f, rich_err[ 1] * self.loglike.f results['npred'] = ugali.utils.stats.interval(npred, npred_lo, npred_hi) # Careful, depends on the isochrone... stellar_mass = self.source.stellar_mass() mass = rich * stellar_mass mass_lo, mass_hi = rich_err[0] * stellar_mass, rich_err[ 1] * stellar_mass results['mass'] = ugali.utils.stats.interval(mass, mass_lo, mass_hi) stellar_luminosity = self.source.stellar_luminosity() lum = rich * stellar_luminosity lum_lo, lum_hi = rich_err[0] * stellar_luminosity, rich_err[ 1] * stellar_luminosity results['luminosity'] = ugali.utils.stats.interval(lum, lum_lo, lum_hi) Mv = self.source.absolute_magnitude(rich) Mv_lo = self.source.absolute_magnitude(rich_err[0]) Mv_hi = self.source.absolute_magnitude(rich_err[1]) results['Mv'] = ugali.utils.stats.interval(Mv, Mv_lo, Mv_hi) # ADW: WARNING this is very fragile. # Also, this is not quite right, should cut on the CMD available space kwargs = dict(richness=rich, mag_bright=16., mag_faint=23., n_trials=5000, alpha=self.alpha, seed=0) martin = self.config['results'].get('martin') if martin: logger.info("Calculating Martin magnitude...") if martin > 1: kwargs['n_trials'] = martin Mv_martin = self.source.isochrone.absolute_magnitude_martin( **kwargs) results['Mv_martin'] = Mv_martin else: logger.warning("Skipping Martin magnitude") results['Mv_martin'] = np.nan mu = surfaceBrightness(Mv, size, dist) results['surface_brightness'] = ugali.utils.stats.interval( mu, np.nan, np.nan) try: results['constellation'] = ugali.utils.projector.ang2const( lon, lat)[1] except: pass results['iau'] = ugali.utils.projector.ang2iau(lon, lat) coord = SkyCoord(ra * u.deg, dec * u.deg, distance=dist * u.kpc) results['ra_sex'] = str(coord.ra.to_string()) results['dec_sex'] = str(coord.dec.to_string()) # Calculate some separations from GC, LMC, SMC #NED coordinates with de Grisj distance LMC = SkyCoord(80.8939 * u.deg, -69.7561 * u.deg, distance=49.89 * u.kpc) #NED coordinates with de Grisj distance SMC = SkyCoord(13.1866 * u.deg, -72.8286 * u.deg, distance=61.94 * u.kpc) # GC from astropy? GC = SkyCoord(266.4168262 * u.deg, -29.0077969 * u.deg, distance=8.0 * u.kpc) results['d_gc'] = coord.separation_3d(GC).value results['d_lmc'] = coord.separation_3d(LMC).value results['d_smc'] = coord.separation_3d(SMC).value try: results['feh'] = float(self.source.isochrone.feh) except: results['feh'] = np.nan output = dict() output['params'] = params output['results'] = results return output
def ra_dec(self): return gal2cel(self.lon, self.lat)
samfile = outfile # samples srcfile = outfile.replace('.npy','.yaml') # srcmdl and results memfile = outfile.replace('.npy','.fits') # membership resfile = srcfile # results file # import pdb; pdb.set_trace() source = ugali.analysis.loglike.createSource(config,section='mcmc') source.name = opts.name if opts.srcmdl is not None: source.load(opts.srcmdl,section=opts.name) if opts.coords: lon,lat,radius = opts.coords[0] if config['coords']['coordsys'].lower() == 'gal': source.set_params(lon=lon,lat=lat) else: lon,lat = gal2cel(lon,lat) source.set_params(lon=lon,lat=lat) if config['mcmc'].get('params'): params = config['mcmc'].get('params') source.set_free_params(params) like = ugali.analysis.loglike.createLoglike(config,source) if opts.grid: grid = ugali.analysis.scan.GridSearch(config,like) grid.search() source.set_params(**grid.mle()) params = list(source.get_free_params().keys()) logger.info(source)