# Oqtant Job Analysis Library

## Capabilities

- Contains job inputs and outputs (if they exist) as well as information about the user, hardware, and submission time.
- Analysis functions for TOF images and some convenient output/plotting utilities

## How the BEC Job Analysis Library works

1. A OqtantJob is a container object for inputs and results generated by the Oqtant system.
   The OqtantJob object has a variety of common utility functions for processing results.

2. Within a Oqtant session, OqtantJob objects are created and stored in active_jobs.
   These jobs are available until the python session ends. All jobs are tracked by their id,
   which is issued at the time of job submit.

3. To handle job results from a previous session, load them into active_jobs with
   load_job_from_id() or load_job_from_file(). This will create the OqtantJob object(s).

4. Each OqtantJob object has a status assigned by the Oqtant hardware:
   - Pending - This job has not run yet. No results available
   - Running - This job is being evaluated. Run time is 1 minute.
   - Complete - This job has run successfully and results are available.
   - Failed - This job has failed. This can occur due to inappropriate input parameters or
     hardware outages. Contact **albert@infleqtion.com** for support

## Helper functions

### round_sig

    (x, sig=2):
    return round(x, sig - int(floor(log10(abs(x)))) - 1)

### TF_dist_2D

    Defines 2D Thomas-Fermi distribution characteristic of zero-temperature Bose-gas
    Requires function(s): get_image_space

    :param xy_mesh: returned by get_image_space
    :type xy_mesh: (2,N,M) Matrix of floats containing mesh grid of image coordinates

    :param TFpOD:
    :type TFpOD: float - Thomas-Fermi peak Optical Density (OD)

    :param rx:
    :type rx: float - Thomas-Fermi radius along the x-direction

    :param ry:
    :type ry: float - Thomas-Fermi radius along the y-direction (along gravity)

    :param xc:
    :type xc: float - Cloud center along the x-direction (along gravity)

    :param yc:
    :type yc: float - Cloud center along the y-direction

    :param os:
    :type os: float - Constant offset

    returns array sampled OD of TF dist, flattened to 1D

### Gaussian_dist_2D

    Defines 2D gaussian distribution characteristic of a thermal ensemble of atoms
    Requires function(s): get_image_space
    :param xy_mesh:
    :type xy_mesh: (2,N,M) Matrix of floats containing meshgrid of image coordinates

    :param GpOD:
    :type GpOD: float - Gaussian peak Optical Density (OD)

    :param sigx:
    :type sigx: float - Gaussian spread along the x-direction

    :param sigy:
    :type sigy: float - Gaussian spread along the y-direction (along gravity)

    :param xc:
    :type xc: float - Cloud center along the x-direction (along gravity)

    :param yc:
    :type yc: float - Cloud center along the y-direction

    :param os:
    :type os: float - Constant offset

    returns array sampled OD of 2d gaussian, flattened to 1D

### bimodal_dist_2D

    Defines 2D bimodal distribution characteristic of finite-temperature Bose-gas
    Requires functions: Gaussian_dist_2D, TF_dist_2D, get_image_space
    :param xy_mesh:
    :type xy_mesh: (2,N,M) Matrix of floats containing meshgrid of image coordinates

    :param GpOD:
    :type GpOD: float - Gaussian peak Optical Density (OD)

    :param sigx:
    :type sigx: float - Gaussian spread along the x-direction

    :param sigy:
    :type sigy: float - Gaussian spread along the y-direction (along gravity)

    :param TFpOD:
    :type TFpOD: float - Thomas-Fermi peak Optical Density (OD)

    :param rx:
    :type rx: float - Thomas-Fermi radius along the x-direction

    :param ry:
    :type ry: float - Thomas-Fermi radius along the y-direction (along gravity)

    :param xc:
    :type xc: float - Cloud center along the x-direction (along gravity)

    :param yc:
    :type yc: float - Cloud center along the y-direction

    :param os:
    :type os: float - Constant offset

    returns array sampled OD, sum of 2d gaussian distribution and TF distribution. flattened to 1D

## OqtantJob class

This is a container class for an Oqtant job in any state

A OqtantJob object contains job parameters and results (if they have been generated).
The OqtantJob class contains analysis functions to apply to TOF images.

### init

    :param job_dict:
    :type job_dict: dict - valid dictionary of job inputs used to submit the job to run on hardware

    attributes:
        job_id - UUID job id from submit (str)
        user_id - unique user id from job submission (str)
        status - job status (Enumerated type). Not automatically updated.
        time_submit - time of submission in timezone of database (UTC) (str)
        name - human readable job name assigned at submit (str)
        input - Job input dictionary from job submit (dict)
        job_type - Job type "BEC" or "BARRIER" (str)
        output - Job results (dictionary). Default = {}
        pix_cal - pixel calibration to microns = 8.71
        sig_abs = 0.297
        omega_x - axial trap frequency =  2 * pi * 80
        omega_y - radial trap frequency = 2 * pi * 1000

### get_TOF

    Returns shaped TOF image if it exists
    :returns: reshaped pixels numpy array (100,100)

### get_IT

    Returns shaped IT image if it exists
    :returns: reshaped pixels numpy array (100,100)

### get_image_space

    Returns meshgrid of image coordinates
    :param datafile:
    :type datafile: (N,M) Matrix of Optical Density (OD) Data

    returns xy_mesh, lx, ly

### fit_bimodal_data2D

    Performs fit via trust region reflective algorithm.
    Requires functions: bimodal_dist_2D, Gaussian_dist_2D, TF_dist_2D, get_image_space
    For better fit performance, tune initial guess 'xi' and lower/upper bounds, 'lb' and 'ub'
    :param xy_mesh:
    :type xy_mesh: (2,N,M) Matrix containing meshgrid of image data coordinates
    :param data2D:
    :type data2D: (N,M) Matrix containing image data
    :param xi:
    :type xi: (1,9) List of fit parameter initial guesses. Default = [0.25, 8, 8, 1, 4, 6, 0, 0, 0.02]
    :param lb:
    :type lb:  (1,9) List of fit parameter lower bounds. Default =[0, 7, 7, 0, 2, 2, -20, -20, 0]
    :param ub:
    :type ub: (1,9) List of fit parameter upper bounds. Default = [2, 20, 20, 2, 20, 20, 20, 20, 1]

    return fit_params, cov_mat, fit_residual, fit_Rsquared

### lm_fit_bimodal_2D

    Fit bimodal distribution to TOF data using non linear least squares fitting toolbox
    Perform Levenberg-Marquart least-squares fit
    Grab the required parameters from distribution functions

    :param initial_guess: guess parameters to begin fit process
    :type initial_guess: list [iGpOD, isigx, isigy, iTFpOD, irx, iry, ixc, iyc, ios]
        Default values:
            Peak ODs - iGpOD, iTFpOD = 0.25, 1
            Cloud centers - ixc, iyc = 0, 0
            Gaussian widths - isigx, isigy = 8, 8
            TF widths - irx, iry = 4, 6
            image offset (noise) - ios = 0.1

    :param lower_bounds: lower bounds for fit parameters
    :type lower_bounds: list [lb_iGpOD, lb_isigx, lb_isigy, lb_iTFpOD, lb_irx, lb_iry, lb_ixc, lb_iyc, lb_ios]
        Default values: [0, 7, 7, 0, 2, 2, -20, -20, 0]

    :param upper_bounds: upper bounds for fit parameters
    :type upper_bounds:list [ub_iGpOD, ub_isigx, ub_isigy, ub_iTFpOD, ub_irx, ub_iry, ub_ixc, ub_iyc, ub_ios]
        Default values: [2, 20, 20, 2, 20, 20, 20, 20, 1]

    returns (list) lmfit_params

### display_fit_result

    Prints fit results to the terminal or notebook.

    :param fit_params:
    :type fit_params: list of parameters from a fit operation

    :param cov_mat:
    :type cov_mat: array of covariances from a fit operation

    :param fit_residual:
    :type fit_residual: list of residuals from a fit operation

    :param fit_Rsquared:
    :type fit_Rsquared: list of R^2 values from a fit operation

### plot_fit_results

    Plot the results of a fit operation

    :param fit_params:
    :type fit_params: list of parameters from a fit operation

    :param model:
    :type model: string "bimodal", "TF", or "gaussian". default "bimodal"

    :param output:
    :type output: string "show" or valid filename

    :param plot_title:
    :type plot_title: string title for the plot. default "job: "+str(self.name)+"\nTOF fit: "+str(model)

### atoms_2dplot

    Generate a 2D plot of atom OD (save or show)

    :param output: how to output the information
    :type output: string "show" or valid filename

    :param figsize:
    :type figsize: tuple. default is (12,12)

    :param gridon: grid lines on plot on/off
    :type gridon: Boolean. default is False

### atoms_sliceplot

    Generate a 1D slice plot of atom OD in x or y

    :param output: how to output the information
    :type output: string "show" or valid filename

    :param sliceaxis:
    :type sliceaxis: string 'x' or 'y'

    :param figsize:
    :type figsize: tuple. default is (12,12)
    :param gridon: grid lines on plot on/off

    :type gridon: Boolean. default is False

### atoms_3dplot

    Generate a 3D slice plot of atom OD

    :param output: how to output the information
    :type output: string "show" or valid filename

    :param view_angle:
    :type view_angle: int (-180, 180). default -45

    :param figsize:
    :type figsize: tuple. default is (10,10)

### atom_numbers

    Calculate atom numbers in thermal and condensed components of the cloud
    Based on fit results

    :param bimodalfit_params:
    :type bimodalfit_params: list of parameters from a bimodal fit

    :param print_results: optional. suppress printouts for many calculations.
    :type print_results: boolean  default True

    list parameters: [GpOD, sigx, sigy, TFpOD, rx, ry, xc, yc, os]

    G_pOD, TF_pOD = 0.25, 1              # peak OD of Gaussian and TF
    xc, yc = 0, 0                        # center of cloud in x, y-direction
    sigx, sigy = 8, 8                    # Gaussian widths
    rx, ry = 4, 6                        # TF widths
    os = 0.1                             # uniform background level

    return Ntot, Ncond, Ntherm

### calculate_temperature

    Calculate the temperature of an atom cloud using the results based on the fit to a bimodal distribution

    :param atom_numbers:
    :type atom_numbers: list of [Ntot, Ncond, Ntherm] generated by atom_numbers

    :param bimodalfit_params:
    :type bimodalfit_params: list of parameters from a bimodal fit

    list parameters: [GpOD, sigx, sigy, TFpOD, rx, ry, xc, yc, os]

    G_pOD, TF_pOD = 0.25, 1              # peak OD of Gaussian and TF
    xc, yc = 0, 0                        # center of cloud in x, y-direction
    sigx, sigy = 8, 8                    # Gaussian widths
    rx, ry = 4, 6                        # TF widths
    os = 0.1                             # uniform background level
