Skip to content

Commit

Permalink
Added the DaRUS upload and cleaned repository
Browse files Browse the repository at this point in the history
  • Loading branch information
samirdarouich committed Nov 27, 2023
1 parent 0a29969 commit 070599e
Show file tree
Hide file tree
Showing 88 changed files with 277 additions and 4,567 deletions.
328 changes: 212 additions & 116 deletions Main.ipynb

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions datamodel/core/experiment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import sdRDM
import json
import numpy as np
import pandas as pd

from datetime import datetime
from pathlib import Path
from typing import List, Optional
from pydantic import Field
Expand Down Expand Up @@ -172,6 +175,11 @@ def volumetric_flow_time_course(self) -> list:
volumetric_flow_datetime_list = mfm_measurement.get( "experimental_data", "quantity", Quantity.DATETIME.value )[0][0].values
volumetric_flow_values_list = mfm_measurement.get( "experimental_data", "quantity", Quantity.VOLUMETRICFLOWRATE.value )[0][0].values

# If data is directly read in from the experiment, it is the correct format, if read from json dataset, it is a string and needs to be converted
if not type( volumetric_flow_datetime_list[0] ) == datetime:
volumetric_flow_datetime_list = [ pd.to_datetime(timestamp, format="%Y-%m-%d %H:%M:%S").to_pydatetime() for timestamp in volumetric_flow_datetime_list ]


return [volumetric_flow_datetime_list, volumetric_flow_values_list]


11 changes: 6 additions & 5 deletions datamodel/tools/auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ def assign_peaks(self):

for peak_area, retention_time in zip(peak_areas_retention_time["peak_areas"], peak_areas_retention_time["retention_time"]):

# Set default values with a given dict
default_value = [trt[0] for trt in self.typical_retention_time.items() if (abs( trt[1] - retention_time ) < 0.6) and (trt[0] in self.species) ]
default_value = default_value[0] if bool(default_value) else ""
# Set default values with a given dict (search for the species with the closest retention time and pick it as standard value)
idx = np.argmin( [ abs( trt[1] - retention_time ) for trt in self.typical_retention_time.items() if trt[0] in self.species ] )
default_value = list( self.typical_retention_time.items() )[idx][0]

dropdown = Dropdown( options = [""] + self.species,
layout = Layout(width="40%", height="30px"),
Expand Down Expand Up @@ -316,7 +316,8 @@ def modify_dropdown_options(self, new_options):

# Set default values with a given dict
retention_time = float( hbox.children[0].value )
default_value = [trt[0] for trt in self.typical_retention_time.items() if (abs( trt[1] - retention_time ) < 0.6) and (trt[0] in new_options) ]
default_value = default_value[0] if bool(default_value) else ""
# Set default values with a given dict (search for the species with the closest retention time and pick it as standard value)
idx = np.argmin( [ abs( trt[1] - retention_time ) for trt in self.typical_retention_time.items() if trt[0] in new_options ] )
default_value = list( self.typical_retention_time.items() )[idx][0]

hbox.children[2].value = default_value
42 changes: 30 additions & 12 deletions datamodel/tools/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

import scipy.constants as const

import logging

# Get the logger from the main file
logger = logging.getLogger(__name__)

class FaradayEfficiencyCalculator(BaseModel):
experiment: Experiment
mean_radius: int = 10
Expand Down Expand Up @@ -54,13 +59,13 @@ def _calculate_volumetric_fractions(self, assigned_peak_areas_dict: dict):
Args:
assigned_peak_areas_dict (dict): Dictionary containing the species and the associated peak area.
"""
self.volumetric_fractions_df = pd.DataFrame( index=[species for species in assigned_peak_areas_dict.keys()], columns=["Volumetric_fraction"] )
self.volumetric_fractions_df = pd.DataFrame( index=[species for species in assigned_peak_areas_dict.keys()], columns=["Volumetric_fraction [-]"] )

# peak areas are given as list, as it is possible for one component to have several assigned peaks
for species, peak_areas in assigned_peak_areas_dict.items():
self.volumetric_fractions_df.loc[species] = self.experiment.get("species_data", "species", species)[0][0].calibration.predict( [ np.sum(peak_areas) ] ) / 100

if self.volumetric_fractions_df["Volumetric_fraction"].sum() < 0.99: print("\n!!! Warning: Volume fractions doesn't add up to 1.0 !!!\n")
if self.volumetric_fractions_df["Volumetric_fraction [-]"].sum() < 0.99: print("\n!!! Warning: Volume fractions doesn't add up to 1.0 !!!\n")

def _calculate_real_volumetric_flow(self):
"""
Expand All @@ -84,25 +89,30 @@ def _calculate_material_flow(self):
Function that computes the real material flow of every component [mol/s].
Given the real volumetric flow and the volumetric fractions (computed from GC measurement and calibration data)
"""
## molecular volume of ideal Gas at 1 atm and 273.15 K: 22.414 l/mol --> 22414 ml/mol (scipy gives m^3/mol = 10^-6*ml^3/mol)
molecular_volume = const.physical_constants["molar volume of ideal gas (273.15 K, 101.325 kPa)"][0] * 10**6
rename = {"Volumetric_fraction": "Material_flow"}
## molecular volume of ideal Gas at 1 atm and 273.15 K: 22.414 l/mol --> 22414 ml/mol (m^3/mol = 10^-6*ml^3/mol)
molecular_volume = const.R * 273.15 / 101325 * 10**6
rename = {"Volumetric_fraction [-]": "Material_flow [mol/s]"}

# Material flow [mol/s] = vol_fraction [vol_% / vol_%] * real_vol_flow [ml/s] / mol_volume_id_gas [ml/mol]
self.material_flow_df = self.volumetric_fractions_df.rename ( columns = rename ) * self.real_volumetric_flow / molecular_volume

def _calculate_theoretical_material_flow(self):
"""
Function that computes the theoretical material flow, using the given current as well as the Faraday constant
and a factor describing the electron transfer for each species
"""
faraday_constant = const.physical_constants["Faraday constant"][0]
factors = { esd.species: esd.faraday_coefficient for esd in self.experiment.species_data }
self.theoretical_material_flow_df = pd.DataFrame( index=[species for species in factors.keys()], columns = ["Theoretical_material_flow"] )
self.theoretical_material_flow_df = pd.DataFrame( index=[species for species in factors.keys()], columns = ["Theoretical_material_flow [mol/s]"] )

# Current_density i provided in mA/cm^2; Electrode surface A is given as cm^2 --> current I = i*A_surface [A]
self.initial_current = abs( self.experiment.get("measurements/metadata", "parameter", "Current")[0][0].value ) * self.experiment.get("measurements/metadata", "parameter", "Electrode surface area")[0][0].value
# Current_density i provided in mA/cm^2; Electrode surface A is given as cm^2 --> current I = i*A_surface * 1A / 1000mA [A]
self.initial_current = ( abs( self.experiment.get("measurements/metadata", "parameter", "Current")[0][0].value )
* self.experiment.get("measurements/metadata", "parameter", "Electrode surface area")[0][0].value / 1000 )

# Faraday constant is C/mol, with C = A*s
# theoretical flow [mol/s]: mA * 1A / 1000mA / ( C/mol ) = mol * A/C = mol * A/(A*s) = mol / s
# theoretical flow [mol/s]: A / ( C/mol ) = mol * A/C = mol * A/(A*s) = mol / s
for species, factor in factors.items():
self.theoretical_material_flow_df.loc[species] = self.initial_current / 1000 / ( factor * faraday_constant )
self.theoretical_material_flow_df.loc[species] = self.initial_current / ( factor * faraday_constant )


def calculate_faraday_efficiencies(self, gc_measurement: Measurement):
Expand All @@ -122,6 +132,9 @@ def calculate_faraday_efficiencies(self, gc_measurement: Measurement):
# Extract the injection time out of the given GC measurement
inj_date_datetime = gc_measurement.get("metadata", "parameter", "Injection Date")[0][0].value

# In the case the dataset is read it from json, every typ is incorrect and needs to be transfered
if not type(inj_date_datetime) == datetime: inj_date_datetime = datetime.strptime( inj_date_datetime, "%Y-%m-%d %H:%M:%S" )

# Extract the peak areas dict out of the given gc_measurement
assigned_peak_areas_dict = {}

Expand All @@ -141,10 +154,15 @@ def calculate_faraday_efficiencies(self, gc_measurement: Measurement):
self._calculate_material_flow()
self._calculate_theoretical_material_flow()

rename = {"Material_flow": "Faraday_efficiency"}
rename = {"Material_flow [mol/s]": "Faraday_efficiency [%]"}

# Compute the Faraday efficency by diving the real by the theoretical material flow
faraday_efficiency_df = self.material_flow_df.divide( self.theoretical_material_flow_df["Theoretical_material_flow"], axis="index", ).rename(columns=rename)
faraday_efficiency_df = self.material_flow_df.divide( self.theoretical_material_flow_df["Theoretical_material_flow [mol/s]"], axis="index", ).rename(columns=rename) * 100
faraday_efficiency_df.dropna(inplace=True)

# Write into logger
logger.info( "\n\nProcessed data of GC measurement:\n", "%s\n"%self.volumetric_fractions_df.to_string(),
"%s\n"%self.material_flow_df.to_string(), "%s\n"%self.theoretical_material_flow_df.to_string(),
"%s\n"%faraday_efficiency_df.to_string(), "\n\n" )

return faraday_efficiency_df
31 changes: 19 additions & 12 deletions datamodel/tools/data_processing_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,12 @@ def choose_data(self,root: Path) -> None:
try:
self.datamodel = DataModel.parse( self.dataset_dropdown.value )
self.dataset, self.lib = self.datamodel
self.experiments.value = [exp.id for exp in self.dataset.experiments]
except:
raise KeyError("\nChoosen dataset cannot be interpreted!\n")

# List of experiments
self.experiments.value = [ exp.id for exp in self.dataset.experiments ]

# Functions for the buttons #
self.button_go_for.on_click(self.go_to_subfolder)
self.button_go_back.on_click(self.go_to_parentfolder)
Expand Down Expand Up @@ -365,7 +367,7 @@ def choose_experiment_input_handler(self,_):
This function provides the peaks of the GC measurement inheritend in the choosen experiment
"""

# Clear existing widgets
# Clear existing output
clear_output(wait=True)

# Display the layout for experiment and species
Expand All @@ -383,6 +385,13 @@ def species_tags_input_handler(self,_):

def do_postprocessing(self,_):

# Clear existing output (in case several post processing are done, remove the print output )
clear_output(wait=True)

# Reexecute the widget
self.choose_experiment_input_handler(None)
display(self.full_layout2)

print("\nStarting the postprocessing\n")

fe_calculator = FaradayEfficiencyCalculator(experiment = self.dataset.experiments[self.experiments_dropdown.value],
Expand Down Expand Up @@ -417,7 +426,9 @@ def choose_experiment(self,datamodel,dataset_path,typical_retention_time={}) ->
self.dataset_path = dataset_path
self.dataset, self.lib = datamodel

self.experiments_dropdown = widgets.Dropdown(options=[(str(exp.id),idx) for idx,exp in enumerate( self.dataset.experiments) ],
if not bool( self.dataset.experiments ): raise ValueError("Dataset contains no experiments!\n")

self.experiments_dropdown = widgets.Dropdown(options=[(str(exp.id),idx) for idx,exp in enumerate( self.dataset.experiments ) ],
description="Choose experiment:",
layout=widgets.Layout(width='auto'),
style={'description_width': 'auto'})
Expand All @@ -431,7 +442,6 @@ def choose_experiment(self,datamodel,dataset_path,typical_retention_time={}) ->
step=1, # Step size
description='Mean radius:')


self.display_button = widgets.Button(description="Start posprocessing",
layout=widgets.Layout(width="30%"),
style={"button_color": 'green'})
Expand All @@ -445,9 +455,6 @@ def choose_experiment(self,datamodel,dataset_path,typical_retention_time={}) ->
are minimized by calculating the mean by averaging over a certain number (=radius) of measuring points before and\
after the time of the GC measurement. The radius has to be specified in accordance with the strength of fluctuations.')

self.elec_surf_area = widgets.FloatText(value=1.0,
description='Electrode surface area [cm^2]:',
style={'description_width': 'auto'})

# Handle switch of experiment
self.experiments_dropdown.observe(self.choose_experiment_input_handler,names="value")
Expand All @@ -462,7 +469,7 @@ def choose_experiment(self,datamodel,dataset_path,typical_retention_time={}) ->

widgets0 = widgets.HBox([self.experiments_dropdown])
widgets1 = widgets.VBox([widgets.Label(value='Species in GC analysis:'), self.species_tags])
widgets2 = widgets.VBox([self.explanation_label,v_space,widgets.HBox([self.mean_radius,self.elec_surf_area])])
widgets2 = widgets.VBox([self.explanation_label,v_space,widgets.HBox([self.mean_radius])])
widgets3 = self.display_button
widgets4 = self.button_save

Expand All @@ -477,9 +484,9 @@ def choose_experiment(self,datamodel,dataset_path,typical_retention_time={}) ->
self.choose_experiment_input_handler(None)

# Do postprocessing and save dataset
layout = widgets.VBox([widgets.VBox([widgets2,v_space]),
widgets.VBox([widgets3,v_space,widgets4],
layout=widgets.Layout(align_items = 'center'))])
self.full_layout2 = widgets.VBox([widgets.VBox([widgets2,v_space]),
widgets.VBox([widgets3,v_space,widgets4],
layout=widgets.Layout(align_items = 'center'))])

display(layout)
display(self.full_layout2)

Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
"handlers": {
"file": {
"class": "logging.FileHandler",
"level": "DEBUG",
"level": "INFO",
"formatter": "simple",
"filename": "datamodel_b07_tc/tools/logging/log_faraday.log",
"filename": "log_faraday_efficency.log",
"mode": "a"
},
"console": {
Expand Down
Binary file removed datamodel_b07_tc/.DS_Store
Binary file not shown.
3 changes: 0 additions & 3 deletions datamodel_b07_tc/__init__.py

This file was deleted.

68 changes: 0 additions & 68 deletions datamodel_b07_tc/core/__init__.py

This file was deleted.

32 changes: 0 additions & 32 deletions datamodel_b07_tc/core/author.py

This file was deleted.

Loading

0 comments on commit 070599e

Please sign in to comment.