Updating the Helper.py file and integrating the averager function into the OzonMonitor submodule, which now includes a class OzoneAnalyser.

This commit is contained in:
tschan_d committed 2026-09-07 19:14:04 +02:00
1 parent bf72e777fa
commit 75d7f6f287
6 files changed
+161 -79

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"configurations": [
{
"name": "Python Debugger: Current File",
"name": "Debug Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
+38 -3
View File
@@ -1,9 +1,40 @@
# Author: David Tschan
# Institute: Paul-Scherrer Institute, Laboratory for Atmospheric Chemistry, Multiphase Chemistry Group,
# Forschungsstrasse 111, 5232 Villigen PSI, Switzerland
# Role: Master Student
# License: n/a
# Date: 2026
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### SUBMODULE DOCSTRING
"""The docstring for this submodule
"""
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### IMPORTS AND CONFIGURATIONS
import pandas as pd
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### Helper.py
class DATFile():
# hekko
"""The docstring for this class
Description: Bla bla bla
Attributes
----------
word: str
A word
Methods
-------
__init__: HelloWorld
The class constructor
"""
def __init__(self, file, data_name = 'value'):
@@ -29,4 +60,8 @@ class DATFile():
pre_datetimes = [date + ' ' + time for date, time in zip(dates, times)]
datetimes = pd.to_datetime(pre_datetimes, format=r'%d.%m.%Y %H:%M:%S')
self.data = pd.DataFrame({'timestamp': datetimes, self.data_name: values})
self.data = pd.DataFrame({'timestamp': datetimes, self.data_name: values})
def exclude_outliers():
pass
-20
View File
@@ -1,20 +0,0 @@
class HelloWorld():
"""The docstring for this class
Description: Bla bla bla
Attributes
----------
word: str
A word
Methods
-------
__init__: HelloWorld
The class constructor
"""
def __init__(self, word = "Hellow"):
self.word = word
+96
View File
@@ -0,0 +1,96 @@
# Author: David Tschan
# Institute: Paul-Scherrer Institute, Laboratory for Atmospheric Chemistry, Multiphase Chemistry Group,
# Forschungsstrasse 111, 5232 Villigen PSI, Switzerland
# Role: Master Student
# License: n/a
# Date: 2026
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### SUBMODULE DOCSTRING
"""The docstring for this submodule
"""
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### IMPORTS AND CONFIGURATIONS
import numpy as np
import pandas as pd
from defs.Helper import DATFile
from defs.SMPS import OFRAnalyser
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### OzoneAnalyser.py
class OzoneAnalyser():
"""The docstring for this class
Description: Bla bla bla
Attributes
----------
word: str
A word
Methods
-------
__init__: HelloWorld
The class constructor
"""
def __init__(self, file: DATFile, on_time_interval):
self.file = file
self.on_time_interval = on_time_interval
self.averaged_data = None
def GetData(self):
self.file.read()
def AverageWithSMPS(self, smps_analyser: OFRAnalyser, cut_edges: int, subtract_baseline = ['yes', 5]):
avg_ozone = []
mprr_data = []
local_smps_data = smps_analyser.data[(smps_analyser.data['Starting Time (-)'] >= smps_analyser.on_time_interval[0]) &
(smps_analyser.data['Starting Time (-)'] <= smps_analyser.on_time_interval[1])].reset_index()
baseline = None
for index, data in local_smps_data.iterrows():
start = data['Starting Time (-)']
if index == 0:
if subtract_baseline[0] == 'yes':
baseline_start = start - pd.Timedelta(minutes = int(subtract_baseline[1]))
baseline_ozone_data = self.file.data[(self.file.data['timestamp'] >= baseline_start) &
(self.file.data['timestamp'] <= start)]
baseline = np.average(baseline_ozone_data['ozone'])
if index in list(range(cut_edges)):
continue
stop = start + pd.Timedelta(seconds = data['Sampling Time (s)'])
mprr_data.append(data['Mass Production Rate (kg/s)'])
local_ozone_data = self.file.data[(self.file.data['timestamp'] >= start) &
(self.file.data['timestamp'] <= stop)]
avg_ozone.append(np.average(local_ozone_data['ozone']))
for sub_index in list(range(cut_edges)):
del avg_ozone[-(sub_index + 1)]
del mprr_data[-(sub_index + 1)]
out_mprr_data = np.array(mprr_data)
if subtract_baseline[0] == 'yes':
out_avg_ozone = np.array([baseline - value for value in avg_ozone])
elif subtract_baseline[0] != 'yes':
out_avg_ozone = np.array([value for value in avg_ozone])
self.averaged_data = pd.DataFrame({'Ozone (ppb)': out_avg_ozone, 'Mass Production Rate (kg/s)': out_mprr_data})
+16 -2
View File
@@ -1,3 +1,13 @@
# Author: David Tschan
# Institute: Paul-Scherrer Institute, Laboratory for Atmospheric Chemistry, Multiphase Chemistry Group,
# Forschungsstrasse 111, 5232 Villigen PSI, Switzerland
# Role: Master Student
# License: n/a
# Date: 2026
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### SUBMODULE DOCSTRING
"""The docstring for this submodule
"""
@@ -10,7 +20,7 @@ import math
import warnings
### ----------------------------------------------------------------------------------------------------------------------------------- ###
### OFR ANALYSIS
### OFR.py
class Distribution():
@@ -305,19 +315,23 @@ class OFRAnalyser:
A string pointing to the flow data source file
sample_number_list: [int]
A list of integers indicating which samples to consider
on_time_interval: [pd.Timestamp]
A list with two elements containing the pd.Timestamp objects when the VOC flow was switched on and off, respectively.
max_samples: int
The highest sample available in the data
data: pandas.DataFrame
A dataframe containing all the data
"""
def __init__(self, data_source_file, flow_source_file, smpl_number_list, data_separator = ',') -> None:
def __init__(self, data_source_file, flow_source_file, smpl_number_list, on_time_interval, data_separator = ',') -> None:
self.data_source_file = data_source_file
self.flow_source_file = flow_source_file
self.smpl_number_list = smpl_number_list
self.on_time_interval = on_time_interval
self.__data_separator = data_separator
with open(self.data_source_file, 'r', errors = 'ignore') as file:
for i, line in enumerate(file.readlines()):
if i == 17:
+10 -53
View File
@@ -1,5 +1,6 @@
# Importing custom code
from defs.OFR import OFRSample, OFRAnalyser
from defs.SMPS import OFRAnalyser
from defs.OzoneMonitor import OzoneAnalyser
from defs.Helper import DATFile
# Importing required libraries
@@ -7,62 +8,18 @@ import numpy as np
from pathlib import Path
import pandas as pd
def ozone_averager(ozon_analyser: DATFile, smps_analyser: OFRAnalyser, voc_on_times, cut_edges = True, subtract_5min_baseline = True) -> np.ndarray:
average_ozon_values = []
mass_production_rates = []
local_smps_data = smps_analyser.data[(smps_analyser.data['Starting Time (-)'] >= voc_on_times[0]) & (smps_analyser.data['Starting Time (-)'] >= voc_on_times[0])].reset_index()
baseline = None
for index, data in local_smps_data.iterrows():
start = data['Starting Time (-)']
if index == 0:
if subtract_5min_baseline == True:
baseline_start = start - pd.Timedelta(minutes=5)
baseline_ozone_data = ozon_analyser.data[(ozon_analyser.data['timestamp'] >= baseline_start) & (ozon_analyser.data['timestamp'] <= start)]
baseline = np.average(baseline_ozone_data['ozone'])
if cut_edges == True:
continue
stop = start + pd.Timedelta(seconds = data['Sampling Time (s)'])
mass_production_rates.append(data['Mass Production Rate (kg/s)'])
local_ozone_data = ozon_analyser.data[(ozon_analyser.data['timestamp'] >= start) & (ozon_analyser.data['timestamp'] <= stop)]
average_ozon_values.append(np.average(local_ozone_data['ozone']))
if cut_edges == True:
del average_ozon_values[-1]
del mass_production_rates[-1]
if subtract_5min_baseline == True:
output_average_ozone_values = [baseline - value for value in average_ozon_values]
elif subtract_5min_baseline == False:
output_average_ozone_values = [value for value in average_ozon_values]
return output_average_ozone_values, mass_production_rates
# Linking to the data
# Specify the source file paths to for SMPS data for the different filters used
smps_analyser = OFRAnalyser(data_source_file = Path(r"Z:\Data\SMPS\processed\2026\09_September\20260903\20260903_aPinene_SOA.txt"),
flow_source_file = Path(r"Z:\People\David_Tschan\OFR_SMPS\flow_files\20260903_SET02_EXP14_flow_file.txt"),
smpl_number_list = range(1, 60))
flow_source_file = Path(r"Z:\People\David_Tschan\OFR_SMPS\flow_files\20260903_SET02_EXP14_flow_file.txt"),
smpl_number_list = range(1, 60),
on_time_interval = [pd.Timestamp('2026-09-03 15:20:00'), pd.Timestamp('2026-09-03 16:20:00')])
# Specify the source file paths to the API O3 monitor data for the different filters used
ozon_analyser =DATFile(file = Path(r"Z:\Data\API_O3\2026\09_September\2026-09-03_14.23.44_PC14750_API_O3.dat"), data_name = 'ozone')
voc_on_times = [pd.Timestamp('2026-09-03 15:20:00'), pd.Timestamp('2026-09-03 16:20:00')]
ozon_analyser = OzoneAnalyser(file = DATFile(file = Path(r"Z:\Data\API_O3\2026\09_September\2026-09-03_14.23.44_PC14750_API_O3.dat"), data_name = 'ozone'),
on_time_interval=[pd.Timestamp('2026-09-03 14:35:00'), pd.Timestamp('2026-09-03 16:50:00')])
smps_analyser.GetData()
ozon_analyser.read()
ozon_analyser.GetData()
ozone_average, mass_production_rates = ozone_averager(ozon_analyser=ozon_analyser, smps_analyser=smps_analyser, voc_on_times = voc_on_times, cut_edges=False, subtract_5min_baseline=True)
ozon_analyser.AverageWithSMPS(smps_analyser = smps_analyser, cut_edges = 2, subtract_baseline = ['yes', 5])
print('hello')
print(len(ozon_analyser.averaged_data))