pyelq 1.1.3__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyelq-1.1.3 → pyelq-1.2.0}/PKG-INFO +45 -44
- {pyelq-1.1.3 → pyelq-1.2.0}/README.md +31 -31
- {pyelq-1.1.3 → pyelq-1.2.0}/pyproject.toml +18 -18
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/background.py +19 -13
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/component.py +2 -1
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/error_model.py +2 -1
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/offset.py +2 -1
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/source_model.py +78 -29
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/coordinate_system.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/data_access/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/data_access/data_access.py +1 -1
- pyelq-1.2.0/src/pyelq/dispersion_model/__init__.py +6 -0
- pyelq-1.2.0/src/pyelq/dispersion_model/dispersion_model.py +202 -0
- pyelq-1.2.0/src/pyelq/dispersion_model/finite_volume.py +1084 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/dispersion_model/gaussian_plume.py +8 -189
- pyelq-1.2.0/src/pyelq/dispersion_model/site_layout.py +97 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/dlm.py +11 -15
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/gas_species.py +1 -0
- pyelq-1.2.0/src/pyelq/meteorology/__init__.py +6 -0
- {pyelq-1.1.3/src/pyelq → pyelq-1.2.0/src/pyelq/meteorology}/meteorology.py +388 -387
- pyelq-1.2.0/src/pyelq/meteorology/meteorology_windfield.py +180 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/model.py +2 -1
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/plotting/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/plotting/plot.py +16 -25
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/preprocessing.py +98 -38
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/sensor.py +70 -5
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/source_map.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/__init__.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/post_processing.py +1 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/spatio_temporal_interpolation.py +1 -0
- pyelq-1.1.3/src/pyelq/dispersion_model/__init__.py +0 -5
- {pyelq-1.1.3 → pyelq-1.2.0}/LICENSE.md +0 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/LICENSES/Apache-2.0.txt +0 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/beam.py +0 -0
- {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/satellite.py +0 -0
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pyelq
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Package for detection, localization and quantification code.
|
|
5
5
|
License: Apache-2.0
|
|
6
|
+
License-File: LICENSE.md
|
|
7
|
+
License-File: LICENSES/Apache-2.0.txt
|
|
6
8
|
Keywords: gas dispersion,emission,detection,localization,quantification
|
|
7
9
|
Author: Bas van de Kerkhof
|
|
8
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.11
|
|
9
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
12
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
17
|
Requires-Dist: geojson (>=3.2.0)
|
|
17
|
-
Requires-Dist: numpy (>=2.0
|
|
18
|
-
Requires-Dist: openmcmc (==1.0.
|
|
19
|
-
Requires-Dist: pandas (>=2.
|
|
20
|
-
Requires-Dist: plotly (>=6.
|
|
21
|
-
Requires-Dist: pymap3d (>=3.
|
|
22
|
-
Requires-Dist: scikit-learn (>=1.
|
|
23
|
-
Requires-Dist: scipy (>=1.
|
|
24
|
-
Requires-Dist: shapely (>=2.
|
|
18
|
+
Requires-Dist: numpy (>=2.4.0)
|
|
19
|
+
Requires-Dist: openmcmc (==1.0.8)
|
|
20
|
+
Requires-Dist: pandas (>=2.3.3,<3.0.0)
|
|
21
|
+
Requires-Dist: plotly (>=6.5.0)
|
|
22
|
+
Requires-Dist: pymap3d (>=3.2.0)
|
|
23
|
+
Requires-Dist: scikit-learn (>=1.8.0)
|
|
24
|
+
Requires-Dist: scipy (>=1.16.3)
|
|
25
|
+
Requires-Dist: shapely (>=2.1.2)
|
|
25
26
|
Project-URL: Documentation, https://sede-open.github.io/pyELQ/
|
|
26
27
|
Project-URL: Homepage, https://sede-open.github.io/pyELQ/
|
|
27
28
|
Project-URL: Repository, https://github.com/sede-open/pyELQ
|
|
@@ -51,27 +52,27 @@ SPDX-License-Identifier: Apache-2.0
|
|
|
51
52
|
</div>
|
|
52
53
|
|
|
53
54
|
# pyELQ
|
|
54
|
-
This repository contains the Python Emission Localization and Quantification software we call pyELQ. It is code used
|
|
55
|
-
for gas dispersion modelling, in particular methane emissions detection, localization and quantification.
|
|
55
|
+
This repository contains the Python Emission Localization and Quantification software we call pyELQ. It is code used
|
|
56
|
+
for gas dispersion modelling, in particular methane emissions detection, localization and quantification.
|
|
56
57
|
|
|
57
58
|
***
|
|
58
59
|
# Background
|
|
59
|
-
The **py**thon **E**mission **L**ocalization and **Q**uantification (pyELQ) code aims to maximize effective use of
|
|
60
|
-
existing measurement data, especially from continuous monitoring solutions. The code has been developed to detect,
|
|
61
|
-
localize, and quantify methane emissions from concentration and wind measurements. It can be used in combination with
|
|
60
|
+
The **py**thon **E**mission **L**ocalization and **Q**uantification (pyELQ) code aims to maximize effective use of
|
|
61
|
+
existing measurement data, especially from continuous monitoring solutions. The code has been developed to detect,
|
|
62
|
+
localize, and quantify methane emissions from concentration and wind measurements. It can be used in combination with
|
|
62
63
|
point or beam sensors that are placed strategically on an area of interest.
|
|
63
64
|
|
|
64
|
-
The algorithms in the pyELQ code are based a Bayesian statistics framework. pyELQ can ingest long-term concentration
|
|
65
|
-
and wind data, and it performs an inversion to predict the likely strengths and locations of persistent methane sources.
|
|
66
|
-
The goal is to arrive at a plausible estimate of methane emissions from an area of interest that matches the measured
|
|
67
|
-
data. The predictions from pyELQ come with uncertainty ranges that are representative of probability density functions
|
|
68
|
-
sampled by a Markov Chain Monte Carlo method. Time series of varying length can be processed by pyELQ: in general,
|
|
69
|
-
the Bayesian inversion leads to a more constrained solution if more high-precision measurement data is available.
|
|
65
|
+
The algorithms in the pyELQ code are based a Bayesian statistics framework. pyELQ can ingest long-term concentration
|
|
66
|
+
and wind data, and it performs an inversion to predict the likely strengths and locations of persistent methane sources.
|
|
67
|
+
The goal is to arrive at a plausible estimate of methane emissions from an area of interest that matches the measured
|
|
68
|
+
data. The predictions from pyELQ come with uncertainty ranges that are representative of probability density functions
|
|
69
|
+
sampled by a Markov Chain Monte Carlo method. Time series of varying length can be processed by pyELQ: in general,
|
|
70
|
+
the Bayesian inversion leads to a more constrained solution if more high-precision measurement data is available.
|
|
70
71
|
We have tested our code under controlled conditions as well as in operating oil and gas facilities.
|
|
71
72
|
|
|
72
|
-
The information on the strength and the approximate location of methane emission sources provided by pyELQ can help
|
|
73
|
-
operators with more efficient identification and quantification of (unexpected) methane sources, in order to start
|
|
74
|
-
appropriate mitigating actions accordingly. The pyELQ code is being made available in an open-source environment,
|
|
73
|
+
The information on the strength and the approximate location of methane emission sources provided by pyELQ can help
|
|
74
|
+
operators with more efficient identification and quantification of (unexpected) methane sources, in order to start
|
|
75
|
+
appropriate mitigating actions accordingly. The pyELQ code is being made available in an open-source environment,
|
|
75
76
|
to support various assets in their quest to reduce methane emissions.
|
|
76
77
|
|
|
77
78
|
Use cases where the pyELQ code has been applied are described in the following papers:
|
|
@@ -81,30 +82,30 @@ Use cases where the pyELQ code has been applied are described in the following p
|
|
|
81
82
|
* Weidmann, D., Hirst, B. et al. "Locating and Quantifying Methane Emissions by Inverse Analysis of Path-Integrated Concentration Data Using a Markov-Chain Monte Carlo Approach." ACS Earth and Space Chemistry 2022 6 (9), 2190-2198 (https://doi.org/10.1021/acsearthspacechem.2c00093)
|
|
82
83
|
|
|
83
84
|
## Deployment design
|
|
84
|
-
The pyELQ code needs high-quality methane concentration and wind data to be able to provide reliable output on location
|
|
85
|
-
and quantification of methane emission sources. This requires methane concentration sensors of sufficiently high
|
|
86
|
-
precision in a layout that allows the detection of relevant methane emission sources, in combination with wind
|
|
87
|
-
measurements of high enough frequency and accuracy. The optimal sensor layout typically depends on the prevailing
|
|
88
|
-
meteorological conditions at the site of interest and requires multiple concentration sensors to cover the site under
|
|
89
|
-
different wind directions.
|
|
85
|
+
The pyELQ code needs high-quality methane concentration and wind data to be able to provide reliable output on location
|
|
86
|
+
and quantification of methane emission sources. This requires methane concentration sensors of sufficiently high
|
|
87
|
+
precision in a layout that allows the detection of relevant methane emission sources, in combination with wind
|
|
88
|
+
measurements of high enough frequency and accuracy. The optimal sensor layout typically depends on the prevailing
|
|
89
|
+
meteorological conditions at the site of interest and requires multiple concentration sensors to cover the site under
|
|
90
|
+
different wind directions.
|
|
90
91
|
|
|
91
92
|
## pyELQ data interpretation
|
|
92
|
-
The results from pyELQ come with uncertainty ranges that are representative of probability density functions sampled
|
|
93
|
-
by a Markov Chain Monte Carlo method. One should take these uncertainty ranges into account when interpreting the pyELQ
|
|
94
|
-
output data. Remember that absence of evidence for methane emissions does not always imply evidence for absence of
|
|
95
|
-
methane emissions; for instance, when meteorological conditions are such that there is no sensor downwind of a methane
|
|
96
|
-
source during the selected monitoring period, then it will be impossible to detect, localize and quantify
|
|
97
|
-
this particular source.
|
|
98
|
-
Also, there are limitations to the forward dispersion model which is used in the analysis.
|
|
99
|
-
For example, the performance of the Gaussian plume dispersion model will degrade at lower wind speeds.
|
|
100
|
-
Therefore, careful interpretation of the data is always required.
|
|
93
|
+
The results from pyELQ come with uncertainty ranges that are representative of probability density functions sampled
|
|
94
|
+
by a Markov Chain Monte Carlo method. One should take these uncertainty ranges into account when interpreting the pyELQ
|
|
95
|
+
output data. Remember that absence of evidence for methane emissions does not always imply evidence for absence of
|
|
96
|
+
methane emissions; for instance, when meteorological conditions are such that there is no sensor downwind of a methane
|
|
97
|
+
source during the selected monitoring period, then it will be impossible to detect, localize and quantify
|
|
98
|
+
this particular source.
|
|
99
|
+
Also, there are limitations to the forward dispersion model which is used in the analysis.
|
|
100
|
+
For example, the performance of the Gaussian plume dispersion model will degrade at lower wind speeds.
|
|
101
|
+
Therefore, careful interpretation of the data is always required.
|
|
101
102
|
|
|
102
103
|
***
|
|
103
104
|
# Installing pyELQ as a package
|
|
104
105
|
Suppose you want to use this pyELQ package in a different project.
|
|
105
|
-
You can install it from [PyPi](https://pypi.org/project/pyelq/) through pip
|
|
106
|
+
You can install it from [PyPi](https://pypi.org/project/pyelq/) through pip
|
|
106
107
|
`pip install pyelq`.
|
|
107
|
-
Or you could clone the repository and install it from the source code.
|
|
108
|
+
Or you could clone the repository and install it from the source code.
|
|
108
109
|
After activating the environment you want to install pyELQ in, open a terminal, move to the main pyELQ folder
|
|
109
110
|
where pyproject.toml is located and run `pip install .`, optionally you can pass the `-e` flag is for editable mode.
|
|
110
111
|
All the main options, info and settings for the package are found in the pyproject.toml file which sits in this repo
|
|
@@ -22,27 +22,27 @@ SPDX-License-Identifier: Apache-2.0
|
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
# pyELQ
|
|
25
|
-
This repository contains the Python Emission Localization and Quantification software we call pyELQ. It is code used
|
|
26
|
-
for gas dispersion modelling, in particular methane emissions detection, localization and quantification.
|
|
25
|
+
This repository contains the Python Emission Localization and Quantification software we call pyELQ. It is code used
|
|
26
|
+
for gas dispersion modelling, in particular methane emissions detection, localization and quantification.
|
|
27
27
|
|
|
28
28
|
***
|
|
29
29
|
# Background
|
|
30
|
-
The **py**thon **E**mission **L**ocalization and **Q**uantification (pyELQ) code aims to maximize effective use of
|
|
31
|
-
existing measurement data, especially from continuous monitoring solutions. The code has been developed to detect,
|
|
32
|
-
localize, and quantify methane emissions from concentration and wind measurements. It can be used in combination with
|
|
30
|
+
The **py**thon **E**mission **L**ocalization and **Q**uantification (pyELQ) code aims to maximize effective use of
|
|
31
|
+
existing measurement data, especially from continuous monitoring solutions. The code has been developed to detect,
|
|
32
|
+
localize, and quantify methane emissions from concentration and wind measurements. It can be used in combination with
|
|
33
33
|
point or beam sensors that are placed strategically on an area of interest.
|
|
34
34
|
|
|
35
|
-
The algorithms in the pyELQ code are based a Bayesian statistics framework. pyELQ can ingest long-term concentration
|
|
36
|
-
and wind data, and it performs an inversion to predict the likely strengths and locations of persistent methane sources.
|
|
37
|
-
The goal is to arrive at a plausible estimate of methane emissions from an area of interest that matches the measured
|
|
38
|
-
data. The predictions from pyELQ come with uncertainty ranges that are representative of probability density functions
|
|
39
|
-
sampled by a Markov Chain Monte Carlo method. Time series of varying length can be processed by pyELQ: in general,
|
|
40
|
-
the Bayesian inversion leads to a more constrained solution if more high-precision measurement data is available.
|
|
35
|
+
The algorithms in the pyELQ code are based a Bayesian statistics framework. pyELQ can ingest long-term concentration
|
|
36
|
+
and wind data, and it performs an inversion to predict the likely strengths and locations of persistent methane sources.
|
|
37
|
+
The goal is to arrive at a plausible estimate of methane emissions from an area of interest that matches the measured
|
|
38
|
+
data. The predictions from pyELQ come with uncertainty ranges that are representative of probability density functions
|
|
39
|
+
sampled by a Markov Chain Monte Carlo method. Time series of varying length can be processed by pyELQ: in general,
|
|
40
|
+
the Bayesian inversion leads to a more constrained solution if more high-precision measurement data is available.
|
|
41
41
|
We have tested our code under controlled conditions as well as in operating oil and gas facilities.
|
|
42
42
|
|
|
43
|
-
The information on the strength and the approximate location of methane emission sources provided by pyELQ can help
|
|
44
|
-
operators with more efficient identification and quantification of (unexpected) methane sources, in order to start
|
|
45
|
-
appropriate mitigating actions accordingly. The pyELQ code is being made available in an open-source environment,
|
|
43
|
+
The information on the strength and the approximate location of methane emission sources provided by pyELQ can help
|
|
44
|
+
operators with more efficient identification and quantification of (unexpected) methane sources, in order to start
|
|
45
|
+
appropriate mitigating actions accordingly. The pyELQ code is being made available in an open-source environment,
|
|
46
46
|
to support various assets in their quest to reduce methane emissions.
|
|
47
47
|
|
|
48
48
|
Use cases where the pyELQ code has been applied are described in the following papers:
|
|
@@ -52,30 +52,30 @@ Use cases where the pyELQ code has been applied are described in the following p
|
|
|
52
52
|
* Weidmann, D., Hirst, B. et al. "Locating and Quantifying Methane Emissions by Inverse Analysis of Path-Integrated Concentration Data Using a Markov-Chain Monte Carlo Approach." ACS Earth and Space Chemistry 2022 6 (9), 2190-2198 (https://doi.org/10.1021/acsearthspacechem.2c00093)
|
|
53
53
|
|
|
54
54
|
## Deployment design
|
|
55
|
-
The pyELQ code needs high-quality methane concentration and wind data to be able to provide reliable output on location
|
|
56
|
-
and quantification of methane emission sources. This requires methane concentration sensors of sufficiently high
|
|
57
|
-
precision in a layout that allows the detection of relevant methane emission sources, in combination with wind
|
|
58
|
-
measurements of high enough frequency and accuracy. The optimal sensor layout typically depends on the prevailing
|
|
59
|
-
meteorological conditions at the site of interest and requires multiple concentration sensors to cover the site under
|
|
60
|
-
different wind directions.
|
|
55
|
+
The pyELQ code needs high-quality methane concentration and wind data to be able to provide reliable output on location
|
|
56
|
+
and quantification of methane emission sources. This requires methane concentration sensors of sufficiently high
|
|
57
|
+
precision in a layout that allows the detection of relevant methane emission sources, in combination with wind
|
|
58
|
+
measurements of high enough frequency and accuracy. The optimal sensor layout typically depends on the prevailing
|
|
59
|
+
meteorological conditions at the site of interest and requires multiple concentration sensors to cover the site under
|
|
60
|
+
different wind directions.
|
|
61
61
|
|
|
62
62
|
## pyELQ data interpretation
|
|
63
|
-
The results from pyELQ come with uncertainty ranges that are representative of probability density functions sampled
|
|
64
|
-
by a Markov Chain Monte Carlo method. One should take these uncertainty ranges into account when interpreting the pyELQ
|
|
65
|
-
output data. Remember that absence of evidence for methane emissions does not always imply evidence for absence of
|
|
66
|
-
methane emissions; for instance, when meteorological conditions are such that there is no sensor downwind of a methane
|
|
67
|
-
source during the selected monitoring period, then it will be impossible to detect, localize and quantify
|
|
68
|
-
this particular source.
|
|
69
|
-
Also, there are limitations to the forward dispersion model which is used in the analysis.
|
|
70
|
-
For example, the performance of the Gaussian plume dispersion model will degrade at lower wind speeds.
|
|
71
|
-
Therefore, careful interpretation of the data is always required.
|
|
63
|
+
The results from pyELQ come with uncertainty ranges that are representative of probability density functions sampled
|
|
64
|
+
by a Markov Chain Monte Carlo method. One should take these uncertainty ranges into account when interpreting the pyELQ
|
|
65
|
+
output data. Remember that absence of evidence for methane emissions does not always imply evidence for absence of
|
|
66
|
+
methane emissions; for instance, when meteorological conditions are such that there is no sensor downwind of a methane
|
|
67
|
+
source during the selected monitoring period, then it will be impossible to detect, localize and quantify
|
|
68
|
+
this particular source.
|
|
69
|
+
Also, there are limitations to the forward dispersion model which is used in the analysis.
|
|
70
|
+
For example, the performance of the Gaussian plume dispersion model will degrade at lower wind speeds.
|
|
71
|
+
Therefore, careful interpretation of the data is always required.
|
|
72
72
|
|
|
73
73
|
***
|
|
74
74
|
# Installing pyELQ as a package
|
|
75
75
|
Suppose you want to use this pyELQ package in a different project.
|
|
76
|
-
You can install it from [PyPi](https://pypi.org/project/pyelq/) through pip
|
|
76
|
+
You can install it from [PyPi](https://pypi.org/project/pyelq/) through pip
|
|
77
77
|
`pip install pyelq`.
|
|
78
|
-
Or you could clone the repository and install it from the source code.
|
|
78
|
+
Or you could clone the repository and install it from the source code.
|
|
79
79
|
After activating the environment you want to install pyELQ in, open a terminal, move to the main pyELQ folder
|
|
80
80
|
where pyproject.toml is located and run `pip install .`, optionally you can pass the `-e` flag is for editable mode.
|
|
81
81
|
All the main options, info and settings for the package are found in the pyproject.toml file which sits in this repo
|
|
@@ -8,7 +8,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
8
8
|
|
|
9
9
|
[tool.poetry]
|
|
10
10
|
name = "pyelq"
|
|
11
|
-
version = "1.
|
|
11
|
+
version = "1.2.0"
|
|
12
12
|
description = "Package for detection, localization and quantification code."
|
|
13
13
|
authors = ["Bas van de Kerkhof", "Matthew Jones", "David Randell"]
|
|
14
14
|
homepage = "https://sede-open.github.io/pyELQ/"
|
|
@@ -20,33 +20,33 @@ keywords = ["gas dispersion", "emission", "detection", "localization", "quantifi
|
|
|
20
20
|
packages = [{ include = "pyelq", from = "src" }]
|
|
21
21
|
|
|
22
22
|
[tool.poetry.dependencies]
|
|
23
|
-
python = ">=3.
|
|
24
|
-
pandas = ">=2.
|
|
25
|
-
numpy = ">=2.0
|
|
26
|
-
plotly = ">=6.
|
|
27
|
-
scipy = ">=1.
|
|
28
|
-
pymap3d = ">=3.
|
|
23
|
+
python = ">=3.11"
|
|
24
|
+
pandas = ">=2.3.3, <3.0.0"
|
|
25
|
+
numpy = ">=2.4.0"
|
|
26
|
+
plotly = ">=6.5.0"
|
|
27
|
+
scipy = ">=1.16.3"
|
|
28
|
+
pymap3d = ">=3.2.0"
|
|
29
29
|
geojson = ">=3.2.0"
|
|
30
|
-
shapely = ">=2.
|
|
31
|
-
scikit-learn = ">=1.
|
|
32
|
-
openmcmc = "==1.0.
|
|
30
|
+
shapely = ">=2.1.2"
|
|
31
|
+
scikit-learn = ">=1.8.0"
|
|
32
|
+
openmcmc = "==1.0.8"
|
|
33
33
|
|
|
34
34
|
[tool.poetry.group.contributor]
|
|
35
35
|
optional = true
|
|
36
36
|
|
|
37
37
|
[tool.poetry.group.contributor.dependencies]
|
|
38
|
-
black = ">=25.
|
|
39
|
-
isort = ">=
|
|
38
|
+
black = ">=25.12.0"
|
|
39
|
+
isort = ">=7.0.0"
|
|
40
40
|
pydocstyle = ">=6.3.0"
|
|
41
|
-
pylint = ">=
|
|
42
|
-
pytest = ">=
|
|
43
|
-
pytest-cov = ">=
|
|
44
|
-
mkdocs-material = ">=9.
|
|
45
|
-
mkdocstrings-python = ">=
|
|
41
|
+
pylint = ">=4.0.4"
|
|
42
|
+
pytest = ">=9.0.2"
|
|
43
|
+
pytest-cov = ">=7.0.0"
|
|
44
|
+
mkdocs-material = ">=9.7.1"
|
|
45
|
+
mkdocstrings-python = ">=2.0.1"
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
[tool.poetry.group.dev.dependencies]
|
|
49
|
-
ipykernel = "^
|
|
49
|
+
ipykernel = "^7.1.0"
|
|
50
50
|
|
|
51
51
|
[tool.pytest.ini_options]
|
|
52
52
|
addopts = "--cov=pyelq --cov-fail-under=90 --ignore-glob=*plot*"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# SPDX-FileCopyrightText: 2024 Shell Global Solutions International B.V. All Rights Reserved.
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
4
|
"""Model components for background modelling."""
|
|
6
5
|
|
|
7
6
|
from abc import abstractmethod
|
|
@@ -22,7 +21,7 @@ from sklearn.neighbors import NearestNeighbors
|
|
|
22
21
|
from pyelq.component.component import Component
|
|
23
22
|
from pyelq.coordinate_system import Coordinate
|
|
24
23
|
from pyelq.gas_species import GasSpecies
|
|
25
|
-
from pyelq.meteorology import MeteorologyGroup
|
|
24
|
+
from pyelq.meteorology.meteorology import MeteorologyGroup
|
|
26
25
|
from pyelq.sensor.beam import Beam
|
|
27
26
|
from pyelq.sensor.sensor import SensorGroup
|
|
28
27
|
|
|
@@ -51,6 +50,7 @@ class Background(Component):
|
|
|
51
50
|
initial_precision (float): initial value for the scalar precision parameter.
|
|
52
51
|
basis_matrix (sparse.csr_array): [n_obs x n_time] matrix mapping the background model parameters on to the
|
|
53
52
|
observations.
|
|
53
|
+
precision_time_0 (float): precision relating to the first time stamp in the model. Defaults to 0.01.
|
|
54
54
|
|
|
55
55
|
"""
|
|
56
56
|
|
|
@@ -65,6 +65,7 @@ class Background(Component):
|
|
|
65
65
|
prior_precision_rate: float = 1e-3
|
|
66
66
|
initial_precision: float = 1.0
|
|
67
67
|
basis_matrix: sparse.csr_array = field(init=False)
|
|
68
|
+
precision_time_0: float = field(init=False, default=0.01)
|
|
68
69
|
|
|
69
70
|
@abstractmethod
|
|
70
71
|
def initialise(self, sensor_object: SensorGroup, meteorology: MeteorologyGroup, gas_species: GasSpecies):
|
|
@@ -168,6 +169,9 @@ class TemporalBackground(Background):
|
|
|
168
169
|
def initialise(self, sensor_object: SensorGroup, meteorology: MeteorologyGroup, gas_species: GasSpecies):
|
|
169
170
|
"""Create temporal background model from sensor, meteorology and gas species inputs.
|
|
170
171
|
|
|
172
|
+
The precision matrix is made to be full rank by adjusting the precision at the first time point using the
|
|
173
|
+
precision_time_0 attribute.
|
|
174
|
+
|
|
171
175
|
Args:
|
|
172
176
|
sensor_object (SensorGroup): sensor data object.
|
|
173
177
|
meteorology (MeteorologyGroup): meteorology data object.
|
|
@@ -180,6 +184,8 @@ class TemporalBackground(Background):
|
|
|
180
184
|
self.n_parameter = len(self.time)
|
|
181
185
|
self.basis_matrix = sparse.csr_array((np.ones(self.n_obs), (np.array(range(self.n_obs)), unique_inverse)))
|
|
182
186
|
self.precision_matrix = gmrf.precision_temporal(time=self.time)
|
|
187
|
+
lam = self.precision_matrix[0, 0]
|
|
188
|
+
self.precision_matrix[0, 0] = lam * (2.0 - lam / (self.precision_time_0 + lam))
|
|
183
189
|
if self.mean_bg is None:
|
|
184
190
|
self.mean_bg = gas_species.global_background
|
|
185
191
|
|
|
@@ -193,8 +199,8 @@ class SpatioTemporalBackground(Background):
|
|
|
193
199
|
The background parameter is an [n_location * n_time x 1] (if self.spatial_dependence is True) or an [n_time x 1]
|
|
194
200
|
vector (if self.spatial_dependence is False). In the spatio-temporal case, the background vector is assumed to
|
|
195
201
|
unwrap over space and time as follows:
|
|
196
|
-
bg = [b_1(t_1), b_2(t_1),...,
|
|
197
|
-
where
|
|
202
|
+
bg = [b_1(t_1), b_2(t_1),..., b_n_lct(t_1),...,b_1(t_k),..., b_n_lct(t_k),...].T
|
|
203
|
+
where n_lct is the number of sensor locations.
|
|
198
204
|
This unwrapping mechanism is chosen as it greatly speeds up the sparse matrix operations in the solver (vs. the
|
|
199
205
|
alternative).
|
|
200
206
|
|
|
@@ -226,7 +232,6 @@ class SpatioTemporalBackground(Background):
|
|
|
226
232
|
spatial_precision_matrix (np.ndarray): spatial component of the precision matrix. The full model precision
|
|
227
233
|
matrix is the Kronecker product of this matrix with the self.temporal_precision_matrix. Simply set to 1 if
|
|
228
234
|
self.spatial_dependence is False.
|
|
229
|
-
precision_time_0 (float): precision relating to the first time stamp in the model. Defaults to 0.01.
|
|
230
235
|
|
|
231
236
|
"""
|
|
232
237
|
|
|
@@ -238,7 +243,6 @@ class SpatioTemporalBackground(Background):
|
|
|
238
243
|
location: Coordinate = field(init=False)
|
|
239
244
|
temporal_precision_matrix: Union[np.ndarray, sparse.csc_matrix] = field(init=False)
|
|
240
245
|
spatial_precision_matrix: np.ndarray = field(init=False)
|
|
241
|
-
precision_time_0: float = field(init=False, default=0.01)
|
|
242
246
|
|
|
243
247
|
def initialise(self, sensor_object: SensorGroup, meteorology: MeteorologyGroup, gas_species: GasSpecies):
|
|
244
248
|
"""Take data inputs and extract relevant properties.
|
|
@@ -303,10 +307,9 @@ class SpatioTemporalBackground(Background):
|
|
|
303
307
|
self.time = pd.array(np.unique(sensor_object.time), dtype="datetime64[ns]")
|
|
304
308
|
self.n_time = len(self.time)
|
|
305
309
|
else:
|
|
306
|
-
self.time = pd.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
)
|
|
310
|
+
self.time = pd.date_range(
|
|
311
|
+
start=np.min(sensor_object.time), end=np.max(sensor_object.time), periods=self.n_time
|
|
312
|
+
).array
|
|
310
313
|
|
|
311
314
|
def make_spatial_knots(self, sensor_object: SensorGroup):
|
|
312
315
|
"""Create the spatial grid for the model.
|
|
@@ -333,6 +336,9 @@ class SpatioTemporalBackground(Background):
|
|
|
333
336
|
|
|
334
337
|
Defined as the Kronecker product of the temporal precision matrix and the spatial precision matrix.
|
|
335
338
|
|
|
339
|
+
The precision matrix is made to be full rank by adjusting the precision at the first time point using the
|
|
340
|
+
precision_time_0 attribute.
|
|
341
|
+
|
|
336
342
|
"""
|
|
337
343
|
self.temporal_precision_matrix = gmrf.precision_temporal(time=self.time)
|
|
338
344
|
lam = self.temporal_precision_matrix[0, 0]
|
|
@@ -386,6 +392,6 @@ class SpatioTemporalBackground(Background):
|
|
|
386
392
|
self.location.north[k] = np.mean(sensor.location.to_enu().north, axis=0)
|
|
387
393
|
self.location.up[k] = np.mean(sensor.location.to_enu().up, axis=0)
|
|
388
394
|
else:
|
|
389
|
-
self.location.east[k] = sensor.location.to_enu().east
|
|
390
|
-
self.location.north[k] = sensor.location.to_enu().north
|
|
391
|
-
self.location.up[k] = sensor.location.to_enu().up
|
|
395
|
+
self.location.east[k] = sensor.location.to_enu().east.item()
|
|
396
|
+
self.location.north[k] = sensor.location.to_enu().north.item()
|
|
397
|
+
self.location.up[k] = sensor.location.to_enu().up.item()
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
5
|
"""Superclass for model components."""
|
|
6
|
+
|
|
6
7
|
from abc import ABC, abstractmethod
|
|
7
8
|
from dataclasses import dataclass
|
|
8
9
|
|
|
9
10
|
from openmcmc.model import Model
|
|
10
11
|
|
|
11
12
|
from pyelq.gas_species import GasSpecies
|
|
12
|
-
from pyelq.meteorology import MeteorologyGroup
|
|
13
|
+
from pyelq.meteorology.meteorology import MeteorologyGroup
|
|
13
14
|
from pyelq.sensor.sensor import SensorGroup
|
|
14
15
|
|
|
15
16
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# -*- coding: utf-8 -*-
|
|
6
6
|
"""Error model module."""
|
|
7
|
+
|
|
7
8
|
from dataclasses import dataclass, field
|
|
8
9
|
from typing import TYPE_CHECKING, Union
|
|
9
10
|
|
|
@@ -15,7 +16,7 @@ from openmcmc.sampler.sampler import NormalGamma
|
|
|
15
16
|
|
|
16
17
|
from pyelq.component.component import Component
|
|
17
18
|
from pyelq.gas_species import GasSpecies
|
|
18
|
-
from pyelq.meteorology import MeteorologyGroup
|
|
19
|
+
from pyelq.meteorology.meteorology import MeteorologyGroup
|
|
19
20
|
from pyelq.sensor.sensor import Sensor, SensorGroup
|
|
20
21
|
|
|
21
22
|
if TYPE_CHECKING:
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# -*- coding: utf-8 -*-
|
|
6
6
|
"""Offset module."""
|
|
7
|
+
|
|
7
8
|
from dataclasses import dataclass, field
|
|
8
9
|
from typing import TYPE_CHECKING, Union
|
|
9
10
|
|
|
@@ -17,7 +18,7 @@ from scipy import sparse
|
|
|
17
18
|
|
|
18
19
|
from pyelq.component.component import Component
|
|
19
20
|
from pyelq.gas_species import GasSpecies
|
|
20
|
-
from pyelq.meteorology import Meteorology
|
|
21
|
+
from pyelq.meteorology.meteorology import Meteorology
|
|
21
22
|
from pyelq.sensor.sensor import Sensor, SensorGroup
|
|
22
23
|
|
|
23
24
|
if TYPE_CHECKING:
|