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:
1 parent
bf72e777fa
commit
75d7f6f287
6 files changed
+161
-79
No files matched your search
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Python Debugger: Current File",
|
||||
"name": "Debug Current File",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
|
||||
+38
-3
@@ -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
|
||||
@@ -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
|
||||
@@ -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})
|
||||
@@ -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:
|
||||
@@ -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))
|
||||
Reference in new issue
Block a user