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.
Files changed (38) hide show
  1. {pyelq-1.1.3 → pyelq-1.2.0}/PKG-INFO +45 -44
  2. {pyelq-1.1.3 → pyelq-1.2.0}/README.md +31 -31
  3. {pyelq-1.1.3 → pyelq-1.2.0}/pyproject.toml +18 -18
  4. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/__init__.py +1 -0
  5. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/__init__.py +1 -0
  6. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/background.py +19 -13
  7. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/component.py +2 -1
  8. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/error_model.py +2 -1
  9. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/offset.py +2 -1
  10. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/component/source_model.py +78 -29
  11. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/coordinate_system.py +1 -0
  12. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/data_access/__init__.py +1 -0
  13. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/data_access/data_access.py +1 -1
  14. pyelq-1.2.0/src/pyelq/dispersion_model/__init__.py +6 -0
  15. pyelq-1.2.0/src/pyelq/dispersion_model/dispersion_model.py +202 -0
  16. pyelq-1.2.0/src/pyelq/dispersion_model/finite_volume.py +1084 -0
  17. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/dispersion_model/gaussian_plume.py +8 -189
  18. pyelq-1.2.0/src/pyelq/dispersion_model/site_layout.py +97 -0
  19. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/dlm.py +11 -15
  20. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/gas_species.py +1 -0
  21. pyelq-1.2.0/src/pyelq/meteorology/__init__.py +6 -0
  22. {pyelq-1.1.3/src/pyelq → pyelq-1.2.0/src/pyelq/meteorology}/meteorology.py +388 -387
  23. pyelq-1.2.0/src/pyelq/meteorology/meteorology_windfield.py +180 -0
  24. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/model.py +2 -1
  25. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/plotting/__init__.py +1 -0
  26. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/plotting/plot.py +16 -25
  27. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/preprocessing.py +98 -38
  28. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/__init__.py +1 -0
  29. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/sensor.py +70 -5
  30. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/source_map.py +1 -0
  31. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/__init__.py +1 -0
  32. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/post_processing.py +1 -0
  33. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/support_functions/spatio_temporal_interpolation.py +1 -0
  34. pyelq-1.1.3/src/pyelq/dispersion_model/__init__.py +0 -5
  35. {pyelq-1.1.3 → pyelq-1.2.0}/LICENSE.md +0 -0
  36. {pyelq-1.1.3 → pyelq-1.2.0}/LICENSES/Apache-2.0.txt +0 -0
  37. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/beam.py +0 -0
  38. {pyelq-1.1.3 → pyelq-1.2.0}/src/pyelq/sensor/satellite.py +0 -0
@@ -1,27 +1,28 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: pyelq
3
- Version: 1.1.3
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.9
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.2)
18
- Requires-Dist: openmcmc (==1.0.6)
19
- Requires-Dist: pandas (>=2.2.3)
20
- Requires-Dist: plotly (>=6.0.0)
21
- Requires-Dist: pymap3d (>=3.1.0)
22
- Requires-Dist: scikit-learn (>=1.6.1)
23
- Requires-Dist: scipy (>=1.13.1)
24
- Requires-Dist: shapely (>=2.0.7)
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.1.3"
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.9"
24
- pandas = ">=2.2.3"
25
- numpy = ">=2.0.2"
26
- plotly = ">=6.0.0"
27
- scipy = ">=1.13.1"
28
- pymap3d = ">=3.1.0"
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.0.7"
31
- scikit-learn = ">=1.6.1"
32
- openmcmc = "==1.0.6"
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.1.0"
39
- isort = ">=6.0.0"
38
+ black = ">=25.12.0"
39
+ isort = ">=7.0.0"
40
40
  pydocstyle = ">=6.3.0"
41
- pylint = ">=3.3.4"
42
- pytest = ">=8.3.4"
43
- pytest-cov = ">=6.0.0"
44
- mkdocs-material = ">=9.6.2"
45
- mkdocstrings-python = ">=1.14.5"
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 = "^6.29.5"
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*"
@@ -2,6 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
  """Main pyELQ module."""
5
+
5
6
  __all__ = [
6
7
  "component",
7
8
  "data_access",
@@ -3,4 +3,5 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  """Components Module."""
6
+
6
7
  __all__ = ["background", "component", "error_model", "offset", "source_model"]
@@ -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),..., b_nlct(t_1),...,b_1(t_k),..., b_nlct(t_k),...].T
197
- where nlct is the number of sensor locations.
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.array(
307
- pd.date_range(start=np.min(sensor_object.time), end=np.max(sensor_object.time), periods=self.n_time),
308
- dtype="datetime64[ns]",
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: