def dereddenData(self): ''' Deredden the data. The interstellar extinction curve by Chiar and Tielens (2006) is used with an Av to Ak conversion factor of 0.112. The correction is done by interpolating the curve, and extrapolating to longer wavelengths. The extrapolation is done with a power law fitted to the long wavelength region (lambda > 22 micron). For short wavelength points below 1.24 micron, the cardelli extinction curve is used. ''' #- Read the extinction curve, then inter/extrapolate it ext_x,ext_y = getExtinctionCurve(self.gal_position,'chiar_tielens',\ 0.112) ext_car_x, ext_car_y = getExtinctionCurve(curve_type='cardelli',\ av_to_ak_conv=0.112) #- Initial param guess for extrapolation of long wavelength extinction curve p0 = [ -2, 0.01 , 1, -1] #- Assuming a power law for the extrapolation, and fitting from 22 mic deredfunc = 'power' extrapol_xmin = 22.0 chiar_min = ext_x[0] #- Fit the power law to the > 22 micron wavelength range plsq = leastsq(Interpol.getResiduals,p0,\ args=(ext_x[ext_x>=extrapol_xmin],\ ext_y[ext_x>=extrapol_xmin],\ deredfunc),maxfev=20000)[0] #- Calculate the extrapolation and interpolation for the datagrids #- Then combine and apply the correction to the data for (dt,fn),data in self.data_raw.items(): if len(data) == 3: data_x, data_y, data_ey = data[0], data[1], data[2] else: data_x, data_y = data[0], data[1] extra = Interpol.pEval(data_x[data_x>=extrapol_xmin],plsq,deredfunc) inter = interp1d(ext_x,ext_y)(data_x[(data_x<extrapol_xmin)\ *(data_x>=chiar_min)]) short = interp1d(ext_car_x,ext_car_y)(data_x[data_x<chiar_min]) corr = hstack([short,inter,extra]) if self.plot_extrapol_extinction: Plotting2.plotCols(x=[ext_x,data_x],y=[ext_y,corr],\ xlogscale=1,ylogscale=1) if len(data) == 3: self.data[(dt,fn)] = (data_x,\ data_y*10**(corr*self.ak*0.4),\ data_ey*10**(corr*self.ak*0.4)) else: self.data[(dt,fn)] = (data_x,data_y*10**(corr*self.ak*0.4))
def alignY(datalists,xmin,xmax,zeropoint=0,p0=[1,0,1.5,-2.5],func='power'): """ *** WILL BE REWRITTEN *** Align two datasets by shifting Y coordinate. Works on multiple data lists at a time. Each dataset is shifted to match with the previous dataset AFTER the previous one has already been shifted. e.g. for the third dataset y_new = zeropoint + shifts[1]*shifts[2]*y The shifts between datasets are multiplicative, the first dataset is shifted additively by the keyword zeropoint. At least 3 points of overlap are required! @param datalists: two or more 2d lists of data giving (x,y) @type datalists: list[list[(.,.)]] @param xmin: the lower boundar(y)(ies) of the overlapping region, used for alignment. Must be 1 value for 2 datasets, n-1 values for more @type xmin: float or list @param xmax: the upper boundar(y)(ies) of the overlapping region, used for alignment. Must be 1 value for 2 datasets, n-1 values for more @type xmax: float or list @keyword zeropoint: The first dataset is shifted additively with this value (default: 0) @type zeropoint: float @keyword p0: initial parameters for fitting function definition (default: [1,0,1.5,-2.5]) @type p0: list @return: The datasets are returned as given, but with shifted Y-values, and the shifts used (first value additively, rest multiplicatively) @rtype: (list[list[(.,.)]], list) """ #- zeropoint correction shifts = [zeropoint] current_data = array(datalists[0]) corrected = [[coord + array([0,zeropoint]) for coord in current_data]] #- Power law is fitted to overlapping xrange for both datasets with leastsq #- x of second list is evaluated with both functions #- second list's y values are corrected by the mean of the ratios of the #- two function evaluations for i in xrange(len(datalists)-1): p_lsqlist1 = leastsq(Interpol.getResiduals,p0,\ args=([x for x in array(corrected[i])[:,0] if x >= xmin[i] and x <= xmax[i]],\ [coord[1] for coord in array(corrected[i]) if coord[0] >= xmin[i] and coord[0] <= xmax[i]],\ func),\ maxfev=2000)[0] p_lsqlist2 = leastsq(Interpol.getResiduals,p0,\ args=([x for x in array(datalists[i+1])[:,0] if x >= xmin[i] and x <= xmax[i]],\ [coord[1] for coord in array(datalists[i+1]) if coord[0] >= xmin[i] and coord[0] <= xmax[i]],\ func),\ maxfev=2000)[0] f1x2 = Interpol.pEval([x for x in array(datalists[i+1])[:,0] if x >= xmin[i] and x <= xmax[i]], p_lsqlist1,func) f2x2 = Interpol.pEval([x for x in array(datalists[i+1])[:,0] if x >= xmin[i] and x <= xmax[i]],\ p_lsqlist2,func) shifts.append(mean(f1x2/f2x2)) corrected.append([coord*array([1,shifts[i+1]]) for coord in array(datalists[i+1])]) return corrected,shifts