def mode2(data, v0, v1, dmin=0.0): """ v0..v1 (both inclusive) are channel selections threshold on dmin for odd number of channels, center line in mode2 will be same as mode1 @todo the frequency axis is not properly calibrated here @todo a full 2D is slow, we only need the 1D version """ print "PVCorr mode2: v0,1=", v0, v1, "dmin=", dmin smin = data.min() s = data[:, v0:v1 + 1] if dmin == 0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s > dmin, s, 0) print "PVCorr dmin:", dmin f0 = np.where(s > smin, 1, 0) f1 = np.where(s > dmin, 1, 0) fmax = f.max() ffsum = (f * f).sum() print "PVCorr mode2:", f1.sum(), '/', f0.sum(), 'min/max', smin, fmax out = scipy.signal.correlate2d(data, f, mode='same') / ffsum print 'PVCorr min/max:', out.min(), out.max() n1, m1, s1, n2, m2, s2 = stats.mystats(out.flatten()) print "PVCorr stats", n1, m1, s1, n2, m2, s2 rms_est = s2 / np.sqrt(f1.sum()) return out, rms_est
def mode3(self, data, v0, v1, dmin=0.0): """ v0..v1 (both inclusive) are channel selections threshold on dmin @todo the frequency axis is not properly calibrated here @todo a full 2D is slow, we only need the 1D version """ print "PVCorr mode3: v0,1=", v0, v1 smin = data.min() #s = data[v0:v1+1,:] s = data[:, v0:v1 + 1] if dmin == 0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s > dmin, s, 0) # find out where the zeros are temp = np.amax(f, axis=1) nz = np.nonzero(temp) # trim the kernel in the y direction, removing rows that are all 0.0 f = f[nz[0][0]:nz[0][-1], :] f0 = np.where(s > smin, 1, 0) f1 = np.where(s > dmin, 1, 0) fmax = f.max() print "PVCorr mode3:", f1.sum(), '/', f0.sum(), 'min/max', smin, fmax out = scipy.signal.correlate2d(data, f, mode='same') self.myplot.map1(data=f, title="PVCorr 2D Kernel", figname='PVCorrKernel', thumbnail=True) print 'PVCorr min/max:', out.min(), out.max() n1, m1, s1, n2, m2, s2 = stats.mystats(out.flatten()) print "PVCorr stats", n1, m1, s1, n2, m2, s2 rms_est = s2 / np.sqrt(f1.sum()) return out, rms_est
def mode2(data,v0,v1, dmin=0.0): """ v0..v1 (both inclusive) are channel selections threshold on dmin for odd number of channels, center line in mode2 will be same as mode1 @todo the frequency axis is not properly calibrated here @todo a full 2D is slow, we only need the 1D version """ print "PVCorr mode2: v0,1=",v0,v1,"dmin=",dmin smin = data.min() s = data[:,v0:v1+1] if dmin==0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s>dmin,s,0) print "PVCorr dmin:",dmin f0 = np.where(s>smin,1,0) f1 = np.where(s>dmin,1,0) fmax = f.max() ffsum = (f*f).sum() print "PVCorr mode2:",f1.sum(),'/',f0.sum(),'min/max',smin,fmax out = scipy.signal.correlate2d(data,f,mode='same')/ffsum print 'PVCorr min/max:',out.min(),out.max() n1,m1,s1,n2,m2,s2 = stats.mystats(out.flatten()) print "PVCorr stats", n1,m1,s1,n2,m2,s2 rms_est = s2/np.sqrt(f1.sum()) return out,rms_est
def mode3(self, data, v0, v1, dmin=0.0): """ v0..v1 (both inclusive) are channel selections threshold on dmin @todo the frequency axis is not properly calibrated here @todo a full 2D is slow, we only need the 1D version """ print "PVCorr mode3: v0,1=",v0,v1 smin = data.min() #s = data[v0:v1+1,:] s = data[:,v0:v1+1] if dmin==0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s>dmin,s,0) # find out where the zeros are temp = np.amax(f,axis=1) nz = np.nonzero(temp) # trim the kernel in the y direction, removing rows that are all 0.0 f = f[nz[0][0]:nz[0][-1],:] f0 = np.where(s>smin,1,0) f1 = np.where(s>dmin,1,0) fmax = f.max() print "PVCorr mode3:",f1.sum(),'/',f0.sum(),'min/max',smin,fmax out = scipy.signal.correlate2d(data,f,mode='same') self.myplot.map1(data=f,title="PVCorr 2D Kernel",figname='PVCorrKernel', thumbnail=True) print 'PVCorr min/max:',out.min(),out.max() n1,m1,s1,n2,m2,s2 = stats.mystats(out.flatten()) print "PVCorr stats", n1,m1,s1,n2,m2,s2 rms_est = s2/np.sqrt(f1.sum()) return out,rms_est
def mode1(data, v0, v1, dmin=0.0, normalize=False): """ faster 1D version of mode2 This works by forcing mode='valid' and making the X (position) dimension of the template the same as the PV diagram. We then pad the ends of the PV with zero's. Introduces some complexity how to return the correct shape v0..v1 (both inclusive) are channel selections threshold on dmin @todo the frequency axis may not be properly calibrated here @todo plot the template for debug, like in mode3 """ logging.info("PVCorr mode1: v0,1= %d %d dmin= %g normalize=%s " % (v0, v0, dmin, str(normalize))) smin = data.min() nx = data.shape[0] ny = data.shape[1] nv = v1 - v0 + 1 pad = np.zeros(nx * nv).reshape( nx, nv) # ValueError: negative dimensions are not allowed (EGNoG) pdata = np.concatenate((pad, data, pad), axis=1) s = data[:, v0:v1 + 1] # the stencil where the line is if dmin == 0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s > dmin, s, 0.0) if normalize: f = np.where(f != 0.0, 1.0, 0.0) f0 = np.where(s > smin, 1, 0) f1 = np.where(s > dmin, 1, 0) if s.max() < dmin: logging.warning("Datamax=%g, no data above dmin=%g; data too noisy?" % (s.max(), dmin)) return np.arange(0), 0.0 fmax = f.max() fsum = f.sum() ssum = s.sum() fssum = (f * s).sum() ffsum = (f * f).sum() logging.info("PVCorr mode1: %d/%d min/max %g %g sums: %g %g %g %g" % (f1.sum(), f0.sum(), smin, fmax, fsum, ssum, ffsum, fssum)) if normalize: out = scipy.signal.correlate2d(pdata, f, mode='valid') / fssum else: out = scipy.signal.correlate2d(pdata, f, mode='valid') / ffsum logging.info('PVCorr min/max: %g %g' % (out.min(), out.max())) n1, m1, s1, n2, m2, s2 = stats.mystats(out.flatten()) logging.info("PVCorr stats %d %g %g %d %g %g" % (n1, m1, s1, n2, m2, s2)) rms_est = s2 logging.info("RMS est: %g" % rms_est) # CAVEAT: # cutting it this way will agree with peaks in mode2, # but between ny=odd or even there is a half channel freq offset # alternatively for one of them an interpolation is needed. # the idea is that half channel should not influence LineID. corr = out[0, nv / 2 + 1:nv / 2 + ny + 1] return corr, rms_est
def mode1(data,v0,v1, dmin=0.0, normalize=False): """ faster 1D version of mode2 This works by forcing mode='valid' and making the X (position) dimension of the template the same as the PV diagram. We then pad the ends of the PV with zero's. Introduces some complexity how to return the correct shape v0..v1 (both inclusive) are channel selections threshold on dmin @todo the frequency axis may not be properly calibrated here @todo plot the template for debug, like in mode3 """ logging.info("PVCorr mode1: v0,1= %d %d dmin= %g normalize=%s " % (v0,v0,dmin,str(normalize))) smin = data.min() nx = data.shape[0] ny = data.shape[1] nv = v1-v0+1 pad = np.zeros(nx*nv).reshape(nx,nv) # ValueError: negative dimensions are not allowed (EGNoG) pdata = np.concatenate((pad,data,pad),axis=1) s = data[:,v0:v1+1] # the stencil where the line is if dmin==0.0: logging.warning("Using all data in crosscorr") f = s else: f = np.where(s>dmin,s,0.0) if normalize: f = np.where(f != 0.0, 1.0, 0.0) f0 = np.where(s>smin,1,0) f1 = np.where(s>dmin,1,0) if s.max() < dmin: logging.warning("Datamax=%g, no data above dmin=%g; data too noisy?" % (s.max(),dmin)) return np.arange(0),0.0 fmax = f.max() fsum = f.sum() ssum = s.sum() fssum = (f*s).sum() ffsum = (f*f).sum() logging.info("PVCorr mode1: %d/%d min/max %g %g sums: %g %g %g %g" % (f1.sum(),f0.sum(),smin,fmax,fsum,ssum,ffsum,fssum)) if normalize: out = scipy.signal.correlate2d(pdata,f,mode='valid')/fssum else: out = scipy.signal.correlate2d(pdata,f,mode='valid')/ffsum logging.info('PVCorr min/max: %g %g' % (out.min(),out.max())) n1,m1,s1,n2,m2,s2 = stats.mystats(out.flatten()) logging.info("PVCorr stats %d %g %g %d %g %g" % (n1,m1,s1,n2,m2,s2)) rms_est = s2 logging.info("RMS est: %g" % rms_est) # CAVEAT: # cutting it this way will agree with peaks in mode2, # but between ny=odd or even there is a half channel freq offset # alternatively for one of them an interpolation is needed. # the idea is that half channel should not influence LineID. corr = out[0,nv/2+1:nv/2+ny+1] return corr,rms_est