Skip to main content

Provides algorithm for photo thermal interferometry and 3x3 couplers

Project description

MiniPTI

flowchart

In this library the python implementation of the algorithm from Waveguide based passively demodulated photothermal interferometer for light absorption measurements is provided.

The library can be split into sub-libraries:

1. Interferometry

The Interferometry library provides algorithms to characterise a 3x3 coupler interferometer (calculating the output phases, amplitudes and offsets of the output DC-signals) for any given, measured DC-signals. It also contains an API for calculating the current phase of the interferometer for given DC signals.

Note that this library is primarily designed for 3x3 couplers, but it can be easily extended for every amount of outputs.

2. PTI

PTI, short for Photo Thermal Inversion, provided the PTI-related algorithm from the mentioned paper above. They include an algorithm for common mode noise rejection of high-resolution AC signals, decimation and the actual PTI inversion.

Note that both sub-libraries provide only offline routines. Future versions will be provided as well routines for live data.

A basic structure of the libraries with their classes is shown in the picture above from the mentioned paper.

The picture below shows the basic file structure and the public members of the classes.

flowchart

Decimation

The measured data for decimation is in binary file format generated from LabView. It is good practice to use the decimation object with the with statement so that the binary fill will automatically be closed. Note that as the binary file itself can be very large (up to GB) the decimation will read the file chunk-wise. read_data reads a block of 50'000 samples of data and decodes them into NumPy arrays. The call of the decimation will then process the algorithms described in [1].

from collections import defaultdict

import pandas as pd
import minipti

binary_file = "data.bin"
output_data = defaultdict(list)
for i in range(3):
    output_data[f"DC CH{i + 1}"].append("s")
    output_data[f"Lock In Amplitude CH{i + 1}"].append("V")
    output_data[f"Lock In Phase CH{i + 1}"].append("rad")
with minipti.pti.Decimation(binary_file) as decimation:
    while decimation.read_data():
        decimation()
    for i in range(3):
        output_data[f"DC CH{i + 1}"].append(decimation.dc_down_sampled[i])
        output_data[f"Lock In Amplitude CH{i}"].append(decimation.lock_in.amplitude[i])
        output_data[f"Lock In Phase CH{i}"].append(decimation.lock_in.phase[i])
pd.DataFrame(output_data).to_csv("Decimation.csv")

Interferometry

The interferometry provides an API for calculating the interferometric phase and characterising the interferometer (output phases, amplitudes and offsets). For proper use, it is needed to provide a configuration file. An example of such a file can be found in src/configs/settings.csv. There are also settings files for other couplers and experiments.

Calculating the interferometric Phase

import minipti
import pandas as pd

interferometer = minipti.interferometry.Interferometer()

interferometer.settings_file_path = "configs/settings.csv"
interferometer.decimation_filepath = "data/Decimation_Commercial.csv"
interferometer.init_settings()
data = pd.read_csv("data/Decimation_Commercial.csv")

dc_signals = data[[f"DC CH{i}" for i in range(1, 4)]].to_numpy()

interferometer.calculate_offsets(dc_signals)  # Estimate offsets
interferometer.calculate_amplitudes(dc_signals)  # Estimate amplitudes
interferometer.calculate_phase(dc_signals)

Characterising the Interferometer

The characterisation uses an interferometer object, as well as the PTI Inversion. The accessed fields (output_phases, amplitudes and offsets) are threadsafe via locks. If no output phases, amplitudes or offsets are known, the field use_settings can be set to False. In this case, the settings will ignore and the parameters will be found by repeating of calculating the interferometric phase and parameters.

characterization itself saves the data directly to data/Characterization.csv if you use the provided wrappers.

import minipti

interferometer = minipti.interferometry.Interferometer()
interferometer.settings_file_path = "configs/settings.csv"
interferometer.decimation_filepath = "data/Decimation_Commercial.csv"
interferometer.init_settings()

characterization = minipti.interferometry.Characterization()
characterization(mode="offline")

characterization.use_settings = False
characterization(mode="offline")

Direct usage of API

import minipti
import pandas as pd

interferometer = minipti.interferometry.Interferometer()
dc_signals = pd.read_csv("data/Decimation_Commercial.csv")
characterization = minipti.interferometry.Characterization()
interferometer.settings_path = "configs/settings.csv"
characterization.signals = dc_signals[[f"DC CH{i}" for i in range(1, 4)]].to_numpy()
interferometer.init_settings()

# Without knowing any parameter
characterization.use_settings = False
characterization.iterate_characterization(characterization.signals.T)

# With knowing the parameters and already calculated phases
phases = pd.read_csv("data/PTI_Inversion_Commercial.csv")
characterization.phases = phases["Interferometric Phase"]
characterization.characterise_interferometer()

PTI Inversion

The PTI inversion algorithms can be applied from a call to the functor or by calling the single function by itself. The first one is recommended if it is needed to run the whole procedure based on Decimation-Files. The second gives access to the actual API.

import minipti

interferometer = minipti.interferometry.Interferometer()
interferometer.decimation_filepath = "data/Decimation_Commercial.csv"
interferometer.settings_path = "configs/settings.csv"
interferometer.init_settings()
inversion = minipti.pti.Inversion(interferometer=interferometer)
inversion(mode="offline")

Direct Usage of API

import pandas as pd
import minipti

interferometer = minipti.interferometry.Interferometer()
interferometer.decimation_filepath = "data/Decimation_Commercial.csv"
interferometer.settings_path = "configs/settings.csv"
interferometer.init_settings()
data = pd.read_csv("data/Decimation_Commercial.csv")

inversion = minipti.pti.Inversion(interferometer=interferometer)

dc_signals = data[[f"DC CH{i}" for i in range(1, 4)]].to_numpy()
amplitudes = data[[f"Lock In Amplitude CH{i}" for i in range(1, 4)]].to_numpy().T
inversion.lock_in.amplitude = amplitudes
inversion.lock_in.phase = data[[f"Lock In Phase CH{i}" for i in range(1, 4)]].to_numpy().T

interferometer.calculate_phase(dc_signals)
inversion.calculate_sensitivity()
inversion.calculate_pti_signal()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minipti-1.0.tar.gz (11.3 kB view hashes)

Uploaded Source

Built Distribution

minipti-1.0-py3-none-any.whl (10.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page