Metadata-Version: 2.4
Name: fwdd
Version: 0.1.0
Summary: Finite Width Dynamical Decoupling (FWDD) implements Dynamical Decoupling considering the effects of Finite Pulse Widths.
Author-email: Noah Huffman <nonohuff@gmail.com>
License: MIT License
        
        Copyright (c) 2025 nonohuff
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/nonohuff/FWDD/tree/main
Project-URL: Repository, https://github.com/nonohuff/FWDD/tree/main
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.22.0
Requires-Dist: scipy>=1.8.0
Requires-Dist: pandas>=1.4.0
Requires-Dist: matplotlib>=3.5.0
Requires-Dist: seaborn>=0.11.0
Requires-Dist: numba>=0.55.0
Requires-Dist: scikit-learn>=1.0.0
Requires-Dist: scikit-optimize>=0.9.0
Requires-Dist: tqdm>=4.60.0
Requires-Dist: joblib>=1.1.0
Requires-Dist: psutil>=5.8.0
Dynamic: license-file

# FWDD
FWDD (Finite Width Dynamical Decoupling) implements Dynamical Decoupling considering the effects of FInite Pulse Widths. All times in the tutorials use microseconds $(\mu s)$. 

The code presented here is used in the paper [Quantum sensing with a spin ensemble in a two-dimensional material](http://arxiv.org/abs/2509.08984) to predict noise spectra.

# Installation

You can install `fwdd` via `pip` or `conda` (from Conda-forge).

## Via pip
```bash
pip install fwdd
```

## Via conda (Conda-forge)
```bash
conda install -c conda-forge fwdd
```

## Local Development & Tutorials
If you are running the tutorial notebooks locally and want to make live changes, run an editable installation:
```bash
git clone https://github.com/nonohuff/FWDD.git
cd FWDD
pip install -e .
```

# Quick Start
Here is how you can import the core modules of `fwdd` in your python code:
```python
from fwdd import filter_function as ff
from fwdd import noise_spectra as ns
from fwdd import coherence_profile as cp
from fwdd import noise_learning_fitting as nlf
from fwdd import fitting_utils as fu
```

# Coherence-Noise Relationship

A given dynamical decoupling pulse sequence of $N$ pulses (e.g. CPMG, XY8) yields a corresponding filter function, $F_N(\omega, t)$, which is related to the coherence decay as follows:

$$
\begin{align}
C_N(t) = e^{-\chi_N(t)}, \quad \chi(t) = (t/T_{2})^\beta, \\
\chi_N(t) = \frac{1}{\pi} \int _{0}^{\infty} d\omega S(\omega) \frac{F_N(\omega,t)}{\omega^2}
\end{align}
$$

Here, $C_N(t)$ is the coherence decay as a function of time characterized by two important parameters: $T_2$ - coherence time and $\beta$ - stretch factor. $F_N(\omega,t)$ is a filer function defined by the dynamical decoupling pulse sequence, and $S(\omega)$ is the power spectral density of the underlying noise (standard units $\frac{Hz^2}{Hz}$). 

## Delta Function Approximation

If $F_N(\omega,t)$ is approximated as a $\delta$ function peaked at $\omega_0 =\pi N/T$, where the total experiment time, $T=2N\tau+Nt_{\pi}$, $2\tau$ being the wait time between the pulses and $t_{\pi}$ is the pulse width. Then, the integral above is trival to invert and we have:

$$
\begin{equation}
    S(\omega) = -\pi \frac{ln(C_N(T))}{T}.
\end{equation}
$$

This approximation holds true when the $\pi$-pulses are themselves much shorter compared to the delay between them and as a consequence the coherence time, $T_2$.

## Finite-width Pulses

When the length of the $\pi$-pulse becomes a sizable fraction of the delay (or $T_2$), such a $\delta$ approximation cannot be made. In that case, the filter function needs to be modified to accommodate for the finite pulse duration and can be expressed as:

$$
F_{N}(\omega,T)=\left|1+(-1)^{N+1}e^{i\omega T} +2\sum_{k=1}^N(-1)^ke^{i\omega t_{k}}\cos\left(\frac{\omega t_{\pi}}{2}\right)\right|^{2}
$$

Where $t_k$ is the time corresponding to the center of the $k^{th}$ pulse, and $t_{\pi}$ is the pulse width.

# Tutorial Notebooks

We have included several tutorial notebooks to make adapting this code to your purposes easier. They cover how we implement noise spectral densities, $S(\omega)$, the finite-width filter function, coherence profile, $C_N(t)$, and finally, how we go about fitting noise profiles to observed $C_N(t)$ data (and how to do it for you own data/noise models!). The reccomended viewwing of these notebooks are. 

`noise_tutorial.ipynb` -> `filter_function_tutorial.ipynb` -> `coherence_profile_tutorial.ipynb` -> `noise_learning_fitting.ipynb`

# Conventions
* $\omega = 2 \pi f$
* $t = \frac{1}{f}$
* Time varibles assume microseconds, so `tau_p = 0.024` means $0.024 \mu s$ or $24 ns$ 
