def pixels_cannon(*args,**kwargs): """ NAME: pixels_cannon PURPOSE: determine continuum pixels using a Cannon-like technique (Ness et al. 2015) INPUT: Either: a) Input for running the apogee.spec.cannon: spec - spectra to fit (nspec,nlambda) specerrs - errors on the spectra (nspec,nlambda); assume no covariances label1, label2, ... - labels (nspec); best to subtract reference values before running this type= ('lin') type of Cannon to run: 'lin' - linear Cannon 'quad' - quadratic Cannon b) Output from a previous Cannon run: coefficients - coefficients from the fit (ncoeffs,nlambda) scatter - scatter from the fit (nlambda) KEYWORDS: baseline_dev= (0.015) maximum deviation from baseline label1_max= (10.**-5.) maximum deviation in first linear coefficient label2_max= (0.006) similar for the second label3_max= (0.012) similar for the third labelN_max= same with default 0.03 ... scatter_max= (0.015) maximum scatter of residuals OUTPUT: Boolean index into the wavelength range with True for continuum pixels HISTORY: 2015-02-05 - Written - Bovy (IAS@KITP) """ # Grab kwargs type= kwargs.pop('type','lin') # Parse input if len(args) == 0: # Use default fit from apogee.spec._train_cannon import load_fit coeffs, scatter, baseline_labels= load_fit() type= 'quad' else: spec= args[0] specerr= args[1] # Determine the type of input if len(specerr.shape) == 2: # Run the Cannon if type.lower() == 'lin': coeffs, scatter= cannon.linfit(*args) elif type.lower() == 'quad': coeffs, scatter= cannon.quadfit(*args) else: coeffs= spec scatter= specerr ncoeffs= coeffs.shape[0] if type.lower() == 'lin': nlabels= ncoeffs-1 elif type.lower() == 'quad': nlabels= int((-3+numpy.sqrt(9+8*(ncoeffs-1))))//2 # Determine continuum pixels out= numpy.ones(len(scatter),dtype='bool') # Deviation from baseline out[numpy.fabs(coeffs[0]-1.) > kwargs.get('baseline_dev',0.015)]= False # Large dependence on labels maxs= numpy.zeros(nlabels) maxs[0]= kwargs.get('label1_max',10.**-5.) maxs[1]= kwargs.get('label2_max',0.006) maxs[2]= kwargs.get('label3_max',0.012) for ii in range(nlabels-3): maxs[ii+3]= kwargs.get('label%i_max' % (ii+4),0.03) for ii in range(1,nlabels+1): out[numpy.fabs(coeffs[ii]) > maxs[ii-1]]= False # Large residuals out[scatter > kwargs.get('scatter_max',0.015)]= False return out
def pixels_cannon(*args, **kwargs): """ NAME: pixels_cannon PURPOSE: determine continuum pixels using a Cannon-like technique (Ness et al. 2015) INPUT: Either: a) Input for running the apogee.spec.cannon: spec - spectra to fit (nspec,nlambda) specerrs - errors on the spectra (nspec,nlambda); assume no covariances label1, label2, ... - labels (nspec); best to subtract reference values before running this type= ('lin') type of Cannon to run: 'lin' - linear Cannon 'quad' - quadratic Cannon b) Output from a previous Cannon run: coefficients - coefficients from the fit (ncoeffs,nlambda) scatter - scatter from the fit (nlambda) KEYWORDS: baseline_dev= (0.015) maximum deviation from baseline label1_max= (10.**-5.) maximum deviation in first linear coefficient label2_max= (0.006) similar for the second label3_max= (0.012) similar for the third labelN_max= same with default 0.03 ... scatter_max= (0.015) maximum scatter of residuals dr= (module-wide default) data release OUTPUT: Boolean index into the wavelength range with True for continuum pixels HISTORY: 2015-02-05 - Written - Bovy (IAS@KITP) """ # Grab kwargs type = kwargs.pop('type', 'lin') dr = kwargs.pop('dr', path._default_dr()) # Parse input if len(args) == 0: # Use default fit from apogee.spec._train_cannon import load_fit coeffs, scatter, baseline_labels = load_fit() type = 'quad' else: spec = args[0] specerr = args[1] # Determine the type of input if len(specerr.shape) == 2: # Run the Cannon if type.lower() == 'lin': coeffs, scatter = cannon.linfit(*args) elif type.lower() == 'quad': coeffs, scatter = cannon.quadfit(*args) else: coeffs = spec scatter = specerr ncoeffs = coeffs.shape[0] if type.lower() == 'lin': nlabels = ncoeffs - 1 elif type.lower() == 'quad': nlabels = int((-3 + numpy.sqrt(9 + 8 * (ncoeffs - 1)))) // 2 # Determine continuum pixels out = numpy.ones(len(scatter), dtype='bool') # Deviation from baseline out[numpy.fabs(coeffs[0] - 1.) > kwargs.get('baseline_dev', 0.015)] = False # Large dependence on labels maxs = numpy.zeros(nlabels) maxs[0] = kwargs.get('label1_max', 10.**-5.) maxs[1] = kwargs.get('label2_max', 0.006) maxs[2] = kwargs.get('label3_max', 0.012) for ii in range(nlabels - 3): maxs[ii + 3] = kwargs.get('label%i_max' % (ii + 4), 0.03) for ii in range(1, nlabels + 1): out[numpy.fabs(coeffs[ii]) > maxs[ii - 1]] = False # Large residuals out[scatter > kwargs.get('scatter_max', 0.015)] = False _, _, _, aspcapDR12length = _aspcapPixelLimits(dr='12') if int(dr) > 12 and coeffs.shape[1] == aspcapDR12length: # Want continuum pixels on >DR12 ASPCAP grid, but using coefficients # from <= DR12 grid dr_module = path._default_dr() path.change_dr(12) out = toApStarGrid(out) path.change_dr(dr) out = toAspcapGrid(out) path.change_dr(dr_module) return out
def polylabels(spec,specerr,coeffs=None,scatter=None,poly='lin', return_cov=False,return_poly=False,baseline_labels=None): """ NAME: polylabels PURPOSE: Get the labels using a polynomial fit INPUT: spec - spectrum/a to fit (nlambda) or (nspec,nlambda) specerrs - error/s on the spectra (nlambda) or (nspec,nlambda); assume no covariances coeffs= array of coefficients from the polynomial fit (ncoeffs,nlambda); if not set the default fit is used scatter= array of scatter from the polynomial fit (nlambda)); if not set the default fit is used poly= ('lin') 'lin' or 'quad' currently return_cov= (False) if True, return the uncertainty covariance matrix for the labels return_poly= (False) if True, return the best-fit labels, labels-squared, etc. baseline_labels= baseline to add to the labels (baseline that was subtracted before the fit) OUTPUT: Best-fit labels (nspec,nlabels) if return_poly, the best-fit linear, quadratic, ... terms are returned HISTORY: 2015-02-23 - Written - Bovy (IAS@KITP) """ if len(spec.shape) == 1: spec= numpy.reshape(spec,(1,len(spec))) specerr= numpy.reshape(specerr,(1,len(specerr))) # Load default fit if necessary if coeffs is None: from apogee.spec._train_cannon import load_fit coeffs, scatter, baseline_labels= load_fit() poly= 'quad' # Setup output nspec= spec.shape[0] ncoeffs= coeffs.shape[0] if 'lin' in poly: nlabels= ncoeffs-1 elif 'quad' in poly: nlabels= int((-3+numpy.sqrt(9+8*(ncoeffs-1))))//2 if return_poly: nout= ncoeffs-1 else: nout= nlabels out= numpy.empty((nspec,nout)) if return_cov: outcov= numpy.empty((nspec,nout,nout)) # Run through the spectra for ii in range(nspec): labels= _polyfit_coeffs(spec[ii]-coeffs[0],specerr[ii], scatter,coeffs[1:].T, return_cov=return_cov) if return_cov: cov= labels[1] labels= labels[0] if return_poly: out[ii]= labels else: out[ii]= labels[:nlabels] if return_cov and return_poly: outcov[ii]= cov elif return_cov: outcov[ii]= cov[:nlabels,:nlabels] if not baseline_labels is None: out+= baseline_labels if return_cov: return (out,outcov) else: return out