Exemplo n.º 1
0
class DipoleWidgetFD(object):
    """DipoleWidget"""

    x = None
    y = None
    z = None
    func = None

    # Fixed spatial range in 3D
    xmin, xmax = -50., 50.
    ymin, ymax = -50., 50.
    zmin, zmax = -50., 50.

    def __init__(self):
        self.dataview = DataView()

    def SetDataview(self, srcLoc, sig, f, orientation, normal, functype, na=100, nb=100, loc=0.):

        self.srcLoc = srcLoc
        self.sig = sig
        self.f = f
        self.normal = normal
        self.SetGrid(normal, loc, na, nb)
        self.functype = functype
        self.dataview.set_xyz(self.x, self.y, self.z, normal=normal) # set plane and locations ...

        if self.functype == "E_from_ED":
            self.func = E_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_ED_galvanic":
            self.func = E_galvanic_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_ED_inductive":
            self.func = E_inductive_from_ElectricDipoleWholeSpace
        elif self.functype == "H_from_ED":
            self.func = H_from_ElectricDipoleWholeSpace
        elif self.functype == "J_from_ED":
            self.func = J_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_MD":
            self.func = E_from_MagneticDipoleWholeSpace
        elif self.functype == "H_from_MD":
            self.func = H_from_MagneticDipoleWholeSpace
        elif self.functype == "J_from_MD":
            self.func = J_from_MagneticDipoleWholeSpace
        else:
            raise NotImplementedError()

        self.dataview.eval_2D(srcLoc, sig, f, orientation, self.func) # evaluate

    def SetGrid(self, normal, loc, na, nb):
        # Assume we are seeing xy plane
        if normal =="X" or normal=="x":
            self.x = np.r_[loc]
            self.y = np.linspace(self.ymin, self.ymax, na)
            self.z = np.linspace(self.zmin, self.zmax, nb)
        if normal =="Y" or normal=="y":
            self.x = np.linspace(self.xmin, self.xmax, na)
            self.y = np.r_[loc]
            self.z = np.linspace(self.zmin, self.zmax, nb)
        if normal =="Z" or normal=="z":
            self.x = np.linspace(self.xmin, self.xmax, na)
            self.y = np.linspace(self.ymin, self.ymax, nb)
            self.z = np.r_[loc]

    def Dipole2Dviz(self, x1, y1, x2, y2, npts2D, npts, sig, f, srcLoc=np.r_[0., 0., 0.], orientation="x", component="real", view="x", normal="Z", functype="E_from_ED", loc=0., scale="log", dx=50.):
        nx, ny = npts2D, npts2D
        x, y = linefun(x1, x2, y1, y2, npts)
        if scale == "log":
            logamp = True
        elif scale == "linear":
            logamp = False
        else:
            raise NotImplementedError()

        self.SetDataview(srcLoc, sig, f, orientation, normal, functype, na=nx, nb=ny, loc=loc)
        plot1D = False
        plotTxProflie = False
        if normal =="X" or normal=="x":
            if abs(loc - 50) < 1e-5:
                plot1D = True
            xyz_line = np.c_[np.ones_like(x)*self.x, x, y]
            self.dataview.xyz_line =  xyz_line
        if normal =="Y" or normal=="y":
            if abs(loc - 0.) < 1e-5:
                plot1D = True
                plotTxProflie = True
            xyz_line = np.c_[x, np.ones_like(x)*self.y, y]
            self.dataview.xyz_line =  xyz_line
        if normal =="Z" or normal=="z":
            xyz_line = np.c_[x, y, np.ones_like(x)*self.z]
            self.dataview.xyz_line =  xyz_line

        fig = plt.figure(figsize=(18*1.5,3.4*1.5))
        gs1 = gridspec.GridSpec(2, 7)
        gs1.update(left=0.05, right=0.48, wspace=0.05)
        ax1 = plt.subplot(gs1[:2, :3])
        ax1.axis("equal")

        ax1, dat1 = self.dataview.plot2D_FD(ax=ax1, component=component,view=view, colorbar=False, logamp=logamp)
        vmin, vmax = dat1.cvalues.min(), dat1.cvalues.max()
        if scale == "log":
            cb = plt.colorbar(dat1, ax=ax1, ticks=np.linspace(vmin, vmax, 5), format="$10^{%.1f}$")
        elif scale == "linear":
            cb = plt.colorbar(dat1, ax=ax1, ticks=np.linspace(vmin, vmax, 5), format="%.1e")

        ax1.text(x[0], y[0], 'A', fontsize = 16, color='w')
        ax1.text(x[-1], y[-1]-5, 'B', fontsize = 16, color='w')
        tempstr = functype.split("_")
        if view == "vec":
            tname = "Vector "
            title = tname+tempstr[0]+"-field from "+tempstr[2]
        elif  view== "amp":
            tname = "|"
            title = tname+tempstr[0]+"|-field from "+tempstr[2]
        else:
            if component == "real":
                tname = "Re("
            elif component == "imag":
                tname = "Im("
            elif component == "amplitude":
                tname = "Amp("
            elif component == "phase":
                tname = "Phase("

            title = tname + tempstr[0]+view+")-field from "+tempstr[2]

        if tempstr[0] == "E":
            unit = " (V/m)"
            fieldname = "Electric field"
        elif tempstr[0] == "H":
            unit = " (A/m)"
            fieldname = "Magnetic field"
        elif tempstr[0] == "J":
            unit =  " (A/m$^2$) "
            fieldname = "Current density"
        else:
            raise NotImplementedError()
        if component == "phase":
            unit = " (rad)"
        label = fieldname + unit
        label_cb = tempstr[0]+view+"-field from "+tempstr[2]
        cb.set_label(label)
        ax1.set_title(title)


        if plotTxProflie:
            ax1.plot(np.r_[-20., 80.],np.zeros(2), 'b-', lw=1)
        if plot1D:
            ax1.plot(x,y, 'r.', ms=4)
            ax2 = plt.subplot(gs1[:, 4:6])
            val_line_x, val_line_y, val_line_z = self.dataview.eval(xyz_line, srcLoc, np.r_[sig], np.r_[f], orientation, self.func)

            if view =="X" or view =="x":
                val_line = val_line_x
            elif view =="Y" or view =="y":
                val_line = val_line_y
            elif view =="Z" or view =="z":
                val_line = val_line_z
            elif view =="vec" or "amp":
                vecamp = lambda a, b, c: np.sqrt((a)**2+(b)**2+(c)**2)
                if component == "real":
                    val_line = vecamp(val_line_x.real, val_line_y.real, val_line_z.real)
                elif component == "imag":
                    val_line = vecamp(val_line_x.imag, val_line_y.imag, val_line_z.imag)
                elif component == "amplitude":
                    val_line = vecamp(abs(val_line_x), abs(val_line_y), abs(val_line_z))
                elif component == "phase":
                    val_line = vecamp(np.angle(val_line_x), np.angle(val_line_y), np.angle(val_line_z))

            distance = np.sqrt((x-x1)**2+(y-y1)**2) - dx # specific purpose


            if component == "real":
                val_line = val_line.real
            elif component == "imag":
                val_line = val_line.imag
            elif component == "amplitude":
                val_line = abs(val_line)
            elif component == "phase":
                val_line = np.angle(val_line)

            if scale == "log":
                temp = val_line.copy()*np.nan
                temp[val_line>0.] = val_line[val_line>0.]
                ax2.plot(temp, distance, 'k.-')
                temp = val_line.copy()*np.nan
                temp[val_line<0.] = -val_line[val_line<0.]
                ax2.plot(temp, distance, 'k.--')
                ax2.set_xlim(abs(val_line).min(), abs(val_line).max())
                ax2.set_xscale(scale)

            elif scale == "linear":
                ax2.plot(val_line, distance, 'k.-')
                ax2.set_xlim(val_line.min(), val_line.max())
                ax2.set_xscale(scale)
                xticks = np.linspace(val_line.min(), val_line.max(), 3)
                plt.plot(np.r_[0., 0.], np.r_[distance.min(), distance.max()], 'k-', lw=2)
                ax2.xaxis.set_ticks(xticks)
                ax2.xaxis.set_major_formatter(ticker.FormatStrFormatter("%.0e"))

            ax2.set_ylim(distance.min(), distance.max())
            ax2.set_ylabel("A-B profile (m)")

            if tempstr[0] == "E":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field (V/m) "
                else:
                    label = tname+tempstr[0]+view+")-field (V/m) "
            elif tempstr[0] == "H":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field field (A/m) "
                else:
                    label = tname+tempstr[0]+view+")-field (A/m) "
            elif tempstr[0] == "J":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field field (A/m$^2$) "
                else:
                    label = tname+tempstr[0]+view+")-field (A/m$^2$) "
            else:
                raise NotImplementedError()

            if component == "phase":
                label = tname+tempstr[0]+view+")-field (rad) "

            ax2.set_title("EM data at Rx hole")
            ax2.set_xlabel(label)

            # ax2.text(distance.min(), val_line.max(), 'A', fontsize = 16)
            # ax2.text(distance.max()*0.97, val_line.max(), 'B', fontsize = 16)
            # ax2.legend((component, ), bbox_to_anchor=(0.5, -0.3))
            ax2.grid(True)
        plt.show()
        pass

    def InteractiveDipoleBH(self, nRx=20, npts2D=50, scale="log", offset_plane=50.,\
                            X1=-20, X2=80, Y1=-50, Y2=50, Z1=-50, Z2=50, \
                            plane="YZ", SrcType="ED", fieldvalue="E", compvalue="z"):

        # x1, x2, y1, y2 = offset_rx, offset_rx, Z1, Z2
        self.xmin, self.xmax = X1, X2
        self.ymin, self.ymax = Y1, Y2
        self.zmin, self.zmax = Z1, Z2

        def foo(Field, AmpDir, Component, ComplexNumber, Frequency, Sigma, Offset, Scale, Slider, FreqLog, SigLog, SrcType=SrcType):
            if Slider ==True:
                f = np.r_[10**FreqLog]
                sig = np.r_[10**SigLog]
            else:
                f = np.r_[Frequency]
                sig = np.r_[Sigma]

            if plane == "XZ":
                normal = "Y"
                self.offset_rx = 50.

            elif plane == "YZ":
                normal = "X"
                self.offset_rx = 0.
            x1, x2, y1, y2 = self.offset_rx, self.offset_rx, Z1, Z2

            if ComplexNumber == "Re":
                ComplexNumber = "real"
            elif ComplexNumber == "Im":
                ComplexNumber = "imag"
            elif ComplexNumber == "Amp":
                ComplexNumber = "amplitude"
            elif ComplexNumber == "Phase":
                ComplexNumber = "phase"

            if AmpDir == "Direction":
                ComplexNumber = "real"
                Component = "vec"
            elif AmpDir == "Amp":
                ComplexNumber = "real"
                Component = "amp"

            if SrcType == "ED":
                Field = Field+"_from_ED"
            elif SrcType == "MD":
                Field = Field+"_from_MD"

            return self.Dipole2Dviz(x1, y1, x2, y2, npts2D, nRx, sig, f, srcLoc=np.r_[0., 0., 0.], orientation="z", component=ComplexNumber, view=Component, normal=normal, functype=Field, loc=Offset, scale=Scale)

        out = widgets.interactive (foo
                        ,Field=widgets.ToggleButtons(options=["E", "H", "J"], value=fieldvalue) \
                        ,AmpDir=widgets.ToggleButtons(options=['None','Amp','Direction'], value="None") \
                        ,Component=widgets.ToggleButtons(options=['x','y','z'], value=compvalue, description='Comp.') \
                        ,ComplexNumber=widgets.ToggleButtons(options=['Re','Im','Amp', 'Phase']) \
                        ,Frequency=widgets.FloatText(value=0., continuous_update=False, description='f (Hz)') \
                        ,Sigma=widgets.FloatText(value=0.01, continuous_update=False, description='$\sigma$ (S/m)') \
                        ,Offset=widgets.FloatText(value = offset_plane, continuous_update=False) \
                        ,Scale=widgets.ToggleButtons(options=['log','linear'], value="log") \
                        ,Slider=widgets.widget_bool.Checkbox(value=False)\
                        ,FreqLog=widgets.FloatSlider(min=-3, max=6, step=0.5, value=-3, continuous_update=False) \
                        ,SigLog=widgets.FloatSlider(min=-3, max=3, step=0.5, value=-3, continuous_update=False) \
                        ,SrcType = fixed(SrcType)
                        )
        return out

    def InteractiveDipole(self):
        def foo(orientation, normal, component, view, functype, flog, siglog, x1, y1, x2, y2, npts2D, npts, loc):
            f = np.r_[10**flog]
            sig = np.r_[10**siglog]
            return self.Dipole2Dviz(x1, y1, x2, y2, npts2D, npts, sig, f, srcLoc=np.r_[0., 0., 0.], orientation=orientation, component=component, view=view, normal=normal, functype=functype, loc=loc, dx=50.)

        out = widgets.interactive (foo
                        ,orientation=widgets.ToggleButtons(options=['x','y','z']) \
                        ,normal=widgets.ToggleButtons(options=['X','Y','Z'], value="Z") \
                        ,component=widgets.ToggleButtons(options=['real','imag','amplitude', 'phase']) \
                        ,view=widgets.ToggleButtons(options=['x','y','z', 'vec']) \
                        ,functype=widgets.ToggleButtons(options=["E_from_ED", "H_from_ED", "E_from_ED_galvanic", "E_from_ED_inductive"]) \
                        ,flog=widgets.FloatSlider(min=-3, max=6, step=0.5, value=-3, continuous_update=False) \
                        ,siglog=widgets.FloatSlider(min=-3, max=3, step=0.5, value=-3, continuous_update=False) \
                        ,loc=widgets.FloatText(value=0.01) \
                        ,x1=widgets.FloatText(value=-10) \
                        ,y1=widgets.FloatText(value=0.01) \
                        ,x2=widgets.FloatText(value=10) \
                        ,y2=widgets.FloatText(value=0.01) \
                        ,npts2D=widgets.IntSlider(min=4,max=200,step=2,value=40) \
                        ,npts=widgets.IntSlider(min=4,max=200,step=2,value=40)
                        )
        return out
Exemplo n.º 2
0
class DipoleWidgetFD(object):
    """DipoleWidget"""

    x = None
    y = None
    z = None
    func = None

    # Fixed spatial range in 3D
    xmin, xmax = -50., 50.
    ymin, ymax = -50., 50.
    zmin, zmax = -50., 50.

    def __init__(self):
        self.dataview = DataView()

    def SetDataview(self,
                    srcLoc,
                    sig,
                    f,
                    orientation,
                    normal,
                    functype,
                    na=100,
                    nb=100,
                    loc=0.):

        self.srcLoc = srcLoc
        self.sig = sig
        self.f = f
        self.normal = normal
        self.SetGrid(normal, loc, na, nb)
        self.functype = functype
        self.dataview.set_xyz(self.x, self.y, self.z,
                              normal=normal)  # set plane and locations ...

        if self.functype == "E_from_ED":
            self.func = E_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_ED_galvanic":
            self.func = E_galvanic_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_ED_inductive":
            self.func = E_inductive_from_ElectricDipoleWholeSpace
        elif self.functype == "H_from_ED":
            self.func = H_from_ElectricDipoleWholeSpace
        elif self.functype == "J_from_ED":
            self.func = J_from_ElectricDipoleWholeSpace
        elif self.functype == "E_from_MD":
            self.func = E_from_MagneticDipoleWholeSpace
        elif self.functype == "H_from_MD":
            self.func = H_from_MagneticDipoleWholeSpace
        elif self.functype == "J_from_MD":
            self.func = J_from_MagneticDipoleWholeSpace
        else:
            raise NotImplementedError()

        self.dataview.eval_2D(srcLoc, sig, f, orientation,
                              self.func)  # evaluate

    def SetGrid(self, normal, loc, na, nb):
        # Assume we are seeing xy plane
        if normal == "X" or normal == "x":
            self.x = np.r_[loc]
            self.y = np.linspace(self.ymin, self.ymax, na)
            self.z = np.linspace(self.zmin, self.zmax, nb)
        if normal == "Y" or normal == "y":
            self.x = np.linspace(self.xmin, self.xmax, na)
            self.y = np.r_[loc]
            self.z = np.linspace(self.zmin, self.zmax, nb)
        if normal == "Z" or normal == "z":
            self.x = np.linspace(self.xmin, self.xmax, na)
            self.y = np.linspace(self.ymin, self.ymax, nb)
            self.z = np.r_[loc]

    def Dipole2Dviz(self,
                    x1,
                    y1,
                    x2,
                    y2,
                    npts2D,
                    npts,
                    sig,
                    f,
                    srcLoc=np.r_[0., 0., 0.],
                    orientation="x",
                    component="real",
                    view="x",
                    normal="Z",
                    functype="E_from_ED",
                    loc=0.,
                    scale="log",
                    dx=50.,
                    plot1D=False,
                    plotTxProfile=False):
        nx, ny = npts2D, npts2D
        x, y = linefun(x1, x2, y1, y2, npts)
        if scale == "log":
            logamp = True
        elif scale == "linear":
            logamp = False
        else:
            raise NotImplementedError()

        self.SetDataview(srcLoc,
                         sig,
                         f,
                         orientation,
                         normal,
                         functype,
                         na=nx,
                         nb=ny,
                         loc=loc)
        # plot1D = False
        # plotTxProfile = False
        if normal == "X" or normal == "x":
            if abs(loc - 50) < 1e-5:
                plot1D = True
            xyz_line = np.c_[np.ones_like(x) * self.x, x, y]
            self.dataview.xyz_line = xyz_line
        if normal == "Y" or normal == "y":
            if abs(loc - 0.) < 1e-5:
                plot1D = True
                plotTxProfile = True
            xyz_line = np.c_[x, np.ones_like(x) * self.y, y]
            self.dataview.xyz_line = xyz_line
        if normal == "Z" or normal == "z":
            xyz_line = np.c_[x, y, np.ones_like(x) * self.z]
            self.dataview.xyz_line = xyz_line

        fig = plt.figure(figsize=(18 * 1.5, 3.4 * 1.5))
        gs1 = gridspec.GridSpec(2, 7)
        gs1.update(left=0.05, right=0.48, wspace=0.05)
        ax1 = plt.subplot(gs1[:2, :3])
        ax1.axis("equal")

        ax1, dat1 = self.dataview.plot2D_FD(ax=ax1,
                                            component=component,
                                            view=view,
                                            colorbar=False,
                                            logamp=logamp)
        vmin, vmax = dat1.cvalues.min(), dat1.cvalues.max()
        if scale == "log":
            cb = plt.colorbar(dat1,
                              ax=ax1,
                              ticks=np.linspace(vmin, vmax, 5),
                              format="$10^{%.1f}$")
        elif scale == "linear":
            cb = plt.colorbar(dat1,
                              ax=ax1,
                              ticks=np.linspace(vmin, vmax, 5),
                              format="%.1e")

        ax1.text(x[0], y[0], 'A', fontsize=16, color='w')
        ax1.text(x[-1], y[-1] - 5, 'B', fontsize=16, color='w')
        tempstr = functype.split("_")
        if view == "vec":
            tname = "Vector "
            title = tname + tempstr[0] + "-field from " + tempstr[2]
        elif view == "amp":
            tname = "|"
            title = tname + tempstr[0] + "|-field from " + tempstr[2]
        else:
            if component == "real":
                tname = "Re("
            elif component == "imag":
                tname = "Im("
            elif component == "amplitude":
                tname = "Amp("
            elif component == "phase":
                tname = "Phase("

            title = tname + tempstr[0] + view + ")-field from " + tempstr[2]

        if tempstr[0] == "E":
            unit = " (V/m)"
            fieldname = "Electric field"
        elif tempstr[0] == "H":
            unit = " (A/m)"
            fieldname = "Magnetic field"
        elif tempstr[0] == "J":
            unit = " (A/m$^2$) "
            fieldname = "Current density"
        else:
            raise NotImplementedError()
        if component == "phase":
            unit = " (rad)"
        label = fieldname + unit
        label_cb = tempstr[0] + view + "-field from " + tempstr[2]
        cb.set_label(label)
        ax1.set_title(title)

        if plotTxProfile:
            ax1.plot(np.r_[-20., 80.], np.zeros(2), 'b-', lw=1)
        if plot1D:
            ax1.plot(x, y, 'r.', ms=4)
            ax2 = plt.subplot(gs1[:, 4:6])
            val_line_x, val_line_y, val_line_z = self.dataview.eval(
                xyz_line, srcLoc, np.r_[sig], np.r_[f], orientation, self.func)

            if view == "X" or view == "x":
                val_line = val_line_x
            elif view == "Y" or view == "y":
                val_line = val_line_y
            elif view == "Z" or view == "z":
                val_line = val_line_z
            elif view == "vec" or "amp":
                vecamp = lambda a, b, c: np.sqrt((a)**2 + (b)**2 + (c)**2)
                if component == "real":
                    val_line = vecamp(val_line_x.real, val_line_y.real,
                                      val_line_z.real)
                elif component == "imag":
                    val_line = vecamp(val_line_x.imag, val_line_y.imag,
                                      val_line_z.imag)
                elif component == "amplitude":
                    val_line = vecamp(abs(val_line_x), abs(val_line_y),
                                      abs(val_line_z))
                elif component == "phase":
                    val_line = vecamp(np.angle(val_line_x),
                                      np.angle(val_line_y),
                                      np.angle(val_line_z))

            distance = np.sqrt((x - x1)**2 +
                               (y - y1)**2) - dx  # specific purpose

            if component == "real":
                val_line = val_line.real
            elif component == "imag":
                val_line = val_line.imag
            elif component == "amplitude":
                val_line = abs(val_line)
            elif component == "phase":
                val_line = np.angle(val_line)

            if scale == "log":
                temp = val_line.copy() * np.nan
                temp[val_line > 0.] = val_line[val_line > 0.]
                ax2.plot(temp, distance, 'k.-')
                temp = val_line.copy() * np.nan
                temp[val_line < 0.] = -val_line[val_line < 0.]
                ax2.plot(temp, distance, 'k.--')
                ax2.set_xlim(abs(val_line).min(), abs(val_line).max())
                ax2.set_xscale(scale)

            elif scale == "linear":
                ax2.plot(val_line, distance, 'k.-')
                ax2.set_xlim(val_line.min(), val_line.max())
                ax2.set_xscale(scale)
                xticks = np.linspace(val_line.min(), val_line.max(), 3)
                plt.plot(np.r_[0., 0.],
                         np.r_[distance.min(), distance.max()],
                         'k-',
                         lw=2)
                ax2.xaxis.set_ticks(xticks)
                ax2.xaxis.set_major_formatter(
                    ticker.FormatStrFormatter("%.0e"))

            ax2.set_ylim(distance.min(), distance.max())
            ax2.set_ylabel("A-B profile (m)")

            if tempstr[0] == "E":
                if view == "vec" or view == "amp":
                    label = "|" + tempstr[0] + "|-field (V/m) "
                else:
                    label = tname + tempstr[0] + view + ")-field (V/m) "
            elif tempstr[0] == "H":
                if view == "vec" or view == "amp":
                    label = "|" + tempstr[0] + "|-field field (A/m) "
                else:
                    label = tname + tempstr[0] + view + ")-field (A/m) "
            elif tempstr[0] == "J":
                if view == "vec" or view == "amp":
                    label = "|" + tempstr[0] + "|-field field (A/m$^2$) "
                else:
                    label = tname + tempstr[0] + view + ")-field (A/m$^2$) "
            else:
                raise NotImplementedError()

            if component == "phase":
                label = tname + tempstr[0] + view + ")-field (rad) "

            ax2.set_title("EM data at Rx hole")
            ax2.set_xlabel(label)

            # ax2.text(distance.min(), val_line.max(), 'A', fontsize = 16)
            # ax2.text(distance.max()*0.97, val_line.max(), 'B', fontsize = 16)
            # ax2.legend((component, ), bbox_to_anchor=(0.5, -0.3))
            ax2.grid(True)
        plt.show()
        pass

    def InteractiveDipoleBH(self, nRx=20, npts2D=50, scale="log", offset_plane=50.,\
                            X1=-20, X2=80, Y1=-50, Y2=50, Z1=-50, Z2=50, \
                            plane="YZ", SrcType="ED", fieldvalue="E", compvalue="z"):

        # x1, x2, y1, y2 = offset_rx, offset_rx, Z1, Z2
        self.xmin, self.xmax = X1, X2
        self.ymin, self.ymax = Y1, Y2
        self.zmin, self.zmax = Z1, Z2

        def foo(Field,
                AmpDir,
                Component,
                ComplexNumber,
                Frequency,
                Sigma,
                Offset,
                Scale,
                Slider,
                FreqLog,
                SigLog,
                SrcType=SrcType):
            if Slider == True:
                f = np.r_[10**FreqLog]
                sig = np.r_[10**SigLog]
            else:
                f = np.r_[Frequency]
                sig = np.r_[Sigma]

            if plane == "XZ":
                normal = "Y"
                self.offset_rx = 50.

            elif plane == "YZ":
                normal = "X"
                self.offset_rx = 0.
            x1, x2, y1, y2 = self.offset_rx, self.offset_rx, Z1, Z2

            if ComplexNumber == "Re":
                ComplexNumber = "real"
            elif ComplexNumber == "Im":
                ComplexNumber = "imag"
            elif ComplexNumber == "Amp":
                ComplexNumber = "amplitude"
            elif ComplexNumber == "Phase":
                ComplexNumber = "phase"

            if AmpDir == "Direction":
                ComplexNumber = "real"
                Component = "vec"
            elif AmpDir == "Amp":
                ComplexNumber = "real"
                Component = "amp"

            if SrcType == "ED":
                Field = Field + "_from_ED"
            elif SrcType == "MD":
                Field = Field + "_from_MD"

            return self.Dipole2Dviz(x1,
                                    y1,
                                    x2,
                                    y2,
                                    npts2D,
                                    nRx,
                                    sig,
                                    f,
                                    srcLoc=np.r_[0., 0., 0.],
                                    orientation="z",
                                    component=ComplexNumber,
                                    view=Component,
                                    normal=normal,
                                    functype=Field,
                                    loc=Offset,
                                    scale=Scale)

        out = widgets.interactive (foo
                        ,Field=widgets.ToggleButtons(options=["E", "H", "J"], value=fieldvalue) \
                        ,AmpDir=widgets.ToggleButtons(options=['None','Amp','Direction'], value="None") \
                        ,Component=widgets.ToggleButtons(options=['x','y','z'], value=compvalue, description='Comp.') \
                        ,ComplexNumber=widgets.ToggleButtons(options=['Re','Im','Amp', 'Phase']) \
                        ,Frequency=widgets.FloatText(value=0., continuous_update=False, description='f (Hz)') \
                        ,Sigma=widgets.FloatText(value=0.01, continuous_update=False, description='$\sigma$ (S/m)') \
                        ,Offset=widgets.FloatText(value = offset_plane, continuous_update=False) \
                        ,Scale=widgets.ToggleButtons(options=['log','linear'], value="log") \
                        ,Slider=widgets.widget_bool.Checkbox(value=False)\
                        ,FreqLog=widgets.FloatSlider(min=-3, max=6, step=0.5, value=-3, continuous_update=False) \
                        ,SigLog=widgets.FloatSlider(min=-3, max=3, step=0.5, value=-3, continuous_update=False) \
                        ,SrcType = fixed(SrcType)
                        )
        return out

    def InteractiveDipole(self):
        def foo(orientation, normal, component, view, functype, flog, siglog,
                x1, y1, x2, y2, npts2D, npts, loc):
            f = np.r_[10**flog]
            sig = np.r_[10**siglog]
            return self.Dipole2Dviz(x1,
                                    y1,
                                    x2,
                                    y2,
                                    npts2D,
                                    npts,
                                    sig,
                                    f,
                                    srcLoc=np.r_[0., 0., 0.],
                                    orientation=orientation,
                                    component=component,
                                    view=view,
                                    normal=normal,
                                    functype=functype,
                                    loc=loc,
                                    dx=50.)

        out = widgets.interactive (foo
                        ,orientation=widgets.ToggleButtons(options=['x','y','z']) \
                        ,normal=widgets.ToggleButtons(options=['X','Y','Z'], value="Z") \
                        ,component=widgets.ToggleButtons(options=['real','imag','amplitude', 'phase']) \
                        ,view=widgets.ToggleButtons(options=['x','y','z', 'vec']) \
                        ,functype=widgets.ToggleButtons(options=["E_from_ED", "H_from_ED", "E_from_ED_galvanic", "E_from_ED_inductive"]) \
                        ,flog=widgets.FloatSlider(min=-3, max=6, step=0.5, value=-3, continuous_update=False) \
                        ,siglog=widgets.FloatSlider(min=-3, max=3, step=0.5, value=-3, continuous_update=False) \
                        ,loc=widgets.FloatText(value=0.01) \
                        ,x1=widgets.FloatText(value=-10) \
                        ,y1=widgets.FloatText(value=0.01) \
                        ,x2=widgets.FloatText(value=10) \
                        ,y2=widgets.FloatText(value=0.01) \
                        ,npts2D=widgets.IntSlider(min=4,max=200,step=2,value=40) \
                        ,npts=widgets.IntSlider(min=4,max=200,step=2,value=40)
                        )
        return out
Exemplo n.º 3
0
class PlanewaveWidget(DipoleWidgetFD):
    """PlanewaveWidget"""

    x = None
    y = None
    z = None
    func = None

    # Fixed spatial range in 3D
    xmin, xmax = -500., 500.
    ymin, ymax = -500., 500.
    zmin, zmax = -1000.,0.

    def __init__(self):
        self.dataview = DataView()

    def SetDataview(self, srcLoc, sig, f, orientation, normal, functype, na=100, nb=100, loc=0.,t=0.):

        self.srcLoc = srcLoc
        self.sig = sig
        self.f = f
        self.normal = normal
        self.SetGrid(normal, loc, na, nb)
        self.functype = functype
        self.dataview.set_xyz(self.x, self.y, self.z, normal=normal) # set plane and locations ...

        if self.functype == "E_from_SheetCurrent":
            self.func = E_field_from_SheetCurruent
        elif self.functype == "H_from_SheetCurrent":
            self.func = H_field_from_SheetCurruent
        elif self.functype == "J_from_SheetCurrent":
            self.func = J_field_from_SheetCurruent
        else:
            raise NotImplementedError()

        self.dataview.eval_2D(srcLoc, sig, f, orientation, self.func, t=t) # evaluate

    def Planewave2Dviz(self, x1, y1, x2, y2, npts2D, npts, sig, f, srcLoc=0., orientation="x", component="real", view="x", normal="Z", functype="E_from_ED", loc=0., scale="log", dx=50., t=0.):
        nx, ny = npts2D, npts2D
        x, y = linefun(x1, x2, y1, y2, npts)
        if scale == "log":
            logamp = True
        elif scale == "linear":
            logamp = False
        else:
            raise NotImplementedError()
        self.SetDataview(srcLoc, sig, f, orientation, normal, functype, na=nx, nb=ny, loc=loc, t=t)
        plot1D = True
        if normal =="X" or normal=="x":
            xyz_line = np.c_[np.ones_like(x)*self.x, x, y]
            self.dataview.xyz_line =  xyz_line
        if normal =="Y" or normal=="y":
            xyz_line = np.c_[x, np.ones_like(x)*self.y, y]
            self.dataview.xyz_line =  xyz_line
        if normal =="Z" or normal=="z":
            xyz_line = np.c_[x, y, np.ones_like(x)*self.z]
            self.dataview.xyz_line =  xyz_line

        fig = plt.figure(figsize=(18*1.5,3.4*1.5))
        gs1 = gridspec.GridSpec(2, 7)
        gs1.update(left=0.05, right=0.48, wspace=0.05)
        ax1 = plt.subplot(gs1[:2, :3])
        ax1.axis("equal")

        ax1, dat1 = self.dataview.plot2D_FD(ax=ax1, component=component,view=view, colorbar=False, logamp=logamp)
        vmin, vmax = dat1.cvalues.min(), dat1.cvalues.max()
        if scale == "log":
            cb = plt.colorbar(dat1, ax=ax1, ticks=np.linspace(vmin, vmax, 5), format="$10^{%.1f}$")
        elif scale == "linear":
            cb = plt.colorbar(dat1, ax=ax1, ticks=np.linspace(vmin, vmax, 5), format="%.1e")

        tempstr = functype.split("_")
        if view == "vec":
            tname = "Vector "
            title = tname+tempstr[0]+"-field from "+tempstr[2]
        elif  view== "amp":
            tname = "|"
            title = tname+tempstr[0]+"|-field from "+tempstr[2]
        else:
            if component == "real":
                tname = "Re("
            elif component == "imag":
                tname = "Im("
            elif component == "amplitude":
                tname = "Amp("
            elif component == "phase":
                tname = "Phase("

            title = tname + tempstr[0]+view+")-field from "+tempstr[2]

        if tempstr[0] == "E":
            unit = " (V/m)"
            fieldname = "Electric field"
        elif tempstr[0] == "H":
            unit = " (A/m)"
            fieldname = "Magnetic field"
        elif tempstr[0] == "J":
            unit =  " (A/m$^2$) "
            fieldname = "Current density"
        else:
            raise NotImplementedError()
        if component == "phase":
            unit = " (rad)"
        label = fieldname + unit
        label_cb = tempstr[0]+view+"-field from "+tempstr[2]
        cb.set_label(label)
        ax1.set_title(title)


        if plot1D:
            ax1.plot(x,y, 'r.', ms=4)
            ax2 = plt.subplot(gs1[:, 4:6])
            val_line_x, val_line_y, val_line_z = self.dataview.eval(xyz_line, srcLoc, np.r_[sig], np.r_[f], orientation, self.func, t=t)

            if view =="X" or view =="x":
                val_line = val_line_x
            elif view =="Y" or view =="y":
                val_line = val_line_y
            elif view =="Z" or view =="z":
                val_line = val_line_z
            elif view =="vec" or "amp":
                vecamp = lambda a, b, c: np.sqrt((a)**2+(b)**2+(c)**2)
                if component == "real":
                    val_line = vecamp(val_line_x.real, val_line_y.real, val_line_z.real)
                elif component == "imag":
                    val_line = vecamp(val_line_x.imag, val_line_y.imag, val_line_z.imag)
                elif component == "amplitude":
                    val_line = vecamp(abs(val_line_x), abs(val_line_y), abs(val_line_z))
                elif component == "phase":
                    val_line = vecamp(np.angle(val_line_x), np.angle(val_line_y), np.angle(val_line_z))

            distance = np.sqrt((x-x1)**2+(y-y1)**2) - dx # specific purpose


            if component == "real":
                val_line = val_line.real
            elif component == "imag":
                val_line = val_line.imag
            elif component == "amplitude":
                val_line = abs(val_line)
            elif component == "phase":
                val_line = np.angle(val_line)

            if scale == "log":
                temp = val_line.copy()*np.nan
                temp[val_line>0.] = val_line[val_line>0.]
                ax2.plot(temp, distance, 'k.-')
                temp = val_line.copy()*np.nan
                temp[val_line<0.] = -val_line[val_line<0.]
                ax2.plot(temp, distance, 'k.--')
                ax2.set_xlim(abs(val_line).min(), abs(val_line).max())
                ax2.set_xscale(scale)

            elif scale == "linear":
                ax2.plot(val_line, distance, 'k.-')
                ax2.set_xlim(val_line.min(), val_line.max())
                ax2.set_xscale(scale)
                xticks = np.linspace(-abs(val_line).max(), abs(val_line).max(), 3)
                plt.plot(np.r_[0., 0.], np.r_[distance.min(), distance.max()], 'k-', lw=2)
                ax2.xaxis.set_ticks(xticks)
                ax2.xaxis.set_major_formatter(ticker.FormatStrFormatter("%.0e"))
                ax2.set_xlim(-abs(val_line).max(), abs(val_line).max())

            ax2.set_ylim(distance.min(), distance.max())
            ax2.set_ylabel("Profile (m)")

            if tempstr[0] == "E":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field (V/m) "
                else:
                    label = tname+tempstr[0]+view+")-field (V/m) "
            elif tempstr[0] == "H":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field field (A/m) "
                else:
                    label = tname+tempstr[0]+view+")-field (A/m) "
            elif tempstr[0] == "J":
                if view == "vec" or view== "amp":
                    label = "|"+tempstr[0]+"|-field field (A/m$^2$) "
                else:
                    label = tname+tempstr[0]+view+")-field (A/m$^2$) "
            else:
                raise NotImplementedError()

            if component == "phase":
                label = tname+tempstr[0]+view+")-field (rad) "

            ax2.set_title("EM data at Rx hole")
            ax2.set_xlabel(label)

            # ax2.text(distance.min(), val_line.max(), 'A', fontsize = 16)
            # ax2.text(distance.max()*0.97, val_line.max(), 'B', fontsize = 16)
            # ax2.legend((component, ), bbox_to_anchor=(0.5, -0.3))
            ax2.grid(True)
        # plt.tight_layout()
        plt.show()
        pass


    def InteractivePlaneWave(self, nRx=100, npts2D=50, scale="log", offset_plane=50., X1=-500, X2=500, Y1=-500, Y2=500, Z1=-1000, Z2=0):

        # x1, x2, y1, y2 = offset_rx, offset_rx, Z1, Z2
        self.xmin, self.xmax = X1, X2
        self.ymin, self.ymax = Y1, Y2
        self.zmin, self.zmax = Z1, Z2

        def foo(Field, AmpDir, ComplexNumber, Frequency, Sigma, Scale, Time):
            f = np.r_[Frequency]
            sig = np.r_[Sigma]

            if Field == "Ex":
                normal = "Y"
                self.offset_rx = 0.
                Field = "E_from_SheetCurrent"
                Component = "x"

            elif Field == "Hy":
                normal = "X"
                self.offset_rx = 0.
                Field = "H_from_SheetCurrent"
                Component = "y"

            x1, x2, y1, y2 = self.offset_rx, self.offset_rx, Z1, Z2

            if ComplexNumber == "Re":
                ComplexNumber = "real"
            elif ComplexNumber == "Im":
                ComplexNumber = "imag"
            elif ComplexNumber == "Amp":
                ComplexNumber = "amplitude"
            elif ComplexNumber == "Phase":
                ComplexNumber = "phase"

            if AmpDir == "Direction":
                ComplexNumber = "real"
                Component = "vec"
            elif AmpDir == "Amp":
                ComplexNumber = "real"
                Component = "amp"



            return self.Planewave2Dviz(x1, y1, x2, y2, npts2D, nRx, sig, f, srcLoc=0., orientation="X", component=ComplexNumber, view=Component, normal=normal, functype=Field, scale=Scale, t=Time)

        out = widgets.interactive (foo
                        ,Field=widgets.ToggleButtons(options=["Ex", "Hy"]) \
                        ,AmpDir=widgets.ToggleButtons(options=['None','Amp','Direction'], value="None") \
                        ,ComplexNumber=widgets.ToggleButtons(options=['Re','Im','Amp', 'Phase']) \
                        ,Frequency=widgets.FloatText(value=10., continuous_update=False) \
                        ,Sigma=widgets.FloatText(value=1, continuous_update=False) \
                        ,Scale=widgets.ToggleButtons(options=['log','linear'], value="linear") \
                        ,Time=widgets.FloatSlider(min=0, max=0.2, step=0.01, value=0.))
        return out