<jupyter_start><jupyter_text>\title{Operatial Amplifier Topology Repository for use with Python}\author{<NAME>}\maketitle Table of Contents1&nbsp;&nbsp;Premise2&nbsp;&nbsp;Libarys3&nbsp;&nbsp;Setup4&nbsp;&nbsp;Ideal OpAmp5&nbsp;&nbsp;TestBench6&nbsp;&nbsp;Buffer7&nbsp;&nbsp;Inverting8&nbsp;&nbsp;Noninverting9&nbsp;&nbsp;Miller Capactive Integrator10&nbsp;&nbsp;Miller Inductive Integrator11&nbsp;&nbsp;Low Pass 1Pole12&nbsp;&nbsp;Miller Capacitive Differentiator13&nbsp;&nbsp;Miller Inductive Differentiator14&nbsp;&nbsp;High Pass 1Zero15&nbsp;&nbsp;AllPass (Phase) Filter15.1&nbsp;&nbsp;First Order Cap First15.2&nbsp;&nbsp;First Order Cap Second16&nbsp;&nbsp;Sallen-Key Filter16.1&nbsp;&nbsp;Low Pass with Voltage Gain16.2&nbsp;&nbsp;Band Pass with Voltage Gain16.3&nbsp;&nbsp;HIgh Pass with Voltage Gain Note:This notebook uses the `ipywidgets` to provided a interactive exploration experience. In order to make use of this experience, this notebook must be downloaded and run on a computer what has `ipywidgets` installed and activated for directions for that see http://ipywidgets.readthedocs.io/en/latest/user_install.htmlthis notebook also uses the [`(some) LaTeX environments for Jupyter`](http://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/latex_envs/README.html) found within the install of https://github.com/ipython-contrib/jupyter_contrib_nbextensionsAnd all diagrams are made in **draw.io** where the source file is `OpAmpTobosDrawing.html` where that file and the exported files should accompany this notebook from its GitHub source  PremiseThis Notebook serves as a Repository of Operational Amplifier Topologies for use in [PySpice](https://pyspice.fabrice-salvaire.fr/) and for the topologies theory. The Goal for the Author personally is to make one or two upgrades to this notebook a week. Whether that be a new feature, expanded theory, or new topology.Some of the intended upgrades include:\begin{itemize}\item Enhanced analyses of output data\item Routines to find figures of merits from output data\item Added calculations from theory \item Simulations from theory and compersion to SPICE sim\item adding GUI interactivity via ipython notebook widgets\end{itemize}  Libarys<jupyter_code>from sympy import *
init_printing()
import ipywidgets as wgs

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
%matplotlib inline

from PySpice.Plot.BodeDiagram import bode_diagram
from PySpice.Probe.Plot import plot
from PySpice.Spice.Netlist import Circuit
from PySpice.Spice.Netlist import SubCircuitFactory
from PySpice.Unit import *

from ipywidgets import widgets
from IPython.display import display

#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information sympy, numpy, matplotlib, pandas, PySPice, ipywidgets<jupyter_output><empty_output><jupyter_text>Setup<jupyter_code>def lambdify2(expresion, ReVars=False):
    """
    Helper Function to more automate sympy `lambdify` function
    
    Args:
        expresion: sympy expresion !Only Pass LHS of Equations
        ReVars (bool; False): Control to return the Vars in a list if True
    
    Note:
        lambdfy is set with `dummify=False` therefore do not pass
        unsantied variabls to functin else error will be thrown
    """
    #collect vars
    Vars=sorted(list(expresion.free_symbols), key=lambda x: str(x))
    #perform lambdfy with waver
    F=lambdify(Vars, expresion, dummify=False)
    if ReVars:
        return F, Vars
    else:
        return F<jupyter_output><empty_output><jupyter_text>Ideal OpAmp Using the Semi Ideal OpAmp model devloped by <NAME> for the OpAmp Exsample [8.10.3. Operational Amplifier](https://pyspice.fabrice-salvaire.fr/examples/operational-amplifier/operational-amplifier.html)<jupyter_code>class BasicOperationalAmplifier(SubCircuitFactory):
    """
    Semi Ideal OpAmp Model SubCir from 
    https://pyspice.fabrice-salvaire.fr/examples/operational-amplifier/operational-amplifier.html
    A0=100e3; pole=100; A=10e6Hz
    Termanals:
        non_inverting_input
        inverting_input
        output
    """

    __name__ = 'BasicOperationalAmplifier'
    __nodes__ = ('non_inverting_input', 'inverting_input', 'output')

    ##############################################

    def __init__(self):

        super().__init__()

        # Input impedance
        self.R('input', 'non_inverting_input', 'inverting_input', 10@u_MΩ)

        # dc gain=100k and pole1=100hz
        # unity gain = dcgain x pole1 = 10MHZ
        self.VCVS('gain', 1, self.gnd, 'non_inverting_input', 'inverting_input', voltage_gain=kilo(100))
        self.R('P1', 1, 2, 1@u_kΩ)
        self.C('P1', 2, self.gnd, 1.5915@u_uF)

        # Output buffer and resistance
        self.VCVS('buffer', 3, self.gnd, 2, self.gnd, 1)
        self.R('out', 3, 'output', 10@u_Ω)<jupyter_output><empty_output><jupyter_text>TestBench<jupyter_code>class OnePortOpAmpTB(Circuit):
    """
    Class for implimenting Bode plot simulation for One Port 
    (Two Termanal) Opertinal Amplifer topology 
    """
    def __init__(self, DUT, **kwargs):
        """
        Args:
            DUT (class SubCircuitFactory): The One Port OpAmp topology class to be tested
            kwargs (dict): Addital Ciricut Parmters to the topology under test
        """
        #bind the DUT class to TB instance
        self.DUT=DUT
        #self.Theory=self.DUT.Theory()
        #create the ciruit name from DUT name
        super().__init__(title=f'{self.DUT.__name__}_TB', **kwargs)
        
    
    def SetupCir(self, **kwargs):
        """
        Sets up the the DUT and the Testbench for simulation
        see diagrm in source IPYNB for cirucit diagram
        Args:
            kwargs (dict): Addital Ciricut Parmters to the topology under test
        """
        #create instatince of DUT and setuo with parmaters
        self.DUT=self.DUT(**kwargs)
        
        #load the DUT in to the circuit
        self.subcircuit(self.DUT)
        self.X('Amp', self.DUT.__name__, 'Vin', 'Vout')
        
        #set up the TB elements
        self.R('Sload', 'Vin' , '1', 50@u_Ω)
        self.SinusoidalVoltageSource('Source', '1', self.gnd, amplitude=1@u_V)

        self.R('Tload', 'Vout', self.gnd, 50@u_Ω)
        #print out the resulting spice list
        print(self)
    
    def Simulate(self, fMin=1, fMax=20e6):
        """
        Method to perform a Bode plot simulation via NgSpice AC sim @25C
        Args:
            fMin(float; 1 [Hz]): the  starting frequnacy for 
            Bode plot sweep in hertz
            
            fMax(float; 100e3[Hz]): the ending  frequnacy for 
            Bode plot sweep in hertz
        
        Retured Attributes:
            results: the ac simulation raw results from NGSpice
            Data: Pandas Dataframe with ouputs and calcs from results
            
        """
        
        simulator = self.simulator(temperature=25, nominal_temperature=25)
        self.results = simulator.ac(start_frequency=fMin@u_Hz, stop_frequency=fMax@u_Hz, number_of_points=10,  variation='dec')
        
        # returned dataframe
        self.Data=pd.DataFrame()
        self.Data['freq[Hz]']=self.results.frequency
        self.Data['Vin']=self.results.Vin
        self.Data['Vout']=self.results.Vout
        #normlized gain in dB
        self.Data['Gain[dB]']=20*np.log10(np.abs(self.Data['Vout']/self.Data['Vin']))
        # phase in radians unwraped
        self.Data['Phase[rad_UW]']=(np.angle(self.Data['Vout']))
    
    def PlotResults(self):
        """
        Create a Bode plot from the simulation
        """
        self.fig, [self.axMag, self.axPh]=plt.subplots(ncols=1, nrows=2, sharex=True)
        
        A=self.Data['Gain[dB]']; F=self.Data['freq[Hz]']
        L=np.abs(np.abs(A-A.max())-3.0).idxmin()
        self.dB3=F[L]
        
        plt.suptitle("Bode Diagram of an Operational Amplifier")
        bode_diagram(axes=(self.axMag, self.axPh),
                     frequency=self.Data['freq[Hz]'],
                     gain=self.Data['Gain[dB]'],
                     phase=self.Data['Phase[rad_UW]'],
                     marker='.',
                     color='blue',
                     linestyle='-',
                    )
        
        self.axMag.axvline(x=self.dB3, label='3dB[Hz]', 
                      linestyle='-.', alpha=.7, color='g')
        self.axPh.axvline(x=self.dB3, label='3dB[Hz]', 
                      linestyle='-.', alpha=.7, color='g')<jupyter_output><empty_output><jupyter_text>\begin{definition}$A$ Open Loop Gain (no feedback)$$A=\dfrac{V_o}{V_i}$$\end{definition}\begin{definition}$G$ Closed Loop Gain (with feedback)$$G=\dfrac{V_o}{V_i}$$\end{definition}\begin{definition}$Z_{\text{i}}$ Open Loop Input Impedance (no feedback)$$Z_{\text{i}}=\dfrac{V_{\text{diff}}}{I_i}$$\end{definition}\begin{definition}$Z_{\text{o}}$ Open Loop Output Impedance (no feedback)$$Z_{\text{o}}=\dfrac{V_o}{I_o}$$\end{definition}\begin{definition}$Z_{\text{ifb}}$ Closed Loop Input Impedance (with feedback)$$Z_{\text{ifb}}=\dfrac{V_i}{I_i}$$\end{definition}\begin{definition}$Z_{\text{ofb}}$ Closed Loop Output Impedance (with feedback)$$Z_{\text{ofb}}=\dfrac{V_o}{I_o}$$\end{definition}\begin{definition}$V_{\text{diff}}$ the differential input voltage$$V_{\text{diff}}=V_+-V_-$$\end{definition}  Buffer  [Analog Electronics: Circuits, Systems and Signal Processing](https://www.amazon.com/Analog-Electronics-Circuits-Systems-Processing-ebook/dp/B00CXO975A/ref=sr_1_1?ie=UTF8&qid=1524885102&sr=8-1&keywords=Analog+Electronics+Crecraft+Gergely) 3.5, 3.5.1, 3.5.2$$V_{\text{diff}}=V_i-V_o$$$$V_o=AV_{\text{diff}}$$$$V_o=AV_i-AV_o$$$$G=\dfrac{V_o}{V_i}=\dfrac{A}{1+A}\approx 1$$ $$I_i=\dfrac{V_{\text{diff}}}{Z_i} $$$$V_{\text{diff}}=\dfrac{1}{1+A}V_i$$$$I_i=\dfrac{1}{1+A} \dfrac{V_i}{Z_i}$$$$Z_{\text{ifb}}=(1+A)Z_i$$ $$V_o=AV_{\text{diff}}-I_LZ_o$$$$(1+A)V_o=AV_i-I_L Z_o$$$$V_o=\dfrac{A}{1+A}V_i -\dfrac{Z_o}{1+A}I_L$$$$V_o=GV_i -Z_{\text{ofb}}I_L$$$$Z_{\text{ifb}}=\dfrac{Z_o}{1+A}$$<jupyter_code>class BufferOpAmp(SubCircuitFactory):
    """
    Buffer OpAmp SubCircuit
    Termanals:
        Vin
        Vout
    
    """
    
    __name__='BufferOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self):
        super().__init__()
       
        #'non_inverting_input', 'inverting_input', 'output'
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', 'Vin', 'Vout', 'Vout')
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_ifb')(s); Zout=Function('Z_ofb')(s)
        TF=Eq(H, A/(1+A)); Zin=Eq(Zin, (1+A)*Zi); Zout=Eq(Zout, Zo/(1+A))
        return TF, Zin, Zout
    
#Print out the Buffer Op Amp Theory
BufferOpAmp.Theory()
#create the Test Bench and Bind to this instance the BufferOpAmp Topo
TB=OnePortOpAmpTB(BufferOpAmp)
#Setup the Testbench and print the TB
TB.SetupCir()
#Run the AC Bode Simulation
TB.Simulate()
#View Bode Simulation
TB.PlotResults()<jupyter_output>.title BufferOpAmp_TB
.subckt BufferOpAmp Vin Vout
.subckt BasicOperationalAmplifier non_inverting_input inverting_input output
Rinput non_inverting_input inverting_input 10MegOhm
Egain 1 0 non_inverting_input inverting_input 100k
RP1 1 2 1kOhm
CP1 2 0 1.5915uF
Ebuffer 3 0 2 0 1
Rout 3 output 10Ohm
.ends BasicOperationalAmplifier
Xop Vin Vout Vout BasicOperationalAmplifier
.ends BufferOpAmp
XAmp Vin Vout BufferOpAmp
RSload Vin 1 50Ohm
VSource 1 0 DC 0V AC SIN(0V 1V 50Hz 0s 0Hz)
RTload Vout 0 50Ohm<jupyter_text>Inverting<jupyter_code>class InvertingOpAmp(SubCircuitFactory):
    """
    Inverting OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R2[Ohms]
    """
    
    __name__='InvertingOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R2=1):
        super().__init__()
        self.R1=R1; self.R2=R2
        
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', self.gnd, '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, R2=symbols('R_1, R_2', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, -R2/R1)
        Zin=Eq(Zin, R1)
        Zout=Eq(Zout, Zo*(R1+R2)/(A*R1))
        return TF, Zin, Zout
        
    
#Print out the Inverting Op Amp Theory
InvertingOpAmp.Theory()
class InvertingExp():
    """
    Class to provide GUI for Inverting Amplifer
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         )
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         )
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              R2=self.R2Slider)
        display(I)
    
    def BackEnd(self, R1, R2):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the InvertingOpAmp Topo
        TB=OnePortOpAmpTB(InvertingOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,R2=5 Ohm and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()

InvertingExp();<jupyter_output><empty_output><jupyter_text>Noninverting<jupyter_code>class NonInvertingOpAmp(SubCircuitFactory):
    """
    Non-Inverting OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1
        R2
    """
    
    __name__='NonInvertingOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1, R2):
        super().__init__()
        self.R1=R1; self.R2=R2
        
        self.R('1', '2', self.gnd, R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', 'Vin', '2', 'Vout')
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        <NAME>"""        
        R1, R2=symbols('R_1, R_2', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, (A(R1+R2))/(R2(1+A)+R1))
        Zin=Eq(Zin, Zi*((1+A)*R2+R1)/(R2+(1-A)*R1))
        Zout=Eq(Zout, Zo*(R1+R2)/(R1+(1+A)*R2))
        return TF, Zin, Zout
        

#Print out the NonInverting Op Amp Theory
NonInvertingOpAmp.Theory()
class NonInvertingExp():
    """
    Class to provide GUI for Inverting Amplifer
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm'
                                         )
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm'
                                         )
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              R2=self.R2Slider)
        display(I)
    
    def BackEnd(self, R1, R2):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the NonInverting Topo
        TB=OnePortOpAmpTB(NonInvertingOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,R2=5 Ohm and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()

NonInvertingExp();<jupyter_output><empty_output><jupyter_text>Miller Capactive Integrator<jupyter_code>class MillerCapIntOpAmp(SubCircuitFactory):
    """
    Inverting OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        C1[Fards]
    """
    
    __name__='MillerCapIntOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, C1=1):
        super().__init__()
        self.R1=R1; self.C1=C1
        
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.C('1', '2', 'Vout', C1@u_F)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', self.gnd, '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, C1=symbols('R_1, C_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, -(1/(s*C1))/R1)
        Zin=simplify(Eq(Zin, R1))
        Zout=Eq(Zout, Zo/(A(1+s*C1*R1)))
        return TF, Zin, Zout
        
    
#Print out the MillerCapInt Op Amp Theory
MillerCapIntOpAmp.Theory()
class MillerCapIntExp():
    """
    Class to provide GUI for  MillerCapInt
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.C1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              C1=self.C1Slider)
        display(I)
    
    def BackEnd(self, R1, C1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the MillerCapInt Topo
        TB=OnePortOpAmpTB(MillerCapIntOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,C1=10 muF and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'C1':C1*1e-12})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()
MillerCapIntExp()<jupyter_output><empty_output><jupyter_text>Miller Inductive Integrator<jupyter_code>class MillerIndIntOpAmp(SubCircuitFactory):
    """
    Inverting OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        L1[Henrys]
    """
    
    __name__='MillerIndIntOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, L1=1):
        super().__init__()
        self.R1=R1; self.L1=L1
        
        self.L('1', 'Vin', '2', L1@u_H)
        self.R('1', '2', 'Vout', R1@u_Ω)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', self.gnd, '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, L1=symbols('R_1, L_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, -R1/(s*L1))
        Zin=Eq(Zin, s*L1)
        Zout=simplify(Eq(Zout, Zo*(s*L1+R1)/(A*s*L1)))
        return TF, Zin, Zout
        
#Print out the MillerIndInt Op Amp Theory
MillerIndIntOpAmp.Theory()
class MillerIndIntExp():
    """
    Class to provide GUI for  MillerIndInt
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        self.L1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='L1 uH')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.L1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              L1=self.L1Slider)
        display(I)
    
    def BackEnd(self, R1, L1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the MillerCapInt Topo
        TB=OnePortOpAmpTB(MillerIndIntOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,L1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'L1':L1*1e-6})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()
MillerIndIntExp();<jupyter_output><empty_output><jupyter_text>Low Pass 1Pole<jupyter_code>class LowPass1POpAmp(SubCircuitFactory):
    """
    Single Pole Low Pass OpAmp SubCir

    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R2[Ohms]
        C1[Farads]
    """
    
    __name__='LowPass1POpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R2=1, C1=1):
        super().__init__()
        self.R1=R1; self.R2=R2; self.C1=C1
        
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        self.C('1', '2', 'Vout', C1@u_F)
        
        self.subcircuit(BasicOperationalAmplifier())
        #non, inv, out
        self.X('op', 'BasicOperationalAmplifier', 'Vin', '2', 'Vout')
        
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, R2, C1=symbols('R_1, R_2, C_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=simplify(Eq(H, -(R2/(R2*s*C1+1))/R1))
        Zin=Eq(Zin, R1)
        Zout=simplify(Eq(Zout, Zo*(R1+(R2/(R2*s*C1+1)))/(A*R1)))
        return TF, Zin, Zout
        

LowPass1POpAmp.Theory()
class LowPass1POpAmpExp():
    """
    Class to provide GUI for  LowPass1POpAmp
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         readout_format='.1e')
        
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider, self.C1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider,
                                  R2=self.R2Slider,
                              C1=self.C1Slider)
        display(I)
    
    def BackEnd(self, R1, R2, C1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the LowPass1POpAmp Topo
        TB=OnePortOpAmpTB(LowPass1POpAmp)
        #Setup the Testbench; use a R1=20 Ohm, R2=5 Ohm,C1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3, 'C1':C1*1e-12})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()


LowPass1POpAmpExp();<jupyter_output><empty_output><jupyter_text>Miller Capacitive Differentiator<jupyter_code>class MillerCapDiff(SubCircuitFactory):
    """
    Miller Capacitive Differentiator  OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        C1[Farads]
    """
    
    __name__='MillerCapDiff'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, C1=1):
        super().__init__()
        self.R1=R1; self.C1=C1
        
        self.C('1', 'Vin', '2', C1@u_F)
        self.R('1', '2', 'Vout', R1@u_Ω)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', self.gnd, '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, R2, C1=symbols('R_1, R_2, C_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, -R1/(1/(s*C1)))
        Zin=Eq(Zin, (1/(s*C1)))
        Zout=simplify(Eq(Zout, Zo*((1/(s*C1))+R1)/(A*(1/(s*C1)))))
        return TF, Zin, Zout
    
MillerCapDiff.Theory()
class MillerCapDiffExp():
    """
    Class to provide GUI for  MillerCapDiff
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.C1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              C1=self.C1Slider)
        display(I)
    
    def BackEnd(self, R1, C1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the MillerCapDiff Topo
        TB=OnePortOpAmpTB(MillerCapDiff)
        #Setup the Testbench; use a R1=20 Ohm,C1=10 muF and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'C1':C1*1e-12})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()
MillerCapDiffExp();<jupyter_output><empty_output><jupyter_text>Miller Inductive Differentiator<jupyter_code>class MillerIndDiff(SubCircuitFactory):
    """
    Miller Inductive Differentiator  OpAmp SubCir
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        L1[Henerys]
    """
    
    __name__='MillerIndDiff'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, L1=1):
        super().__init__()
        self.R1=R1; self.L1=L1
        
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.L('1', '2', 'Vout', L1@u_H)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', self.gnd, '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, R2, L1=symbols('R_1, R_2, L_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=Eq(H, -(s*L1)/R1)
        Zin=Eq(Zin, R1)
        Zout=Eq(Zout, Zo*(R1+(s*L1))/(A*R1))
        return TF, Zin, Zout
        
MillerIndDiff.Theory()
class MillerIndDiffExp():
    """
    Class to provide GUI for  MillerIndDiff
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        self.L1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='L1 uH')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.L1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              L1=self.L1Slider)
        display(I)
    
    def BackEnd(self, R1, L1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the MillerCapInt Topo
        TB=OnePortOpAmpTB(MillerIndDiff)
        #Setup the Testbench; use a R1=20 Ohm,L1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'L1':L1*1e-12})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()
MillerIndDiffExp();<jupyter_output><empty_output><jupyter_text>High Pass 1Zero<jupyter_code>class HighPass1ZOpAmp(SubCircuitFactory):
    """
    Single Pole Low Pass OpAmp SubCir

    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R2[Ohms]
        L1[Henerys]
    """
    
    __name__='HighPass1ZOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R2=1, L1=1):
        super().__init__()
        self.R1=R1; self.R2=R2; self.L1=L1
        
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        self.L('1', '2', 'Vout', L1@u_H)
        
        self.subcircuit(BasicOperationalAmplifier())
        #non, inv, out
        self.X('op', 'BasicOperationalAmplifier', 'Vin', '2', 'Vout')
        
    @staticmethod
    def Theory():
        """Analog Electronics: Circuits, Systems and Signal Processing 
        Crecraft Gergely"""        
        R1, R2, L1=symbols('R_1, R_2, L_1', real=True, postive=True)
        A,Zi, Zo, s=symbols('A, Z_i, Z_o s')
        H=Function('H')(s); Zin=Function('Z_in')(s); Zout=Function('Z_out')(s)
        TF=simplify(Eq(H, -((R2*s*L1)/(s*L1+R2))/R1))
        Zin=Eq(Zin, R1)
        Zout=simplify(Eq(Zout, Zo*(R1+((R2*s*L1)/(s*L1+R2)))/(A*R1)))
        return TF, Zin, Zout
        

HighPass1ZOpAmp.Theory()
class HighPass1ZExp():
    """
    Class to provide GUI for  HighPass1ZOpAmp
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         readout_format='.1e')
        
        self.L1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='L1 uH')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider, self.L1Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider,
                                  R2=self.R2Slider,
                              L1=self.L1Slider)
        display(I)
    
    def BackEnd(self, R1, R2, L1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the HighPass1ZOpAmp Topo
        TB=OnePortOpAmpTB(HighPass1ZOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,R2=5 Ohm, L1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3, 'L1':L1*1e-6})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()


HighPass1ZExp();<jupyter_output><empty_output><jupyter_text>AllPass (Phase) Filterhttp://www.analog.com/media/en/training-seminars/tutorials/MT-202.pdf  First Order Cap First<jupyter_code>class AllPass1CapFOpAmp(SubCircuitFactory):
    """
    AllPass 1st Order Cap First
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R2[Ohms]
        R3[Ohms]
        C1[Farads]
        
    """
    
    __name__='AllPass1CapFOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R2=1, R3=1, C1=1):
        super().__init__()
        self.R1=R1; self.R2=R2; self.R3=R3
        self.C1=C1
        
        #inverting feedback stucter
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        
        #Voltage Divider
        self.C('1', 'Vin', '3', C1@u_F)
        self.R('3', '3', self.gnd, R3@u_Ω)
        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', '3', '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        A, R1, R2, R3, C1=symbols('A, R_1, R_2, R_3, C_1', real=True, postive=True)
        Vn, Vp, Vo, Vi=symbols('V_n, V_p, V_o, V_i')
        s=symbols('s')
        VpEq=Eq(Vp, (s*C1*R3)/(1+s*C1*R3)* Vi); VpEq
        VnEq=Eq(Vn, (R1/(R1+R2))*Vo+(R2/(R1+R2))*Vi); VnEq
        VoEq=Eq(Vo, A*(Vp-Vn)); VoEq
        VoEq=VoEq.subs({VpEq.lhs: VpEq.rhs, VnEq.lhs:VnEq.rhs})
        H=Function('H')(s)
        TF=Eq(H, (solve(VoEq, Vo)[0]/Vi)); TF
        return TF

class AllPass1CapFExp():
    """
    Class to provide GUI for Inverting AllPass1CapF
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         )
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         )
        
        self.R3Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         )
        
        
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              R2=self.R2Slider, R3=self.R3Slider, C1=self.C1Slider)
        display(I)
    
    def BackEnd(self, R1, R2, R3, C1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the HighPass1ZOpAmp Topo
        TB=OnePortOpAmpTB(AllPass1CapFOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,R2=5 Ohm, L1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3, 'R3':R3*1e3, 'C1':C1*1e-9})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()

AllPass1CapFExp()<jupyter_output><empty_output><jupyter_text>First Order Cap Second<jupyter_code>class AllPass1CapSOpAmp(SubCircuitFactory):
    """
    AllPass 1st Order Cap Second
    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R2[Ohms]
        R3[Ohms]
        C1[Farads]
        
    """
    
    __name__='AllPass1CapSOpAmp'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R2=1, R3=1, C1=1):
        super().__init__()
        self.R1=R1; self.R2=R2; self.R3=R3
        self.C1=C1
        
        #inverting feedback stucter
        self.R('1', 'Vin', '2', R1@u_Ω)
        self.R('2', '2', 'Vout', R2@u_Ω)
        
        #Voltage Divider
        self.R('3', 'Vin', '3', R3@u_Ω)
        self.C('1', '3', self.gnd, C1@u_F)

        
        self.subcircuit(BasicOperationalAmplifier())
        self.X('op', 'BasicOperationalAmplifier', '3', '2', 'Vout')
        self.Theory()
    
    @staticmethod
    def Theory():
        A, R1, R2, R3, C1=symbols('A, R_1, R_2, R_3, C_1', real=True, postive=True)
        Vn, Vp, Vo, Vi=symbols('V_n, V_p, V_o, V_i')
        s=symbols('s')
        VpEq=simplify(Eq(Vp, ((1/(s*C1))/((1/s*C1 +R3)))* Vi)); VpEq
        VnEq=Eq(Vn, (R1/(R1+R2))*Vo+(R2/(R1+R2))*Vi); VnEq
        VoEq=Eq(Vo, A*(Vp-Vn)); VoEq
        VoEq=VoEq.subs({VpEq.lhs: VpEq.rhs, VnEq.lhs:VnEq.rhs})
        H=Function('H')(s)
        TF=Eq(H, (solve(VoEq, Vo)[0]/Vi)); TF
        return TF

AllPass1CapSOpAmp.Theory()
class AllPass1CapSExp():
    """
    Class to provide GUI for Inverting AllPass1CapS
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         )
        self.R2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         )
        
        self.R3Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R2 kOhm',
                                         )
        
        
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, R1=self.R1Slider, 
                              R2=self.R2Slider, R3=self.R3Slider, C1=self.C1Slider)
        display(I)
    
    def BackEnd(self, R1, R2, R3, C1):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the HighPass1ZOpAmp Topo
        TB=OnePortOpAmpTB(AllPass1CapSOpAmp)
        #Setup the Testbench; use a R1=20 Ohm,R2=5 Ohm, L1=10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R2':R2*1e3, 'R3':R3*1e3, 'C1':C1*1e-9})
        #Run the AC Bode Simulation
        TB.Simulate()
        #View Bode Simulation
        TB.PlotResults()

AllPass1CapSExp()<jupyter_output><empty_output><jupyter_text>Sallen-Key Filter[Analog Electronics: Circuits, Systems and Signal Processing Crecraft & Gergely](https://www.amazon.com/Analog-Electronics-Circuits-Systems-Processing-ebook/dp/B00CXO975A/ref=sr_1_1?ie=UTF8&qid=1524885102&sr=8-1&keywords=Analog+Electronics+Crecraft+Gergely) 10.6.2 $$G=\dfrac{A_V Y_1 Y_3}{Y_5(Y_1+Y_2+Y_3+Y_4)+Y_3(Y_1+Y_2+Y_4(1+A_V))}$$  Low Pass with Voltage Gain$$Y_1=R_1$$$$Y_2=0$$$$Y_3=R_3$$$$Y_4=sC_4$$$$Y_5=sC_5$$<jupyter_code>class LPSKV(SubCircuitFactory):
    """
    Low Pass Sallen-Key with Voltage Gain NonInverting Amp

    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R3[Ohms]
        C4[Farads]
        C5[Farads]
        RF1[Ohms]: NonInverting Feedback R1
        RF2[Ohms]: NonInverting Feedback R2
        
    """
    
    __name__='LPSKV'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R3=1, C4=1e-12, C5=1e-12, RF1=1, RF2=1):
        super().__init__()
        self.R1=R1; self.R3=R3; self.C4=C4; self.C5=C5
        self.RF1=RF1; self.RF2=RF2
        
        self.R('1', 'Vin', '1', R1@u_Ω)
        self.R('3', '1', '2', R3@u_Ω)
        self.C('4', '1', 'Vout', C4@u_F)
        self.C('5', '2', self.gnd, C5@u_F)
        
        
        self.subcircuit(NonInvertingOpAmp(R1=RF1, R2=RF2))
        self.X('Av', 'NonInvertingOpAmp', '2', 'Vout')
        
    
class LPSKVExp():
    """
    Class to provide GUI for  LPSKV
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        
        self.R3Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R5 kOhm',
                                         readout_format='.1e')
        
        self.C4Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C4 pF')
        
        self.C5Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C5 pF')
        
        self.RF1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF1 kOhm',
                                         readout_format='.1e')
        
        self.RF2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF2 kOhm',
                                         readout_format='.1e')
        
        
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R3Slider, 
                                  self.C4Slider, self.C5Slider,
                                 self.RF1Slider, self.RF2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, 
                                  R1=self.R1Slider, 
                                  R3=self.R3Slider, 
                                  C4=self.C4Slider, 
                                  C5=self.C5Slider, 
                                  RF1=self.RF1Slider, 
                                  RF2=self.RF2Slider)
        display(I)
    
    def BackEnd(self, R1, R3, C4, C5, RF1, RF2):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the LPSKV Topo
        TB=OnePortOpAmpTB(LPSKV)
        #Setup the Testbench; use a R1:20 Ohm,R2:5 Ohm, L1:10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R3':R3*1e3, 'C4':C4*1e-12, 'C5':C5*1e-12, 
                     'RF1':RF1*1e3, 'RF2':RF2*1e3})
        #Run the AC Bode Simulation
        TB.Simulate(fMax=10e9)
        #View Bode Simulation
        TB.PlotResults()

LPSKVExp();<jupyter_output><empty_output><jupyter_text>Band Pass with Voltage Gain$$Y_1=R_1$$$$Y_2=0$$$$Y_3=C_3$$$$Y_4=R_4$$$$Y_5=sC_5$$<jupyter_code>class BPSKV(SubCircuitFactory):
    """
    Band Pass Sallen-Key with Voltage Gain NonInverting Amp

    Termanals:
        Vin
        Vout
    Parms:
        R1[Ohms]
        R4[Ohms]
        R5[Ohms]
        C3[Farads]
        C5[Farads]
        RF1[Ohms]: NonInverting Feedback R1
        RF2[Ohms]: NonInverting Feedback R2
        
    """
    
    __name__='BPSKV'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R1=1, R4=1, R5=1, C3=1e-12, C5=1e-12, RF1=1, RF2=1):
        super().__init__()
        self.R1=R1; self.R4=R4; self.C3=C3; self.C5=C5
        self.RF1=RF1; self.RF2=RF2
        
        self.R('1', 'Vin', '1', R1@u_Ω)
        self.C('3', '1', '2', C3@u_F)
        self.R('4', '1', 'Vout', R4@u_Ω)
        self.C('5', '2', self.gnd, C5@u_F)
        self.R('5', '2', self.gnd, R5@u_Ω)
        
        
        self.subcircuit(NonInvertingOpAmp(R1=RF1, R2=RF2))
        self.X('Av', 'NonInvertingOpAmp', '2', 'Vout')
        
    
class BPSKVExp():
    """
    Class to provide GUI for  BPSKV
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R1 kOhm',
                                         readout_format='.1e')
        
        self.R4Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R4 kOhm',
                                         readout_format='.1e')
        self.R5Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R5 kOhm',
                                         readout_format='.1e')
        
        self.C3Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C3 pF')
        
        self.C5Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=5,
                                         description='C5 pF')
        
        self.RF1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF1 kOhm',
                                         readout_format='.1e')
        
        self.RF2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF2 kOhm',
                                         readout_format='.1e')
        
        
        #layout
        self.RSVBox=widgets.VBox([self.R1Slider, self.R4Slider, self.R5Slider, 
                                  self.C3Slider, self.C5Slider,
                                 self.RF1Slider, self.RF2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, 
                                  R1=self.R1Slider, 
                                  R4=self.R4Slider,
                                  R5=self.R5Slider, 
                                  C3=self.C3Slider, 
                                  C5=self.C5Slider, 
                                  RF1=self.RF1Slider, 
                                  RF2=self.RF2Slider)
        display(I)
    
    def BackEnd(self, R1, R4, R5, C3, C5, RF1, RF2):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the BPSKV Topo
        TB=OnePortOpAmpTB(BPSKV)
        #Setup the Testbench; use a R1:20 Ohm,R2:5 Ohm, L1:10 muH and print the TB
        TB.SetupCir(**{'R1':R1*1e3, 'R4':1e3, 'R5':1e3, 
                       'C3':C3*1e-12, 'C5':C5*1e-12, 
                     'RF1':RF1*1e3, 'RF2':RF2*1e3})
        #Run the AC Bode Simulation
        TB.Simulate(fMax=10e9)
        #View Bode Simulation
        TB.PlotResults()

BPSKVExp();<jupyter_output><empty_output><jupyter_text>HIgh Pass with Voltage Gain$$Y_1=sC_1$$$$Y_2=0$$$$Y_3=sC_3$$$$Y_4=R_4$$$$Y_5=R_5$$<jupyter_code>class HPSKV(SubCircuitFactory):
    """
    High Pass Sallen-Key with Voltage Gain NonInverting Amp

    Termanals:
        Vin
        Vout
    Parms:
        R4[Ohms]
        R5[Ohms]
        C1[Farads]
        C3[Farads]
        RF1[Ohms]: NonInverting Feedback R1
        RF2[Ohms]: NonInverting Feedback R2
        
    """
    
    __name__='HPSKV'
    __nodes__=('Vin','Vout')
    
    def __init__(self, R4=1, R5=1, C1=1e-12, C3=1e-12, RF1=1, RF2=1):
        super().__init__()
        self.R4=R4; self.R5=R5; self.C1=C1; self.C3=C3
        self.RF1=RF1; self.RF2=RF2
        
        self.C('1', 'Vin', '1', C1@u_F)
        self.C('3', '1', '2', C3@u_F)
        self.R('4', '1', 'Vout', R4@u_Ω)
        self.R('5', '2', self.gnd, R5@u_Ω)
        
        
        self.subcircuit(NonInvertingOpAmp(R1=RF1, R2=RF2))
        self.X('Av', 'NonInvertingOpAmp', '2', 'Vout')
        
    
class HPSKVExp():
    """
    Class to provide GUI for  HPSKV
    """
    def __init__(self):
        """
        Front end and binding to backend
        """
        #create the GUI elments
        self.R4Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R4 kOhm',
                                         readout_format='.1e')
        
        
        self.R5Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='R5 kOhm',
                                         readout_format='.1e')
        
        self.C1Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=25,
                                         description='C1 pF')
        
        self.C3Slider=widgets.FloatSlider(value=50,
                                         min=1, max=500, step=5,
                                         description='C5 pF')
        
        self.RF1Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF1 kOhm',
                                         readout_format='.1e')
        
        self.RF2Slider=widgets.FloatSlider(value=50,
                                         min=10, max=100, step=5,
                                         description='RF2 kOhm',
                                         readout_format='.1e')
        
        
        #layout
        self.RSVBox=widgets.VBox([self.R4Slider, self.R5Slider,
                                  self.C1Slider, self.C3Slider,
                                 self.RF1Slider, self.RF2Slider])
        
        #bind to the backend
        I=widgets.interact_manual(self.BackEnd, 
                                  R4=self.R4Slider,
                                  R5=self.R5Slider, 
                                  C1=self.C1Slider, 
                                  C3=self.C3Slider, 
                                  RF1=self.RF1Slider, 
                                  RF2=self.RF2Slider)
        
        display(I)
    
    def BackEnd(self, R4, R5, C1, C3, RF1, RF2):
        """
        The backend wrapper to the TB and simulation
        """
        
        #create the Test Bench and Bind to this instance the LPSKV Topo
        TB=OnePortOpAmpTB(HPSKV)
        #Setup the Testbench; use a R1:20 Ohm,R2:5 Ohm, L1:10 muH and print the TB
        TB.SetupCir(**{'R4':R4*1e3, 'R5':R5*1e3, 'C1':C1*1e-12, 'C3':C3*1e-12, 
                     'RF1':RF1*1e3, 'RF2':RF2*1e3})
        #Run the AC Bode Simulation
        TB.Simulate(fMax=10e9)
        #View Bode Simulation
        TB.PlotResults()
HPSKVExp();<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12455028267945863, 'fraction_numerical': 0.03405478461157749, 'mean_word_length': 1.8103568180602365, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 75, 'https://': 7, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 263, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '118861', 'license': 'MIT', 'n_tokens_mistral': 18651, 'n_tokens_neox': 17753, 'n_words': 3416, 'path': 'Operational AmplifierTopologies/.ipynb_checkpoints/OpAmpLearn-checkpoint.ipynb', 'repo_name': 'PyLCARS/PySpiceExsamples', 'size': '52562'}