This repository provides the Flask back‑end for the Raston Lab Virtual FTMW Spectrometer.
git clone https://github.com/FTMW-Scientific-Simulator/Virtual-FTMW-Spectrometer
cd Virtual-FTMW-Functions
python3 -m venv .venv
pip install -r requirements.txt
python app.py
-
app.py
-
Initializes a Flask application with CORS enabled.
-
Reads
version.txt
(if present) and exposes it viaapp.config["VERSION"]
. -
Defines three routes:
-
GET /
- Returns a simple HTML title showing the API name and version.
-
POST /acquire_spectrum
- Parses incoming JSON parameters and forwards them to
acquire_spectra
inacquire_spectra.py
. - Returns JSON with success status and arrays of X and Y values.
- Parses incoming JSON parameters and forwards them to
-
POST /find_peaks
- Parses incoming JSON containing
x
,y
, andthreshold
, then callsfind_peaks
inacquire_spectra.py
. - Returns JSON with success status and a mapping of peak frequencies to intensities.
- Parses incoming JSON containing
-
-
When run as a script, listens on
0.0.0.0:5001
(debug off by default).
-
-
acquire_spectra_utils.py
-
Contains helper functions shared by acquisition and peak‑finding logic:
-
get_datafile(molecule, directory="linelists")
- Maps a molecule string to a local data filename and returns its full path.
- Raises
ValueError
if no mapping exists.
-
param_check(params)
- Verifies that the incoming parameter dictionary has exactly the expected keys and no null values.
- Returns
True
if all checks pass, otherwiseFalse
.
-
lorentzian_profile(grid, center, fwhm)
- Generates a Lorentzian line shape on
grid
, centered atcenter
with given full width at half maximum.
- Generates a Lorentzian line shape on
-
add_white_noise(spectrum, num_cycles_per_step, is_cavity_mode)
- Adds Gaussian noise scaled by
num_cycles_per_step
; uses different noise levels for cavity mode.
- Adds Gaussian noise scaled by
-
apply_cavity_mode_response(params, frequency_grid, spectrum, v_res=8206.4, Q=10000, Pmax=1.0)
- Applies one or more cavity‑mode filter functions to
spectrum
, based onacquisitionType
. - Adds white noise to the cavity response before multiplying it into the spectrum.
- Applies one or more cavity‑mode filter functions to
-
-
-
acquire_spectra.py
-
Implements two main functions:
-
acquire_spectra(params, window=25, resolution=0.001, fwhm=0.007, Q=10000, Pmax=1.0)
-
Validates
params
withparam_check
. Returns error JSON if invalid. -
Extracts molecule name and resolution parameter
vres
. -
Loads line list data via
get_datafile
, reads into a DataFrame, and filters by frequency bounds. -
For each spectral line:
- Builds a local frequency grid around the line center ±
window
. - Computes two Lorentzian components (Doppler‑shifted split peaks).
- Sums them into a local spectrum.
- Builds a local frequency grid around the line center ±
-
Defines a global frequency grid (
crop_min
tocrop_max
) and interpolates all local spectra onto it. -
Adds white noise and applies cavity mode response.
-
Returns JSON:
{ "success": true, "x": ["freq1","freq2",...], "y": ["int1","int2",...] }
-
-
find_peaks(x_data, y_data, threshold=0, min_distance=100)
- Converts inputs to NumPy arrays and calls SciPy’s
find_peaks
. - Catches exceptions and returns an error JSON if something goes wrong.
- Builds and returns a dictionary mapping each peak frequency (to 4 decimal places) to its intensity (to 4 decimals).
- Converts inputs to NumPy arrays and calls SciPy’s
-
-
This section describes how incoming requests are handled:
-
Version handling
- On startup, attempts to read
version.txt
. If found, setsapp.config["VERSION"]
. - The root route displays this version in the HTML header.
- On startup, attempts to read
-
Spectrum acquisition
POST /acquire_spectrum
→ callsacquire_spectra
→ returns spectrum JSON.
-
Peak finding
POST /find_peaks
→ callsfind_peaks
→ returns peaks JSON.
Returns the path to a line list file for the requested molecule. Mappings:
{
"C6H5CN": "C6H5CN.dat",
"HC7N": "HC7N.dat",
…
}
Ensures exactly 11 keys: molecule, stepSize, frequencyMin, frequencyMax, numCyclesPerStep, microwavePulseWidth, mwBand, repetitionRate, molecularPulseWidth, acquisitionType, vres
.
(1/pi) * (hwhm / ((grid - center)**2 + hwhm**2))
where hwhm = fwhm/2
.
Draws from np.random.normal(0, noise_level, spectrum.shape)
with noise_level
scaled by 1/sqrt(num_cycles_per_step)
.
- single mode: one Lorentzian filter at
vres
. - range mode: sum of Lorentzian filters spaced by
stepSize
.
- Reads frequency/intensity pairs from the line list.
- Filters by
vres +/- window
or[frequencyMin-window, frequencyMax+window]
. - For each line, makes two Lorentzian peaks to simulate Doppler splitting.
- Interpolates and sums onto a global grid.
- Adds noise and cavity response, then takes absolute value.
- Uses
scipy.signal.find_peaks(y, height=threshold, distance=min_distance)
. - Maps results to a JSON of
{ "freq": "intensity" }
entries.