Skip to content

Commit b4854b9

Browse files
committed
fixed unit conversion bug
1 parent 069a1f6 commit b4854b9

File tree

5 files changed

+94
-64
lines changed

5 files changed

+94
-64
lines changed
Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
11
[All]
2-
network = eea/eionet
3-
ghost_version = 1.5
4-
species = sconco3 #,sconco3,sconcco,pm10,pm2p5
5-
resolution = hourly # daily for interpolation, hourly/3hourly for download
6-
start_date = 20230101
7-
end_date = 20230201
2+
network = EEA,CHILE_SINCA,CNEMC,US_EPA_AQS,GHOST #,CHILE_SINCA,CNEMC,EEA,US_EPA_AQS,GHOST,CHILE_SINCA,CNEMC,EEA,US_EPA_AQS,GHOST
3+
ghost_version = 1.6
4+
species = sconco3,sconcno2 #sconco3,sconcno2,sconcco #sconco3,sconco3,sconco3,sconco3,sconco3,sconcno2,sconcno2,sconcno2,sconcno2,sconcno2,sconcco,sconcco,sconcco,sconcco,sconcco #,pm10,pm2p5
5+
resolution = hourly # daily/hourly for interpolation, hourly/3hourly for download, hourly for report
6+
start_date = 20231201
7+
end_date = 20240301
8+
domain = global
89
map_extent = -180, 180, -90, 90
9-
experiments = a59g-regional-000 # cams_reanalysis for EAC4 reanalysis; cams_forecast for forecast
10+
experiments = cams_forecast (camsf) # camsr for EAC4 reanalysis; camsf for forecast
11+
ensemble = default
1012
interp_n_neighbours = default
1113
interpolated = False # download non interpolated experiments
12-
forecast = day1,day4 # for interpolation: will interpolate all forecast data available (no matter what is set here)
13-
temporal_colocation = True
14-
spatial_colocation = True
14+
forecast = day1 # for interpolation: will interpolate all forecast data available (no matter what is set here)
15+
resampling = 3hourly # resample to this resolution after interpolation
16+
17+
temporal_colocation = True # between exp and obs
18+
spatial_colocation = False # across species
1519
report_type = cams2_82_bis
1620
report_summary = True
1721
report_stations = False
18-
report_title = CAMS2_82_bis_2024_MAM
19-
report_filename = CAMS2_82_bis_2024_MAM
22+
report_title = CAMS2_82_bis_2024_DJF_EEA_JP
23+
report_filename = CAMS2_82_bis_2024_DJF_EEA_JP
24+
statistic_mode = Temporal|Spatial
2025
statistic_aggregation = Median
2126
periodic_statistic_mode = Independent
2227
periodic_statistic_aggregation = Median
23-
timeseries_statistic_aggregation = Median
24-
25-
[[Aggregation_temporal_spatial]]
26-
statistic_mode = Temporal|Spatial
27-
28-
[[Aggregation_spatial_temporal]]
29-
statistic_mode = Spatial|Temporal
30-
31-
[[Aggregation_Flattened]]
32-
statistic_mode = Flattened
28+
timeseries_statistic_aggregation = Median

providentia/auxiliar.py

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -191,22 +191,22 @@ def get_standard_parameters_by_speci(speci, ghost_version):
191191
return standard_parameters[standard_parameter]
192192

193193

194-
def get_conversion_factor(initial_units, final_units, standard_parameter_speci):
195-
""" Get conversion factor to convert from initial to final units
194+
def unit_conversion(initial_units, final_units, standard_parameter_speci):
195+
""" Use unit_converter class to return conversion object from initial to final units.
196196
197197
Parameters
198198
----------
199-
final_units : str
200-
Input units
201199
initial_units : str
200+
Input units
201+
final_units : str
202202
Output units
203203
standard_parameter_speci : dict
204204
GHOST standard parameters dictionary
205205
206206
Returns
207207
-------
208-
float, str
209-
Conversion factor or error
208+
obj, str
209+
Conversion object or error
210210
"""
211211

212212
# import unit converter
@@ -215,43 +215,43 @@ def get_conversion_factor(initial_units, final_units, standard_parameter_speci):
215215

216216
# if units are unitless, then no need for conversion (i.e. conversion factor = 1.0)
217217
if (final_units == 'unitless') or (final_units == '-') or (final_units == '1'):
218-
return 1.0
218+
return type('convert_units', (object,), {'conversion_factor':1.0, 'output_standard_units':'unitless'})
219219

220220
# determine chemical formula of species
221221
if 'chemical_formula_charge' in list(standard_parameter_speci.keys()):
222222
speci_chemical_formula = standard_parameter_speci['chemical_formula_charge']
223223
else:
224224
speci_chemical_formula = standard_parameter_speci['chemical_formula']
225225

226-
# get observational quantity for conversion
227-
if ('units_quantity' in list(standard_parameter_speci.keys())) and (final_units == standard_parameter_speci['standard_units']):
228-
final_quantity = standard_parameter_speci['units_quantity']
226+
# get input (model) quantity for conversion
227+
if ('units_quantity' in list(standard_parameter_speci.keys())) and (initial_units == standard_parameter_speci['standard_units']):
228+
initial_quantity = standard_parameter_speci['units_quantity']
229229
else:
230-
conv_obj = unit_converter.convert_units(final_units, final_units, 1,
230+
conv_obj = unit_converter.convert_units(initial_units, initial_units, 1,
231231
species=speci_chemical_formula)
232-
final_quantity = conv_obj.output_quantity
232+
initial_quantity = conv_obj.output_quantity
233233

234-
# get model quantity for conversion
234+
# get output (observational) quantity for conversion
235235
if ('units_quantity' in list(standard_parameter_speci.keys())) and (final_units == standard_parameter_speci['standard_units']):
236-
initial_quantity = standard_parameter_speci['units_quantity']
236+
final_quantity = standard_parameter_speci['units_quantity']
237237
else:
238-
conv_obj = unit_converter.convert_units(initial_units, initial_units, 1,
238+
conv_obj = unit_converter.convert_units(final_units, final_units, 1,
239239
species=speci_chemical_formula)
240-
initial_quantity = conv_obj.output_quantity
240+
final_quantity = conv_obj.output_quantity
241241

242242
# unit converter module does not produce conversion factor for temperature,
243-
# but both observational and model units should be Kelvin (i.e. conversion factor = 1.0)
244-
# if model not in K then return error
243+
# but both input and output units should be Kelvin (i.e. conversion factor = 1.0)
244+
# if input not in K then return error
245245
if final_quantity == 'temperature':
246246
if initial_units == 'K':
247-
return 1.0
247+
return type('convert_units', (object,), {'conversion_factor':1.0, 'output_standard_units':'K'})
248248
else:
249-
error = "Experiment units should be 'K', but are set as '{}'".format(initial_units)
249+
error = "Error: Experiment units should be 'K', but are set as '{}'".format(initial_units)
250250
return error
251251

252252
# initial and final quantities not equal (convert to observational units,
253253
# standard_temperature=293.15, standard_pressure=1013.25)
254-
if final_quantity != initial_quantity:
254+
if initial_quantity != final_quantity:
255255

256256
# convert units
257257
input_units = {'temperature': 'K',
@@ -266,12 +266,57 @@ def get_conversion_factor(initial_units, final_units, standard_parameter_speci):
266266
species=speci_chemical_formula,
267267
input_quantity=initial_quantity,
268268
output_quantity=final_quantity)
269-
return conv_obj.conversion_factor
270269

271270
# same quantity conversion
272271
else:
273272
conv_obj = unit_converter.convert_units(initial_units, final_units, 1.0,
274273
species=speci_chemical_formula,
275274
input_quantity=initial_quantity,
276275
output_quantity=final_quantity)
277-
return conv_obj.conversion_factor
276+
277+
# return conversion object
278+
return conv_obj
279+
280+
281+
def get_conversion_factor(initial_units, final_units, standard_parameter_speci):
282+
""" Get conversion factor to convert from initial to final units.
283+
Convenience wrapper for unit_conversion function.
284+
285+
Parameters
286+
----------
287+
initial_units : str
288+
Input units
289+
final_units : str
290+
Output units
291+
standard_parameter_speci : dict
292+
GHOST standard parameters dictionary
293+
294+
Returns
295+
-------
296+
float, str
297+
Conversion factor or error
298+
"""
299+
300+
conv_obj = unit_conversion(initial_units, final_units, standard_parameter_speci)
301+
return conv_obj.conversion_factor
302+
303+
304+
def get_standard_units(initial_units, standard_parameter_speci):
305+
""" Get Standarsised units for given initial units.
306+
Convenience wrapper for unit_conversion function.
307+
308+
Parameters
309+
----------
310+
initial_units : str
311+
Input units
312+
standard_parameter_speci : dict
313+
GHOST standard parameters dictionary
314+
315+
Returns
316+
-------
317+
str
318+
Output standard units or error
319+
"""
320+
321+
conv_obj = unit_conversion(initial_units, initial_units, standard_parameter_speci)
322+
return conv_obj.output_standard_units

providentia/interpolation/experiment_interpolation.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@
4242
# load the defined experiments paths and agrupations jsons
4343
interp_experiments = yaml.safe_load(open(join(PROVIDENTIA_ROOT, 'settings', 'interp_experiments.yaml')))
4444

45-
# add unit-converter submodule to python load path
46-
sys.path.append(join(PROVIDENTIA_ROOT,'providentia','dependencies','unit-converter'))
47-
import unit_converter
48-
4945
class ExperimentInterpolation(object):
5046
""" Class which handles interpolation of experiment data to surface observations. """
5147

providentia/interpolation/experiment_interpolation_submission.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ def submit_job_multiprocessing(self):
891891
"""Submit interpolation jobs using multiprocessing pool."""
892892

893893
# set resource usage parameters for estimating safe number of pool workers
894-
self.per_worker_mem_gb=0.75
894+
self.per_worker_mem_gb=2.0
895895
self.per_worker_cpu_fraction=1.0/self.n_cpus
896896
self.per_worker_swap_gb=0.1
897897
self.cpu_fraction_limit=0.75

providentia/read.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import numpy as np
1414
import pandas as pd
1515

16-
from providentia.auxiliar import CURRENT_PATH, join
16+
from providentia.auxiliar import CURRENT_PATH, join, get_standard_units, get_standard_parameters_by_speci
1717
from .fields_menus import (init_representativity, init_period, init_metadata,
1818
update_representativity_fields, update_period_fields, update_metadata_fields,
1919
representativity_conf, period_conf, metadata_conf)
@@ -280,24 +280,17 @@ def read_setup(self, operations, experiments_to_remove=None, experiments_to_read
280280
# update measurement units for all species (take standard units for each speci from parameter dictionary)
281281
# non-GHOST
282282
if not self.read_instance.reading_ghost:
283-
# import unit converter
284-
sys.path.insert(1, join(CURRENT_PATH, 'dependencies/unit-converter'))
285-
import unit_converter
286283

287284
# convert non-GHOST units to standard format
288285
nonghost_standard_units = {}
289286
for speci in self.read_instance.nonghost_units.keys():
290287
input_units = self.read_instance.nonghost_units[speci]
291-
if input_units not in ['-', 'unitless']:
292-
output_units = copy.deepcopy(input_units)
293-
if 'chemical_formula_charge' in list(self.read_instance.parameter_dictionary[speci].keys()):
294-
formula = self.read_instance.parameter_dictionary[speci]['chemical_formula_charge']
295-
else:
296-
formula = self.read_instance.parameter_dictionary[speci]['chemical_formula']
297-
conv_obj = unit_converter.convert_units(input_units, output_units, 1, species=formula)
298-
nonghost_standard_units[speci] = conv_obj.output_standard_units
299-
else:
300-
nonghost_standard_units[speci] = 'unitless'
288+
standard_parameter_speci = get_standard_parameters_by_speci(speci, self.read_instance.ghost_version)
289+
standard_input_units = get_standard_units(input_units, standard_parameter_speci)
290+
if 'Error:' in standard_input_units:
291+
self.read_instance.logger.error(standard_input_units)
292+
sys.exit(1)
293+
nonghost_standard_units[speci] = standard_input_units
301294
self.read_instance.measurement_units = {speci.split('|')[1]:nonghost_standard_units[speci.split('|')[1]]
302295
for speci in self.read_instance.networkspecies}
303296
# GHOST

0 commit comments

Comments
 (0)