def run(self, dataSlice, slicePoint=None): snr = np.zeros(len(dataSlice), dtype='float') for filt in self.filters: inFilt = np.where(dataSlice[self.filterCol] == filt) snr[inFilt] = mafUtils.m52snr(self.mags[filt], dataSlice[self.m5Col][inFilt]) position_errors = np.sqrt( mafUtils.astrom_precision(dataSlice[self.seeingCol], snr)**2 + self.atm_err**2) x_coord = np.tan(dataSlice['zenithDistance']) * np.sin( dataSlice[self.PACol]) # Things should be the same for RA and dec. # Now I want to compute the error if I interpolate/extrapolate to +/-1. # function is of form, y=ax. a=y/x. da = dy/x. # Only strictly true if we know the unshifted position. But this should be a reasonable approx. slope_uncerts = position_errors / x_coord total_slope_uncert = 1. / np.sqrt(np.sum(1. / slope_uncerts**2)) # So, this will be the uncertainty in the RA or Dec offset at x= +/- 1. result = total_slope_uncert return result
def _computeWeights(self, dataSlice, snr): # Compute centroid uncertainty in each visit position_errors = np.sqrt( mafUtils.astrom_precision(dataSlice[self.seeingCol], snr)**2 + self.atm_err**2) weights = 1. / position_errors**2 return weights
def run(self, dataslice, slicePoint=None): filters = np.unique(dataslice['filter']) precis = np.zeros(dataslice.size, dtype='float') for f in filters: observations = np.where(dataslice['filter'] == f) if np.size(observations[0]) < 2: precis[observations] = self.badval else: snr = mafUtils.m52snr(self.mags[f], dataslice[self.m5Col][observations]) precis[observations] = mafUtils.astrom_precision( dataslice[self.seeingCol][observations], snr) precis[observations] = np.sqrt(precis[observations]**2 + self.atm_err**2) good = np.where(precis != self.badval) result = mafUtils.sigma_slope(dataslice['expMJD'][good], precis[good]) result = result*365.25*1e3 #convert to mas/yr if (self.normalize) & (good[0].size > 0): new_dates=dataslice['expMJD'][good]*0 nDates = new_dates.size new_dates[nDates/2:] = self.baseline*365.25 result = (mafUtils.sigma_slope(new_dates, precis[good])*365.25*1e3)/result # Observations that are very close together can still fail if np.isnan(result): result = self.badval return result
def run(self, dataslice, slicePoint=None): filters = np.unique(dataslice['filter']) filters = [str(f) for f in filters] precis = np.zeros(dataslice.size, dtype='float') for f in filters: observations = np.where(dataslice['filter'] == f) if np.size(observations[0]) < 2: precis[observations] = self.badval else: snr = mafUtils.m52snr(self.mags[f], dataslice[self.m5Col][observations]) precis[observations] = mafUtils.astrom_precision( dataslice[self.seeingCol][observations], snr) precis[observations] = np.sqrt(precis[observations]**2 + self.atm_err**2) good = np.where(precis != self.badval) result = mafUtils.sigma_slope(dataslice[self.mjdCol][good], precis[good]) result = result * 365.25 * 1e3 # Convert to mas/yr if (self.normalize) & (good[0].size > 0): new_dates = dataslice[self.mjdCol][good] * 0 nDates = new_dates.size new_dates[nDates // 2:] = self.baseline * 365.25 result = (mafUtils.sigma_slope(new_dates, precis[good]) * 365.25 * 1e3) / result # Observations that are very close together can still fail if np.isnan(result): result = self.badval return result
def run(self, dataSlice, slicePoint=None): obs = np.where(dataSlice[self.mjdCol]<min(dataSlice[self.mjdCol])+365*self.surveyduration) deltamag= np.arange(self.MagIterLim[0],self.MagIterLim[1],self.MagIterLim[2]) out = {} for dm in deltamag: if self.mode == 'distance': pmnew= self.mu_sag /(10**(dm/5)) mag = self.mag_sag + dm elif self.mode == 'density': pmnew= self.mu_sag mag = self.mag_sag + dm else: print('##### ERROR: the metric is not implemented for this mode.') mjd = dataSlice[self.mjdCol][obs] flt = dataSlice[self.filterCol][obs] if ('g' in flt) and ('r' in flt): # select objects above the limit magnitude threshold snr = m52snr(mag[:, np.newaxis],dataSlice[self.m5Col][obs]) row, col =np.where(snr>self.snr_lim) if self.gap_selection: Times = np.sort(mjd) dt = np.array(list(combinations(Times,2))) DeltaTs = np.absolute(np.subtract(dt[:,0],dt[:,1])) DeltaTs = np.unique(DeltaTs) if np.size(DeltaTs)>0: dt_pm = 0.05*np.amin(dataSlice[self.seeingCol])/pmnew[np.unique(row)] selection = np.where((dt_pm>min(DeltaTs)) & (dt_pm<max(DeltaTs))) else: selection = np.unique(row) precis = astrom_precision(dataSlice[self.seeingCol][obs], snr[row,:]) sigmapm= self.sigma_slope(dataSlice[self.mjdCol][obs], precis) Hg = mag[selection]+5*np.log10(pmnew[selection])-10 sigmaHg = np.sqrt((mag[selection]/m52snr(mag[selection],np.median(dataSlice[self.m5Col])))**(2)+ (4.715*sigmapm[selection]/np.ceil(pmnew[selection]))**2) sigmag = np.sqrt((mag[selection]/m52snr(mag[selection],np.median(dataSlice[self.m5Col])))**2+((mag[selection]-self.gr[selection])/m52snr((mag[selection]-self.gr[selection]),np.median(dataSlice[self.m5Col])))**2) err_ellipse = np.pi*sigmaHg*sigmag if self.dataout: CI = np.array([np.nansum((([gr-gcol ])/sigmag)**2 + ((Hg-h)/sigmaHg)**2 <= 1)/np.size(pmnew[selection]) for (gcol,h) in zip(gr,Hg)]) out[dm] = {'CI':CI,'alpha':np.size(pmnew[selection])/np.size(pmnew) ,'err':err_ellipse,'Hg':Hg,'gr':gr, 'sigmaHg':sigmaHg,'sigmagr':sigmag} else: out[dm] = {'alpha':np.size(pmnew[selection])/np.size(pmnew) ,'err':err_ellipse} else: if self.dataout: out[dm] = {'CI':0,'alpha':0,'err':0,'Hg':Hg,'gr':gr, 'sigmaHg':sigmaHg,'sigmagr':sigmag} else: out[dm] = {'alpha':0 ,'err':0} if self.dataout: return out else: if ('g' in flt) and ('r' in flt): res = out[dm]['alpha']/np.nanmean(out[dm]['err'][np.isfinite(out[dm]['err'])]) return res
def run(self, dataslice, slicePoint=None): filters = np.unique(dataslice[self.filterCol]) snr = np.zeros(len(dataslice), dtype='float') # compute SNR for all observations for filt in filters: good = np.where(dataslice[self.filterCol] == filt) snr[good] = mafUtils.m52snr(self.mags[filt], dataslice[self.m5Col][good]) position_errors = np.sqrt(mafUtils.astrom_precision(dataslice[self.seeingCol], snr)**2+self.atm_err**2) sigma = self._final_sigma(position_errors,dataslice['ra_pi_amp'],dataslice['dec_pi_amp'] ) if self.normalize: # Leave the dec parallax as zero since one can't have ra and dec maximized at the same time. sigma = self._final_sigma(position_errors,dataslice['ra_pi_amp']*0+1.,dataslice['dec_pi_amp']*0 )/sigma return sigma
def run(self, dataSlice, slicePoint=None): # The idea here is that we calculate position errors (in RA and Dec) for all observations. # Then we generate arrays of the parallax offsets (delta RA parallax = ra_pi_amp, etc) # and the DCR offsets (delta RA DCR = ra_dcr_amp, etc), and just add them together into one # RA (and Dec) offset. Then, we try to fit for how we combined these offsets, but while # considering the astrometric noise. If we can figure out that we just added them together # (i.e. the curve_fit result is [a=1, b=1] for the function _positions above) # then we should be able to disentangle the parallax and DCR offsets when fitting 'for real'. # compute SNR for all observations snr = np.zeros(len(dataSlice), dtype='float') for filt in self.filters: inFilt = np.where(dataSlice[self.filterCol] == filt) snr[inFilt] = mafUtils.m52snr(self.mags[filt], dataSlice[self.m5Col][inFilt]) # Compute the centroiding uncertainties # Temporary fix for FWHMeff to FWHMgeom calculation. if self.seeingCol.endswith('Eff'): seeing = dataSlice[self.seeingCol] * 0.822 + 0.052 else: seeing = dataSlice[self.seeingCol] position_errors = np.sqrt( mafUtils.astrom_precision(seeing, snr)**2 + self.atm_err**2) # Construct the vectors of RA/Dec offsets. xdata is the "input data". ydata is the "output". xdata = np.empty((2, dataSlice.size * 2), dtype=float) xdata[0, :] = np.concatenate( (dataSlice['ra_pi_amp'], dataSlice['dec_pi_amp'])) xdata[1, :] = np.concatenate( (dataSlice['ra_dcr_amp'], dataSlice['dec_dcr_amp'])) ydata = np.sum(xdata, axis=0) # Use curve_fit to compute covariance between parallax and dcr amplitudes # Set the initial guess slightly off from the correct [1,1] to make sure it iterates. popt, pcov = curve_fit(self._positions, xdata, ydata, p0=[1.1, 0.9], sigma=np.concatenate( (position_errors, position_errors)), absolute_sigma=True) # Catch if the fit failed to converge on the correct solution. if np.max(np.abs(popt - np.array([1., 1.]))) > self.tol: return self.badval # Covariance between best fit parallax amplitude and DCR amplitude. cov = pcov[1, 0] # Convert covarience between parallax and DCR amplitudes to normalized correlation perr = np.sqrt(np.diag(pcov)) correlation = cov / (perr[0] * perr[1]) result = correlation # This can throw infs. if np.isinf(result): result = self.badval return result
def run(self, dataslice, slicePoint=None): filters = np.unique(dataslice[self.filterCol]) if hasattr(filters[0], 'decode'): filters = [str(f.decode('utf-8')) for f in filters] snr = np.zeros(len(dataslice), dtype='float') # compute SNR for all observations for filt in filters: good = np.where(dataslice[self.filterCol] == filt) snr[good] = mafUtils.m52snr(self.mags[str(filt)], dataslice[self.m5Col][good]) position_errors = np.sqrt(mafUtils.astrom_precision(dataslice[self.seeingCol], snr)**2+self.atm_err**2) sigma = self._final_sigma(position_errors, dataslice['ra_pi_amp'], dataslice['dec_pi_amp']) if self.normalize: # Leave the dec parallax as zero since one can't have ra and dec maximized at the same time. sigma = self._final_sigma(position_errors, dataslice['ra_pi_amp']*0+1., dataslice['dec_pi_amp']*0)/sigma return sigma
def run(self, dataSlice, slicePoint=None): snr = np.zeros(len(dataSlice), dtype='float') # compute SNR for all observations for filt in self.filters: inFilt = np.where(dataSlice[self.filterCol] == filt) snr[inFilt] = mafUtils.m52snr(self.mags[filt], dataSlice[self.m5Col][inFilt]) # Compute the centroiding uncertainties position_errors = np.sqrt( mafUtils.astrom_precision(dataSlice[self.seeingCol], snr)**2 + self.atm_err**2) # Construct the vectors xdata = np.empty((2, dataSlice.size * 2), dtype=float) xdata[0, :] = np.concatenate( (dataSlice['ra_pi_amp'], dataSlice['dec_pi_amp'])) xdata[1, :] = np.concatenate( (dataSlice['ra_dcr_amp'], dataSlice['dec_dcr_amp'])) ydata = np.sum(xdata, axis=0) # Use curve_fit to compute covariance between parallax and dcr amplitudes # Set the initial guess slightly off from the correct [1,1] to make sure it iterates. popt, pcov = curve_fit(self._positions, xdata, ydata, p0=[1.1, 0.9], sigma=np.concatenate( (position_errors, position_errors)), absolute_sigma=True) # Catch if the fit failed to converge on the correct solution. if np.max(np.abs(popt - np.array([1., 1.]))) > self.tol: return self.badval # Covariance between best fit parallax amplitude and DCR amplitude. cov = pcov[1, 0] # Convert covarience between parallax and DCR amplitudes to normalized correlation perr = np.sqrt(np.diag(pcov)) correlation = cov / (perr[0] * perr[1]) result = correlation # This can throw infs. if np.isinf(result): result = self.badval return result
def run(self, dataSlice, slicePoint=None): # The idea here is that we calculate position errors (in RA and Dec) for all observations. # Then we generate arrays of the parallax offsets (delta RA parallax = ra_pi_amp, etc) # and the DCR offsets (delta RA DCR = ra_dcr_amp, etc), and just add them together into one # RA (and Dec) offset. Then, we try to fit for how we combined these offsets, but while # considering the astrometric noise. If we can figure out that we just added them together # (i.e. the curve_fit result is [a=1, b=1] for the function _positions above) # then we should be able to disentangle the parallax and DCR offsets when fitting 'for real'. # compute SNR for all observations snr = np.zeros(len(dataSlice), dtype='float') for filt in self.filters: inFilt = np.where(dataSlice[self.filterCol] == filt) snr[inFilt] = mafUtils.m52snr(self.mags[filt], dataSlice[self.m5Col][inFilt]) # Compute the centroiding uncertainties # Note that these centroiding uncertainties depend on the physical size of the PSF, thus # we are using seeingFwhmGeom for these metrics, not seeingFwhmEff. position_errors = np.sqrt(mafUtils.astrom_precision(dataSlice[self.seeingCol], snr)**2 + self.atm_err**2) # Construct the vectors of RA/Dec offsets. xdata is the "input data". ydata is the "output". xdata = np.empty((2, dataSlice.size * 2), dtype=float) xdata[0, :] = np.concatenate((dataSlice['ra_pi_amp'], dataSlice['dec_pi_amp'])) xdata[1, :] = np.concatenate((dataSlice['ra_dcr_amp'], dataSlice['dec_dcr_amp'])) ydata = np.sum(xdata, axis=0) # Use curve_fit to compute covariance between parallax and dcr amplitudes # Set the initial guess slightly off from the correct [1,1] to make sure it iterates. popt, pcov = curve_fit(self._positions, xdata, ydata, p0=[1.1, 0.9], sigma=np.concatenate((position_errors, position_errors)), absolute_sigma=True) # Catch if the fit failed to converge on the correct solution. if np.max(np.abs(popt - np.array([1., 1.]))) > self.tol: return self.badval # Covariance between best fit parallax amplitude and DCR amplitude. cov = pcov[1, 0] # Convert covarience between parallax and DCR amplitudes to normalized correlation perr = np.sqrt(np.diag(pcov)) correlation = cov/(perr[0]*perr[1]) result = correlation # This can throw infs. if np.isinf(result): result = self.badval return result
def run(self, dataSlice, slicePoint=None): np.random.seed(2500) obs = np.where((dataSlice['filter'] == self.f) & (dataSlice[self.mjdCol] < min(dataSlice[self.mjdCol]) + 365 * self.surveyduration)) d = np.array(self.simobj['d']) M = np.array(self.simobj['MAG']) fieldRA, fieldDec = np.mean(dataSlice['fieldRA']), np.mean( dataSlice['fieldDec']) z, R = d * np.sin(fieldRA), d * np.cos(fieldRA) component = self.position_selection(R, z) mjd = dataSlice[self.mjdCol][obs] fwhm = dataSlice[self.seeingCol][obs] V_galactic = np.vstack((self.U, self.V, self.W)) Pv = self.DF(V_galactic, component, R, z) marg_P = np.nanmean(Pv / np.nansum(Pv, axis=0), axis=0) marg_P /= np.nansum(marg_P) vel_idx = np.random.choice(np.arange(0, len(V_galactic[0, :]), 1)[np.isfinite(marg_P)], p=marg_P[np.isfinite(marg_P)], size=3) vT_unusual = V_galactic[0, vel_idx][2] if self.prob_type == 'uniform': p_vel_unusual = uniform(-100, 100) v_unusual = p_vel_unusual.rvs(size=(3, np.size(d))) vT = v_unusual[2, :] else: p_vel_un = pd.read_csv(self.prob_type) vel_idx = np.random.choice(p_vel_un['vel'], p=p_vel_un['fraction'] / np.sum(p_vel_un['fraction']), size=3) vT_unusual = V_galactic[0, vel_idx][2] #vel_unusual = V_galactic[0,vel_idx] direction = np.random.choice((-1, 1)) mu = direction * vT / 4.75 / d mu_unusual = direction * vT_unusual / 4.75 / d if len(dataSlice[self.m5Col][obs]) > 2: # select objects above the limit magnitude threshold snr = m52snr(M[:, np.newaxis], dataSlice[self.m5Col][obs]) row, col = np.where(snr > self.snr_lim) if self.gap_selection: Times = np.sort(mjd) dt = np.array(list(combinations(Times, 2))) DeltaTs = np.absolute(np.subtract(dt[:, 0], dt[:, 1])) DeltaTs = np.unique(DeltaTs) if np.size(DeltaTs) > 0: dt_pm = 0.05 * np.amin( dataSlice[self.seeingCol][obs]) / muf[np.unique(row)] selection = np.where((dt_pm > min(DeltaTs)) & (dt_pm < max(DeltaTs))) else: selection = np.unique(row) precis = astrom_precision(dataSlice[self.seeingCol][obs], snr[row, :]) sigmapm = self.sigma_slope(dataSlice[self.mjdCol][obs], precis) * 365.25 * 1e3 if np.size(selection) > 0: pa = np.random.uniform(0, 2 * np.pi, len(mu_unusual[selection])) pm_alpha, pm_delta = mu[selection] * np.sin( pa), mu[selection] * np.cos(pa) pm_un_alpha, pm_un_delta = mu_unusual[selection] * np.sin( pa), mu_unusual[selection] * np.cos(pa) #p_min,p_max,p_mean = self.percentiles[0],self.percentiles[1],self.percentiles[2] mu = mu[selection] * 1e3 mu_unusual = mu_unusual[selection] * 1e3 variance_k = np.array([ np.std(mu[np.where(component[selection] == p)]) for p in ['H', 'D', 'B'] ]) variance_mu = np.std(mu) sigmaL = np.sqrt( np.prod(variance_k, where=np.isfinite(variance_k))**2 + variance_mu**2 + np.nanmedian(sigmapm)**2) unusual = np.where((mu_unusual < np.mean(mu_unusual) - self.sigma_threshold * sigmaL / 2) | (mu_unusual > np.mean(mu_unusual) + self.sigma_threshold * sigmaL / 2)) res = np.size(unusual) / np.size(selection) if self.dataout: dic = { 'detected': res, 'pixID': radec2pix(nside=16, ra=np.radians(fieldRA), dec=np.radians(fieldDec)), 'PM': pd.DataFrame({ 'pm_alpha': pm_alpha, 'pm_delta': pm_delta }), 'PM_un': pd.DataFrame({ 'pm_alpha': pm_un_alpha, 'pm_delta': pm_un_delta }) } return dic else: return res
def _computeWeights(self, dataSlice, snr): # Compute centroid uncertainty in each visit position_errors = np.sqrt(mafUtils.astrom_precision(dataSlice[self.seeingCol], snr)**2+self.atm_err**2) weights = 1./position_errors**2 return weights