@hestia-earth/engine-models 0.81.2 → 0.81.5
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 -14
- 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/src/models.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { EmissionMethodTier } from '@hestia-earth/schema';
|
|
2
|
-
import * as data from '../model-links.json';
|
|
3
|
-
|
|
4
|
-
export interface IModel {
|
|
5
|
-
/**
|
|
6
|
-
* Path to the implementation (code) of the model.
|
|
7
|
-
*/
|
|
8
|
-
path: string;
|
|
9
|
-
/**
|
|
10
|
-
* Path to the documentation of the model.
|
|
11
|
-
*/
|
|
12
|
-
docPath: string;
|
|
13
|
-
/**
|
|
14
|
-
* Path to the documentation of the model on the guide.
|
|
15
|
-
*/
|
|
16
|
-
guidePath: string;
|
|
17
|
-
/**
|
|
18
|
-
* The name of the model used as `methodModel`.
|
|
19
|
-
*/
|
|
20
|
-
model: string;
|
|
21
|
-
/**
|
|
22
|
-
* The term the model is associated with.
|
|
23
|
-
*/
|
|
24
|
-
term?: string;
|
|
25
|
-
/**
|
|
26
|
-
* The methodTier of the Emission (if applicable).
|
|
27
|
-
*/
|
|
28
|
-
methodTier?: EmissionMethodTier;
|
|
29
|
-
/**
|
|
30
|
-
* A key in the model if term does not exist.
|
|
31
|
-
*/
|
|
32
|
-
modelKey?: string;
|
|
33
|
-
/**
|
|
34
|
-
* List of other models this model needs to run.
|
|
35
|
-
*/
|
|
36
|
-
dependencies?: string[];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export type modelLookup = Record<
|
|
40
|
-
string,
|
|
41
|
-
Pick<IModel, 'model' | 'term' | 'modelKey'>[]
|
|
42
|
-
>;
|
|
43
|
-
|
|
44
|
-
export interface IModelLinks {
|
|
45
|
-
links: IModel[];
|
|
46
|
-
lookups: Record<string, modelLookup>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export const models = data as IModelLinks;
|
package/src/utils.spec.ts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals';
|
|
2
|
-
|
|
3
|
-
import { IModel } from './models';
|
|
4
|
-
import { findMatchingModel, findMatchingModelFromConfig } from './utils';
|
|
5
|
-
|
|
6
|
-
describe('models', () => {
|
|
7
|
-
describe('findMatchingModel', () => {
|
|
8
|
-
const model = 'stehfestBouwman2006';
|
|
9
|
-
const term = 'noxToAirInorganicFertiliser';
|
|
10
|
-
const path =
|
|
11
|
-
'hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py';
|
|
12
|
-
|
|
13
|
-
test('should find by model', () => {
|
|
14
|
-
const params = { model, term } as Partial<IModel>;
|
|
15
|
-
|
|
16
|
-
expect(findMatchingModel(params)).toEqual(
|
|
17
|
-
expect.objectContaining({ model, term, path })
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test('should handle values with dot', () => {
|
|
22
|
-
expect(
|
|
23
|
-
findMatchingModel(
|
|
24
|
-
{
|
|
25
|
-
model: 'ipcc2019',
|
|
26
|
-
term: 'animal.pregnancyRateTotal'
|
|
27
|
-
},
|
|
28
|
-
{ useDotValues: true }
|
|
29
|
-
)
|
|
30
|
-
).toEqual(
|
|
31
|
-
expect.objectContaining({
|
|
32
|
-
model: 'ipcc2019',
|
|
33
|
-
term: 'pregnancyRateTotal'
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe('findMatchingModelFromConfig', () => {
|
|
40
|
-
test('should handle completeness', () => {
|
|
41
|
-
const model = 'cycle';
|
|
42
|
-
|
|
43
|
-
expect(
|
|
44
|
-
findMatchingModelFromConfig({
|
|
45
|
-
model,
|
|
46
|
-
value: 'completeness'
|
|
47
|
-
})
|
|
48
|
-
).toEqual(
|
|
49
|
-
expect.objectContaining({
|
|
50
|
-
model: 'cycle',
|
|
51
|
-
modelKey: 'completeness.animalFeed'
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('should handle feedConversionRatio', () => {
|
|
57
|
-
const model = 'hestia';
|
|
58
|
-
|
|
59
|
-
expect(
|
|
60
|
-
findMatchingModelFromConfig({
|
|
61
|
-
model,
|
|
62
|
-
value: 'feedConversionRatio'
|
|
63
|
-
})
|
|
64
|
-
).toEqual(
|
|
65
|
-
expect.objectContaining({
|
|
66
|
-
model: 'hestia',
|
|
67
|
-
term: 'feedConversionRatioCarbon'
|
|
68
|
-
})
|
|
69
|
-
);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('should handle ecoinventV3AndEmberClimate', () => {
|
|
73
|
-
const model = 'ecoinventV3AndEmberClimate';
|
|
74
|
-
|
|
75
|
-
expect(
|
|
76
|
-
findMatchingModelFromConfig({
|
|
77
|
-
model,
|
|
78
|
-
value: 'all'
|
|
79
|
-
})
|
|
80
|
-
).toEqual(
|
|
81
|
-
expect.objectContaining({
|
|
82
|
-
model
|
|
83
|
-
})
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test('should handle ecoinventV3AndEmberClimate', () => {
|
|
88
|
-
const model = 'ecoinventV3AndEmberClimate';
|
|
89
|
-
|
|
90
|
-
expect(
|
|
91
|
-
findMatchingModelFromConfig({
|
|
92
|
-
model,
|
|
93
|
-
value: 'all'
|
|
94
|
-
})
|
|
95
|
-
).toEqual(
|
|
96
|
-
expect.objectContaining({
|
|
97
|
-
model
|
|
98
|
-
})
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('should handle seed_emissions', () => {
|
|
103
|
-
const model = 'hestia';
|
|
104
|
-
|
|
105
|
-
expect(
|
|
106
|
-
findMatchingModelFromConfig({
|
|
107
|
-
model,
|
|
108
|
-
value: 'seed_emissions'
|
|
109
|
-
})
|
|
110
|
-
).toEqual(
|
|
111
|
-
expect.objectContaining({
|
|
112
|
-
model,
|
|
113
|
-
modelKey: 'seed_emissions'
|
|
114
|
-
})
|
|
115
|
-
);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
});
|
package/src/utils.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { IOrchestratorModelConfig } from './config';
|
|
2
|
-
import { IModel, models } from './models';
|
|
3
|
-
|
|
4
|
-
type findMatchFunc = (
|
|
5
|
-
model: IModel,
|
|
6
|
-
key: string,
|
|
7
|
-
value: string | string[]
|
|
8
|
-
) => boolean;
|
|
9
|
-
|
|
10
|
-
const matchWithDot: findMatchFunc = (model, key, value) =>
|
|
11
|
-
typeof value === 'string' && value.split('.').pop() === model[key];
|
|
12
|
-
|
|
13
|
-
const matchPath: findMatchFunc = (model, key, value) =>
|
|
14
|
-
key === 'path' && typeof value === 'string' && model[key].startsWith(value);
|
|
15
|
-
|
|
16
|
-
export const findMatchingModel = (
|
|
17
|
-
model: Partial<IModel>,
|
|
18
|
-
config: {
|
|
19
|
-
useDotValues?: boolean;
|
|
20
|
-
} = {
|
|
21
|
-
useDotValues: false
|
|
22
|
-
}
|
|
23
|
-
): IModel =>
|
|
24
|
-
Object.keys(model).length > 0
|
|
25
|
-
? models.links.find((m) =>
|
|
26
|
-
Object.entries(model).every(
|
|
27
|
-
([key, value]) =>
|
|
28
|
-
value === m[key] ||
|
|
29
|
-
(config.useDotValues && matchWithDot(m, key, value)) ||
|
|
30
|
-
matchPath(m, key, value)
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
: null;
|
|
34
|
-
|
|
35
|
-
const modelMatchOrder = ({
|
|
36
|
-
model,
|
|
37
|
-
value
|
|
38
|
-
}: Pick<IOrchestratorModelConfig, 'model' | 'value'>) =>
|
|
39
|
-
[
|
|
40
|
-
{ model, term: value },
|
|
41
|
-
{ model, modelKey: value },
|
|
42
|
-
{
|
|
43
|
-
model,
|
|
44
|
-
modelKey: value.split('.').pop()
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
model,
|
|
48
|
-
term: value.split('.').pop()
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
model,
|
|
52
|
-
path: ['hestia_earth', 'models', model, value].join('/')
|
|
53
|
-
},
|
|
54
|
-
!value || value === 'all' ? { model } : null
|
|
55
|
-
].filter(Boolean) as Partial<IModel>[];
|
|
56
|
-
|
|
57
|
-
export const findMatchingModelFromConfig = (
|
|
58
|
-
model: Pick<IOrchestratorModelConfig, 'model' | 'value'>
|
|
59
|
-
) =>
|
|
60
|
-
modelMatchOrder(model)
|
|
61
|
-
.map(
|
|
62
|
-
(params) =>
|
|
63
|
-
findMatchingModel(params) ||
|
|
64
|
-
findMatchingModel(params, { useDotValues: true })
|
|
65
|
-
)
|
|
66
|
-
?.filter(Boolean)
|
|
67
|
-
?.shift();
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from '@jest/globals';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
validateConfigOrder,
|
|
5
|
-
validateConfigDuplicates
|
|
6
|
-
} from './validate-config';
|
|
7
|
-
import { allowedTypes } from './config';
|
|
8
|
-
|
|
9
|
-
describe('validate-config', () => {
|
|
10
|
-
describe('validateConfigOrder', () => {
|
|
11
|
-
for (const nodeType of allowedTypes) {
|
|
12
|
-
describe(nodeType, () => {
|
|
13
|
-
test('should not have broken dependencies', () => {
|
|
14
|
-
const results = validateConfigOrder(nodeType);
|
|
15
|
-
expect(results).toEqual([]);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('validateConfigDuplicates', () => {
|
|
22
|
-
for (const nodeType of allowedTypes) {
|
|
23
|
-
describe(nodeType, () => {
|
|
24
|
-
test('should not have duplicates', () => {
|
|
25
|
-
const results = validateConfigDuplicates(nodeType);
|
|
26
|
-
expect(results).toEqual([]);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
});
|
package/src/validate-config.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { allowedType, IOrchestratorModelConfig, loadConfig } from './config';
|
|
2
|
-
import { findMatchingModelFromConfig } from './utils';
|
|
3
|
-
|
|
4
|
-
// models not included in the links
|
|
5
|
-
const skipModels = ['emissions.deleted', 'transformations'];
|
|
6
|
-
|
|
7
|
-
const isHestiaResidueCyclicModel = ({
|
|
8
|
-
model,
|
|
9
|
-
value
|
|
10
|
-
}: IOrchestratorModelConfig) =>
|
|
11
|
-
model === 'hestia' && value?.startsWith('residue');
|
|
12
|
-
|
|
13
|
-
const isOrganicCarbonCyclicModel = ({
|
|
14
|
-
model,
|
|
15
|
-
value
|
|
16
|
-
}: IOrchestratorModelConfig) =>
|
|
17
|
-
model === 'hestia' && value?.startsWith('organicCarbonPer');
|
|
18
|
-
|
|
19
|
-
const includeModel = (model: IOrchestratorModelConfig) =>
|
|
20
|
-
[
|
|
21
|
-
!skipModels.includes(model.model),
|
|
22
|
-
// cyclic dependencies
|
|
23
|
-
!isHestiaResidueCyclicModel(model),
|
|
24
|
-
!isOrganicCarbonCyclicModel(model),
|
|
25
|
-
!model.key.startsWith('cache')
|
|
26
|
-
].every(Boolean);
|
|
27
|
-
|
|
28
|
-
// dependencies that cannot be validated
|
|
29
|
-
const skipDependencies = [
|
|
30
|
-
// completeness gap-fills after other models run
|
|
31
|
-
'completeness'
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
const matchDependencies =
|
|
35
|
-
(models: IOrchestratorModelConfig[]) => (model: IOrchestratorModelConfig) => {
|
|
36
|
-
const { dependencies } = findMatchingModelFromConfig(model);
|
|
37
|
-
const previousModels = models.slice(0, models.indexOf(model));
|
|
38
|
-
const existing =
|
|
39
|
-
dependencies?.filter((value) =>
|
|
40
|
-
previousModels.some(
|
|
41
|
-
(config) => config.value?.split('.').pop() === value
|
|
42
|
-
)
|
|
43
|
-
) ?? [];
|
|
44
|
-
return {
|
|
45
|
-
model,
|
|
46
|
-
existing,
|
|
47
|
-
missing:
|
|
48
|
-
dependencies
|
|
49
|
-
// skip dependencies that dont exist at all
|
|
50
|
-
?.filter((value) => models.some((config) => config.value === value))
|
|
51
|
-
?.filter(
|
|
52
|
-
(v) =>
|
|
53
|
-
!existing.includes(v) &&
|
|
54
|
-
!skipDependencies.includes(v) &&
|
|
55
|
-
v !== model.value
|
|
56
|
-
) ?? []
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Use inter-dependencies to detect models that are in the wrong order.
|
|
62
|
-
*
|
|
63
|
-
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
64
|
-
* @returns List of models that have dependencies that could not be found prior to running.
|
|
65
|
-
*/
|
|
66
|
-
export const validateConfigOrder = (nodeType: allowedType) => {
|
|
67
|
-
const config = loadConfig(nodeType);
|
|
68
|
-
// flatten all models to process one by one, starting with the last one
|
|
69
|
-
const models = config.models.flat();
|
|
70
|
-
|
|
71
|
-
const results = models.filter(includeModel).map(matchDependencies(models));
|
|
72
|
-
|
|
73
|
-
return results.filter((r) => r.missing.length > 0);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const findDuplicatedConfigs = (models: IOrchestratorModelConfig[]) => {
|
|
77
|
-
const modelsByValue = models.reduce(
|
|
78
|
-
(prev, curr) => ({
|
|
79
|
-
...prev,
|
|
80
|
-
[curr.value]: [...(prev[curr.value] || []), curr]
|
|
81
|
-
}),
|
|
82
|
-
{} as Record<string, IOrchestratorModelConfig[]>
|
|
83
|
-
);
|
|
84
|
-
return Object.values(modelsByValue)
|
|
85
|
-
.map((values) => values.filter((v) => !v.mergeArgs?.sameMethodModel))
|
|
86
|
-
.filter((values) => values.length > 1);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Detect multiple models running in parallel when they should not.
|
|
91
|
-
* Note: we use the `mergeArgs` to handle special cases when multiple identical models CAN run in parallel
|
|
92
|
-
*
|
|
93
|
-
* @param nodeType Cycle, Site, or ImpactAssessment
|
|
94
|
-
*/
|
|
95
|
-
export const validateConfigDuplicates = (nodeType: allowedType) => {
|
|
96
|
-
const config = loadConfig(nodeType);
|
|
97
|
-
|
|
98
|
-
const duplicates = config.models
|
|
99
|
-
.map((value) => (Array.isArray(value) ? findDuplicatedConfigs(value) : []))
|
|
100
|
-
.flat(2);
|
|
101
|
-
|
|
102
|
-
return duplicates;
|
|
103
|
-
};
|
package/src/version.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const ENGINE_VERSION = '0.81.2';
|
|
File without changes
|
/package/{dist → cjs}/config.js
RENAMED
|
File without changes
|
/package/{dist → cjs}/index.d.ts
RENAMED
|
File without changes
|
/package/{dist → cjs}/index.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/{dist → cjs}/models.js
RENAMED
|
File without changes
|
/package/{dist → cjs}/utils.d.ts
RENAMED
|
File without changes
|
/package/{dist → cjs}/utils.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|