def mag_theory(qdt, fig_width=9.0, fig_height=6.0): pl=Plotter(fig_width=fig_width, fig_height=fig_height) fw0=linspace(2e9, 8e9, 2000) voltage=linspace(-5, 5, 3000) fq=qdt._get_flux_parabola(voltage=voltage) L=qdt._get_L(fq=fq) print "yo" S11=qdt._get_S11(f=fw0, L=L) print "done s11" colormesh(fw0/1e9, voltage, absolute(S11), plotter=pl) #line(*qdt._get_ls_voltage_from_flux_par_many(f=fw0), plotter=pl, linewidth=0.5, alpha=0.5, color="cyan") print "done plot" return pl ls_f=sqrt(fw0*(fw0-2*qdt._get_Lamb_shift(f=fw0)-2*qdt._get_coupling(f=fw0))) Ec=qdt._get_Ec() Ej=qdt._get_Ej_get_fq(fq=ls_f, Ec=Ec) flux_d_flux0=qdt._get_flux_over_flux0_get_Ej(Ej=Ej) V1=qdt._get_voltage(flux_over_flux0=flux_d_flux0) line(fw0/1e9, qdt._get_voltage(flux_over_flux0=flux_d_flux0), plotter=pl, linewidth=0.3, color="darkgray") print "yo2" ls_f=sqrt(fw0*(fw0-2*qdt._get_Lamb_shift(f=fw0)+2*qdt._get_coupling(f=fw0))) Ec=qdt._get_Ec() Ej=qdt._get_Ej_get_fq(fq=ls_f, Ec=Ec) flux_d_flux0=qdt._get_flux_over_flux0_get_Ej(Ej=Ej) V2=qdt._get_voltage(flux_over_flux0=flux_d_flux0) line(fw0/1e9,V2, plotter=pl, linewidth=0.3, color="darkgray") p, pf=line(fw0/1e9, absolute(V2-V1)/max(absolute(V2-V1)), linewidth=0.3, color="blue") line(fw0/1e9, qdt._get_coupling(f=fw0)/qdt.max_coupling, linewidth=0.3, color="red", plotter=p) print "yo3" #fw02=(qdt._get_Ga(f=fw0)-qdt._get_Ba(f=fw0))/(4*pi*qdt.C) #line(fw0, fw0+fw02, plotter=pl) #line(*qdt._get_ls_voltage_from_flux_par_many(f=fw0+fw02), plotter=pl, linewidth=0.5, alpha=0.5, color="cyan") return pl
def anharm_plot2(qdt, fig_width=9.0, fig_height=6.0, ymin=-1.5, ymax=1.0): """Lamb shifted anharmonicity plot""" pl=Plotter(fig_width=fig_width, fig_height=fig_height) fw0=linspace(2e9, 7e9, 2000) lsfw0=array([sqrt(f*(f-2*qdt._get_Lamb_shift(f=f))) for f in fw0]) Ej=qdt._get_Ej_get_fq(fq=lsfw0) E0, E1, E2=qdt._get_transmon_energy_levels(Ej=Ej, n_energy=3) anharm=(E2-E1)-(E1-E0) E0p, E1p, E2p=qdt._get_lamb_shifted_transmon_energy_levels(Ej=Ej, n_energy=3) anharmp=(E2p-E1p)-(E1p-E0p) line(lsfw0/1e9, anharm/h/1e9, plotter=pl, linewidth=0.5, color="purple", label=r"anharm") line(lsfw0/1e9, anharmp/h/1e9, plotter=pl, linewidth=0.5, color="black", label=r"ls anharm") line(fw0/1e9, qdt._get_coupling(fw0)/qdt.max_coupling, label=r"$G_a/2C$", color="blue", plotter=pl) pl.xlabel=r"$E_J/E_C$" pl.ylabel=r"$\Delta$ (GHz)" pl.legend(loc='lower left') return pl
def S13_phase_theory(qdt, fig_width=9.0, fig_height=6.0): pl=Plotter(fig_width=fig_width, fig_height=fig_height) fw0=linspace(2e9, 8e9, 2000) voltage=linspace(-5, 5, 1000) fq=qdt._get_flux_parabola(voltage=voltage) L=qdt._get_L(fq=fq) S13=qdt._get_S13(f=fw0, L=L) colormesh(fw0/1e9, voltage, angle(S13), plotter=pl) line(*qdt._get_ls_voltage_from_flux_par_many(f=fw0), plotter=pl, linewidth=0.5, alpha=0.5, color="cyan") return pl
def _default_plotter(self): if self.plot_name == "": self.plot_name = self.name pl = Plotter(name=self.name) for param in get_all_tags(self, "plot"): print param pl, pf = line(*getattr(self, param), plot_name=get_tag(self, param, "plot"), plotter=pl) self.data_dict[param] = pf.plot_name return pl
def anharm_plot2(qdt, fig_width=9.0, fig_height=6.0, ymin=-1.5, ymax=1.0): """Lamb shifted anharmonicity plot""" pl = Plotter(fig_width=fig_width, fig_height=fig_height) fw0 = linspace(2e9, 7e9, 2000) lsfw0 = array([sqrt(f * (f - 2 * qdt._get_Lamb_shift(f=f))) for f in fw0]) Ej = qdt._get_Ej_get_fq(fq=lsfw0) E0, E1, E2 = qdt._get_transmon_energy_levels(Ej=Ej, n_energy=3) anharm = (E2 - E1) - (E1 - E0) E0p, E1p, E2p = qdt._get_lamb_shifted_transmon_energy_levels(Ej=Ej, n_energy=3) anharmp = (E2p - E1p) - (E1p - E0p) line(lsfw0 / 1e9, anharm / h / 1e9, plotter=pl, linewidth=0.5, color="purple", label=r"anharm") line(lsfw0 / 1e9, anharmp / h / 1e9, plotter=pl, linewidth=0.5, color="black", label=r"ls anharm") line(fw0 / 1e9, qdt._get_coupling(fw0) / qdt.max_coupling, label=r"$G_a/2C$", color="blue", plotter=pl) pl.xlabel = r"$E_J/E_C$" pl.ylabel = r"$\Delta$ (GHz)" pl.legend(loc='lower left') return pl
def coupling_plot(): pl=Plotter(fig_width=6.0, fig_height=4.0) fw0=linspace(4e9, 7e9, 2000) line(fw0/1e9, qdt._get_coupling(fw0)/1e9, label=r"$G_a/2C$", color="blue", plotter=pl) line(fw0/1e9, qdt._get_Lamb_shift(fw0)/1e9, label=r"$-B_a/2C$", color="red", plotter=pl) line(fw0/1e9, idt._get_coupling(fw0)/4/1e9, label=r"$G_a^{IDT}/2C/4$", color="green", linewidth=1.0, plotter=pl) pl.set_ylim(-1.0, 1.5) pl.legend(loc='lower right') return pl
class JDF_Top(Operative): """Top class that controls distribution of patterns into JDF""" base_name="jdf" def show(self): shower(self, self.wafer_coords) def gen_jdf(self, agents): self.clear_JDF() for n, p in enumerate(agents): if p.plot_sep: self.patterns.append(JDF_Pattern(num=n+1, name=p.name)) self.sub_arrays.append(JDF_Array(array_num=n+1, assigns=[JDF_Assign(assign_type=["P({0})".format(n+1)], short_name=p.name, pos_assign=[(1, 1)])])) self.main_arrays[0].assigns.append(JDF_Assign(assign_type=["A({0})".format(n+1)], short_name=p.name, pos_assign=[(n+1, 1)])) self.input_jdf=self.jdf_produce() wafer_coords=FullWafer(name="jdf_wafer_coords") plot=Plotter(name="jdf_plot") @private_property def xy_offsets(self): """recursive traces down locations of all patterns""" overall_dict={} for pd in [self.p_off_recur(m_arr, p_off={}) for m_arr in self.main_arrays]: for key in pd: overall_dict[key]=overall_dict.get(key, [])+pd[key] return overall_dict def p_off_recur(self, p_arr, x_off_in=0, y_off_in=0, p_off={}): """recursive search function for pattern locations""" for a in p_arr.assigns: for pa in a.pos_assign: x_off=x_off_in+p_arr.x_start+(pa[0]-1)*p_arr.x_step y_off=y_off_in+p_arr.y_start-(pa[1]-1)*p_arr.y_step for p in [pattern for pattern in self.patterns if pattern.num in a.P_nums]: if p.name not in p_off: p_off[p.name]=[] p_off[p.name].append((x_off+p.x, y_off+p.y)) for arr in [array for array in self.sub_arrays if array.array_num in a.A_nums]: self.p_off_recur(arr, x_off, y_off, p_off) return p_off def assign_condition(self, item, n=0): return [assign.short_name for assign in self.main_arrays[n].assigns if item in assign.pos_assign] distribute_event=Event() def _observe_distribute_event(self, change): self.distribute_coords() self.get_member("xy_offsets").reset(self) xmin=-0.05 xmax=0.05 ymin=-0.05 ymax=0.05 self.plot.axe.texts=[] for main_arr in self.main_arrays: for asgn in main_arr.assigns: for pos_asgn in asgn.pos_assign: x_off=main_arr.x_start+(pos_asgn[0]-1)*main_arr.x_step y_off=main_arr.y_start-(pos_asgn[1]-1)*main_arr.y_step self.plot.add_text(asgn.short_name, x_off, y_off, size=4.5, alpha=0.8, ha='center') xmin=min(xmin, x_off) xmax=max(xmax, x_off) ymin=min(ymin, y_off) ymax=max(ymax, y_off) STRETCH=self.wafer_coords.gap_size self.plot.set_xlim(xmin-STRETCH, xmax+STRETCH) self.plot.set_ylim(ymin-STRETCH, ymax+STRETCH) self.plot.xlabel="x (um)" self.plot.ylabel="y (um)" self.plot.title="JDF Pattern Distribution" self.plot.draw() @private_property def view_window(self): return JDF_View(jdf=self) def append_valcom(self, inlist, name, fmt_str="{0}{1}", sep=";"): comment=format_comment(get_tag(self, name, "comment", "")) value=getattr(self, name) inlist.append(fmt_str.format(value, comment)) @property def arrays(self): return sqze(self.main_arrays, self.sub_arrays) def distribute_coords(self, num=None): """distribute coords using wafer_coords object""" for qw in self.wafer_coords.quarter_wafers: qw.get_member('bad_coords').reset(qw) qw.get_member('good_coords').reset(qw) self.comments=["distributed main array for quarter wafer {}".format(self.wafer_coords.wafer_type)] self.Px, self.Py, self.Qx, self.Qy=self.wafer_coords.GLM if self.wafer_coords.wafer_type=="Full" and len(self.main_arrays)<4: assigns=[assign.dup_assign() for assign in self.main_arrays[0].assigns] self.main_arrays=self._default_main_arrays() for arr in self.main_arrays: arr.assigns=[assign.dup_assign() for assign in assigns] for m, qw in enumerate(self.wafer_coords.quarter_wafers): if num is None: our_num=len(self.main_arrays[m].assigns) else: our_num=num for n, c in enumerate(qw.distribute_coords(our_num)): self.main_arrays[m].assigns[n].pos_assign=c[:] self.main_arrays[m].x_start=qw.x_offset self.main_arrays[m].x_num=qw.N_chips self.main_arrays[m].x_step=qw.step_size self.main_arrays[m].y_start=qw.y_offset self.main_arrays[m].y_num=qw.N_chips self.main_arrays[m].y_step=qw.step_size self.output_jdf=self.jdf_produce() self.input_jdf=self.output_jdf input_jdf=Unicode() output_jdf=Unicode() comments=List() Px=Coerced(int, (-40000,)).tag(desc="X coordinate of global P mark") Py=Coerced(int, (4000,)).tag(desc="Y coordinate of global P mark") Qx=Coerced(int, (-4000,)) Qy=Coerced(int, (40000,)) mgn_name=Unicode("IDT") wafer_diameter=Coerced(int, (4,)) write_diameter=Coerced(float, (-4.2,)) stdcur=Coerced(int, (2,)).tag(desc="Current to use in nA") shot=Coerced(int, (8,)).tag(desc="Shot size in nm. should divide 4 um evenly") resist=Coerced(int, (165,)).tag(desc="dose") resist_comment=Unicode() main_arrays=List().tag(desc="main arrays in JDF", private=True) sub_arrays=List().tag(desc="arrays in JDF")#.tag(width='max', inside_type=jdf_array) patterns=List().tag(desc="patterns in JDF")#.tag(width='max', inside_type=jdf_pattern) jdis=List().tag(desc="jdis in JDF") def _default_main_arrays(self): if self.wafer_coords.wafer_type=="Full": return [JDF_Main_Array(), JDF_Main_Array(), JDF_Main_Array(), JDF_Main_Array()] return [JDF_Main_Array()] def _observe_input_jdf(self, change): self.jdf_parse(self.input_jdf) self.output_jdf=self.jdf_produce() def clear_JDF(self): self.comments=[] self.main_arrays=self._default_main_arrays() self.sub_arrays=[] self.patterns=[] self.jdis=[] def add_pattern(self, tempstr, comment): self.patterns.append(JDF_Pattern(tempstr=tempstr, comment=comment)) def add_array(self, tempstr, comment): if ":" in tempstr: array=JDF_Array(tempstr=tempstr, comment=comment) self.sub_arrays.append(array) else: array=JDF_Main_Array(tempstr=tempstr, comment=comment) self.main_arrays.append(array) return array def jdf_parse(self, jdf_data): """reads a jdf text and puts the data into objects""" jdf_list=jdf_data.split("\n") inside_path=False inside_layer=False self.clear_JDF() for n, line in enumerate(jdf_list): tempstr, comment=parse_comment(line) if tempstr=="" and comment!="": self.comments.append(comment) if tempstr.startswith('GLMPOS'): self.Px, self.Py, self.Qx, self.Qy=xy_string_split(tempstr) elif tempstr.startswith('JOB'): mgn_name, self.wafer_diameter, self.write_diameter=tempstr.split(",") self.mgn_name=mgn_name.split("'")[1].strip() elif tempstr.startswith("PATH"): inside_path=True elif "LAYER" in tempstr: inside_layer=True if inside_path: if 'ARRAY' in tempstr: array=self.add_array(tempstr, comment) elif 'ASSIGN' in tempstr: array.add_assign(tempstr, comment) elif 'CHMPOS' in tempstr: M1x, M1y=tuple_split(tempstr) if len(self.main_arrays)>0: self.main_arrays[-1].M1x=M1x self.main_arrays[-1].M1y=M1y elif "PEND" in tempstr: inside_path=False elif inside_layer: if 'END' in tempstr: inside_layer=False elif 'STDCUR' in tempstr: set_attr(self, "stdcur", tempstr.split("STDCUR")[1], comment=comment) elif 'SHOT' in tempstr: set_attr(self, "shot", tempstr.split(',')[1], comment=comment) elif 'RESIST' in tempstr: set_attr(self, "resist", tempstr.split('RESIST')[1], comment=comment) elif 'P(' in tempstr: self.add_pattern(tempstr, comment) elif tempstr.startswith('@'): jdi_str=tempstr.split("'")[1].split(".jdi")[0] self.jdis.append(jdi_str) def jdf_produce(self): """produces a jdf from the data stored in the object""" jl=[] jl.append("JOB/W '{name}', {waf_diam}, {write_diam}\n".format(name=self.mgn_name, waf_diam=self.wafer_diameter, write_diam=self.write_diameter)) if len(self.comments)>0: jl.append(";{comment}\n".format(comment=self.comments[0])) jl.append("GLMPOS P=({Px}, {Py}), Q=({Qx},{Qy})".format(Px=self.Px, Py=self.Py, Qx=self.Qx, Qy=self.Qy)) jl.append("PATH") for n, item in enumerate(self.arrays): jl.extend(item.jdf_output) jl.append("PEND\n\nLAYER 1") for n, item in enumerate(self.patterns): jl.append(item.jdf_output) self.append_valcom(jl, "stdcur", "\nSTDCUR {0}{1}") self.append_valcom(jl, "shot", "SHOT A, {0}{1}") self.append_valcom(jl, "resist", "RESIST {0}{1}\n") for item in self.jdis: jl.append("@ '{jdi_name}.jdi'".format(jdi_name=item)) jl.append("\nEND 1\n") if len(self.comments)>1: for item in self.comments[1:]: jl.append(";{}".format(item)) return "\n".join(jl)
class EBL_Polygons(Operative): base_name = "EBL_Polygons" initial_position = (0, 300) color = Enum("green", "blue", "red", "purple", "brown", "black").tag( desc="color or datatype of item, could be used for dosing possibly") layer = Enum("Al", "Al_35nA", "Au").tag(desc='layer of item') save_file = Typed(Save_DXF, ()).tag(no_spacer=True) name_sug = Unicode().tag(no_spacer=True) shot_mod_table = Unicode() bmr = Typed(BeamerGen).tag(private=True) plot_sep = Bool(True) verts = List(default=[]).tag(private=True) jdf = JDF_Top() plot = Plotter(name="EBL Plot", xlabel="x (um)", ylabel="y (um)", title="EBL Plot") def show(self): if self.jdf.input_jdf == "": self.jdf.gen_jdf([ agent for agent in self.agent_dict.values() if isinstance(agent, EBL_Polygons) ]) self.plot_JDF() shower(self, self.plot) @property def cls_run_funcs(self): return [self.plot_JDF, self.save_JDF_DXF] # @classmethod # def activated(cls): # print "hello" # if cls.jdf.input_jdf=="": # cls.jdf.gen_jdf([agent for agent in cls.agent_dict.values() if isinstance(agent, EBL_Polygons)]) # cls.plot_JDF() @classmethod def plot_JDF(cls): xmin = minx([]) xmax = maxx([]) ymin = miny([]) ymax = maxy([]) cls.jdf.get_member("xy_offsets").reset(cls.jdf) xy_off = cls.jdf.xy_offsets log_debug(2) for p in cls.jdf.patterns: a = cls.agent_dict[p.name] reset_properties(a) #fix updating of properties reset_property(a, "polylist") log_debug(a) verts = [] for chip in xy_off.get(p.name, []): sPoly(a, x_off=chip[0] * 1.0e-6, y_off=chip[1] * 1.0e-6, vs=verts) log_debug(a) pf = cls.plot.plot_dict.get(a.name + "_plot", None) if pf is None: cls.plot.polygon(verts, color=a.color, plot_name=a.name + "_plot") else: pf.alter_xy(verts, color=a.color) log_debug(a) xmin = min([minx(verts), xmin]) xmax = max([maxx(verts), xmax]) ymin = min([miny(verts), ymin]) ymax = max([maxy(verts), ymax]) log_debug(1) cls.plot.set_xlim(xmin, xmax) cls.plot.set_ylim(ymin, ymax) cls.plot.draw() @classmethod def save_JDF_DXF(cls): cls.jdf.get_member("xy_offsets").reset(cls.jdf) xy_off = cls.jdf.xy_offsets verts = [] for p in cls.jdf.patterns: a = cls.agent_dict[ p. name] #[agent for agent in self.agents if agent.name==p.name][0] for chip in xy_off.get(p.name, []): sPoly(a, x_off=chip[0] * 1.0e-6, y_off=chip[1] * 1.0e-6, vs=verts) save_dxf(verts, color="green", layer="PADS", file_path="newtomtest.dxf", write_mode="w") def add_to_jdf(self): self.chief.patterns[self.name_sug] = {"shot_mod": self.shot_mod_table} def make_name_sug(self): name_sug = "" self.name_sug = name_sug def full_EBL_save( self, dir_path="""/Users/thomasaref/Dropbox/Current stuff/TA_software/discard/S2015_06_22_180739/""" ): self.make_name_sug() file_path = dir_path + self.name_sug + ".dxf" self.save_file.direct_save(self.polylist[:], self.color, self.layer, file_path=file_path, write_mode='w') self.bmr = BeamerGen(file_name=self.name_sug, mod_table_name=self.shot_mod_table, bias=-0.009, base_path=dir_path, extentLLy=-150, extentURy=150) self.bmr.gen_flow() self.add_to_jdf() @observe('save_file.save_event') def obs_save_event(self, change): self.save_file.direct_save(self.verts[:], self.color, self.layer, write_mode='w') @property def xmin(self): return minx(self.verts) @property def xmax(self): return maxx(self.verts) @property def ymin(self): return miny(self.verts) @property def ymax(self): return maxy(self.verts) @private_property def polylist(self): """example polylist. to be overwritten in child classes In general, self.verts should be cleared first i.e. self.verts=[] but this case is interesting for testing out functions""" #self.verts=[] return self.verts def P(self, verts): """adds a polygon to the polylist with vertices given as a list of tuples""" sP(verts, self.verts) #extend necesary def Poly(self, obj, x_off=0.0, y_off=0.0, theta=0.0, orient="TL"): """adds polygons to verts using an EBL_Polygons object as the source""" sPoly(obj, x_off, y_off, theta, orient, vs=self.verts) def R(self, xr, yr, wr, hr): """creates a rectangle EBLpolygon with (x,y) coordinates=(xr,yr), width=wr, height=hr""" sR(xr, yr, wr, hr, self.verts) def C(self, xr, yr, wr, hr): """Adds a centered rectangle to the polylist""" sC(xr, yr, wr, hr, self.verts) def T(self, xr, yr, wr, hr, ot="R", nt=10): """adds a toothed rectangle to the polylist""" sT(xr, yr, wr, hr, ot=ot, nt=nt, vs=self.verts) def CT(self, xr, yr, wr, hr, ot="R", nt=10): """adds a centered toothed rectangle to the polylist""" sCT(xr, yr, wr, hr, ot=ot, nt=nt, vs=self.verts) def Cross(self, xr, yr, wr, hr, lw): """adds a cross to the polylist""" sCross(xr, yr, wr, hr, lw, self.verts) def Dig(self, dig_key, xr, yr, wr, hr): """adds a digit to the polylist""" sDig(dig_key, xr, yr, wr, hr, self.verts) def WaferDig(self, wafer_type, x_dig, y_dig, xr, yr, wr, hr): sWaferDig(wafer_type, x_dig, y_dig, xr, yr, wr, hr, self.verts)