def GenerateCarbonylTips(Ls=numpy.linspace(30,20e3,100),a=30,\ wavelength=6e3,taper_angles=[10,20],\ geometries=['cone','hyperboloid']): skin_depth = .05 if wavelength is None: freq = 0 else: freq = a / numpy.float(wavelength) Ls = Ls / numpy.float(a) for i, geometry in enumerate(geometries): for k, taper_angle in enumerate(taper_angles): for j, L in enumerate(Ls): Logger.write('Currently working on geometry "%s", L/a=%s...' % (geometry, L)) tip.build_charge_distributions(Nqs=144,Nzs=144,L=L,taper_angle=taper_angle,quadrature='TS',\ geometry=geometry,freq=freq,skin_depth=skin_depth) progress = ( (i * len(taper_angles) + k) * len(Ls) + j + 1) / numpy.float( len(Ls) * len(geometries) * len(taper_angles)) * 100 Logger.write('\tProgress: %1.1f%%' % progress) Logger.write('Done!')
def get_tip_eigenbasis_expansion(z=.1,freq=1000,a=30,\ smoothing=0,reload_signal=True,\ *args,**kwargs): """Appears to render noise past the first 15 eigenvalues. Smoothing by ~4 may be justified, removing zeros probably not...""" # Rely on Lightning Rod Model only to load tip data from file in its process of computing a signal # if reload_signal: tip.verbose=False signal=tip.LRM(freq,rp=mat.Au.reflection_p,zmin=z,amplitude=0,\ normalize_to=None,normalize_at=1000,Nzs=1,demodulate=False,\ *args,**kwargs) tip.verbose=True global L,g,M,alphas,P,Ls,Es #Get diagonal basis for the matrix L=tip.LRM.LambdaMatrix(tip.LRM.qxs) g=numpy.matrix(numpy.diag(-tip.LRM.qxs*numpy.exp(-2*tip.LRM.qxs*z/numpy.float(a))*tip.LRM.wqxs)) M=AWA(L*g,axes=[tip.LRM.qxs]*2,axis_names=['q']*2) #Smooth along s-axis (first), this is where we truncated the integral xform if smoothing: M=numrec.smooth(M,axis=0,window_len=smoothing) alphas,P=linalg.eig(numpy.matrix(M)) P=numpy.matrix(P) Ls=numpy.array(P.getI()*tip.LRM.Lambda0Vector(tip.LRM.qxs)).squeeze() Es=numpy.array(numpy.matrix(tip.LRM.get_dipole_moments(tip.LRM.qxs))*g*P).squeeze() Rs=-Es*Ls/alphas**2 Ps=1/alphas return {'Rs':Rs,'Ps':Ps,'Es':Es,'alphas':alphas,'Ls':Ls}
def get_tip_expansion_coeffs(z=.1,freq=1000,a=30,\ N=10,inv_beta=False): signal=tip.LRM(freq,rp=mat.Au.reflection_p,a=a,zmin=z,amplitude=0,\ normalize_to=None,normalize_at=1000,Nzs=1,demodulate=False) global M L=tip.LRM.LambdaMatx g=-numpy.matrix(numpy.diag(tip.LRM.qxs*numpy.exp(-2*tip.LRM.qxs*z/numpy.float(a))*tip.LRM.wqxs)) M=L*g if inv_beta: M=numrec.InvertIntegralOperator(M) eg_vec=numpy.matrix(tip.LRM.get_dipole_moments(tip.LRM.qxs))*g Lvec=tip.LRM.Lambda0Vecx if inv_beta: Lvec=-M*Lvec #Verified: gives correct signal, both relative and absolute return numpy.array([numpy.array(eg_vec*M**n*Lvec) for n in range(N)]).squeeze()
def PlotApproachCurves(zmax=30,materials={'Gold':(mat.Au,1000),\ 'Carbonyl':(mat.PMMA,1735),\ r'$\mathrm{SiC}(\omega_{SO})$':(mat.SiC_6H_Ellips,945),\ r'$\mathrm{SiC}(\omega_{-})$':(mat.SiC_6H_Ellips,920),\ r'$\mathrm{SiC}(\omega_{+})$':(mat.SiC_6H_Ellips,970)},\ Nterms=15): ordered=['Gold','Carbonyl', r'$\mathrm{SiC}(\omega_{-})$', r'$\mathrm{SiC}(\omega_{SO})$',\ r'$\mathrm{SiC}(\omega_{+})$'] colors=['c','g',(1,0,0),(.7,0,.7),(0,0,1)] global beta,LRM_signals,EFM_signals,material_name zs=numpy.logspace(numpy.log(.1/30.)/numpy.log(10.),numpy.log(zmax)/numpy.log(10.),100) zs2=numpy.logspace(numpy.log(.1/30.)/numpy.log(10.),numpy.log(15)/numpy.log(10.),100) LRM_signals={} EFM_signals={} for i,(material_name,pair) in enumerate(materials.items()): material,freq=pair beta=material.reflection_p(freq,q=1/(30e-7)) LRM_signals[material_name]=tip.LRM(freq,rp=beta,a=30,zs=zs*30,\ Nqs=244,demodulate=False,normalize_to=None)['signals'] LRM_signals[material_name].set_axes([zs]) EFM_signals[material_name]=EigenfieldModel(beta,zs=zs2,Nterms=Nterms) if i==0: tip.LRM.load_params['reload_model']=False tip.LRM.load_params['reload_model']=True figure() ref_signal=LRM_signals['Gold'].cslice[zmax] subplot(121) for material_name,color in zip(ordered,colors): numpy.abs(LRM_signals[material_name]/ref_signal).plot(label=material_name,plotter=loglog,color=color) numpy.abs(EFM_signals[material_name]/ref_signal).plot(color=color,marker='o',ls='') ylabel('$|E_\mathrm{rad}|\,[\mathrm{a.u.}]$') xlabel('$d/a$') ylim(3e-1,3e1) grid() leg=legend(loc='lower left',fancybox=True,shadow=True) leg.get_frame().set_linewidth(.1) for t in leg.texts: t.set_fontsize(18) subplot(122) for material_name,color in zip(ordered,colors): p_LRM=AWA(numpy.unwrap(numpy.angle(LRM_signals[material_name]/ref_signal))) p_LRM.adopt_axes(LRM_signals[material_name]) p_EFM=AWA(numpy.unwrap(numpy.angle(EFM_signals[material_name]/ref_signal))) p_EFM.adopt_axes(EFM_signals[material_name]) (p_LRM/(2*numpy.pi)).plot(label=material_name,plotter=semilogx,color=color) (p_EFM/(2*numpy.pi)).plot(color=color,marker='o',ls='') ylabel(r'$\mathrm{arg}(E_\mathrm{rad})\,/\,2\pi$') xlabel('$d/a$') ylim(-.05,.5) grid() gcf().set_size_inches([12.5,7],forward=True) tight_layout() subplots_adjust(wspace=.3)
def CompareCarbonylTips(Ls=numpy.linspace(30,20e3,100),a=30,\ wavelength=6e3,amplitude=60,lift=30,\ geometries=['cone','hyperboloid'],\ taper_angles=[20],\ load=True,save=True,demo_file='CarbonylTips.pickle',\ enhancement_index=2): carbonyl_freqs = numpy.linspace(1730, 1750, 10) normalize_at_freq = numpy.mean(carbonyl_freqs) freqs = [a / numpy.float(wavelength) ] #load frequency should be quite close to `sio2_freq` Ls = Ls / float(a) freq_labels = ['ED'] skin_depth = .05 ################################################## ## Load or compute Carbonyl measurement metrics ## ################################################## global d d_keys=['max_s3','max_s2',\ 'max_rel_absorption','max_absorption','max_freq',\ 'charges0','charges_q0','Lambda0','enhancement',\ 'signals','norm_signals','DCSD_contact','DCSD_lift',\ 'psf_contact','psf_lift'] demo_path = os.path.join(root_dir, demo_file) if load and os.path.isfile(demo_path): Logger.write('Loading lengths data...') d = pickle.load(open(demo_path)) else: tip.LRM.load_params['reload_model'] = True tip.LRM.geometric_params['skin_depth'] = skin_depth d = {} for i, geometry in enumerate(geometries): for n, taper_angle in enumerate(taper_angles): #If geometry is not conical, do not iterate to additional taper angles, these are all the same. if geometry not in ['PtSi', 'hyperboloid', 'cone'] and n > 0: break tip.LRM.geometric_params['geometry'] = geometry tip.LRM.geometric_params['taper_angle'] = taper_angle signals_for_geometry = {} for j, freq in enumerate(freqs): signals_for_freq = dict([(key, []) for key in d_keys]) for k, L in enumerate(Ls): tip.LRM.geometric_params['L'] = int(L) Logger.write( 'Currently working on geometry "%s", freq=%s, L/a=%s...' % (geometry, freq, L)) #Make sure to calculate on zs all the way up to zmax=2*amplitude+lift carbonyl_vals=tip.LRM(carbonyl_freqs,rp=Carbonyl.reflection_p,Nqs=72,zmin=.1,a=a,amplitude=amplitude+lift/2.,\ normalize_to=mat.Si.reflection_p,normalize_at=normalize_at_freq,load_freq=freq,Nzs=30) ##Get overall signal with approach curve## global carbonyl_sigs carbonyl_sigs = carbonyl_vals['signals'] * numpy.exp( -1j * numpy.angle( carbonyl_vals['norm_signals'].cslice[0])) carbonyl_rel_sigs = carbonyl_vals[ 'signals'] / carbonyl_vals['norm_signals'].cslice[0] ind = numpy.argmax(carbonyl_rel_sigs.imag.cslice[0] ) #Find maximum phase in contact signals_for_freq['max_s3'].append( carbonyl_vals['signal_3'] [ind]) #Pick out the peak frequency signals_for_freq['max_s2'].append( carbonyl_vals['signal_2'] [ind]) #Pick out the peak frequency signals_for_freq['max_rel_absorption'].append( carbonyl_rel_sigs[:, ind].imag.cslice[0] ) #Relative to out-of-contact on reference signals_for_freq['max_absorption'].append( carbonyl_sigs[:, ind].imag.cslice[0] ) #Absolute signal signals_for_freq['max_freq'].append( carbonyl_freqs[ind]) signals_for_freq['charges0'].append( tip.LRM.charges0 / (2 * numpy.pi * tip.LRM.charge_radii)) signals_for_freq['charges_q0'].append( tip.LRM.charges.cslice[0] / (2 * numpy.pi * tip.LRM.charge_radii)) signals_for_freq['Lambda0'].append(tip.LRM.Lambda0) signals_for_freq['enhancement'].append( numpy.abs(2 * tip.LRM.charges0[enhancement_index])) signals_for_freq['signals'].append( carbonyl_sigs[:, ind]) #Pick out the peak frequency signals_for_freq['norm_signals'].append( carbonyl_vals['norm_signals']) signals_for_freq['DCSD_contact'].append( get_DCSD(carbonyl_sigs[:, ind], zmin=0.1, amplitude=60, lift=0)) signals_for_freq['DCSD_lift'].append( get_DCSD(carbonyl_sigs[:, ind], zmin=0.1, amplitude=60, lift=lift)) ##Isolate some point-spread functions## rs = numpy.linspace(0, 5, 200).reshape((200, 1)) integrand_contact=AWA(tip.LRM.qxs**2*\ special.j0(tip.LRM.qxs*rs)*tip.LRM.get_dipole_moments(tip.LRM.qxs)*\ tip.LRM.wqxs,axes=[rs.squeeze(),tip.LRM.qxs]) integrand_contact=integrand_contact.interpolate_axis(numpy.logspace(numpy.log(tip.LRM.qxs.min())/numpy.log(10),\ numpy.log(tip.LRM.qxs.max())/numpy.log(10),1000),\ axis=1) psf_contact = numpy.sum(integrand_contact, axis=1) signals_for_freq['psf_contact'].append( AWA(psf_contact, axes=[rs.squeeze()], axis_names=['r/a'])) integrand_lift=AWA(tip.LRM.qxs**2*numpy.exp(-tip.LRM.qxs*lift/numpy.float(a))*\ special.j0(tip.LRM.qxs*rs)*tip.LRM.get_dipole_moments(tip.LRM.qxs)*\ tip.LRM.wqxs,axes=[rs.squeeze(),tip.LRM.qxs]) integrand_lift=integrand_lift.interpolate_axis(numpy.logspace(numpy.log(tip.LRM.qxs.min())/numpy.log(10),\ numpy.log(tip.LRM.qxs.max())/numpy.log(10),1000),\ axis=1) psf_lift = numpy.sum(integrand_lift, axis=1) signals_for_freq['psf_lift'].append( AWA(psf_lift, axes=[rs.squeeze()], axis_names=['r/a'])) progress = (i * len(Ls) * len(freqs) + j * len(Ls) + k + 1) / numpy.float( len(Ls) * len(freqs) * len(geometries)) * 100 Logger.write('\tProgress: %1.1f%%' % progress) for key in list(signals_for_freq.keys()): if numpy.array( signals_for_freq[key] ).ndim == 2: #Prepend probe length axis and expand these into AWA's axes = [ a * Ls / numpy.float(wavelength), signals_for_freq[key][0].axes[0] ] axis_names = [ '$L/\lambda_\mathrm{C=O}$', signals_for_freq[key][0].axis_names[0] ] signals_for_freq[key]=AWA(numpy.array(signals_for_freq[key],dtype=numpy.complex),\ axes=axes,axis_names=axis_names) else: signals_for_freq[key]=AWA(numpy.array(signals_for_freq[key],dtype=numpy.complex),\ axes=[a*Ls/numpy.float(wavelength)],\ axis_names=['$L/\lambda_\mathrm{C=O}$']) signals_for_geometry[freq_labels[j]] = signals_for_freq geometry_name = geometry if geometry in ['PtSi', 'hyperboloid', 'cone']: geometry_name += str(taper_angle) d[geometry_name] = signals_for_geometry if not load and save: Logger.write('Saving tip comparison data...') file = open(demo_path, 'wb') pickle.dump(d, file) file.close() return d
def PlotIdealProbePerformance(ideal_length=404,wavelength=6e3,lift=30,\ approach=False,compare_spectra=True): freq = 30 / wavelength tip.LRM.geometric_params['L'] = ideal_length if approach: gold=tip.LRM(1180,rp=mat.Au.reflection_p,a=30,amplitude=60,\ normalize_to=mat.Si.reflection_p,Nqs=72,normalize_at=1738,Nzs=30,\ load_freq=freq) p = numpy.exp(-1j * numpy.angle(gold['norm_signals'].cslice[120])) figure() approach = gold['sample_signal_v_time'] approach *= p peak = abs(approach).max() approach /= peak approach += numpy.cos(2 * numpy.pi * tip.LRM.ts) * 10 + 50 numpy.abs(approach).plot(label='Approach on $Au$') plot(-1 - tip.LRM.ts, numpy.abs(approach), color='b') plot(-1 + tip.LRM.ts, numpy.abs(approach), color='b') plot(-tip.LRM.ts, numpy.abs(approach), color='b') plot(1 - tip.LRM.ts, numpy.abs(approach), color='b') plot(1 + tip.LRM.ts, numpy.abs(approach), color='b') approximation = gold['sample_signal_0'] / 2. + gold[ 'sample_signal_1'] * numpy.cos(2 * numpy.pi * tip.LRM.ts) approximation *= p approximation = AWA(approximation, axes=[tip.LRM.ts]) approximation /= peak numpy.abs(approximation).plot(label='1st Harmonic') plot(-1 - tip.LRM.ts, numpy.abs(approximation), color='g', ls='-') plot(-1 + tip.LRM.ts, numpy.abs(approximation), color='g', ls='-') plot(-tip.LRM.ts, numpy.abs(approximation), color='g', ls='-') plot(1 - tip.LRM.ts, numpy.abs(approximation), color='g', ls='-') plot(1 + tip.LRM.ts, numpy.abs(approximation), color='g', ls='-') xlabel('t/T') ylabel('Near-field Signal [a.u.]') leg = legend(loc='upper right', fancybox=True, shadow=True) for t in leg.texts: t.set_fontsize(18) leg.get_frame().set_linewidth(.1) grid() tight_layout() ylim(.35, 1.18) if compare_spectra: freqs = numpy.linspace(1100, 1900, 200) layer = mat.LayeredMedia((mat.PMMA, 100e-7), exit=mat.Si) PMMA=tip.LRM(freqs,rp=layer.reflection_p,a=30,amplitude=60+lift/2.,\ normalize_to=mat.Si.reflection_p,Nqs=72,normalize_at=1000,Nzs=30,\ load_freq=freq) figure() PMMA['signal_2'].imag.plot(color='b') ylabel(r'$\mathrm{Im}[\,S_2\,]\,[\mathrm{norm.}]$', color='b') tick_params(color='b', axis='y') yticks(color='b') xlabel(r'$\omega\,[cm^{-1}]$') gca().spines['left'].set_color('b') gca().spines['right'].set_color('r') p = numpy.angle(PMMA['norm_signals'].cslice[0]) DCSD1 = get_DCSD(PMMA['signals']) * numpy.exp(-1j * p) DCSD2 = get_DCSD(PMMA['signals'], lift=lift) * numpy.exp(-1j * p) twinx() (DCSD1.imag / numpy.abs(DCSD2)).plot(color='r') ylabel(r'$\mathrm{DCSD}\,[\mathrm{norm.}]$', color='r', rotation=270) tick_params(color='r', axis='y') yticks(color='r') tight_layout() subplots_adjust(right=.85)
def update_parameters(): sample = M.TabulatedMaterialFromFile(subMat.value + '.csv') thick = float(thickness.value) * 1e-9 a = float(size.value) * 1e-9 amplitude = float(oscAmplitude.value) * 1e-9 freqNumber = int(freqNum.value) Nqs = int(numQ.value) Nzs = int(numZ.value) normFrequency = float(normFreq.value) normMaterial = normMat.value f0 = sample._eps_data.axes[0] freqs = linspace(f0.min(), f0.max(), freqNumber) ##only plot at 1st panel; generalize to allow radio button group determine which panel to plot if panel.value == "Plot in 1st panel": graph = s1 elif panel.value == "Plot in 2nd panel": graph = s2 elif panel.value == "Plot in 3rd panel": graph = s3 elif panel.value == "Plot in 4th panel": graph = s4 else: graph = s1 if quantity.value == "near-field signal": ##no normalization calculated=T.LightningRodModel(freqs,rp=sample.reflection_p,a=a,Nqs=Nqs,Nzs=Nzs,\ amplitude=amplitude,normalize_to=None,\ normalize_at=normFrequency) global nfs nfs = graph.line(freqs, abs(calculated['signal_3']), legend="s3", line_color="#0093dd", line_width=2) graph.title.text = subMat.value graph.title.align = "center" elif quantity.value == "far-field reflectivity (p-polarized)": ##picked angle 0 as default, generalize rp_farfield = sample.reflection_p(freqs, angle=0) global fReflecP fReflecP = graph.line(freqs, abs(rp_farfield), legend="far field (p) amplitude", line_color="#0093dd", line_width=2) graph.title.text = subMat.value graph.title.align = "center" elif quantity.value == "far-field reflectivity (s-polarized)": ##picked angle 0 as default, generalize rs_farfield = sample.reflection_s(freqs, angle=0) global fReflecS fReflecS = graph.line(freqs, abs(rs_farfield), legend="far field (s) amplitude", line_color="#0093dd", line_width=2) graph.title.text = subMat.value graph.title.align = "center" #need to add far-field transmission elif quantity.value == "permittivity": eps = sample.epsilon(freqs) global rl rl = graph.line(freqs, eps.real, legend="real", line_color="#0093dd", line_width=2) global img img = graph.line(freqs, eps.imag, legend="imaginary", line_color="orange", line_width=2) graph.title.text = subMat.value graph.title.align = "center" elif quantity.value == "near-field reflectivity": rp_nearfield = sample.reflection_p(freqs, angle=None, q=1 / a) global nReflec nReflec = graph.line(freqs, abs(rp_nearfield), legend="near field amplitude", line_color="orange", line_width=2) graph.title.text = subMat.value graph.title.align = "center" else: #plot a thick red cross on panel x1 = linspace(0, 10, 100) y1 = x1 y2 = 10 - x1 global x x = graph.line(x1, y1, legend="ERROR", line_color="red", line_width=6) global xx xx = graph.line(x1, y2, legend="ERROR", line_color="red", line_width=6) graph.title.text = subMat.value graph.title.align = "center"