@hestia-earth/engine-models 0.81.2 → 0.81.4
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.
- package/README.md +144 -0
- package/cjs/version.d.ts +1 -0
- package/{dist → cjs}/version.js +1 -1
- package/config/Cycle.json +8 -0
- package/esm/config.d.ts +31 -0
- package/esm/config.js +39 -0
- package/esm/index.js +5 -0
- package/esm/models.d.ts +41 -0
- package/esm/models.js +2 -0
- package/esm/utils.d.ts +6 -0
- package/esm/utils.js +33 -0
- package/esm/validate-config.d.ts +19 -0
- package/esm/validate-config.js +65 -0
- package/esm/version.d.ts +1 -0
- package/esm/version.js +1 -0
- package/model-links.json +8 -8
- package/package.json +25 -5
- package/LICENSE +0 -21
- package/dist/version.d.ts +0 -1
- package/search-results.json +0 -1
- package/src/config.spec.ts +0 -88
- package/src/config.ts +0 -101
- package/src/models.spec.ts +0 -11
- package/src/models.ts +0 -49
- package/src/utils.spec.ts +0 -118
- package/src/utils.ts +0 -67
- package/src/validate-config.spec.ts +0 -31
- package/src/validate-config.ts +0 -103
- package/src/version.ts +0 -1
- /package/{dist → cjs}/config.d.ts +0 -0
- /package/{dist → cjs}/config.js +0 -0
- /package/{dist → cjs}/index.d.ts +0 -0
- /package/{dist → cjs}/index.js +0 -0
- /package/{dist → cjs}/models.d.ts +0 -0
- /package/{dist → cjs}/models.js +0 -0
- /package/{dist → cjs}/utils.d.ts +0 -0
- /package/{dist → cjs}/utils.js +0 -0
- /package/{dist → cjs}/validate-config.d.ts +0 -0
- /package/{dist → cjs}/validate-config.js +0 -0
- /package/{src/index.ts → esm/index.d.ts} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# HESTIA Engine Models
|
|
2
|
+
|
|
3
|
+
[](https://gitlab.com/hestia-earth/hestia-engine-models/commits/master)
|
|
4
|
+
[](https://gitlab.com/hestia-earth/hestia-engine-models/commits/master)
|
|
5
|
+
|
|
6
|
+
HESTIA's set of models for running calculations or retrieving data using external datasets and internal lookups.
|
|
7
|
+
|
|
8
|
+
## Documentation
|
|
9
|
+
|
|
10
|
+
Documentation for every model can be found in the [HESTIA Guide](https://hestia.earth/guide/models).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
1. Install python `3.12` minimum
|
|
15
|
+
2. Install the module:
|
|
16
|
+
```bash
|
|
17
|
+
pip install hestia_earth.models
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Usage
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from hestia_earth.models.pooreNemecek2018 import run
|
|
24
|
+
|
|
25
|
+
cycle_data = {"@type": "Cycle", ...}
|
|
26
|
+
# cycle is a JSONLD node Cycle
|
|
27
|
+
result = run('no3ToGroundwaterSoilFlux', cycle_data)
|
|
28
|
+
print(result)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This will display only the result of the `no3ToGroundwaterSoilFlux` model (Emission).
|
|
32
|
+
|
|
33
|
+
Additionally, to reduce the number of queries to the HESTIA API and run the models faster, prefetching can be enabled:
|
|
34
|
+
```python
|
|
35
|
+
from hestia_earth.models.preload_requests import enable_preload
|
|
36
|
+
|
|
37
|
+
enable_preload()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Using the orchestrator
|
|
41
|
+
|
|
42
|
+
The models come with an "orchestrator", which allows you to run a pre-configured set of models instead of a single one.
|
|
43
|
+
|
|
44
|
+
The configuration for each Node (Cycle, Site or ImpactAssessment) can be found in the [config](./config) folder.
|
|
45
|
+
|
|
46
|
+
Usage:
|
|
47
|
+
```python
|
|
48
|
+
from hestia_earth.orchestrator import run
|
|
49
|
+
from hestia_earth.models.config import load_config
|
|
50
|
+
|
|
51
|
+
cycle = {"@type": "Cycle", ...}
|
|
52
|
+
result = run(cycle, load_config(cycle))
|
|
53
|
+
print(result)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This will display the Cycle recalculated with all HESTIA default models running.
|
|
57
|
+
|
|
58
|
+
#### Using Spatial Models
|
|
59
|
+
|
|
60
|
+
We have models that can gap-fill geographical information on a `Site`. If you want to use these models:
|
|
61
|
+
1. Install the library: `pip install hestia-earth-earth-engine`
|
|
62
|
+
2. Follow the [Getting Started instructions](https://gitlab.com/hestia-earth/hestia-earth-engine#getting-started).
|
|
63
|
+
|
|
64
|
+
### Collecting logs in JSON format
|
|
65
|
+
|
|
66
|
+
:info: This is an experimental feature and is not yet integrated in all the HESTIA tools.
|
|
67
|
+
|
|
68
|
+
To collect logs in JSON format:
|
|
69
|
+
1. Set the env variable `LOG_JSON_ENABLED` to `true`
|
|
70
|
+
1. Use the following code to collect contribution logs:
|
|
71
|
+
```python
|
|
72
|
+
from hestia_earth.orchestrator import run
|
|
73
|
+
from hestia_earth.models.config import load_config
|
|
74
|
+
from hestia_earth.models.jlog import reset_collected_logs, get_collected_logs
|
|
75
|
+
|
|
76
|
+
# make sure the logs are reset before each run
|
|
77
|
+
reset_collected_logs()
|
|
78
|
+
|
|
79
|
+
# run the models as usual
|
|
80
|
+
impact = {"@type": "ImpactAssessment", ...}
|
|
81
|
+
result = run(impact, load_config(impact))
|
|
82
|
+
print(result)
|
|
83
|
+
|
|
84
|
+
# write the logs to a JSON file
|
|
85
|
+
logs = get_collected_logs()
|
|
86
|
+
with open("logs.json", "w") as f:
|
|
87
|
+
f.write(to_string(logs, indent=2))
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
When a node is recalculated in separate passes (e.g. stage 1 then stage 2 in different
|
|
91
|
+
processes), seed the later pass with the earlier one's logs so stage-1-only placements
|
|
92
|
+
are not lost:
|
|
93
|
+
```python
|
|
94
|
+
from hestia_earth.models.jlog import load_collected_logs, get_collected_logs
|
|
95
|
+
|
|
96
|
+
# stage 2: load the logs collected during stage 1, then run stage 2 as usual
|
|
97
|
+
load_collected_logs(stage1_logs)
|
|
98
|
+
result = run(impact, load_config(impact), stage=2)
|
|
99
|
+
logs = get_collected_logs() # contains both stage 1 and stage 2
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Collecting contribution data
|
|
103
|
+
|
|
104
|
+
:info: This is an experimental feature and is not yet integrated in all the HESTIA tools.
|
|
105
|
+
|
|
106
|
+
To collect contribution data of impacts/endpoints on ImpactAssessment:
|
|
107
|
+
1. Set the env variable `LOG_CONTRIBUTION_ENABLED` to `true`
|
|
108
|
+
1. Use the following code to collect contribution logs:
|
|
109
|
+
```python
|
|
110
|
+
from hestia_earth.orchestrator import run
|
|
111
|
+
from hestia_earth.models.config import load_config
|
|
112
|
+
from hestia_earth.models.log_contribution import reset_contributions, get_contributions
|
|
113
|
+
|
|
114
|
+
# make sure the contributions are reset before each run
|
|
115
|
+
reset_contributions()
|
|
116
|
+
|
|
117
|
+
# run the models as usual
|
|
118
|
+
impact = {"@type": "ImpactAssessment", ...}
|
|
119
|
+
result = run(impact, load_config(impact))
|
|
120
|
+
print(result)
|
|
121
|
+
|
|
122
|
+
# write the contributions to a JSON file
|
|
123
|
+
contributions = get_contributions()
|
|
124
|
+
with open("contributions.json", "w") as f:
|
|
125
|
+
f.write(to_string(contributions, indent=2))
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The contribution data will store the factors used for each `emissionsResourceUse` that contributes to specific `impacts`, and likewise `impacts` that contribute to `endpoints`. The index in the data represents the index of the blank node in the list of contributing blank nodes.
|
|
129
|
+
|
|
130
|
+
#### Using the ecoinventV3 model
|
|
131
|
+
|
|
132
|
+
:warning: This model has been deprecated and no further support will be provided.
|
|
133
|
+
|
|
134
|
+
ecoinvent is a consistent, transparent, and well validated life cycle inventory database.
|
|
135
|
+
We use ecoinvent data to ascertain the environmental impacts of activities that occur outside of our system boundary, for example data on the environmental impacts of extracting oil and producing diesel, or the impacts of manufacturing plastics.
|
|
136
|
+
|
|
137
|
+
The `ecoinventV3` model requires a valid [license](https://ecoinvent.org/offerings/licences/) to run. We are currently working on a way to enable users of this code with a valid ecoinvent licence to run these models themselves, but for now, these models are only available on the public platform.
|
|
138
|
+
|
|
139
|
+
### Amortising Land Use Change Emissions Using Linear Discounting
|
|
140
|
+
|
|
141
|
+
:info: This is an experimental feature and is not yet integrated in all the HESTIA tools. All carbon stock change models (`ipcc2019.aboveGroundBiomass`, _etc._) and their associated emission models (`ipcc2019.co2ToAirAboveGroundBiomassStockChange`, _etc._) have been updated; however, changes to `hestia.landCover` are required to make linear discounting fully functional (see work item [#1623](https://gitlab.com/hestia-earth/hestia-engine-models/-/work_items/1623) for further information).
|
|
142
|
+
|
|
143
|
+
To amortise the impacts of land use change using linear discounting across IPCC (2019) models:
|
|
144
|
+
1. Set the env variable `USE_LINEAR_DISCOUNTING` to `true`
|
package/cjs/version.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ENGINE_VERSION = "0.81.4";
|
package/{dist → cjs}/version.js
RENAMED
package/config/Cycle.json
CHANGED
|
@@ -2607,6 +2607,14 @@
|
|
|
2607
2607
|
},
|
|
2608
2608
|
"stage": 2
|
|
2609
2609
|
},
|
|
2610
|
+
{
|
|
2611
|
+
"key": "completeness",
|
|
2612
|
+
"model": "cycle",
|
|
2613
|
+
"value": "completeness",
|
|
2614
|
+
"runStrategy": "always",
|
|
2615
|
+
"mergeStrategy": "node",
|
|
2616
|
+
"stage": 2
|
|
2617
|
+
},
|
|
2610
2618
|
{
|
|
2611
2619
|
"key": "emissions",
|
|
2612
2620
|
"model": "cycle",
|
package/esm/config.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NodeType } from '@hestia-earth/schema';
|
|
2
|
+
export interface IOrchestratorModelConfig {
|
|
3
|
+
key: string;
|
|
4
|
+
model: string;
|
|
5
|
+
value: string;
|
|
6
|
+
runStrategy: 'always' | 'add_key_if_missing' | 'add_blank_node_if_missing';
|
|
7
|
+
runArgs?: Record<string, any>;
|
|
8
|
+
mergeStrategy: 'default' | 'append' | 'list' | 'node';
|
|
9
|
+
mergeArgs?: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
export interface IOrchestratorConfig {
|
|
12
|
+
models: (IOrchestratorModelConfig | IOrchestratorModelConfig[])[];
|
|
13
|
+
}
|
|
14
|
+
export type allowedType = NodeType.Cycle | NodeType.Site | NodeType.ImpactAssessment;
|
|
15
|
+
export declare const allowedTypes: allowedType[];
|
|
16
|
+
/**
|
|
17
|
+
* Load orchestrator configuration.
|
|
18
|
+
*
|
|
19
|
+
* @param nodeType NodeType associated with configuration.
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export declare const loadConfig: (nodeType: allowedType) => IOrchestratorConfig;
|
|
23
|
+
interface ICalculationConfigData {
|
|
24
|
+
key: 'related' | 'nested';
|
|
25
|
+
type: allowedType;
|
|
26
|
+
stage: number;
|
|
27
|
+
}
|
|
28
|
+
export declare const loadRunConfig: (nodeType: allowedType, stage: number) => ICalculationConfigData[];
|
|
29
|
+
export declare const loadTriggerConfig: (nodeType: allowedType, stage: number) => ICalculationConfigData[];
|
|
30
|
+
export declare const getMaxStage: (nodeType: allowedType) => any;
|
|
31
|
+
export {};
|
package/esm/config.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { NodeType } from '@hestia-earth/schema';
|
|
2
|
+
import * as runConfig from '../config/run-calculations.json';
|
|
3
|
+
import * as triggerConfig from '../config/trigger-calculations.json';
|
|
4
|
+
import * as Cycle from '../config/Cycle.json';
|
|
5
|
+
import * as ImpactAssessment from '../config/ImpactAssessment.json';
|
|
6
|
+
import * as Site from '../config/Site.json';
|
|
7
|
+
export const allowedTypes = [
|
|
8
|
+
NodeType.Cycle,
|
|
9
|
+
NodeType.Site,
|
|
10
|
+
NodeType.ImpactAssessment
|
|
11
|
+
];
|
|
12
|
+
const validateType = (nodeType) => allowedTypes.includes(nodeType) ||
|
|
13
|
+
(() => {
|
|
14
|
+
throw new Error(`Invalid type ${nodeType}. Allowed types: ${allowedTypes.join(', ')}`);
|
|
15
|
+
})();
|
|
16
|
+
const typeToConfig = {
|
|
17
|
+
[NodeType.Cycle]: Cycle,
|
|
18
|
+
[NodeType.ImpactAssessment]: ImpactAssessment,
|
|
19
|
+
[NodeType.Site]: Site
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Load orchestrator configuration.
|
|
23
|
+
*
|
|
24
|
+
* @param nodeType NodeType associated with configuration.
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
export const loadConfig = (nodeType) => validateType(nodeType) && typeToConfig[nodeType];
|
|
28
|
+
const validateStage = (config, nodeType, stage) => `stage-${stage}` in config[nodeType]
|
|
29
|
+
? config[nodeType][`stage-${stage}`]
|
|
30
|
+
: (() => {
|
|
31
|
+
throw new Error(`Invalid stage configuration for ${nodeType}: ${stage}`);
|
|
32
|
+
})();
|
|
33
|
+
export const loadRunConfig = (nodeType, stage) => validateType(nodeType) &&
|
|
34
|
+
validateStage(runConfig, nodeType, stage);
|
|
35
|
+
export const loadTriggerConfig = (nodeType, stage) => validateType(nodeType) &&
|
|
36
|
+
validateStage(triggerConfig, nodeType, stage);
|
|
37
|
+
export const getMaxStage = (nodeType) => validateType(nodeType)
|
|
38
|
+
? Math.max.apply(Math.max, Object.keys(runConfig[nodeType]).map((key) => Number(key.replace('stage-', ''))))
|
|
39
|
+
: null;
|
package/esm/index.js
ADDED
package/esm/models.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EmissionMethodTier } from '@hestia-earth/schema';
|
|
2
|
+
export interface IModel {
|
|
3
|
+
/**
|
|
4
|
+
* Path to the implementation (code) of the model.
|
|
5
|
+
*/
|
|
6
|
+
path: string;
|
|
7
|
+
/**
|
|
8
|
+
* Path to the documentation of the model.
|
|
9
|
+
*/
|
|
10
|
+
docPath: string;
|
|
11
|
+
/**
|
|
12
|
+
* Path to the documentation of the model on the guide.
|
|
13
|
+
*/
|
|
14
|
+
guidePath: string;
|
|
15
|
+
/**
|
|
16
|
+
* The name of the model used as `methodModel`.
|
|
17
|
+
*/
|
|
18
|
+
model: string;
|
|
19
|
+
/**
|
|
20
|
+
* The term the model is associated with.
|
|
21
|
+
*/
|
|
22
|
+
term?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The methodTier of the Emission (if applicable).
|
|
25
|
+
*/
|
|
26
|
+
methodTier?: EmissionMethodTier;
|
|
27
|
+
/**
|
|
28
|
+
* A key in the model if term does not exist.
|
|
29
|
+
*/
|
|
30
|
+
modelKey?: string;
|
|
31
|
+
/**
|
|
32
|
+
* List of other models this model needs to run.
|
|
33
|
+
*/
|
|
34
|
+
dependencies?: string[];
|
|
35
|
+
}
|
|
36
|
+
export type modelLookup = Record<string, Pick<IModel, 'model' | 'term' | 'modelKey'>[]>;
|
|
37
|
+
export interface IModelLinks {
|
|
38
|
+
links: IModel[];
|
|
39
|
+
lookups: Record<string, modelLookup>;
|
|
40
|
+
}
|
|
41
|
+
export declare const models: IModelLinks;
|
package/esm/models.js
ADDED
package/esm/utils.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IOrchestratorModelConfig } from './config';
|
|
2
|
+
import { IModel } from './models';
|
|
3
|
+
export declare const findMatchingModel: (model: Partial<IModel>, config?: {
|
|
4
|
+
useDotValues?: boolean;
|
|
5
|
+
}) => IModel;
|
|
6
|
+
export declare const findMatchingModelFromConfig: (model: Pick<IOrchestratorModelConfig, "model" | "value">) => IModel;
|
package/esm/utils.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { models } from './models';
|
|
2
|
+
const matchWithDot = (model, key, value) => typeof value === 'string' && value.split('.').pop() === model[key];
|
|
3
|
+
const matchPath = (model, key, value) => key === 'path' && typeof value === 'string' && model[key].startsWith(value);
|
|
4
|
+
export const findMatchingModel = (model, config = {
|
|
5
|
+
useDotValues: false
|
|
6
|
+
}) => Object.keys(model).length > 0
|
|
7
|
+
? models.links.find((m) => Object.entries(model).every(([key, value]) => value === m[key] ||
|
|
8
|
+
(config.useDotValues && matchWithDot(m, key, value)) ||
|
|
9
|
+
matchPath(m, key, value)))
|
|
10
|
+
: null;
|
|
11
|
+
const modelMatchOrder = ({ model, value }) => [
|
|
12
|
+
{ model, term: value },
|
|
13
|
+
{ model, modelKey: value },
|
|
14
|
+
{
|
|
15
|
+
model,
|
|
16
|
+
modelKey: value.split('.').pop()
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
model,
|
|
20
|
+
term: value.split('.').pop()
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
model,
|
|
24
|
+
path: ['hestia_earth', 'models', model, value].join('/')
|
|
25
|
+
},
|
|
26
|
+
!value || value === 'all' ? { model } : null
|
|
27
|
+
].filter(Boolean);
|
|
28
|
+
export const findMatchingModelFromConfig = (model) => {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
return (_b = (_a = modelMatchOrder(model)
|
|
31
|
+
.map((params) => findMatchingModel(params) ||
|
|
32
|
+
findMatchingModel(params, { useDotValues: true }))) === null || _a === void 0 ? void 0 : _a.filter(Boolean)) === null || _b === void 0 ? void 0 : _b.shift();
|
|
33
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { allowedType, IOrchestratorModelConfig } from './config';
|
|
2
|
+
/**
|
|
3
|
+
* Use inter-dependencies to detect models that are in the wrong order.
|
|
4
|
+
*
|
|
5
|
+
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
6
|
+
* @returns List of models that have dependencies that could not be found prior to running.
|
|
7
|
+
*/
|
|
8
|
+
export declare const validateConfigOrder: (nodeType: allowedType) => {
|
|
9
|
+
model: IOrchestratorModelConfig;
|
|
10
|
+
existing: string[];
|
|
11
|
+
missing: string[];
|
|
12
|
+
}[];
|
|
13
|
+
/**
|
|
14
|
+
* Detect multiple models running in parallel when they should not.
|
|
15
|
+
* Note: we use the `mergeArgs` to handle special cases when multiple identical models CAN run in parallel
|
|
16
|
+
*
|
|
17
|
+
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
18
|
+
*/
|
|
19
|
+
export declare const validateConfigDuplicates: (nodeType: allowedType) => IOrchestratorModelConfig[];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { loadConfig } from './config';
|
|
2
|
+
import { findMatchingModelFromConfig } from './utils';
|
|
3
|
+
// models not included in the links
|
|
4
|
+
const skipModels = ['emissions.deleted', 'transformations'];
|
|
5
|
+
const isHestiaResidueCyclicModel = ({ model, value }) => model === 'hestia' && (value === null || value === void 0 ? void 0 : value.startsWith('residue'));
|
|
6
|
+
const isOrganicCarbonCyclicModel = ({ model, value }) => model === 'hestia' && (value === null || value === void 0 ? void 0 : value.startsWith('organicCarbonPer'));
|
|
7
|
+
const includeModel = (model) => [
|
|
8
|
+
!skipModels.includes(model.model),
|
|
9
|
+
// cyclic dependencies
|
|
10
|
+
!isHestiaResidueCyclicModel(model),
|
|
11
|
+
!isOrganicCarbonCyclicModel(model),
|
|
12
|
+
!model.key.startsWith('cache')
|
|
13
|
+
].every(Boolean);
|
|
14
|
+
// dependencies that cannot be validated
|
|
15
|
+
const skipDependencies = [
|
|
16
|
+
// completeness gap-fills after other models run
|
|
17
|
+
'completeness'
|
|
18
|
+
];
|
|
19
|
+
const matchDependencies = (models) => (model) => {
|
|
20
|
+
var _a, _b, _c;
|
|
21
|
+
const { dependencies } = findMatchingModelFromConfig(model);
|
|
22
|
+
const previousModels = models.slice(0, models.indexOf(model));
|
|
23
|
+
const existing = (_a = dependencies === null || dependencies === void 0 ? void 0 : dependencies.filter((value) => previousModels.some((config) => { var _a; return ((_a = config.value) === null || _a === void 0 ? void 0 : _a.split('.').pop()) === value; }))) !== null && _a !== void 0 ? _a : [];
|
|
24
|
+
return {
|
|
25
|
+
model,
|
|
26
|
+
existing,
|
|
27
|
+
missing: (_c = (_b = dependencies === null || dependencies === void 0 ? void 0 : dependencies
|
|
28
|
+
// skip dependencies that dont exist at all
|
|
29
|
+
.filter((value) => models.some((config) => config.value === value))) === null || _b === void 0 ? void 0 : _b.filter((v) => !existing.includes(v) &&
|
|
30
|
+
!skipDependencies.includes(v) &&
|
|
31
|
+
v !== model.value)) !== null && _c !== void 0 ? _c : []
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Use inter-dependencies to detect models that are in the wrong order.
|
|
36
|
+
*
|
|
37
|
+
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
38
|
+
* @returns List of models that have dependencies that could not be found prior to running.
|
|
39
|
+
*/
|
|
40
|
+
export const validateConfigOrder = (nodeType) => {
|
|
41
|
+
const config = loadConfig(nodeType);
|
|
42
|
+
// flatten all models to process one by one, starting with the last one
|
|
43
|
+
const models = config.models.flat();
|
|
44
|
+
const results = models.filter(includeModel).map(matchDependencies(models));
|
|
45
|
+
return results.filter((r) => r.missing.length > 0);
|
|
46
|
+
};
|
|
47
|
+
const findDuplicatedConfigs = (models) => {
|
|
48
|
+
const modelsByValue = models.reduce((prev, curr) => (Object.assign(Object.assign({}, prev), { [curr.value]: [...(prev[curr.value] || []), curr] })), {});
|
|
49
|
+
return Object.values(modelsByValue)
|
|
50
|
+
.map((values) => values.filter((v) => { var _a; return !((_a = v.mergeArgs) === null || _a === void 0 ? void 0 : _a.sameMethodModel); }))
|
|
51
|
+
.filter((values) => values.length > 1);
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Detect multiple models running in parallel when they should not.
|
|
55
|
+
* Note: we use the `mergeArgs` to handle special cases when multiple identical models CAN run in parallel
|
|
56
|
+
*
|
|
57
|
+
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
58
|
+
*/
|
|
59
|
+
export const validateConfigDuplicates = (nodeType) => {
|
|
60
|
+
const config = loadConfig(nodeType);
|
|
61
|
+
const duplicates = config.models
|
|
62
|
+
.map((value) => (Array.isArray(value) ? findDuplicatedConfigs(value) : []))
|
|
63
|
+
.flat(2);
|
|
64
|
+
return duplicates;
|
|
65
|
+
};
|
package/esm/version.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ENGINE_VERSION = "0.81.4";
|
package/esm/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const ENGINE_VERSION = '0.81.4';
|
package/model-links.json
CHANGED
|
@@ -2067,14 +2067,14 @@
|
|
|
2067
2067
|
{
|
|
2068
2068
|
"path": "hestia_earth/models/impact_assessment/allocationMethod.py",
|
|
2069
2069
|
"docPath": "hestia_earth/models/impact_assessment/allocationMethod.md",
|
|
2070
|
-
"guidePath": "
|
|
2070
|
+
"guidePath": "impact-assessment-allocationMethod#Impact%20Assessment",
|
|
2071
2071
|
"model": "impact_assessment",
|
|
2072
2072
|
"modelKey": "allocationMethod"
|
|
2073
2073
|
},
|
|
2074
2074
|
{
|
|
2075
2075
|
"path": "hestia_earth/models/impact_assessment/emissions.py",
|
|
2076
2076
|
"docPath": "hestia_earth/models/impact_assessment/emissions.md",
|
|
2077
|
-
"guidePath": "
|
|
2077
|
+
"guidePath": "impact-assessment-emissions#Impact%20Assessment",
|
|
2078
2078
|
"model": "impact_assessment",
|
|
2079
2079
|
"modelKey": "emissions",
|
|
2080
2080
|
"dependencies": [
|
|
@@ -2084,21 +2084,21 @@
|
|
|
2084
2084
|
{
|
|
2085
2085
|
"path": "hestia_earth/models/impact_assessment/irrigated.py",
|
|
2086
2086
|
"docPath": "hestia_earth/models/impact_assessment/irrigated.md",
|
|
2087
|
-
"guidePath": "
|
|
2087
|
+
"guidePath": "impact-assessment-irrigated#Impact%20Assessment",
|
|
2088
2088
|
"model": "impact_assessment",
|
|
2089
2089
|
"modelKey": "irrigated"
|
|
2090
2090
|
},
|
|
2091
2091
|
{
|
|
2092
2092
|
"path": "hestia_earth/models/impact_assessment/organic.py",
|
|
2093
2093
|
"docPath": "hestia_earth/models/impact_assessment/organic.md",
|
|
2094
|
-
"guidePath": "
|
|
2094
|
+
"guidePath": "impact-assessment-organic#Impact%20Assessment",
|
|
2095
2095
|
"model": "impact_assessment",
|
|
2096
2096
|
"modelKey": "organic"
|
|
2097
2097
|
},
|
|
2098
2098
|
{
|
|
2099
2099
|
"path": "hestia_earth/models/impact_assessment/product/economicValueShare.py",
|
|
2100
2100
|
"docPath": "hestia_earth/models/impact_assessment/product/economicValueShare.md",
|
|
2101
|
-
"guidePath": "
|
|
2101
|
+
"guidePath": "impact-assessment-product-economicValueShare#Impact%20Assessment",
|
|
2102
2102
|
"model": "impact_assessment",
|
|
2103
2103
|
"modelKey": "product.economicValueShare",
|
|
2104
2104
|
"dependencies": [
|
|
@@ -2108,7 +2108,7 @@
|
|
|
2108
2108
|
{
|
|
2109
2109
|
"path": "hestia_earth/models/impact_assessment/product/value.py",
|
|
2110
2110
|
"docPath": "hestia_earth/models/impact_assessment/product/value.md",
|
|
2111
|
-
"guidePath": "
|
|
2111
|
+
"guidePath": "impact-assessment-product-value#Impact%20Assessment",
|
|
2112
2112
|
"model": "impact_assessment",
|
|
2113
2113
|
"modelKey": "product.value",
|
|
2114
2114
|
"dependencies": [
|
|
@@ -4873,7 +4873,7 @@
|
|
|
4873
4873
|
{
|
|
4874
4874
|
"path": "hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py",
|
|
4875
4875
|
"docPath": "hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.md",
|
|
4876
|
-
"guidePath": "noxToAirInorganicFertiliser#Stehfest%20Bouwman%20(2006)",
|
|
4876
|
+
"guidePath": "noxToAirInorganicFertiliser#Stehfest%20Bouwman%20(2006)%20GIS%20Implementation",
|
|
4877
4877
|
"model": "stehfestBouwman2006GisImplementation",
|
|
4878
4878
|
"term": "noxToAirInorganicFertiliser",
|
|
4879
4879
|
"methodTier": "tier 1",
|
|
@@ -4884,7 +4884,7 @@
|
|
|
4884
4884
|
{
|
|
4885
4885
|
"path": "hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py",
|
|
4886
4886
|
"docPath": "hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.md",
|
|
4887
|
-
"guidePath": "noxToAirOrganicFertiliser#Stehfest%20Bouwman%20(2006)",
|
|
4887
|
+
"guidePath": "noxToAirOrganicFertiliser#Stehfest%20Bouwman%20(2006)%20GIS%20Implementation",
|
|
4888
4888
|
"model": "stehfestBouwman2006GisImplementation",
|
|
4889
4889
|
"term": "noxToAirOrganicFertiliser",
|
|
4890
4890
|
"methodTier": "tier 1",
|
package/package.json
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hestia-earth/engine-models",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.4",
|
|
4
4
|
"description": "HESTIA Engine Models",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "cjs/index.js",
|
|
6
|
+
"module": "esm/index.js",
|
|
7
|
+
"types": "cjs/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./cjs/index.d.ts",
|
|
11
|
+
"import": "./esm/index.js",
|
|
12
|
+
"require": "./cjs/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./*.js": {
|
|
15
|
+
"types": "./cjs/*.d.ts",
|
|
16
|
+
"import": "./esm/*.js",
|
|
17
|
+
"require": "./cjs/*.js"
|
|
18
|
+
},
|
|
19
|
+
"./*": {
|
|
20
|
+
"types": "./cjs/*.d.ts",
|
|
21
|
+
"import": "./esm/*.js",
|
|
22
|
+
"require": "./cjs/*.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"sideEffects": false,
|
|
7
26
|
"directories": {
|
|
8
27
|
"test": "tests"
|
|
9
28
|
},
|
|
@@ -12,7 +31,8 @@
|
|
|
12
31
|
"build:models": "npm run build:ecoinvent-terms && node scripts/generate-models-links.js",
|
|
13
32
|
"build:documentation": "node scripts/generate-documentation.js",
|
|
14
33
|
"build": "./build-models-json.sh && npm run build:models && npm run build:documentation",
|
|
15
|
-
"build:module": "rm -rf dist && tsc -p tsconfig.dist.json",
|
|
34
|
+
"build:module": "rm -rf dist && tsc -p tsconfig.dist.json && tsc -p tsconfig.esm.json && npm run build:module:data",
|
|
35
|
+
"build:module:data": "mkdir -p dist/config && cp model-links.json dist/ && cp config/*.json dist/config/ && cp package.json README.md dist/",
|
|
16
36
|
"lint": "tsc --noEmit && eslint .",
|
|
17
37
|
"lint:fix": "npm run lint -- --fix",
|
|
18
38
|
"test": "jest --coverage",
|
|
@@ -56,7 +76,7 @@
|
|
|
56
76
|
"@hestia-earth/json-schema": "^37.3.1",
|
|
57
77
|
"@hestia-earth/schema": "^37.3.1",
|
|
58
78
|
"@hestia-earth/schema-validation": "^37.3.1",
|
|
59
|
-
"@hestia-earth/utils": "^0.17.
|
|
79
|
+
"@hestia-earth/utils": "^0.17.19",
|
|
60
80
|
"@jest/globals": "^29.7.0",
|
|
61
81
|
"@types/node": "^22.19.15",
|
|
62
82
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2019-2025 Harmonised Environmental Storage and Tracking of the Impacts of Agriculture (HESTIA) Project
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/dist/version.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const ENGINE_VERSION = "0.81.2";
|