def test_pchip_interpolate(self): assert_array_almost_equal( pchip_interpolate([1, 2, 3], [4, 5, 6], [0.5], der=1), [1.]) assert_array_almost_equal( pchip_interpolate([1, 2, 3], [4, 5, 6], [0.5], der=0), [3.5]) assert_array_almost_equal( pchip_interpolate([1, 2, 3], [4, 5, 6], [0.5], der=[0, 1]), [[3.5], [1]])
def calc_1d_interpolation(x, y, kind=None, no=50): ''' Return linspaced x and interpolated y for average, with pm std dev. Parameters ---------- x : float x-values y : float y-values Returns ------- xls : float x-values, unique ya : float y-values, average yp : float y-values, average + standard deviation ym : float y-values, average - standard deviation ''' # Calculate and sort variables xu, ya, ys = calc_statistics(x, y) xls = np.linspace(min(xu), max(xu), num=no) yp = ya + ys ym = ya - ys # 'linear' is safe but not that nice # 'quadratic' seems to oscillate # 'cubic' seems to oscillate # 1 d interpolation kinds = [ 'pchip', 'linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic' ] if kind is None: kind = kinds[0] if not len(xu) > 1: kind = 'few_xu' logger.info(f'Skipping interpolation, too few points: {len(xu)}') if kind == 'few_xu': ya = np.array([ya for xi in xls]) yp = np.array([yp for xi in xls]) ym = np.array([ym for xi in xls]) elif kind == 'pchip': ya = interpolate.pchip_interpolate(xu, ya, xls) yp = interpolate.pchip_interpolate(xu, yp, xls) ym = interpolate.pchip_interpolate(xu, ym, xls) else: # Only linear interpolation seems to work well for a small dataset ya = interpolate.interp1d(xu, ya, kind=kind)(xls) yp = interpolate.interp1d(xu, yp, kind=kind)(xls) ym = interpolate.interp1d(xu, ym, kind=kind)(xls) return xls, ya, yp, ym
def test_pchip_interpolate(self): assert_array_almost_equal( pchip_interpolate([1,2,3], [4,5,6], [0.5], der=1), [1.]) assert_array_almost_equal( pchip_interpolate([1,2,3], [4,5,6], [0.5], der=0), [3.5]) assert_array_almost_equal( pchip_interpolate([1,2,3], [4,5,6], [0.5], der=[0, 1]), [[3.5], [1]])
def CorrectAbsorption(wl_abs, abs_data, Name, Type): data = np.loadtxt('materials/' + Name + '_nk.txt') n = pchip_interpolate(data[:, 0], data[:, 1], wl_abs) k = pchip_interpolate(data[:, 0], data[:, 2], wl_abs) t = 160 * 1e-6 t_array = np.ones((len(wl_abs), )) * t alpha = 4 * np.pi * k / (wl_abs * 1e-9) if Type == "Tiedje": return abs_data * alpha / (alpha + (1 / (4 * (n**2) * t_array))) elif Type == "2Pass": Tout = abs_data * np.exp(-alpha * 2 * t_array) return abs_data - Tout
def interp_1d_values_from_profiles(self): """Interpolate values in 1D (lateral + longitudinal) from profiles""" new_values = np.zeros((self.nb_var, self.nb_nodes_in_riverbed)) for i_zone in np.unique(self.points['zone']): filter_points = self.points['zone'] == i_zone section_us = self.section_seq[i_zone] section_ds = self.section_seq[i_zone + 1] xt_us = section_us.coord.array['Xt'] xt_ds = section_ds.coord.array['Xt'] xt_us_target = self.points['Xt_upstream'][filter_points] xt_ds_target = self.points['Xt_downstream'][filter_points] for i, var in enumerate(self.var_names()): values_us = section_us.coord.values[var] values_ds = section_ds.coord.values[var] if self.interp_values == 'LINEAR': new_values_us = np.interp(xt_us_target, xt_us, values_us) new_values_ds = np.interp(xt_ds_target, xt_ds, values_ds) elif self.interp_values == 'B-SPLINE': splrep_us = interpolate.splrep(xt_us, values_us) splrep_ds = interpolate.splrep(xt_ds, values_ds) new_values_us = interpolate.splev(xt_us_target, splrep_us) new_values_ds = interpolate.splev(xt_ds_target, splrep_ds) elif self.interp_values == 'AKIMA': new_values_us = interpolate.Akima1DInterpolator( xt_us, values_us)(xt_us_target) new_values_ds = interpolate.Akima1DInterpolator( xt_ds, values_ds)(xt_ds_target) elif self.interp_values == 'PCHIP': new_values_us = interpolate.pchip_interpolate( xt_us, values_us, xt_us_target) new_values_ds = interpolate.pchip_interpolate( xt_ds, values_ds, xt_ds_target) elif self.interp_values == 'CUBIC_SPLINE': new_values_us = interpolate.CubicSpline( xt_us, values_us)(xt_us_target) new_values_ds = interpolate.CubicSpline( xt_ds, values_ds)(xt_ds_target) else: raise NotImplementedError new_values[i, filter_points] = new_values_us * (1 - self.points['xl'][filter_points]) + \ new_values_ds * self.points['xl'][filter_points] return new_values
def calc_func(antenna_pol, field_pol): """antenna_pol should be 0 or 1 for X or Y antenna, and field_pol is 0 or 1 for zenithal or azimuthal field""" nonlocal temp_AVE_matrix, tmp3 ## first average Npairs = int((end_i - start_i) / 2) for pair_i in range(Npairs): ant_i = 2 * pair_i + antenna_pol + start_i get_ant_i(ant_i, field_pol) ## this fills temp_matrix temp_AVE_matrix += temp_matrix ## error prone, but should be okay if not np.all(np.isfinite(temp_AVE_matrix)): print('YO problem!', pair_i, np.all(np.isfinite(temp_matrix))) quit() temp_AVE_matrix /= Npairs upsample_grid = np.empty( [num_zeniths, num_azimuths, len(interpolant_frequencies)], dtype=np.complex) ## now interpolate frequencies for zi, ze in enumerate(self.AART_thetas): for ai, az in enumerate(self.AART_Phis): np.abs(temp_AVE_matrix[zi, ai, :], out=tmp3) interp_ampltude = pchip_interpolate( self.all_frequencies, tmp3, interpolant_frequencies) angles = np.angle(temp_AVE_matrix[zi, ai, :]) angles = np.unwrap(angles) interp_angle = pchip_interpolate(self.all_frequencies, angles, interpolant_frequencies) ## now convert back to real and imag interp_angle = interp_angle * 1j np.exp(interp_angle, out=upsample_grid[zi, ai, :]) upsample_grid[zi, ai, :] *= interp_ampltude ## and final angle-frequency interpolant return RegularGridInterpolator( (self.AART_thetas, self.AART_Phis, interpolant_frequencies), upsample_grid, bounds_error=False, fill_value=0.0)
def patch_bokeh(self, start, mid, end, *args, **kwargs): xs = [start[0], mid[0], end[0]] ys = [start[1], mid[1], end[1]] x2 = np.linspace(xs[0], xs[-1], 100) y2 = interpolate.pchip_interpolate(xs, ys, x2) self._bokeh_fig.line(x2, y2, *args, **kwargs)
def curved_line(x0, x1, y0, angle=0, x_spread=4, y_spread=20, num_points=0): if num_points == 0: num_points = np.random.randint(3, 6) * 2 ### get x points x = np.linspace(x0, x1, num_points) for i in range(len(x)): x[i] += rand.randint(-x_spread, x_spread) x[0], x[-1] = x0, x1 ### get y points y = np.full(num_points, y0) for i in range(len(y)): y[i] += rand.randint(-y_spread, y_spread) y[0], y[-1] = y0, y0 ### interpolate line_res = 5 x2 = np.linspace(x[0], x[-1], (x[-1] - x[0]) * line_res) x2, indices = np.unique(x2, return_index=True) y2 = interpolate.pchip_interpolate(x, y, x2[indices]) vx, vy = [], [] for i in range(len(hx) - 1): coord = rotate((x0, y0), (x2[i], y2[i]), math.radians(angle)) vx.append(coord[0]) vy.append(coord[1]) vx, vy = quantize_line_pair(vx, vy) return vx, vy
def FittedTransmission(voltages, offset, amplitude, *params): """ Return the transmission function for a shaper """ V, M = GetVM(*params) return amplitude * np.cos(pchip_interpolate( V, M, voltages))**2 + offset
def phs4(reducedTemperature): # Reduced collision integral for a hard sphere - 4 potential Xt = [ 0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1.00, 1.21, 1.44, 1.69, 1.96, 2.25, 2.56, 2.89, 3.24, 3.61, 4.00, 4.84, 5.76, 6.76, 7.84, 9.00, 10.24, 11.56, 12.96, 14.44, 16.00, 19.36, 23.04, 27.04, 31.36, 36.00, 40.96, 46.24, 51.84, 57.76, 64.00, 100.00, 1000.00 ] YtG = [ 13.67, 6.640, 4.343, 3.213, 2.548, 2.117, 1.823, 1.617, 1.472, 1.368, 1.292, 1.236, 1.194, 1.161, 1.136, 1.116, 1.100, 1.087, 1.076, 1.067, 1.054, 1.044, 1.036, 1.031, 1.026, 1.023, 1.020, 1.017, 1.015, 1.014, 1.010, 1.005, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000 ] #sets up to see if the temperature is even in range It might not be neccesary with pchip interpolation, #but it will at least catch some odd errors coming through. if reducedTemperature >= Xt[41]: q = 1.00 return float(q) if reducedTemperature <= Xt[0]: q = 1.4691 / math.sqrt(reducedTemperature) return float(q) #interpolates using scipy "pchip" tested to give best results with this data set. q = interpolate.pchip_interpolate(Xt, YtG, reducedTemperature) #this is a numpy object so you have to convert it to something useful to the rest of the program. return float(q)
def stopPicking(self,proj): filename = fd.asksaveasfilename() if filename is not '': self.picking = False print("Picking mode off") np.savetxt(filename+'_profile.txt',self.picked,delimiter='\t') print('saved picked file as "%s"' %(filename+'_profile.txt')) # If we have 3D info, also plot it as 3D points if proj.threeD is not None: # First calculate along-track points topoVal = proj.threeD[:,2] npos = proj.threeD.shape[0] steplen = np.sqrt( np.power( proj.threeD[1:npos,0]-proj.threeD[0:npos-1,0] ,2.0) + np.power( proj.threeD[1:npos,1]-proj.threeD[0:npos-1,1] ,2.0) + np.power( proj.threeD[1:npos,2]-proj.threeD[0:npos-1,2] ,2.0) ) alongdist = np.cumsum(steplen) topoPos = np.append(0,alongdist) pick3D = np.zeros((self.picked.shape[0],3)) # If profile is adjusted, need to start the picked at zero. pickProfileShifted = self.picked[:,0] - np.min(proj.profilePos) #for i in range(0,3): for i in range(0,2): pick3D[:,i] = interp.pchip_interpolate(topoPos, proj.threeD[:,i], pickProfileShifted).squeeze() #self.picked[:,0]).squeeze() pick3D[:,2] = self.picked[:,1].squeeze() np.savetxt(filename+'_3D.txt',pick3D,delimiter='\t') print('saved picked file as "%s"' %(filename+'_3D.txt'))
def getCurrent_trapz(wl_abs, abs_data, wl_min, wl_max, theta_in): cdir = os.path.dirname( os.path.abspath(inspect.getfile( inspect.currentframe()))) # script directory am15data = opencsv(os.path.join(cdir, 'ASTMG173.csv')) wl_am15 = am15data[:, 0] e = 1.6021765e-19 h = 6.62607004e-34 c = 299792458 am15jphdata = np.multiply(wl_am15, am15data[:, 2]) am15jphdata *= 1.e-9 * e / (h * c) / 10 am15jphdata *= np.cos( theta_in) #Correct for incident angles different from 0 #print "am15 shape " + str(np.shape(wl_am15)) #print "wl_abs shape " + str(np.shape(wl_abs)) #print "abs_data shape " + str(np.shape(abs_data)) abs_fine = pchip_interpolate(wl_abs, abs_data, wl_am15) #abs_fine = abs_spline(wl_am15) abs_int_data = np.multiply(am15jphdata, abs_fine) n_wl = wl_am15.size for i in range(0, n_wl): if wl_am15[i] < wl_min: abs_int_data[i] = 0 elif wl_am15[i] > wl_max: abs_int_data[i] = 0 j_abs = np.trapz(abs_int_data, wl_am15) return j_abs
def perlinNoise1D(npts, weights): if not isinstance(weights, list): weights = range(int(round(weights))) weights = np.power([2] * len(weights), weights) n = len(weights) xvals = np.linspace(0, 1, npts) total = np.zeros((npts, 1)) for i in range(n): frequency = 2**i this_npts = round(npts / frequency) if this_npts > 1: total += weights[i] * pchip_interpolate( np.linspace(0, 1, this_npts), np.random.random((this_npts, 1)), xvals) # else: # TODO does it matter print("Maxed out at octave {}".format(i)) total = total - np.min(total) total = total / np.max(total) return total.reshape(-1)
def interp_steeper(Nodes,paramNode,TS,SPLINE,K=0.4): """Function to interpolate by making steeper increasing or decreasing pieces of the spline. 'pchip' method extrapolates with constant to the right """ ''' :param array Nodes: length-4 list composed of four dates [StartDate,DateOfImposedSanctions1,DateOfImposedSanctions2,EndDate0] :param array betaNode: length-4 list composed of estimated beta values :param array TS: time series of float values indicating all dates with available data :param str SPLINE: method for interpolation 'spline' or 'pchip' ! Currently developed only for 'pchip' :param float K: K=0.4 by default ''' # obtain spline if SPLINE == 'spline': warnings.warn("The 'spline' calculation is not currently implemented. The method will default to 'pchip'.") SPLINE = 'pchip' if SPLINE == 'pchip': paramVal = sci.pchip_interpolate(Nodes,paramNode,TS) paramVal_new = paramVal.copy() else: sys.exit('SPLINE method not recognized: "spline" and "pchip" available only') time_interval = [x-Nodes[0] for x in Nodes] #start modifying all parts of the spline and make them steeper for i in range(len(Nodes)-1): if paramNode[i] > paramNode[i+1]: time_range = range(time_interval[i],time_interval[i+1]+1) I=[time_interval[i],time_interval[i+1]] steeper_segment=steeper(paramVal[time_range],I,K) paramVal_new[time_range]=steeper_segment #we allow overlap due to interpolation else: time_range = range(time_interval[i],time_interval[i+1]+1) I=[time_interval[i],time_interval[i+1]] steeper_segment = np.array([-x for x in steeper([-x for x in paramVal[time_range]], I, K)]); paramVal_new[time_range]=steeper_segment #we allow overlap due to interpolation return paramVal_new
def _interpolate_z(self, z, t): ''' Interpolate t and return instantaneous velocity. ''' tl = np.linspace(min(t), max(t), 50) za = pchip_interpolate(t, z, tl) v = -np.diff(za) / np.diff(tl) v = np.insert(v, 0, 0) # insert 0 as first speed return v, za, tl
def plot_Mohr(self): # Cu is the undrained shear strength Cu = 0.5 * max(self.data['Stress (lb/in2)']) x = [0, Cu, max(self.data['Stress (lb/in2)'])] y = [0, Cu, 0] x2 = np.linspace(x[0], x[-1], 100) y2 = interpolate.pchip_interpolate(x, y, x2) plt.plot(x2, y2, color='blue') plt.plot(x, y, "ro", color='red') # The following three codes are for the sake of specifying and labeling what the three points represent plt.plot(Cu, Cu, 'ro', color='red', label='undrained shear strength') plt.plot(0, 0, 'ro', color='green', label='normal stress failure') plt.plot(max(self.data['Stress (lb/in2)']), 0, 'ro', color='purple', label='unconfined compression strength') # These next lines are for the titles, labels, and design of the plot itslef plt.title('Mohrโs Circle for Unconfined Compression Test', fontweight='black', fontfamily='monospace') plt.xlabel('Normal Stress (lb/in2)') plt.ylabel('Shear Stress (lb/in2)') plt.grid(ls='-') plt.legend(loc="lower center") plt.show()
def Ac_hier(Rmax, R_idx, R_tmp, g_idx, eigen_cumsum, R_norm, A, R, C_orig, a, num, Ct): R_set = Rmax[R_idx] - R_tmp eigen_sum = np.zeros(np.shape(R_tmp)) acc_r_sum = np.zeros(np.shape(R_tmp)) for i3 in range(np.shape(R_tmp)[1]): ig = g_idx[i3] eigen_tmp = np.asarray(eigen_cumsum[ig][0][:]) eigen_sum[:, i3] = (eigen_tmp[np.array(R_set[:, i3], dtype=int) - 1] - eigen_cumsum[ig][0][0]) / (eigen_cumsum[ig][0][-1] - eigen_cumsum[ig][0][0]) acc_r_sum[:, i3] = interpolate.pchip_interpolate( R_norm[:, ig], A[:, ig], R_set[:, i3] / R[-1, ig].astype(float)) C_tmp = R_set.astype(float).dot(a[np.asarray(g_idx)]) / C_orig eigen_prod = np.multiply(np.prod(eigen_sum, axis=1), C_tmp) eigen_prod = np.prod(acc_r_sum, axis=1) + eigen_prod eigen_prod2 = eigen_prod[eigen_prod.argsort()[::-1]] tmp_num = min(len(R_tmp), num) tmp_val = eigen_prod2[tmp_num - 1] tmp_idx = eigen_prod >= tmp_val R_ = R_tmp[tmp_idx] return R_
def interpolate_nan(self, y): """Interpolate over NaN points in data with monotonic cubic splines.""" assert y.ndim == 1, "Input must be 1D" from scipy import interpolate x = np.arange(len(y)) y_interp = interpolate.pchip_interpolate(x[~np.isnan(y)], y[~np.isnan(y)], x) return y_interp
def _interpolate_t(self, z, t): ''' Interpolate t and return instantaneous velocity. ''' zu, ta, ts, tmin, tmax = self._calc_stat(z, t, sort=True) zl = np.linspace(min(zu), max(zu), 50) ta = pchip_interpolate(zu, ta, zl) v = -np.diff(zl) / np.diff(ta) v = np.insert(v, 0, 0) # insert 0 as first speed return v, zl, ta
def QRED(t, g, r): Q3 = P16_6_4(t, g).real Q2 = P12_6_4(t, g).real Q1 = P8_6_4(t, g).real Q = [round(Q1, 5), round(Q2, 5), round(Q3, 5)] X = [8., 12., 16.] QN = interpolate.pchip_interpolate(X, Q, r) return QN
def make_R(L, E_norm, R_norm_tmp, R, Amax): Rmax = np.empty(L, dtype=int) for i in range(L): x = E_norm[i] y = R_norm_tmp[i] Rmax[i] = np.round( interpolate.pchip_interpolate(x, y, Amax) * R[-1, i]) return Rmax
def _ax_minmaxfill(self, ax, x, z, desc=None): '''Add fill min-max to plot. ''' logger.log(5, self._ax_minmaxfill.__doc__) desc = desc or dict(self.desc, **self.interp_desc) desc.pop('ls', None) # invalid key desc.pop('marker', None) # invalid key desc.pop('edgecolor', None) # invalid key desc.pop('s', None) # invalid key xu, za, zs, zmin, zmax = self._calc_stat(x, z, sort=True) xl = np.linspace(min(xu), max(xu), 500) za = pchip_interpolate(xu, za, xl) zmin = pchip_interpolate(xu, zmin, xl) zmax = pchip_interpolate(xu, zmax, xl) diff = (zmax - zmin) / 20 * 0 # center space? ax.fill_between(xl, zmax, za - diff, alpha=.15, **desc) ax.fill_between(xl, za + diff, zmin, alpha=.15, **desc) self.update_min_max(xl, za)
def scribble(canvas, color): num_points = np.random.randint(3, 6) splat_width = 4 splat_height = 20 x_neighbor_width = 80 x = np.random.randint(0, canvas.shape[0], size=num_points) while ((min(abs(np.ediff1d(x))) < x_neighbor_width) | (max(x) - min(x) <= ((splat_width + 1) * num_points)) | (x.shape[0] != np.unique(x).shape[0]) | (x[1] - x[0] <= splat_width) | (x[-1] - x[-2] <= splat_width)): x = np.random.randint(0, canvas.shape[0], size=num_points) x.sort() y = np.random.randint(0, canvas.shape[1], size=num_points) v, w = x.copy(), y.copy() for i in range(num_points - 2): v_temp = v[i + 1] + rand.randint(-splat_width, splat_width) while v_temp in v: v_temp = v[i + 1] + rand.randint(-splat_width, splat_width) v[i + 1, ] = min(max(v_temp, 0), canvas.shape[0] - 1) w[i + 1, ] += min(max(rand.randint(-splat_height, splat_height), 0), canvas.shape[1] - 1) v.sort() line_res = 5 x2 = np.linspace(x[0], x[-1], (x[-1] - x[0]) * line_res) x2, indices = np.unique(x2, return_index=True) y2 = interpolate.pchip_interpolate(x, y, x2[indices]) v2 = np.linspace(v[0], v[-1], (v[-1] - v[0]) * line_res) v2, indices = np.unique(v2, return_index=True) w2 = interpolate.pchip_interpolate(v, w, v2[indices]) #do splatter for i in range(len(x2)): if y2[i] < canvas.shape[1]: canvas[int(math.ceil(x2[i]))][int(math.ceil(y2[i]))] = color canvas[int(math.floor(x2[i]))][int(math.floor(y2[i]))] = color if (v2[i] >= 0) & (w2[i] >= 0) & (v2[i] < canvas.shape[0]) & ( w2[i] < canvas.shape[1] - 1): canvas[int(math.ceil(v2[i]))][int(math.ceil(w2[i]))] = color canvas[int(math.floor(v2[i]))][int(math.floor(w2[i]))] = color
def correctTopo(data, velocity, profilePos, topoPos, topoVal, twtt): ''' Corrects for topography along the profile by shifting each Trace up or down depending on provided coordinates. INPUT: data data matrix whose columns contain the traces velocity subsurface RMS velocity in m/ns profilePos along-profile coordinates of the traces topoPos along-profile coordinates for provided elevation in meters topoVal elevation values for provided along-profile coordinates, in meters twtt two-way travel time values for the samples, in ns OUTPUT: newdata data matrix with shifted traces, padded with NaN newtwtt twtt for the shifted / padded data matrix maxElev maximum elevation value minElev minimum elevation value ''' # We assume that the profilePos are the correct along-profile # points of the measurements (they can be correted with adj profile) # For some along-profile points, we have the elevation from prepTopo # So we can just interpolate if not ((all(np.diff(topoPos) > 0)) or (all(np.diff(topoPos) < 0))): raise ValueError( '\x1b[1;31;47m' + 'The profile vs topo file does not have purely increasing or decreasing along-profile positions' + '\x1b[0m') else: elev = interp.pchip_interpolate(topoPos, topoVal, profilePos) elevdiff = elev - np.min(elev) # Turn each elevation point into a two way travel-time shift. # It's two-way travel time etime = 2 * elevdiff / velocity timeStep = twtt[3] - twtt[2] # Calculate the time shift for each trace tshift = (np.round(etime / timeStep)).astype(int) maxup = np.max(tshift) # We want the highest elevation to be zero time. # Need to shift by the greatest amount, where we are the lowest tshift = np.max(tshift) - tshift # Make new datamatrix newdata = np.empty((data.shape[0] + maxup, data.shape[1])) newdata[:] = np.nan # Set new twtt newtwtt = np.arange(0, twtt[-1] + maxup * timeStep, timeStep) nsamples = len(twtt) # Enter every trace at the right place into newdata for pos in range(0, len(profilePos)): #print(type(tshift[pos][0])) # print("POS", pos) # print(len(profilePos)) newdata[tshift[pos][0]:tshift[pos][0] + nsamples, pos] = np.squeeze(data[:, pos]) return newdata, newtwtt, np.max(elev), np.min(elev)
def RF_From_Calibre(calibre): InterpCalibre = [ 20, 30, 40, 60, 75, 81, 90, 105, 120, 130, 155, 175, 203, 225, 250, 275, 300, 325, 350, 375, 400, 450, 500, 550, 600, 650, 700, 800, 900, 1000 ] InterpRF = [ 295, 260, 225, 175, 152, 144, 134, 113, 99, 90, 60, 47, 30, 25, 22, 18, 16, 15, 13, 12, 10, 8, 7, 5, 3, 2, 2, 2, 2, 2 ] return int(pchip_interpolate(InterpCalibre, InterpRF, calibre))
def _ax_interpolate_zx(self, ax, x, z, desc=None): '''Add interpolation to plot. Use x = x(z).''' logger.log(5, self._ax_interpolate.__doc__) desc = desc or dict(self.desc, **self.interp_desc) if np.unique(z).size < 2: msg = 'Skipping interpolate, too few datapoints ({}).' logger.info(msg.format(np.unique(z).size)) return zu, xa, xs, xmin, xmax = self._calc_stat(z, x, sort=True) zl = np.linspace(min(zu), max(zu), 500) xa = pchip_interpolate(zu, xa, zl) ax.plot(xa, zl, **desc) self.update_min_max(xa, zl)
def _ax_interpolate(self, ax, x, z, desc=None): '''Add interpolation to plot. ''' logger.log(5, self._ax_interpolate.__doc__) desc = desc or dict(self.desc, **self.interp_desc) if np.unique(x).size < 2: msg = 'Skipping interpolate, too few datapoints ({}).' logger.info(msg.format(np.unique(x))) return xu, za, zs, zmin, zmax = self._calc_stat(x, z, sort=True) xl = np.linspace(min(xu), max(xu), 500) za = pchip_interpolate(xu, za, xl) ax.plot(xl, za, **desc) self.update_min_max(xl, za)
def projection_penalty(xx, yy, xx0, yy0, dxx0, dyy0, points_weight, length3d): # standard deviation ''' Assume that xx0, yy0 - are equidistantly spaced in terms of arc length ''' N = len(xx0) slist_norm = np.linspace(0, 1, N, endpoint=True) slist = curve3d.calc_slist(xx, yy) xx_interp = pchip_interpolate(slist / slist[-1], xx, slist_norm) yy_interp = pchip_interpolate(slist / slist[-1], yy, slist_norm) points_penalty = points_weight * np.sum( (xx_interp - xx0)**2 + (yy_interp - yy0)**2) / N * length3d**-2 ## Add penalty for tangents deviation # works as penalty on derivative deviation (see Sobolev space) dxx_interp = np.diff(xx_interp) dyy_interp = np.diff(yy_interp) ds = slist[-1] / (N - 1) # To normalize; ds in 2D tangent_penalty = np.sum((dxx_interp - dxx0)**2 + (dyy_interp - dyy0)**2) * ds**-2 / (N - 1) return (points_penalty + tangent_penalty)
def edit_init_file(config_set): base_output_dir = pathlib.Path('ic_special') if not base_output_dir.exists(): print("No *.h5 files have been generated in {}".format( str(base_output_dir))) exit(-1) output_dir = str(base_output_dir / config_set['name']) # here we load the esp_initial.h5 and edit the thermodynamic properties init_file = output_dir + '/esp_initial.h5' if os.path.exists(init_file): openh5 = h5py.File(init_file) else: print("Initial h5 file {} not found!".format(init_file)) exit(-1) #--------vertical------------------------------ nv = np.int(config_set['vlevel']) glev = np.int(config_set['glevel']) point_num = 2 + 10 * 2**(2 * glev) dh = np.float(config_set['Top_altitude']) / nv final_height = np.arange(dh / 2, np.float(config_set['Top_altitude']), dh) fvert = open(config_set['vertical_file'], 'r+') vert_keys = fvert.readlines()[0].split() fvert.close() if not 'Height' in vert_keys: print("Error! Vertical data file {} must include 'Height'".format( config_set['vertical_file'])) exit(-1) columns = np.loadtxt(config_set['vertical_file'], skiprows=1) vert_struct = {} for col in np.arange(len(vert_keys)): vert_struct[vert_keys[col]] = columns[:, col] vert_out = {} for key in vert_struct.keys(): if key in openh5.keys(): vert_out[key] = interp.pchip_interpolate(vert_struct['Height'], vert_struct[key], final_height) for i in np.arange(np.int(point_num)): for key in vert_out.keys(): openh5[key][i * nv:i * nv + nv] = vert_out[key] openh5.close()
def generate_kml_file(trajGen, trajectory, gps_trajectory, trajectory_name, ith): kml_traj = np.zeros((5, trajGen.nStages + 1)) if gps_trajectory.shape[0] == 5: gpsMeter = GPSMeterConverter(gps_trajectory[1, 0], gps_trajectory[0, 0], gps_trajectory[2, 0]) else: gpsMeter = GPSMeterConverter(gps_trajectory[7, 0], gps_trajectory[6, 0], gps_trajectory[8, 0]) [kml_traj[0, :], kml_traj[1, :], kml_traj[2, :] ] = gpsMeter.meter_to_gps(trajectory[trajGen.posStateIndices[0], :], trajectory[trajGen.posStateIndices[1], :], trajectory[trajGen.posStateIndices[2], :]) kml_traj[3, :] = np.rad2deg(trajectory[trajGen.yawStateIndex, :]) kml_traj[4, :] = np.rad2deg(trajectory[trajGen.pitchStateIndex, :]) # interpolate trajectory time_step = 0.01 end_time = trajectory[trajGen.endTimeStateIndex, 0] dt = end_time / trajGen.nStages times_mpcc = np.arange(0, trajGen.nStages + 1) * dt interp_mpcc = np.linspace(times_mpcc[0], times_mpcc[-1], int(end_time / time_step)) longitude = pchip_interpolate(times_mpcc, kml_traj[0, :], interp_mpcc) latitude = pchip_interpolate(times_mpcc, kml_traj[1, :], interp_mpcc) altitude = pchip_interpolate(times_mpcc, kml_traj[2, :], interp_mpcc) heading = pchip_interpolate(times_mpcc, kml_traj[3, :], interp_mpcc) tilt = pchip_interpolate(times_mpcc, kml_traj[4, :], interp_mpcc) # generate kml file # filepath = './kmls/' + trajectory_name.replace('.h5', str(ith) + '.kml') filepath = './kmls/' + 'test' + str(ith) + '.kml' write_to_kml_file(filepath, time_step, longitude, latitude, altitude, heading, tilt)
def reconstruct_angles(rr, num_segments): ''' ''' from scipy.interpolate import pchip_interpolate r0 = rr[0] xx, yy, zz = rr.T slist = calc_slist(xx, yy, zz) slist_norm = sp.linspace(0, 1, num_segments + 1, endpoint=True) # Interpolate to equal arc length spacing xx_interp = pchip_interpolate(slist / slist[-1], xx, slist_norm) yy_interp = pchip_interpolate(slist / slist[-1], yy, slist_norm) zz_interp = pchip_interpolate(slist / slist[-1], zz, slist_norm) thetas = [] psis = [] for dx, dy, dz in zip(sp.diff(xx_interp), sp.diff(yy_interp), sp.diff(zz_interp)): _, theta, psi = get_ds_angles(dx, dy, dz) thetas.append(theta) psis.append(psi) ds = slist[-1] / num_segments return r0, ds, thetas, psis
def cmfxyz(lam, e=None, **kwargs): """ Color matching function for xyz tristimulus :param lam: wavelength ๐ [m] :type lam: float or array_like :param e: illlumination spectrum defined at the wavelengths ๐ :type e: numpy array (N,1) :return: xyz-chromaticity :rtype: numpy array, shape = (N,3) The color matching function is the XYZ tristimulus required to match a particular wavelength excitation. ``cmfxyz(๐)`` is the CIE XYZ color matching function (N,3) for illumination at wavelength ๐ (N,1) [m]. If ๐ is a vector then each row of XYZ is the color matching function of the corresponding element of ๐. ``cmfxzy(๐, e)`` is the CIE XYZ color matching (1,3) function for an illumination spectrum e (N,1) defined at corresponding wavelengths ๐ (N,1). Example: .. runblock:: pycon .. note:: - CIE 1931 2-deg XYZ CMFs from cvrl.ioo.ucl.ac.uk . :references: - Robotics, Vision & Control, Chapter 14.3, P. Corke, Springer 2011. """ lam = base.getvector(lam) xyz = _loaddata('cmfxyz.dat', comments='%') XYZ = interpolate.pchip_interpolate(xyz[:, 0], xyz[:, 1:], lam, axis=0, **kwargs) if e is not None: # approximate rectangular integration dlam = lam[1] - lam[0] XYZ = e.reshape((1, -1)) @ XYZ * dlam return XYZ
def curveInterp(t, curve): #zero rates tempCurve = -numpy.log(curve[1])/curve[0] tempCurve[0] = 0.0000 if t < 0: return 1 elif t > 30: f = numpy.exp(numpy.interp(t, curve[0], numpy.log(curve[1]), right = numpy.log(curve[1,9])*t/30)) return f else: f = interpolate.pchip_interpolate(curve[0], tempCurve, t) tnew = numpy.exp(-f * t) return tnew
def interimpulse_fit(driver, kernel, minima, maxima, original_time, original_signal, original_fs): """ Estimate the tonic EDA driver and signal. The mean (or median) of data between impulses is used to estimate the tonic driver. This driver is then convolved with the kernel to produce the tonic signal. Parameters ---------- driver : array_like The composite EDA driver kernel : array_like The kernel impulse response minima : numpy.ndarray The minima in the composite EDA driver maxima : The maxima in the composite EDA driver original_time : array_like The timestamps of the original EDA signal original_signal : array_like The original EDA signal original_fs : float The sample rate of the original EDA signal Returns ------- tonic_driver : numpy.ndarray The estimated tonic EDA driver tonic_data : numpy.ndarray The estimated tonic EDA signal """ # FIXME: Add tests from scipy.interpolate import pchip_interpolate from scipy.signal import convolve tonic_driver = np.array([]) tonic_data = np.array([]) # Original timestamps (comes from leda2.analysis0.target.t) original_time = original_time.copy() # Original EDA signal (comes from leda2.analysis0.target.d) original_signal = original_signal.copy() # Original sample rate (comes from leda2.analysis0.target.sr) original_fs = original_fs # Hard coded value came from observing first run during continuous analysis (comes from # leda2.set.tonicGridSize_sdeco) grid_spacing = 10 # Number of samples in the kernel kernel_length = kernel.size # Get inter-impulse data index interimpulse_indices = np.array([], dtype='int64') # If there are more than two maximum indices in maxima if maxima.size > 2: # Iterate from the first to the penultimate for i in range(maxima.size - 1): # Indices of samples between following minimum and next minimum. These indices are the indices of the gaps # between impulses. current_interimpulse_indices = np.arange(minima[i, 1], minima[i + 1, 0] + 1) # Append these indices to interimpulse_indices interimpulse_indices = np.concatenate([interimpulse_indices, current_interimpulse_indices]) # Add the index of the first minimum for the second maximum to the beginning of interimpulse_indices. Add the index of the second minimum for the last maximum, plus all remaining samples except for the last second of data, to the end of interimpulse_indices. interimpulse_indices = np.concatenate([[minima[1, 0]], interimpulse_indices, np.arange(minima[-1, 1], driver.size - original_fs + 1)]) # There weren'original_time any maxima (except for first and last 'global' maxima), so # the entire driver is tonic. Set interimpulse_indices to be all those indices where the # timestamp is greater than zero. else: #no peaks (exept for pre-peak and may last peak) so data represents tonic only, so ise all data for tonic estimation interimpulse_indices = np.nonzero(original_time > 0)[0] interimpulse_indices = np.int64(interimpulse_indices) # interimpulse_times are the timestamps corresponding to the interimpulse_indices indices. interimpulse_times = original_time[interimpulse_indices] # interimpulse_data is the driver corresponding to the interimpulse_indices indices. interimpulse_data = driver[interimpulse_indices] # I don'original_time know what the significance of the name grid_time is, but # grid_time is a vector from 0 to the penultimate timestamp with a step size # of grid_spacing, and the last timestamp added to the end. grid_time = np.arange(0, original_time[-2], grid_spacing) grid_time = np.concatenate([grid_time, [original_time[-1]]]) ### I don'original_time know why they do this... if grid_spacing < 30: grid_spacing = grid_spacing * 2 # Initialize vector of ground levels tonic_level = np.zeros(grid_time.size) # Iterate over length of grid_time vector for i in range(0, grid_time.size): # Select relevant interimpulse time points for tonic estimate at # grid_time # If i represents the first grid_time entry if i == 0: # time_indices is all inter-impulse timestamp indices that are less than or equal # to the first grid_time entry plus the grid size, and greater # than one. time_indices = np.nonzero((interimpulse_times <= (grid_time[i] + grid_spacing)) & (interimpulse_times > 1.0))[0] # grid_indices is the same except using all timestamps. grid_indices = np.nonzero((original_time <= (grid_time[i] + grid_spacing)) & (original_time > 1.0))[0] # If i represents the last grid_time entry elif i == grid_time.size - 1: # time_indices is all inter-impulse timestamp indices that are after the last # grid_time entry minus the grid size, and less than the last # overall timestamp minus one second. time_indices = np.nonzero((interimpulse_times > (grid_time[i] - grid_spacing)) & (interimpulse_times < (original_time[-1] - 1.0)))[0] # grid_indices is the same except using all timestamps. grid_indices = np.nonzero((original_time > (grid_time[i] - grid_spacing)) & (original_time < (original_time[-1] - 1.0)))[0] else: # time_indices is all inter-impulse timestamp indices that are a half a grid size # before and after grid_time(i) # TODO: The spacing calculated here is different from Ledalab. Confirm that this is a bug in Ledalab. time_indices = np.nonzero((interimpulse_times > (grid_time[i] - grid_spacing/2)) & (interimpulse_times <= (grid_time[i] + grid_spacing/2)))[0] # grid_indices is the same except using all timestamps. grid_indices = np.nonzero((original_time > (grid_time[i] - grid_spacing/2)) & (original_time <= (grid_time[i] + grid_spacing/2)))[0] # Estimate tonic_level at grid_time # If there are more than two inter-impulse timestamps in this grid # window if time_indices.size > 2: # Take the ground level as the minimum of the mean of inter-impulse # data over the window, or the original signal at the nearest # possible time index. closest_index, closest_time = Pypsy.signal.utilities.closest_time_index(original_time, grid_time[i]) tonic_level[i] = np.min(np.array([np.mean(interimpulse_data[time_indices]), original_signal[closest_index]])) # If there are two or fewer inter-impulse timestamps in this grid # window else: # Take the ground level as the minimum of the median of # inter-impulse data over the window, or the original signal at the # nearest possible time index. closest_index, closest_time = Pypsy.signal.utilities.closest_time_index(original_time, grid_time[i]) tonic_level[i] = np.min([np.median(driver[grid_indices]), original_signal[closest_index]]) # tonic_driver is the tonic_level signal PCHIP interpolated across the # original timestamps tonic_driver = pchip_interpolate(grid_time, tonic_level, original_time) # Stash currently-computed data grid_time_stored = grid_time tonic_level_stored = tonic_level tonic_driver_stored = tonic_driver # Prepend tonic_driver with a kernel-length of the initial value and # convolve it with the kernel. tonic_driver_extended = np.concatenate([np.ones(kernel_length) * tonic_driver[0], tonic_driver]) tonic_data = convolve(tonic_driver_extended, kernel) # Trim kernel length from beginning and end of convolved signal tonic_data = tonic_data[kernel_length:tonic_data.size - kernel_length + 1] # Stash data tonic_data_stored = tonic_data # Correction for tonic sections still higher than raw data # Move closest grid_time at time of maximum difference of tonic surpassing data # Iterate i from length(grid_time) - 1 down to 0 for i in range(grid_time.size - 2, 0, -1): # Get subrange of original timestamps that are closest to our # grid_time timestamps time_indices = Pypsy.signal.utilities.subrange_indices(original_time, grid_time[i], grid_time[i+1]) # Find the max in the tonic data convolved with the kernel plus a # minimum allowable distance (defaults to 0) minus the original signal minimum_difference = 0 eps = np.finfo(float).eps difference = (tonic_data[time_indices] + minimum_difference) - original_signal[time_indices] maximum_difference = np.max(difference) # If this max is greater than the distance from 1.0 to the next larget # double-precision number (2.2204e-16) if maximum_difference > eps: index = np.nonzero(difference == maximum_difference)[0] # Subtract this max from this tonic_level and the next tonic_level[i] = tonic_level[i] - maximum_difference tonic_level[i+1] = tonic_level[i+1] - maximum_difference # Interpolate tonic_driver and convolve again tonic_driver = pchip_interpolate(grid_time, tonic_level, original_time) tonic_driver_extended = np.concatenate([np.ones(kernel_length) * tonic_driver[0], tonic_driver]) tonic_data = convolve(tonic_driver_extended, kernel) # Trim kernel length from beginning and end of convolved signal tonic_data = tonic_data[kernel_length:tonic_data.size - kernel_length + 1] # FIXME: The actual Ledalab function saves all this analysis (and the piecewise polynomial) back to globals return tonic_driver, tonic_data
def FittedTransmission (voltages, offset, amplitude, *params) : """ Return the transmission function for a shaper """ V, M = GetVM(*params) return amplitude*np.cos( pchip_interpolate(V,M,voltages) )**2 + offset
def GetDispersionPhaseCurves (self, wavelengths, scans, voltages, pixels_edges, calibration, pixel2lambda_func, pulse_shaper_pixel_num ) : """ Surface calibration: Find dispersion and phase curves based on a result of the method `self.FitSpectralScans` `calibration` is the return of `self.FitSpectralScans` """ import operator # Find the calibration function that was best fitted best_calibation_voltage, best_calib_phase, _ = min(calibration, key=operator.itemgetter(2)) # Form a function representing calibration curve (best fitted) # Normalizing calibration curve best_calib_phase -= best_calib_phase.min() best_calib_phase /= best_calib_phase.max() best_calibration_curve = PchipInterpolator (best_calibation_voltage, best_calib_phase) # Selecting the voltage range V_min = max( best_calibation_voltage.min(), voltages.min() ) V_max = min( best_calibation_voltage.max(), voltages.max() ) V_indx = np.nonzero( (V_min <= voltages)&(voltages <= V_max) ) # Select scanning range that corresponds to a valid region of voltages and wavelength scans = scans[V_indx[0], pixels_edges[0]:pixels_edges[-1]] # Wavelength position of pixels in a new sliced scan wavelengths_cut = wavelengths[ pixels_edges[0]:pixels_edges[-1] ] # Central wavelength of each pixels logical_pixel_lambda = 0.5*( wavelengths[pixels_edges[1:]] + wavelengths[pixels_edges[:-1]] ) # Construct the initial guess for the dispersion curve # use the cubic polynomial interpolation # normalize it to the best fitted calibration curve best_min = best_calibration_curve(V_min) best_max = best_calibration_curve(V_max) # values of the calibration curves calibration_values = best_calibration_curve( voltages[V_indx] )[:,np.newaxis] def TransmissionC (calibration_values, params) : """ Transmission coefficient for fitting """ offset = params[:len(params)/2] multiplier = params[len(params)/2:] phase = calibration_values * np.polyval(multiplier, wavelengths_cut) phase += np.polyval(offset, wavelengths_cut) return np.cos( phase )**2 def Fit_TransmissionC (calibration_values, *params) : return np.ravel( TransmissionC(calibration_values, params) ) # Initial guess for fitting parameters c_min, c_max = zip(*[ pchip_interpolate(c[0],c[1],[V_min, V_max]) for c in calibration ]) c_min = np.array(c_min); c_max = np.array(c_max) # Use different power fits power_fits = [] for power in [1, 3, 5, 7] : offset = np.polyfit(logical_pixel_lambda, (best_max*c_min-best_min*c_max)/(best_max-best_min), power) multiplier = np.polyfit(logical_pixel_lambda, (c_max-c_min)/(best_max-best_min), power) p0=np.append(offset, multiplier) try : popt, _ = curve_fit(Fit_TransmissionC, calibration_values, np.ravel(scans), p0=p0) except RuntimeError : popt = p0 # Calculate the Transmission coefficients for plotting TC_fitted = TransmissionC(calibration_values, popt) # Calculate fitting error error = np.sum( (TC_fitted - scans)**2 ) power_fits.append( (error, popt, TC_fitted) ) # Select the best power fit _, popt, TC_fitted = min(power_fits) # Extracted the fitted parameters offset = popt[:len(popt)/2] multiplier = popt[len(popt)/2:] # Get wavelength for each physical pixel in the pulse shaper physical_pixel_lambda = pixel2lambda_func(np.arange(pulse_shaper_pixel_num)) # Calculate offset and multiplier for each physical pixel offset = np.polyval(offset, physical_pixel_lambda) multiplier = np.polyval(multiplier, physical_pixel_lambda) # Return results return TC_fitted, scans, { "offset" : offset, "multiplier" : multiplier, "calibration_curve_voltage" : best_calibation_voltage, "calibration_curve_phase" : best_calib_phase }
corr_centered_flow = [] for i in range(len(centered_flow)): for j in range(len(cal_error)): if round(centered_flow[i], 1) == round(cal_inflow[j], 1): corr = cal_error[j] break else: corr = 0.0 corr_centered_flow.append(centered_flow[i]*(1.0 + corr/100)) interpolate_corr_flow = interp1d(centered_times, corr_centered_flow,kind='cubic') interpolate_flow = interp1d(centered_times, centered_flow,kind='cubic') das_t_interpolation = np.array(das_t)[(np.array(das_t) > centered_times[0]) & (np.array(das_t)<centered_times[-1])] interpolated_flow = interpolate_flow(das_t_interpolation) interpolated_corr_flow = interpolate_corr_flow(das_t_interpolation) pchip_interpolated_flow = pchip_interpolate(centered_times, corr_centered_flow,das_t_interpolation) import matplotlib matplotlib.rcParams.update({'font.size':15}) corr_fig = plt.figure('Poster') # Siphon tk_ax3 = corr_fig.add_subplot(3, 1, 1) tk_ax3.plot(t, sg_h, '-b') tk_ax3.set_ylabel('level in \nsiphon gauge [mm]') tk_ax3.set_axis_bgcolor('0.95') tk_ax3.grid(True) # DAS frequencies das_ax2 = corr_fig.add_subplot(3, 1, 2, sharex=tk_ax3) das_ax2.plot(das_t, das_frequencies, '-r') das_ax2.set_ylabel('DAS Frequencies [Hz]') das_ax2.set_axis_bgcolor('0.95') das_ax2.grid(True)
def obtener_rcsda(energiaMeV,medio): from record import record class Material(record): matname = "" densidad = 0 # densidad escrita en g/cm**3 material1 = Material(matname = "Liquid water", densidad = 1.0) material2 = Material(matname = "Air dry", densidad = 1.20479E-03) material3 = Material(matname = "Compact bone", densidad = 1.85000E+00) material4 = Material(matname = "Lung", densidad = 1.05000E+00) material5 = Material(matname = "Soft tissue", densidad = 1.00000E+00) tissue = [] if medio == 1: tissue = material1.matname elif medio == 2: tissue = material2.matname elif medio == 3: tissue = material3.matname elif medio == 4: tissue = material4.matname elif medio == 5: tissue = material5.matname else: print "Please choose an allowed value for selecting medium." sys.exit() # esta funcion necesita la energia en unidades de MeV y el codigo del medio (i.e. agua = 1) if medio == 1: energias = open("Rcsda_tables/tabla_electrones_Rcsda_agua", "r") elif medio == 2: energias = open("Rcsda_tables/tabla_electrones_Rcsda_Air_Dry","r") elif medio == 3: energias = open("Rcsda_tables/tabla_electrones_Rcsda_Compact_Bone","r") elif medio == 4: energias = open("Rcsda_tables/tabla_electrones_Rcsda_Lung","r") elif medio == 5: energias = open("Rcsda_tables/tabla_electrones_Rcsda_Soft_Tissue","r") else: print "Please choose an allowed medium" linea = energias.readline() n = 0 xi = [] #energies yi = [] #ranges in g/cm**3 while linea != "": linea = linea.strip() n += 1 if n <= 6: linea = energias.readline() else: lista = linea.split() xi.append(float(lista[0])) if medio == 1: yi.append(float(lista[1])/material1.densidad) elif medio == 2: yi.append(float(lista[1])/material2.densidad) elif medio == 3: yi.append(float(lista[1])/material3.densidad) elif medio == 4: yi.append(float(lista[1])/material4.densidad) elif medio == 5: yi.append(float(lista[1])/material5.densidad) else: print "There is no material with this code" linea = energias.readline() energias.close() from scipy.interpolate import pchip_interpolate rcsda = float(pchip_interpolate(xi, yi, energiaMeV)) return (rcsda, tissue)
def FitSpectralScans (self, scans, voltages, pixels_edges) : """ Perform fitting to the pulse shaper's mask transmission coefficient """ def FitIndividualPixel (voltages, pixel, modulation, p0=None) : """ Find fit for individual pixel with initial guess for phase function given by `modulation`. `voltages` voltage values for which `pixel` was measured `pixel` measured transmission (to be fitted) `p0` is the initial guess for fitting parametres """ def GetVM (V0, V1, m0, m1) : """ Return voltage and phase modulation from parameters """ M = m0 + m1*modulation V = np.linspace(V0, V1, M.size) return V, M def FittedTransmission (voltages, offset, amplitude, *params) : """ Return the transmission function for a shaper """ V, M = GetVM(*params) return amplitude*np.cos( pchip_interpolate(V,M,voltages) )**2 + offset # Set fitting parameters to their default values if p0 is None : p0 = [0., 1., voltages.min(), voltages.max(), 0., 1.] # Fitting the transmission try : popt, _ = curve_fit(FittedTransmission, voltages, pixel, p0=p0) except RuntimeError : popt = p0 # Get fitting error fitting_error = np.sum( ( FittedTransmission(voltages, *popt) - pixel )**2 ) return fitting_error, GetVM(*popt[2:]), popt ############################################################################ # Selecting the voltage range V_min = max( voltages_trial.min(), voltages.min() ) V_max = min( voltages_trial.max(), voltages.max() ) indx = np.nonzero( (V_min <= voltages)&(voltages <= V_max) ) # Number of calibration points lying within the voltage region num_vol_trial = np.sum( (V_min <= voltages_trial)&(voltages_trial <= V_max) ) if num_vol_trial < 2 : num_vol_trial = 2 # Re-sample modulation provided by CRi so that the voltage is equidistantly spaced resampled_vis_modulation = pchip_interpolate(voltages_trial, vis_modulation, np.linspace(V_min, V_max, min(len(voltages), num_vol_trial) ) ) resampled_nir_modulation = pchip_interpolate(voltages_trial, nir_modulation, np.linspace(V_min, V_max, min(len(voltages), num_vol_trial) ) ) # Normalizing scans scans -= scans.min(axis=0); scans /= scans.max(axis=0) # Bin the spectrum into pixels spectral_slices = map( lambda begin,end : scans[:,begin:end].mean(axis=1), pixels_edges[:-1], pixels_edges[1:] ) # List containing calibration data for each pixel calibration = [] # Initial guesses for fitting vis_p0 = None; nir_p0 = None; # Fit individual pulse shaper pixels them for pixel_num, pixel in enumerate(spectral_slices) : # Smoothing and normalizing each pixel #pixel = gaussian_filter(pixel,sigma=1) pixel -= pixel.min(); pixel /= pixel.max() # Fit the pixel by using the vis calibration curve as the initial guess vis_err, vis_calibration, vis_p0 = FitIndividualPixel(voltages[indx], pixel[indx], resampled_vis_modulation, vis_p0) # Fit the pixel by using the nir calibration curve as the initial guess nir_err, nir_calibration, nir_p0 = FitIndividualPixel(voltages[indx], pixel[indx], resampled_nir_modulation, nir_p0) # Choose the best fit if nir_err > vis_err : calibation_voltage, calibration_phase = vis_calibration fit_err = vis_err else : calibation_voltage, calibration_phase = nir_calibration fit_err = nir_err ###################### Plot ######################## visvis.clf() # Plot measured data visvis.plot( voltages, pixel, lc='r',ms='*', mc='r') # Plot fitted data plot_voltages = np.linspace( calibation_voltage.min(), calibation_voltage.max(), 500) transmission_fit = np.cos( pchip_interpolate(calibation_voltage, calibration_phase, plot_voltages) )**2 visvis.plot( plot_voltages, transmission_fit, lc='b') visvis.title ('Calibrating pixel %d / %d' % (pixel_num, len(spectral_slices)-1) ) visvis.legend(['measured', 'fitted']) visvis.xlabel ('voltages') visvis.ylabel ('Transmission coefficient') self.fig.DrawNow() ############ Save the calibration data ################## calibration.append( ( calibation_voltage, calibration_phase, fit_err ) ) return calibration