From daa5a6695c72353a24d615aca34b29f3f3683e1c Mon Sep 17 00:00:00 2001 From: John Garrett Date: Sun, 10 Mar 2019 12:00:57 +0000 Subject: [PATCH] Minor changes to docstrings [ci skip] --- qmix/circuit.py | 104 +++++++++++++++++++++++------------------------- qmix/respfn.py | 96 ++++++++++++++++++++++++-------------------- 2 files changed, 102 insertions(+), 98 deletions(-) diff --git a/qmix/circuit.py b/qmix/circuit.py index 044d50d..f0b1e21 100644 --- a/qmix/circuit.py +++ b/qmix/circuit.py @@ -6,8 +6,8 @@ In experimental systems, SIS junctions are embedded within complex RF networks. These networks are referred to as the embedding circuit. Since all of the components in these embedding circuits are **linear**, the - embedding circuit can be reduced to a **Thevenin equivalent circuit** for - **each tone and harmonic.** + embedding circuit can be reduced to a **Thevenin equivalent circuit**, with + one for **each tone and harmonic.** To fully describe the embedding circuit, 3 bits of information are needed for each signal that is applied to the junction: @@ -53,7 +53,7 @@ class EmbeddingCircuit(object): set manually. In this way, this class is sort of like a fancy struct. The class attributes that have to be set manually are: - - ``vph``: photon voltage (freq / gap freq) + - ``vph``: photon voltage (normalized to the gap voltage) - ``vt``: Thevenin voltage (normalized to the gap voltage) - ``zt``: Thevenin impedance (normalized to the normal resistance) @@ -62,38 +62,33 @@ class EmbeddingCircuit(object): Example: - To create an instance of the embedding circuit class with 2 tones and - 3 harmonices: + Here we will create an instance of the embedding circuit class with + 2 tones and 3 harmonics: >>> cct1 = EmbeddingCircuit(2, 3, name='Test 1') >>> print(cct1) Embedding circuit (Tones:2, Harmonics:3): Test 1 - Once initialized, you can begin defining the properties of the + Once initialized, we can begin defining the properties of the embedding circuit. I normally start with the photon voltages (or, equivalently, the normalized frequencies): >>> cct1.vph[1] = 0.30 # first tone >>> cct1.vph[2] = 0.32 # second tone - Then, you have to set the voltages and impedances for all of the + Then, we have to set the voltages and impedances for all of the different signals. For example, for the 1st harmonic of the 1st tone: >>> cct1.vt[1,1] = 0.5 # Thevenin voltage >>> cct1.zt[1,1] = 0.3 + 1j * 0.1 # Thevenin impedance - If you would like the ability to use non-normalized values (e.g., set - the available power of a signal in units [W]), you need to define the - properties of the junction during initialization. For example: + This has to be done for each signal (a total of 6 times in this case). - >>> cct2 = EmbeddingCircuit(1, 1, vgap=2.8e-3, rn=14.) - - Note that you only need to define either the gap voltage or the gap - frequency since they can be calculated from each other. + In order to use non-normalized values (e.g., set the available power of + a signal in units [W]), we need to define the electrical properties of + the junction during initialization. For example: - >>> fgap = cct2.fgap - >>> round(fgap / 1e9) # to display in [GHz] - 677 + >>> cct2 = EmbeddingCircuit(1, 1, vgap=2.8e-3, rn=14.) You can now set the photon voltage using the frequency of the applied signal. E.g.: @@ -115,17 +110,19 @@ class EmbeddingCircuit(object): -50.0 Args: - num_f (int, optional, default is 1): Number of fundamental frequencies (tones) - applied to the junction. - num_p (int, optional, default is 1): Number of harmonics included for each tone. + num_f (int, optional, default is 1): Number of fundamental frequencies + (tones) applied to the junction. + num_p (int, optional, default is 1): Number of harmonics included for + each tone. vb_min (float, optional, default is 0): Minimum bias voltage for array. vb_max (float, optional, default is 2): Maximum bias voltage for array. - vb_npts (int, optional, default is 201): Number of bias voltage points for array. - fgap (float, optional): Gap frequency of the junction in units [Hz]. This is - equal to ``e*Vgap/h``, where ``e`` is the charge of an electron, - ``Vgap`` is the gap voltage, and ``h`` is the Planck constant. - ``fgap`` is used to normalize and de-normalize frequency values - (that't it). + vb_npts (int, optional, default is 201): Number of points in bias + voltage sweep. + fgap (float, optional): Gap frequency of the junction in units [Hz]. + This is equal to ``e*Vgap/h``, where ``e`` is the charge of an + electron, ``Vgap`` is the gap voltage, and ``h`` is the Planck + constant. ``fgap`` is used to normalize and de-normalize frequency + values (that't it). vgap (float, optional): Gap voltage of the junction in units [V]. This is the voltage where the sharp non-linearity in the DC I-V curve occurs (a.k.a., the transition voltage). @@ -144,7 +141,7 @@ class EmbeddingCircuit(object): frequency of the fundamental tone, and ``e`` is the charge of an electron. However, since this value is normalized to the gap voltage, the photon voltage is also equal to the normalized - frequency: ``f/fgap``, where ``fgap`` is the gap frequency. Note + frequency, ``f/fgap``, where ``fgap`` is the gap frequency. Note that this array is 1-based, meaning that the photon voltage of the 1st tone is located in ``.vph[1]``. (The index represents the tone number.) **This attribute must be set after initialization!** @@ -269,9 +266,8 @@ def initialize_vj(self): saved within this class, but it is okay for this class to initialize ``vj`` since it has all the data about what the matrix sizes should be. - This function is useful when the embedding impedances aren't included, - and you want to set the voltage across the junction manually (skipping - harmonic balance). + This function is useful when you want to set the voltage across the + junction directly (skipping the harmonic balance procedure). Returns: ndarray: An empty matrix for the junction voltage @@ -281,7 +277,7 @@ def initialize_vj(self): return np.zeros((self.num_f + 1, self.num_p + 1, self.vb_npts), dtype=complex) def available_power(self, f=1, p=1, units='W'): - """ Return available power of tone f and harmonic p. + """Return available power of tone ``f`` and harmonic ``p``. Note: @@ -292,7 +288,7 @@ def available_power(self, f=1, p=1, units='W'): f (int, optional, default is 1): Tone index number. p (int, optional, default is 1): Harmonic index number. units (str, optional, default is 'W'): Units for power. One of 'W', - 'mW', 'uW', 'nW', 'pW', 'fW', 'dBm', or 'dBW'. + 'mW', 'uW', 'nW', 'pW', 'fW', 'dBm', or 'dBW'. Returns: float: Available power in specified units @@ -327,7 +323,10 @@ def available_power(self, f=1, p=1, units='W'): raise ValueError('Not a recognized unit for power.') def set_available_power(self, power, f=1, p=1, units='W'): - """ Set available power of tone f and harmonic p. + """Set available power of tone ``f`` and harmonic ``p``. + + This method will set the Thevenin voltage in order to provide the + correct power level. Note: @@ -376,17 +375,11 @@ def set_available_power(self, power, f=1, p=1, units='W'): self.vt[f, p] = volt_v / self.vgap def set_alpha(self, alpha, f=1, p=1, zj=0.66): - """ Set the drive level of tone f and harmonic p (approximately). + """Set the drive level of tone ``f`` and harmonic ``p`` (approximate). This method guesses what the Thevenin voltage should be in order to get - the desired drive level. E.g.: - - >>> cct = EmbeddingCircuit(1, 1, vgap=2.8e-3, rn=14.) - >>> cct.vph[1] = 0.3 - >>> cct.zt[1,1] = 0.5 - >>> cct.set_alpha(1., f=1, p=1, zj=2/3.) - - You won't actually know the drive level until you run the simulation. + the desired drive level, but you won't actually know what the drive + level is until you run the simulation. Note: @@ -409,10 +402,10 @@ def set_alpha(self, alpha, f=1, p=1, zj=0.66): self.vt[f, p] = alpha * self.vph[f] * (self.zt[f, p] / zj + 1) def set_vph(self, value, f=1, units='Hz'): - """ Set photon voltage of tone f. + """Set the photon voltage of tone ``f``. - This method sets the normalized photon voltage of tone f. Normally, - this can be done by setting the value of the attribute directly. E.g.: + Normally, this can be done by setting the value of the attribute + directly. E.g.: >>> cct = EmbeddingCircuit(1, 1, vgap=2.8e-3, rn=14.) >>> cct.vph[1] = 0.5 @@ -420,7 +413,9 @@ def set_vph(self, value, f=1, units='Hz'): However, if you would instead like to use non-normalized units, this method can be very handy. E.g.: - >>> cct.set_vph(700, f=1, units='GHz') + >>> cct.set_vph(350, f=1, units='GHz') + >>> round(cct.vph[1], 2) + 0.52 Note: @@ -474,9 +469,7 @@ def set_name(self, name, f=1, p=1): self.comment[f][p] = name def print_info(self): - """ Print information about the embedding circuit to the terminal. - - """ + """Print information about the embedding circuit to the terminal.""" print(self) @@ -517,8 +510,11 @@ def print_info(self): def save_info(self, filename='embedding-circuit.txt'): """Save this embedding circuit to a text file. + This text file can then be read in by ``read_circuit`` in order to + regenerate the embedding circuit. + Args: - filename (string): Filename for information file + filename (string): Filename for embedding circuit file """ @@ -567,14 +563,14 @@ def unlock(self): def read_circuit(filename): - """Build embedding circuit from an embedding circuit file. + """Build an embedding circuit from an embedding circuit file. - This function will build an instance of the EmbeddingCircuit class + This function will build an instance of the ``EmbeddingCircuit`` class based on a file previously generated by the - ``EmbeddingCircuit.save_info()`` method. + ``EmbeddingCircuit.save_info`` method. Args: - filename (str): filename + filename (str): filename of the embedding circuit file Returns: qmix.circuit.EmbeddingCircuit: instance of the embedding circuit class diff --git a/qmix/respfn.py b/qmix/respfn.py index fa4e09d..033d702 100644 --- a/qmix/respfn.py +++ b/qmix/respfn.py @@ -1,15 +1,15 @@ -""" This module contains classes to represent the response function of the +"""This module contains classes to represent the response function of the SIS junction. There are several different types of response function classes: - - Response functions generated directly from voltage and current data: + - Response functions generated directly from I-V data: - ``RespFn``: This is the base class for all of the other response function classes. This class will generate a response function based on a DC I-V curve (i.e., DC voltage and current data). Note that this class assumes that you have "pre-processed" the data. This means - that it will use voltage and current data to generate the + that it will use the voltage and current data to generate the interpolation directly. Normally, you want to have more data points around curvier regions in order to minimize how much time the interpolation takes. If you haven't done this, it is a good idea to use @@ -20,18 +20,22 @@ ``RespFn``, this class will resample the response function in order to optimize the interpolation. - - Response functions generated from mathematical models: + - Response functions generated from I-V curve models: - ``RespFnPerfect``: This class will generate a response function based on an ideal DC I-V curve (i.e., the subgap current is exactly zero below the gap voltage and exactly equal to the bias voltage above the gap, assuming normalized values). This DC I-V curve has an infinitely - sharp transition. + sharp transition. Note however that you can smear the transition using + the ``v_smear`` argument. This will convolve the ideal reasponse + function with a Gaussian distribution, allowing you to control the + sharpness of the transition. - ``RespFnPolynomial``: This class will generate a response function - based on the polynomial model from Kennedy (1999). This class can be - used to simulate the effect of the transition's sharpness (i.e., how do - the results change when the gap is more or less sharp). + based on the polynomial model from Kennedy (1999). The order of the + polynomial controls how sharp the transition is, so this class can be + used to simulate the effect of the transition's sharpness (i.e., how + do the results change when the gap is more or less sharp). - ``RespFnExponential``: This class will generate a response function based on the exponential model from Rashid et al. (2016). This model is @@ -188,10 +192,11 @@ def __init__(self, voltage, current, **params): def plot_interpolation(self, fig_name=None, ax=None): # pragma: no cover """Plot the interpolation of the response function. - Note: If ``fig_name`` is defined, this method will not return the - figure axis. It will instead close the figure, to ensure that there - aren't too many figures open at the same time (a common problem when - saving many figures at the same time). + Note: If ``fig_name`` is provided, this method will save the plot + to the specified folder and then close the plot. This means + that the Matplotlib axis object will not be returned in this + case. This is done to prevent too many plots from being open + at the time. Args: fig_name (str, default is None): name of figure file name, if you @@ -241,12 +246,11 @@ def plot_interpolation(self, fig_name=None, ax=None): # pragma: no cover def show_current(self, fig_name=None, ax=None): # pragma: no cover """Plot the interpolation of the response function. - This method can be used to check the interpolation of the response - function. - - Note: If ``fig_name`` is defined, this method will save the figure - in the specified file. Otherwise, this method will return the - Matplotlib axis. + Note: If ``fig_name`` is provided, this method will save the plot + to the specified folder and then close the plot. This means + that the Matplotlib axis object will not be returned in this + case. This is done to prevent too many plots from being open + at the time. Warning: @@ -263,9 +267,11 @@ def show_current(self, fig_name=None, ax=None): # pragma: no cover return self.plot_interpolation(fig_name, ax) def idc(self, vbias): - """Interpolate the DC I-V curve at the given bias voltage. + """Interpolate the DC I-V curve. - This is the imaginary component of the respones function. + This is the imaginary component of the respones function, and it is + used to calculate the quasiparticle tunneling currents in + ``qmix.qtcurrent.qtcurrent``. Args: vbias (ndarray): Bias voltage (normalized) @@ -281,7 +287,9 @@ def ikk(self, vbias): """Interpolate the Kramers-Kronig transform of the DC I-V curve at the given bias voltage. - This is the real component of the response function. + This is the real component of the response function, and it is + used to calculate the quasiparticle tunneling currents in + ``qmix.qtcurrent.qtcurrent``. Args: vbias (ndarray): Bias voltage (normalized) @@ -302,9 +310,9 @@ def didc(self, vbias): Note: - This method is not used by QMix, but it can be useful if you are - calculating the tunneling currents using Tucker theory (Tucker and - Feldman, 1985). + This method is not used directly by QMix, but it can be useful if + you are calculating the tunneling currents using Tucker theory + (Tucker and Feldman, 1985). Args: vbias (ndarray): Bias voltage (normalized) @@ -317,8 +325,7 @@ def didc(self, vbias): return self._f_didc(vbias) def dikk(self, vbias): - """Interpolate the derivative of the Kramers-Kronig transform of the DC - I-V curve at the given bias voltage. + """Interpolate the derivative of the Kramers-Kronig transform. This is defined as ``d(ikk) / d(vb)`` where ``ikk`` is the Kramers- Kronig transform of the DC tunneling current and ``vb`` is the bias @@ -326,9 +333,9 @@ def dikk(self, vbias): Note: - This method is not used by QMix, but it can be useful if you are - calculating the tunneling currents using Tucker theory (Tucker and - Feldman, 1985). + This method is not used directly by QMix, but it can be useful if + you are calculating the tunneling currents using Tucker theory + (Tucker and Feldman, 1985). Args: vbias (ndarray): Bias voltage (normalized) @@ -341,27 +348,27 @@ def dikk(self, vbias): return self._f_dikk(vbias) def resp(self, vbias): - """Interpolate the response function current at the given bias voltage. + """Interpolate the response function. Args: vbias (ndarray): Bias voltage (normalized) Returns: - ndarray: Response function current (complex value) + ndarray: Response function (a complex value) """ return self._f_ikk(vbias) + 1j * self._f_idc(vbias) def resp_conj(self, vbias): - """Interpolate the complex conjugate of the response function current - at the given bias voltage. + """Interpolate the complex conjugate of the response function + . Note: - This method is not used by QMix, but it can be useful if you are - calculating the tunneling currents using Tucker theory (Tucker and - Feldman, 1985). + This method is not used directly by QMix, but it can be useful if + you are calculating the tunneling currents using Tucker theory + (Tucker and Feldman, 1985). This method is included because it might be *slightly* faster than ``np.conj(resp.resp(vb))`` where ``resp`` is an instance of this @@ -371,21 +378,21 @@ def resp_conj(self, vbias): vbias (ndarray): Bias voltage (normalized) Returns: - ndarray: Conjugate of the response function current + ndarray: Complex conjugate of the response function """ return self._f_ikk(vbias) - 1j * self._f_idc(vbias) def resp_swap(self, vbias): - """Interpolate the response function current, with the real and - imaginary components swapped, at the given bias voltage. + """Interpolate the response function, with the real and imaginary + components swapped,. Note: - This method is not used by QMix, but it can be useful if you are - calculating the tunneling currents using Tucker theory (Tucker and - Feldman, 1985). + This method is not used directly by QMix, but it can be useful if + you are calculating the tunneling currents using Tucker theory + (Tucker and Feldman, 1985). This method is included because it might be *slightly* faster than ``1j * np.conj(resp.resp(vb))`` where ``resp`` is an instance of @@ -396,7 +403,8 @@ def resp_swap(self, vbias): vbias (ndarray): Bias voltage (normalized) Returns: - ndarray: Response function current with real and imaginary swapped + ndarray: Response function with the real and imaginary components + swapped """ @@ -505,7 +513,7 @@ class RespFnExponential(RespFn): Class to contain, interpolate and plot the response function. - Ref: + Reference: H. Rashid, et al., "Harmonic and reactive behavior of the quasiparticle tunnel current in SIS junctions," AIP Advances,