Source code for data_extraction

# -*- coding: utf-8 -*-
"""
The data extraction allows to retrieve kinetic data from one or multiple files.

In addition to retrieving data from .txt or .csv files, this module also check the validity
of provided data.

.. note::
    To improve computational costs, the data is retrieved as numpy arrays.
"""

import numpy as np
import os

[docs] def extract_dsc_data_multiple_files(file_paths, delimiter=',', has_header=False, skip_lines=0): """ Extract DSC data from multiple txt or csv files and perform data validation. Parameters ---------- file_paths : list List of file paths to input txt or csv files containing DSC data. delimiter : str, optional Delimiter used in the input files. Default is ','. has_header : bool, optional Whether the input files have headers. Default is False. skip_lines : int, optional Number of lines to skip at the beginning of each file. Default is 0. Returns ------- Tuple of concatenated numpy arrays (time, temperature, rate_of_reaction, extent_of_reaction) """ try: concatenated_time = [] concatenated_temperature = [] concatenated_rate_of_reaction = [] concatenated_extent_of_reaction = [] for file_path in file_paths: # Load data from the file if has_header: data = np.genfromtxt(file_path, delimiter=delimiter, skip_header=1 + skip_lines) # Skip the header and specified lines else: data = np.genfromtxt(file_path, delimiter=delimiter, skip_header=skip_lines) # Separate columns from the data time = data[:, 0] temperature = data[:, 1] rate_of_reaction = data[:, 2] extent_of_reaction = data[:, 3] # Check if extent of reaction is within [0, 1] range initial_extent = extent_of_reaction[0] final_extent = extent_of_reaction[-1] # Integral of reaction rate should be equal to extent of reaction extent_of_reaction_recorded = extent_of_reaction[-1]-extent_of_reaction[0] if initial_extent < 0 or initial_extent > 1 or final_extent < 0 or final_extent > 1: print(f"Error in file {os.path.basename(file_path)}: Extent of reaction should be between 0 and 1. Initial extent: {initial_extent}, Final extent: {final_extent}") else: print(f"Info in file {os.path.basename(file_path)}:\n Initial extent: {initial_extent}, Final extent: {final_extent}") # Warn about issues with initial extent being zero if initial_extent == 0: print(f"Info: in file {os.path.basename(file_path)}: Initial extent being zero can lead to issues for some kinetic models.") # Check if extent of reaction is non-decreasing if not np.all(np.diff(extent_of_reaction) >= 0): print(f"Error in file {os.path.basename(file_path)}: Extent of reaction is not non-decreasing.") # Check temperature unit if temperature[0] < 173.15: print(f"Warning in file {os.path.basename(file_path)}: Starting temperature should be in Kelvin not Celsius.\n Make sure you're using the appropriate units.") # Calculate the integral of rate of reaction and compare with global extent integral_rate = np.trapz(rate_of_reaction, time) if not np.isclose(integral_rate, extent_of_reaction_recorded): print(f"Error in file {os.path.basename(file_path)}: Integral of rate of reaction is not equal to the final extent.") #Check if there's extent equal or greater than 1 if np.any(extent_of_reaction >= 1): # Remove data after extent reaches 1 complete_reaction_index = np.argmax(extent_of_reaction >= 1) + 1 else: complete_reaction_index = len(extent_of_reaction) time = time[:complete_reaction_index] temperature = temperature[:complete_reaction_index] rate_of_reaction = rate_of_reaction[:complete_reaction_index] extent_of_reaction = extent_of_reaction[:complete_reaction_index] concatenated_time.extend(time) concatenated_temperature.extend(temperature) concatenated_rate_of_reaction.extend(rate_of_reaction) concatenated_extent_of_reaction.extend(extent_of_reaction) concatenated_time = np.array(concatenated_time) concatenated_temperature = np.array(concatenated_temperature) concatenated_rate_of_reaction = np.array(concatenated_rate_of_reaction) concatenated_extent_of_reaction = np.array(concatenated_extent_of_reaction) return concatenated_time, concatenated_temperature, concatenated_rate_of_reaction, concatenated_extent_of_reaction except Exception as e: print(f"Error in file {os.path.basename(file_path)}:{e}") return 0,0,0,0
[docs] def extract_dsc_data_single_file(file_path, delimiter=',', has_header=False, skip_lines=0): """ Extract DSC data from multiple txt or csv files and perform data validation. Parameters ---------- file_path : list File path to input txt or csv files containing DSC data. delimiter : str, optional Delimiter used in the input file. Default is ','. has_header : bool, optional Whether the input file has headers. Default is False. skip_lines : int, optional Number of lines to skip at the beginning of the file. Default is 0. Returns ------- Tuple of numpy arrays (time, temperature, rate_of_reaction, extent_of_reaction) """ # Load data from the file if has_header: data = np.loadtxt(file_path, delimiter=delimiter, skiprows=1 + skip_lines) # Skip the header and specified lines else: data = np.loadtxt(file_path, delimiter=delimiter, skiprows=skip_lines) # Separate columns from the data time = data[:, 0] temperature = data[:, 1] rate_of_reaction = data[:, 2] extent_of_reaction = data[:, 3] #Check if there's extent equal or greater than 1 if np.any(extent_of_reaction >= 1): # Remove data after extent reaches 1 complete_reaction_index = np.argmax(extent_of_reaction >= 1) + 1 else: complete_reaction_index = len(extent_of_reaction) time = time[:complete_reaction_index] temperature = temperature[:complete_reaction_index] rate_of_reaction = rate_of_reaction[:complete_reaction_index] extent_of_reaction = extent_of_reaction[:complete_reaction_index] return time, temperature, rate_of_reaction, extent_of_reaction
if __name__=="__main__": print("You've run the data extraction module.")