Skip to content

Commit

Permalink
Update the way to handle spectra type (#133)
Browse files Browse the repository at this point in the history
* Map data types and spectra layouts

* FIx: process lower/mixed case data types
  • Loading branch information
f-idiris authored and Lan Le committed Nov 6, 2023
1 parent 6ed1a53 commit d47f738
Show file tree
Hide file tree
Showing 11 changed files with 359 additions and 116 deletions.
15 changes: 15 additions & 0 deletions chem_spectra/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from flask import Flask
from flask_jwt_extended import JWTManager
from datetime import timedelta

import logging

Expand All @@ -23,6 +25,11 @@ def create_app(test_config=None):
except OSError:
pass

app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(days=1)
app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=30)

jwt = JWTManager(app)

#create logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
Expand All @@ -39,6 +46,10 @@ def create_app(test_config=None):
@app.route('/ping')
def ping():
return 'pong'

# Refresh token api
from chem_spectra.controller.refresh_token_api import refresh_token_api
app.register_blueprint(refresh_token_api)

# file api
from chem_spectra.controller.file_api import file_api
Expand All @@ -52,4 +63,8 @@ def ping():
from chem_spectra.controller.transform_api import trans_api
app.register_blueprint(trans_api)

# spectra layout api
from chem_spectra.controller.spectra_layout_api import spectra_layout_api
app.register_blueprint(spectra_layout_api)

return app
19 changes: 19 additions & 0 deletions chem_spectra/controller/refresh_token_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from flask import jsonify, Blueprint
from flask_jwt_extended import jwt_required, create_access_token, get_jwt_identity, create_refresh_token


refresh_token_api = Blueprint('refresh_token_api', __name__)

@refresh_token_api.route("/api/v1/chemspectra/login", methods=["POST"])
def login():
access_token = create_access_token(identity="user")
refresh_token = create_refresh_token(identity="user")
return jsonify(access_token=access_token, refresh_token=refresh_token)


@refresh_token_api.route("/api/v1/chemspectra/refresh", methods=["POST"])
@jwt_required(refresh=True)
def refresh():
identity = get_jwt_identity()
access_token = create_access_token(identity=identity)
return jsonify(access_token=access_token)
65 changes: 65 additions & 0 deletions chem_spectra/controller/spectra_layout_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import json
from flask import jsonify, Blueprint, request
import os
import shutil
from flask_jwt_extended import jwt_required

spectra_layout_api = Blueprint('spectra_layout_api', __name__)
script_dir = os.path.dirname(__file__)
data_type_json_path = os.path.join(script_dir, '../lib/converter/jcamp/data_type.json')

def load_data_types():
try:
with open(data_type_json_path, 'r') as mapping_file:
return json.load(mapping_file)
except FileNotFoundError:
example_json_path = os.path.join(script_dir, '../lib/converter/jcamp/data_type.json.example')
shutil.copy(example_json_path, data_type_json_path)
with open(data_type_json_path, 'r') as mapping_file:
return json.load(mapping_file)

def save_data_types(data_types):
with open(data_type_json_path, 'w') as mapping_file:
json.dump(data_types, mapping_file, indent=4)

@spectra_layout_api.route('/api/v1/chemspectra/spectra_layouts', methods=['GET', 'PUT', 'DELETE'])
@jwt_required()
def update_or_fetch_mapping():
if request.method == 'GET':
existing_data_types = load_data_types()
return jsonify(existing_data_types["datatypes"]), 200

elif request.method == 'PUT':
request_data = request.get_json()
new_data_type_mapping = request_data.get("new_data_type")
existing_data_types = load_data_types()

for layout, data_type in new_data_type_mapping.items():
if data_type == '':
return jsonify({"message": "Invalid Data Type"}), 400
elif layout in existing_data_types["datatypes"] and data_type not in existing_data_types['datatypes'][layout]:
existing_data_types["datatypes"][layout].append(data_type)
elif layout in existing_data_types["datatypes"] and data_type in existing_data_types['datatypes'][layout]:
return jsonify({"message": f"Data type '{data_type}' already exists"}), 400
else:
return jsonify({"message": f"Layout '{layout}' does not exist"}), 400

save_data_types(existing_data_types)
return jsonify({"message": "Data type created successfully"}), 200

elif request.method == 'DELETE':
request_data = request.get_json()
data_type_mapping = request_data.get("data_type")
existing_data_types = load_data_types()
for layout, data_type in data_type_mapping.items():
if layout in existing_data_types["datatypes"]:
if data_type in existing_data_types['datatypes'][layout]:
existing_data_types['datatypes'][layout].remove(data_type)
save_data_types(existing_data_types)
return jsonify({"message": f"Data type '{data_type}' deleted successfully"}), 200
else:
return jsonify({"message": f"Data type '{data_type}' not found in layout '{layout}'"}), 404
else:
return jsonify({"message": f"Layout '{layout}' does not exist"}), 400
else:
return jsonify({"message": "Method not allowed"}), 405
116 changes: 36 additions & 80 deletions chem_spectra/lib/converter/jcamp/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import nmrglue as ng
import json

from chem_spectra.lib.converter.share import parse_params, parse_solvent
import os

data_type_json = os.path.join(os.path.dirname(__file__), 'data_type.json')


class JcampBaseConverter:
Expand Down Expand Up @@ -43,82 +47,36 @@ def __read(self, path):

def __set_datatype(self):
dts = self.datatypes
if 'NMR SPECTRUM' in dts:
return 'NMR SPECTRUM'
elif 'NMRSPECTRUM' in dts: # MNova
return 'NMR SPECTRUM'
elif 'INFRARED SPECTRUM' in dts:
return 'INFRARED SPECTRUM'
elif 'RAMAN SPECTRUM' in dts:
return 'RAMAN SPECTRUM'
elif 'MASS SPECTRUM' in dts:
return 'MASS SPECTRUM'
elif 'HPLC UV/VIS SPECTRUM' in dts:
return 'HPLC UV/VIS SPECTRUM'
elif 'HPLC UV-VIS' in dts:
return 'HPLC UV/VIS SPECTRUM'
elif 'UV/VIS SPECTRUM' in dts:
return 'UV/VIS SPECTRUM'
elif 'UV-VIS' in dts:
return 'UV/VIS SPECTRUM'
elif 'ULTRAVIOLET SPECTRUM' in dts:
return 'UV/VIS SPECTRUM'
elif 'THERMOGRAVIMETRIC ANALYSIS' in dts:
return 'THERMOGRAVIMETRIC ANALYSIS'
elif 'X-RAY DIFFRACTION' in dts:
return 'X-RAY DIFFRACTION'
elif 'CYCLIC VOLTAMMETRY' in dts:
return 'CYCLIC VOLTAMMETRY'
elif 'SIZE EXCLUSION CHROMATOGRAPHY' in dts:
return 'SIZE EXCLUSION CHROMATOGRAPHY'
elif 'CIRCULAR DICHROISM SPECTROSCOPY' in dts:
return 'CIRCULAR DICHROISM SPECTROSCOPY'
elif 'SORPTION-DESORPTION MEASUREMENT' in dts:
return 'SORPTION-DESORPTION MEASUREMENT'
elif 'Emissions' in dts or 'EMISSIONS' in dts or 'FLUORESCENCE SPECTRUM' in dts or 'FL SPECTRUM' in dts:
return 'Emissions'
elif 'DLS ACF' in dts:
return 'DLS ACF'
elif 'DLS INTENSITY' in dts or 'DLS intensity' in dts:
return 'DLS intensity'
dt_dict = {
'NMR': 'NMR SPECTRUM',
'INFRARED': 'INFRARED SPECTRUM',
'RAMAN': 'RAMAN SPECTRUM',
'MS': 'MASS SPECTRUM',
'HPLC UVVIS': 'HPLC UV/VIS SPECTRUM',
'UVVIS': 'UV/VIS SPECTRUM',
}

with open(data_type_json, 'r') as mapping_file:
data_type_mappings = json.load(mapping_file)["datatypes"]
for key, values in data_type_mappings.items():
values = [value.upper() for value in values]
for dt in dts:
if dt in values and key in dt_dict:
return dt_dict[key]
elif dt in values and not key in dt_dict:
return key
return ''

def __typ(self):
dt = self.datatype
if 'NMR SPECTRUM' == dt:
return 'NMR'
elif 'NMRSPECTRUM' == dt: # MNova
return 'NMR'
elif 'INFRARED SPECTRUM' == dt:
return 'INFRARED' # TBD
elif 'RAMAN SPECTRUM' == dt:
return 'RAMAN' # TBD
elif 'MASS SPECTRUM' == dt:
return 'MS'
elif 'HPLC UV/VIS SPECTRUM' == dt:
return 'HPLC UVVIS'
elif 'HPLC UV-VIS' == dt:
return 'HPLC UVVIS'
elif 'UV/VIS SPECTRUM' == dt or 'UV-VIS' == dt or 'ULTRAVIOLET SPECTRUM' == dt:
return 'UVVIS'
elif 'THERMOGRAVIMETRIC ANALYSIS' == dt:
return 'THERMOGRAVIMETRIC ANALYSIS'
elif 'X-RAY DIFFRACTION' == dt:
return 'X-RAY DIFFRACTION'
elif 'CYCLIC VOLTAMMETRY' in dt:
return 'CYCLIC VOLTAMMETRY'
elif 'SIZE EXCLUSION CHROMATOGRAPHY' in dt:
return 'SIZE EXCLUSION CHROMATOGRAPHY'
elif 'CIRCULAR DICHROISM SPECTROSCOPY' in dt:
return 'CIRCULAR DICHROISM SPECTROSCOPY'
elif 'SORPTION-DESORPTION MEASUREMENT' in dt:
return 'SORPTION-DESORPTION MEASUREMENT'
elif 'Emissions' in dt or 'EMISSIONS' in dt or 'FLUORESCENCE SPECTRUM' in dt or 'FL SPECTRUM' in dt:
return 'Emissions'
elif 'DLS ACF' in dt:
return 'DLS ACF'
elif 'DLS INTENSITY' in dt or 'DLS intensity' in dt:
return 'DLS intensity'

with open(data_type_json, 'r') as mapping_file:
data_type_mappings = json.load(mapping_file)["datatypes"]

for key, values in data_type_mappings.items():
values = [value.upper() for value in values]
if dt.upper() in values:
return key
return ''

def __set_dataclass(self):
Expand All @@ -140,12 +98,10 @@ def __is_em_wave(self):
return self.typ in ['INFRARED', 'RAMAN', 'UVVIS']

def __non_nmr(self):
return self.typ in [
'INFRARED', 'RAMAN', 'UVVIS', 'HPLC UVVIS',
'THERMOGRAVIMETRIC ANALYSIS', 'MS', 'X-RAY DIFFRACTION',
'CYCLIC VOLTAMMETRY', 'SIZE EXCLUSION CHROMATOGRAPHY',
'CIRCULAR DICHROISM SPECTROSCOPY', 'SORPTION-DESORPTION MEASUREMENT', 'Emissions',
'DLS ACF', 'DLS intensity']
with open(data_type_json, 'r') as mapping_file:
data_type_mappings = json.load(mapping_file).get("datatypes")
dts = [dt for dt in data_type_mappings.keys() if dt != 'NMR']
return self.typ in dts

def __is_ir(self):
return self.typ in ['INFRARED']
Expand Down Expand Up @@ -175,13 +131,13 @@ def __is_aif(self):
return self.typ in ['SORPTION-DESORPTION MEASUREMENT']

def __is_emissions(self):
return self.typ in ['Emissions', 'EMISSIONS', 'FLUORESCENCE SPECTRUM', 'FL SPECTRUM']
return self.typ in ['Emissions']

def __is_dls_acf(self):
return self.typ in ['DLS ACF']

def __is_dls_intensity(self):
return self.typ in ['DLS INTENSITY', 'DLS intensity']
return self.typ in ['DLS intensity']

def __ncl(self):
try:
Expand Down
19 changes: 19 additions & 0 deletions chem_spectra/lib/converter/jcamp/data_type.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"datatypes": {
"NMR": ["NMR SPECTRUM", "NMRSPECTRUM"],
"INFRARED": ["INFRARED SPECTRUM"],
"RAMAN": ["RAMAN SPECTRUM"],
"MS": ["MASS SPECTRUM"],
"HPLC UVVIS": ["HPLC UV/VIS SPECTRUM", "HPLC UV-VIS"],
"UVVIS": ["UV/VIS SPECTRUM", "UV-VIS", "ULTRAVIOLET SPECTRUM"],
"THERMOGRAVIMETRIC ANALYSIS": ["THERMOGRAVIMETRIC ANALYSIS"],
"X-RAY DIFFRACTION": ["X-RAY DIFFRACTION"],
"CYCLIC VOLTAMMETRY": ["CYCLIC VOLTAMMETRY"],
"SIZE EXCLUSION CHROMATOGRAPHY": ["SIZE EXCLUSION CHROMATOGRAPHY"],
"CIRCULAR DICHROISM SPECTROSCOPY": ["CIRCULAR DICHROISM SPECTROSCOPY"],
"SORPTION-DESORPTION MEASUREMENT": ["SORPTION-DESORPTION MEASUREMENT"],
"Emissions": ["Emissions", "EMISSIONS", "FLUORESCENCE SPECTRUM", "FL SPECTRUM"],
"DLS ACF": ["DLS ACF"],
"DLS intensity": ["DLS INTENSITY", "DLS intensity"]
}
}
19 changes: 19 additions & 0 deletions chem_spectra/lib/converter/jcamp/data_type.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"datatypes": {
"NMR": ["NMR SPECTRUM", "NMRSPECTRUM"],
"INFRARED": ["INFRARED SPECTRUM"],
"RAMAN": ["RAMAN SPECTRUM"],
"MS": ["MASS SPECTRUM"],
"HPLC UVVIS": ["HPLC UV/VIS SPECTRUM", "HPLC UV-VIS"],
"UVVIS": ["UV/VIS SPECTRUM", "UV-VIS", "ULTRAVIOLET SPECTRUM"],
"THERMOGRAVIMETRIC ANALYSIS": ["THERMOGRAVIMETRIC ANALYSIS"],
"X-RAY DIFFRACTION": ["X-RAY DIFFRACTION"],
"CYCLIC VOLTAMMETRY": ["CYCLIC VOLTAMMETRY"],
"SIZE EXCLUSION CHROMATOGRAPHY": ["SIZE EXCLUSION CHROMATOGRAPHY"],
"CIRCULAR DICHROISM SPECTROSCOPY": ["CIRCULAR DICHROISM SPECTROSCOPY"],
"SORPTION-DESORPTION MEASUREMENT": ["SORPTION-DESORPTION MEASUREMENT"],
"Emissions": ["Emissions", "EMISSIONS", "FLUORESCENCE SPECTRUM", "FL SPECTRUM"],
"DLS ACF": ["DLS ACF"],
"DLS intensity": ["DLS INTENSITY", "DLS intensity"]
}
}
Loading

0 comments on commit d47f738

Please sign in to comment.