예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
 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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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)
예제 #8
0
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)