@iiasa/ixmp4-ts 0.6.0 → 0.8.0
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/dist/cjs/core/exceptions.js +2 -2
- package/dist/cjs/core/iamc/data.js +57 -34
- package/dist/cjs/core/iamc/variable.js +10 -0
- package/dist/cjs/core/meta.js +15 -5
- package/dist/cjs/core/model.js +10 -0
- package/dist/cjs/core/region.js +10 -0
- package/dist/cjs/core/run.js +14 -4
- package/dist/cjs/core/scenario.js +10 -0
- package/dist/cjs/core/unit.js +10 -0
- package/dist/cjs/core/utils.js +187 -55
- package/dist/cjs/data/base.js +25 -7
- package/dist/cjs/data/iamc/datapoint.js +20 -11
- package/dist/cjs/data/iamc/timeseries.js +12 -12
- package/dist/cjs/data/iamc/variable.js +9 -4
- package/dist/cjs/data/meta.js +9 -4
- package/dist/cjs/data/model.js +9 -4
- package/dist/cjs/data/region.js +9 -4
- package/dist/cjs/data/run.js +9 -4
- package/dist/cjs/data/scenario.js +9 -4
- package/dist/cjs/data/unit.js +9 -4
- package/dist/cjs/data/utils.js +4 -5
- package/dist/cjs/dataframe/dataframe.js +1 -5
- package/dist/cjs/dataframe/utils.js +4 -5
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/core/iamc/data.js +51 -30
- package/dist/esm/core/iamc/variable.js +8 -0
- package/dist/esm/core/meta.js +8 -0
- package/dist/esm/core/model.js +8 -0
- package/dist/esm/core/region.js +8 -0
- package/dist/esm/core/run.js +8 -0
- package/dist/esm/core/scenario.js +8 -0
- package/dist/esm/core/unit.js +8 -0
- package/dist/esm/core/utils.js +176 -50
- package/dist/esm/data/base.js +16 -0
- package/dist/esm/data/iamc/datapoint.js +8 -1
- package/dist/esm/data/iamc/variable.js +3 -0
- package/dist/esm/data/meta.js +3 -0
- package/dist/esm/data/model.js +3 -0
- package/dist/esm/data/region.js +3 -0
- package/dist/esm/data/run.js +3 -0
- package/dist/esm/data/scenario.js +3 -0
- package/dist/esm/data/unit.js +3 -0
- package/dist/esm/dataframe/dataframe.js +1 -5
- package/dist/esm/index.js +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -0
- package/dist/types/core/iamc/data.d.ts +35 -5
- package/dist/types/core/iamc/variable.d.ts +6 -0
- package/dist/types/core/meta.d.ts +6 -0
- package/dist/types/core/model.d.ts +6 -0
- package/dist/types/core/region.d.ts +6 -0
- package/dist/types/core/run.d.ts +6 -0
- package/dist/types/core/scenario.d.ts +6 -0
- package/dist/types/core/unit.d.ts +6 -0
- package/dist/types/core/utils.d.ts +30 -1
- package/dist/types/data/base.d.ts +4 -0
- package/dist/types/data/iamc/datapoint.d.ts +3 -1
- package/dist/types/data/iamc/variable.d.ts +1 -0
- package/dist/types/data/meta.d.ts +1 -0
- package/dist/types/data/model.d.ts +1 -0
- package/dist/types/data/region.d.ts +1 -0
- package/dist/types/data/run.d.ts +1 -0
- package/dist/types/data/scenario.d.ts +1 -0
- package/dist/types/data/unit.d.ts +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/package.json +4 -5
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.InvalidCredentials = exports.BadFilterArguments = exports.InvalidRunMeta = exports.NoDefaultRunVersion = exports.SchemaError = exports.OperationNotSupported = exports.DeletionPrevented = exports.NotUnique = exports.NotFound = exports.Forbidden = exports.InvalidToken = exports.MissingToken = exports.PlatformNotUnique = exports.PlatformNotFound = exports.UnknownApiError = exports.ManagerApiError = exports.ImproperlyConfigured = exports.BadRequest = exports.InconsistentIamcType = exports.ProgrammingError = exports.IxmpError =
|
3
|
+
exports.InvalidCredentials = exports.BadFilterArguments = exports.InvalidRunMeta = exports.NoDefaultRunVersion = exports.SchemaError = exports.OperationNotSupported = exports.DeletionPrevented = exports.NotUnique = exports.NotFound = exports.Forbidden = exports.InvalidToken = exports.MissingToken = exports.PlatformNotUnique = exports.PlatformNotFound = exports.UnknownApiError = exports.ManagerApiError = exports.ImproperlyConfigured = exports.BadRequest = exports.InconsistentIamcType = exports.ProgrammingError = exports.IxmpError = void 0;
|
4
|
+
exports.createError = createError;
|
4
5
|
class ProgrammingError extends Error {
|
5
6
|
}
|
6
7
|
exports.ProgrammingError = ProgrammingError;
|
@@ -210,7 +211,6 @@ function createError(options) {
|
|
210
211
|
return new ImproperlyConfigured(Object.assign({ message: 'Could not find remote exception in registry. Are you sure client and server ixmp versions are compatible?' }, options));
|
211
212
|
}
|
212
213
|
}
|
213
|
-
exports.createError = createError;
|
214
214
|
// Register all error classes
|
215
215
|
registerError(InconsistentIamcType);
|
216
216
|
registerError(BadRequest);
|
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.PlatformIamcData = exports.RunIamcData = void 0;
|
24
24
|
const dataframe_1 = require("../../dataframe");
|
25
25
|
const base_1 = require("../base");
|
26
|
+
const datapoint_1 = require("../../data/iamc/datapoint");
|
26
27
|
const utils_1 = require("../utils");
|
27
28
|
const variable_1 = require("./variable");
|
28
29
|
/**
|
@@ -70,18 +71,12 @@ class RunIamcData extends base_1.BaseFacade {
|
|
70
71
|
yield this.backend.iamc.datapoints.bulkDelete(df);
|
71
72
|
});
|
72
73
|
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
*/
|
80
|
-
tabulate(_a = {
|
81
|
-
wide: false,
|
82
|
-
}) {
|
83
|
-
var { wide = false } = _a, filter = __rest(_a, ["wide"]);
|
84
|
-
return __awaiter(this, void 0, void 0, function* () {
|
74
|
+
tabulate() {
|
75
|
+
return __awaiter(this, arguments, void 0, function* (_a = {
|
76
|
+
wide: false,
|
77
|
+
splitByType: false,
|
78
|
+
}) {
|
79
|
+
var { wide = false, splitByType = false } = _a, filter = __rest(_a, ["wide", "splitByType"]);
|
85
80
|
if (filter !== undefined && filter !== null) {
|
86
81
|
// these filters do not make sense when applied from a Run
|
87
82
|
const illegalFilter = Object.keys(filter).filter((key) => {
|
@@ -91,7 +86,9 @@ class RunIamcData extends base_1.BaseFacade {
|
|
91
86
|
throw new Error(`Illegal filter for 'iamc.tabulate()': ${illegalFilter}`);
|
92
87
|
}
|
93
88
|
}
|
94
|
-
|
89
|
+
const df = yield this.repository.tabulate(Object.assign(Object.assign({}, filter), { run: { id: this.run.id, defaultOnly: false }, joinRuns: false, wide,
|
90
|
+
splitByType }));
|
91
|
+
return df;
|
95
92
|
});
|
96
93
|
}
|
97
94
|
contractParameters(df) {
|
@@ -135,19 +132,9 @@ class PlatformIamcData extends base_1.BaseFacade {
|
|
135
132
|
super(backend);
|
136
133
|
this.variables = new variable_1.VariableRepository(this.backend);
|
137
134
|
}
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
* @param joinRuns Optional. Whether to join runs or not, defaults to true.
|
142
|
-
* @param wide Optional. Whether to return the data in IAMC wide format or not, defaults to false.
|
143
|
-
* @returns A Promise that resolves to a DataFrame containing the tabulated data.
|
144
|
-
*/
|
145
|
-
tabulate(_a = {
|
146
|
-
joinRuns: true,
|
147
|
-
wide: false,
|
148
|
-
}) {
|
149
|
-
var { joinRuns = true, wide = false } = _a, filter = __rest(_a, ["joinRuns", "wide"]);
|
150
|
-
return __awaiter(this, void 0, void 0, function* () {
|
135
|
+
tabulate() {
|
136
|
+
return __awaiter(this, arguments, void 0, function* (_a = { joinRuns: true, wide: false, splitByType: false }) {
|
137
|
+
var { joinRuns = true, joinRunId = false, wide = false, splitByType = false } = _a, filter = __rest(_a, ["joinRuns", "joinRunId", "wide", "splitByType"]);
|
151
138
|
if (filter === undefined) {
|
152
139
|
filter = {};
|
153
140
|
}
|
@@ -156,19 +143,55 @@ class PlatformIamcData extends base_1.BaseFacade {
|
|
156
143
|
filter['run'] = { defaultOnly: true };
|
157
144
|
}
|
158
145
|
const joinParameters = true;
|
159
|
-
let df = yield this.backend.iamc.datapoints.tabulate({
|
146
|
+
let df = (yield this.backend.iamc.datapoints.tabulate({
|
160
147
|
joinRuns,
|
148
|
+
joinRunId,
|
161
149
|
joinParameters,
|
162
150
|
filter,
|
163
|
-
});
|
164
|
-
|
165
|
-
|
166
|
-
|
151
|
+
}));
|
152
|
+
if (splitByType) {
|
153
|
+
const splitDfs = (0, utils_1.splitDataFrameByType)(df);
|
154
|
+
const typeMapping = {
|
155
|
+
annual: datapoint_1.DataPointType.ANNUAL,
|
156
|
+
categorical: datapoint_1.DataPointType.CATEGORICAL,
|
157
|
+
datetime: datapoint_1.DataPointType.DATETIME,
|
158
|
+
};
|
159
|
+
const presentTypes = [];
|
160
|
+
Object.entries(typeMapping).forEach(([key, type]) => {
|
161
|
+
const typedKey = key;
|
162
|
+
if (splitDfs[typedKey]) {
|
163
|
+
presentTypes.push(type);
|
164
|
+
if (wide) {
|
165
|
+
splitDfs[typedKey] = (0, utils_1.toIamcWide)(splitDfs[typedKey]);
|
166
|
+
}
|
167
|
+
splitDfs[typedKey] = (0, utils_1.standardizeIamcDf)(splitDfs[typedKey]);
|
168
|
+
}
|
169
|
+
});
|
170
|
+
return Object.assign({ presentTypes }, splitDfs);
|
167
171
|
}
|
168
|
-
|
169
|
-
|
172
|
+
else {
|
173
|
+
if (wide) {
|
174
|
+
df = (0, utils_1.toIamcWide)(df);
|
175
|
+
}
|
176
|
+
return (0, utils_1.standardizeIamcDf)(df);
|
177
|
+
}
|
178
|
+
});
|
179
|
+
}
|
180
|
+
/**
|
181
|
+
* Counts IAMC datapoints with optional filtering.
|
182
|
+
* @param filter Optional. Filter for counting IAMC datapoints.
|
183
|
+
* @returns A promise that resolves to the count of datapoints.
|
184
|
+
*/
|
185
|
+
count(filter) {
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
187
|
+
if (filter === undefined) {
|
188
|
+
filter = {};
|
189
|
+
}
|
190
|
+
// return only default runs unless a run-filter is provided
|
191
|
+
if (!Object.hasOwn(filter, 'run')) {
|
192
|
+
filter['run'] = { defaultOnly: true };
|
170
193
|
}
|
171
|
-
return
|
194
|
+
return this.backend.iamc.datapoints.count(filter);
|
172
195
|
});
|
173
196
|
}
|
174
197
|
}
|
@@ -136,5 +136,15 @@ class VariableRepository extends base_1.BaseFacade {
|
|
136
136
|
return this.backend.iamc.variables.tabulate(filter);
|
137
137
|
});
|
138
138
|
}
|
139
|
+
/**
|
140
|
+
* Counts Variables with optional filtering.
|
141
|
+
* @param filter Optional. Filter for counting Variables.
|
142
|
+
* @returns A Promise that resolves to the count of Variables.
|
143
|
+
*/
|
144
|
+
count(filter) {
|
145
|
+
return __awaiter(this, void 0, void 0, function* () {
|
146
|
+
return this.backend.iamc.variables.count(filter);
|
147
|
+
});
|
148
|
+
}
|
139
149
|
}
|
140
150
|
exports.VariableRepository = VariableRepository;
|
package/dist/cjs/core/meta.js
CHANGED
@@ -33,17 +33,27 @@ class MetaIndicatorRepository extends base_1.BaseFacade {
|
|
33
33
|
* @param joinRunIndex Optional. Whether to join the run index to the tabulated data, defaults to true.
|
34
34
|
* @returns A promise that resolves to a DataFrame containing the tabulated meta indicators.
|
35
35
|
*/
|
36
|
-
tabulate(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
tabulate() {
|
37
|
+
return __awaiter(this, arguments, void 0, function* (_a = {
|
38
|
+
joinRunIndex: true,
|
39
|
+
}) {
|
40
|
+
var { joinRunIndex = true } = _a, filter = __rest(_a, ["joinRunIndex"]);
|
41
41
|
if (filter === undefined) {
|
42
42
|
filter = {};
|
43
43
|
}
|
44
44
|
return yield this.backend.meta.tabulate(filter, joinRunIndex);
|
45
45
|
});
|
46
46
|
}
|
47
|
+
/**
|
48
|
+
* Counts meta indicators with optional filtering.
|
49
|
+
* @param filter Optional. Filter for counting meta indicators.
|
50
|
+
* @returns A promise that resolves to the count of meta indicators.
|
51
|
+
*/
|
52
|
+
count(filter) {
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
54
|
+
return this.backend.meta.count(filter || {});
|
55
|
+
});
|
56
|
+
}
|
47
57
|
}
|
48
58
|
exports.MetaIndicatorRepository = MetaIndicatorRepository;
|
49
59
|
/**
|
package/dist/cjs/core/model.js
CHANGED
@@ -137,5 +137,15 @@ class ModelRepository extends base_1.BaseFacade {
|
|
137
137
|
return this.backend.models.tabulate((0, utils_1.withIamcDefault)(filter));
|
138
138
|
});
|
139
139
|
}
|
140
|
+
/**
|
141
|
+
* Counts models with optional filtering.
|
142
|
+
* @param filter Optional. Filter for counting models.
|
143
|
+
* @returns A promise that resolves to the count of models.
|
144
|
+
*/
|
145
|
+
count(filter) {
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
147
|
+
return this.backend.models.count((0, utils_1.withIamcDefault)(filter));
|
148
|
+
});
|
149
|
+
}
|
140
150
|
}
|
141
151
|
exports.ModelRepository = ModelRepository;
|
package/dist/cjs/core/region.js
CHANGED
@@ -168,5 +168,15 @@ class RegionRepository extends base_1.BaseFacade {
|
|
168
168
|
return this.backend.regions.tabulate((0, utils_1.withIamcDefault)(filter));
|
169
169
|
});
|
170
170
|
}
|
171
|
+
/**
|
172
|
+
* Counts regions with optional filtering.
|
173
|
+
* @param filter Optional. Filter for counting regions.
|
174
|
+
* @returns A promise that resolves to the count of regions.
|
175
|
+
*/
|
176
|
+
count(filter) {
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
178
|
+
return this.backend.regions.count((0, utils_1.withIamcDefault)(filter));
|
179
|
+
});
|
180
|
+
}
|
171
181
|
}
|
172
182
|
exports.RegionRepository = RegionRepository;
|
package/dist/cjs/core/run.js
CHANGED
@@ -151,8 +151,8 @@ class RunRepository extends base_1.BaseFacade {
|
|
151
151
|
* @param filter Optional. Filter for retriving runs.
|
152
152
|
* @returns A promise that resolves to an array of Run instances.
|
153
153
|
*/
|
154
|
-
list(
|
155
|
-
return __awaiter(this,
|
154
|
+
list() {
|
155
|
+
return __awaiter(this, arguments, void 0, function* (filter = {}) {
|
156
156
|
if (filter.defaultOnly === undefined) {
|
157
157
|
filter.defaultOnly = true;
|
158
158
|
}
|
@@ -168,8 +168,8 @@ class RunRepository extends base_1.BaseFacade {
|
|
168
168
|
* @param filter Optional. Filter for tabulating runs.
|
169
169
|
* @returns A promise that resolves to a DataFrame containing the tabulated runs.
|
170
170
|
*/
|
171
|
-
tabulate(
|
172
|
-
return __awaiter(this,
|
171
|
+
tabulate() {
|
172
|
+
return __awaiter(this, arguments, void 0, function* (filter = {}) {
|
173
173
|
if (filter.defaultOnly === undefined) {
|
174
174
|
filter.defaultOnly = true;
|
175
175
|
}
|
@@ -190,5 +190,15 @@ class RunRepository extends base_1.BaseFacade {
|
|
190
190
|
});
|
191
191
|
});
|
192
192
|
}
|
193
|
+
/**
|
194
|
+
* Counts runs with optional filtering.
|
195
|
+
* @param filter Optional. Filter for counting runs.
|
196
|
+
* @returns A promise that resolves to the count of runs.
|
197
|
+
*/
|
198
|
+
count() {
|
199
|
+
return __awaiter(this, arguments, void 0, function* (filter = {}) {
|
200
|
+
return this.backend.runs.count((0, utils_1.withIamcDefault)(filter));
|
201
|
+
});
|
202
|
+
}
|
193
203
|
}
|
194
204
|
exports.RunRepository = RunRepository;
|
@@ -145,5 +145,15 @@ class ScenarioRepository extends base_1.BaseFacade {
|
|
145
145
|
return this.backend.scenarios.tabulate((0, utils_1.withIamcDefault)(filter));
|
146
146
|
});
|
147
147
|
}
|
148
|
+
/**
|
149
|
+
* Counts scenarios with optional filtering.
|
150
|
+
* @param filter Optional. Filter for counting scenarios.
|
151
|
+
* @returns A promise that resolves to the count of scenarios.
|
152
|
+
*/
|
153
|
+
count(filter) {
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
155
|
+
return this.backend.scenarios.count((0, utils_1.withIamcDefault)(filter));
|
156
|
+
});
|
157
|
+
}
|
148
158
|
}
|
149
159
|
exports.ScenarioRepository = ScenarioRepository;
|
package/dist/cjs/core/unit.js
CHANGED
@@ -182,5 +182,15 @@ class UnitRepository extends base_1.BaseFacade {
|
|
182
182
|
return this.backend.units.tabulate((0, utils_1.withIamcDefault)(filter));
|
183
183
|
});
|
184
184
|
}
|
185
|
+
/**
|
186
|
+
* Counts units with optional filtering.
|
187
|
+
* @param filter Optional. Filter for counting units.
|
188
|
+
* @returns A promise that resolves to the count of units.
|
189
|
+
*/
|
190
|
+
count(filter) {
|
191
|
+
return __awaiter(this, void 0, void 0, function* () {
|
192
|
+
return this.backend.units.count((0, utils_1.withIamcDefault)(filter));
|
193
|
+
});
|
194
|
+
}
|
185
195
|
}
|
186
196
|
exports.UnitRepository = UnitRepository;
|
package/dist/cjs/core/utils.js
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.substitudeType = substitudeType;
|
4
|
+
exports.unitToDimensionless = unitToDimensionless;
|
5
|
+
exports.dfToDimensionless = dfToDimensionless;
|
6
|
+
exports.standardizeIamcDf = standardizeIamcDf;
|
7
|
+
exports.toIamcWide = toIamcWide;
|
8
|
+
exports.withIamcDefault = withIamcDefault;
|
9
|
+
exports.getIamcRowIndex = getIamcRowIndex;
|
10
|
+
exports.sortTimesWithYearFirst = sortTimesWithYearFirst;
|
11
|
+
exports.splitDataFrameByType = splitDataFrameByType;
|
4
12
|
const dataframe_1 = require("../dataframe");
|
5
13
|
const datapoint_1 = require("../data/iamc/datapoint");
|
6
14
|
function substitudeType(df, type) {
|
@@ -23,91 +31,144 @@ function substitudeType(df, type) {
|
|
23
31
|
}
|
24
32
|
return df;
|
25
33
|
}
|
26
|
-
exports.substitudeType = substitudeType;
|
27
34
|
function unitToDimensionless(name) {
|
28
35
|
if (name === 'dimensionless') {
|
29
36
|
throw new Error("Unit name 'dimensionless' is reserved, use an empty string '' instead.");
|
30
37
|
}
|
31
38
|
return name === '' ? 'dimensionless' : name;
|
32
39
|
}
|
33
|
-
exports.unitToDimensionless = unitToDimensionless;
|
34
40
|
function dfToDimensionless(df) {
|
35
41
|
if (df
|
36
42
|
.loc({ columns: ['unit'] })
|
37
|
-
.values.map(
|
43
|
+
.values.map(String)
|
38
44
|
.includes('dimensionless')) {
|
39
45
|
throw new Error("Unit name 'dimensionless' is reserved, use an empty string '' instead.");
|
40
46
|
}
|
41
47
|
df.replaceValue('', 'dimensionless', 'unit');
|
42
48
|
return df;
|
43
49
|
}
|
44
|
-
|
50
|
+
/**
|
51
|
+
* Standardizes the columns of a DataFrame in IAMC format.
|
52
|
+
* @param df DataFrame in IAMC format
|
53
|
+
* @returns DataFrame in IAMC format with standardized columns
|
54
|
+
*/
|
55
|
+
function standardizeIamcDf(df) {
|
56
|
+
if (df.columns.includes('time_series__id')) {
|
57
|
+
df = df.dropColumns(['time_series__id']);
|
58
|
+
}
|
59
|
+
if (df.columns.includes('unit')) {
|
60
|
+
df = df.replaceValue('dimensionless', ' ', 'unit');
|
61
|
+
}
|
62
|
+
// Rename step_category to subannual
|
63
|
+
if (df.columns.includes('step_category')) {
|
64
|
+
df = df.renameColumns({ step_category: 'subannual' });
|
65
|
+
}
|
66
|
+
return df;
|
67
|
+
}
|
68
|
+
/**
|
69
|
+
* Converts a DataFrame in IAMC long format to wide format.
|
70
|
+
* @param df The DataFrame to convert
|
71
|
+
* @returns A DataFrame in IAMC wide format
|
72
|
+
*/
|
45
73
|
function toIamcWide(df) {
|
46
|
-
//
|
74
|
+
// empty df: drop long-format columns if present
|
47
75
|
if (df.shape[0] === 0) {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
const
|
63
|
-
|
64
|
-
|
65
|
-
const
|
66
|
-
|
76
|
+
const longCols = [
|
77
|
+
'step_year',
|
78
|
+
'step_datetime',
|
79
|
+
'step_category',
|
80
|
+
'subannual',
|
81
|
+
'value',
|
82
|
+
];
|
83
|
+
const toDrop = longCols.filter((c) => df.columns.includes(c));
|
84
|
+
return toDrop.length ? df.dropColumns(toDrop) : df;
|
85
|
+
}
|
86
|
+
// column index map
|
87
|
+
const colIdx = Object.fromEntries(df.columns.map((c, i) => [c, i]));
|
88
|
+
// collect unique, non-null times
|
89
|
+
const uniqueNonNull = (arr) => [...new Set(arr.filter((v) => v !== null && v !== undefined))];
|
90
|
+
const years = df.columns.includes('step_year')
|
91
|
+
? uniqueNonNull(df.columnValues('step_year')).sort((a, b) => a - b)
|
92
|
+
: [];
|
93
|
+
const datetimes = df.columns.includes('step_datetime')
|
94
|
+
? uniqueNonNull(df.columnValues('step_datetime')).sort()
|
95
|
+
: [];
|
96
|
+
const allTimes = sortTimesWithYearFirst(years, datetimes);
|
97
|
+
// indices to carry over (everything but time and value)
|
98
|
+
const takeOverIdx = df.columns
|
67
99
|
.map((_, i) => i)
|
68
|
-
.filter((i) =>
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
const
|
76
|
-
|
77
|
-
|
100
|
+
.filter((i) => {
|
101
|
+
var _a, _b, _c;
|
102
|
+
return i !== ((_a = colIdx['step_year']) !== null && _a !== void 0 ? _a : -1) &&
|
103
|
+
i !== ((_b = colIdx['step_datetime']) !== null && _b !== void 0 ? _b : -1) &&
|
104
|
+
i !== ((_c = colIdx['value']) !== null && _c !== void 0 ? _c : -1);
|
105
|
+
});
|
106
|
+
// base schema (carry-over columns + dtypes)
|
107
|
+
const columns = takeOverIdx.map((i) => df.columns[i]);
|
108
|
+
const dtypes = takeOverIdx.map((i) => df.dtypes[i]);
|
109
|
+
// add time columns
|
110
|
+
const yearColIdx = new Map();
|
111
|
+
const dtColIdx = new Map();
|
112
|
+
for (const time of allTimes) {
|
113
|
+
columns.push(String(time));
|
78
114
|
dtypes.push(dataframe_1.DType.FLOAT32);
|
79
|
-
|
115
|
+
const newIdx = columns.length - 1;
|
116
|
+
if (typeof time === 'number')
|
117
|
+
yearColIdx.set(time, newIdx);
|
118
|
+
else
|
119
|
+
dtColIdx.set(time, newIdx);
|
80
120
|
}
|
81
|
-
|
121
|
+
// row identifiers: prefer step_category, fall back to subannual if present
|
122
|
+
const stepCategoryCol = df.columns.includes('step_category')
|
123
|
+
? 'step_category'
|
124
|
+
: df.columns.includes('subannual')
|
125
|
+
? 'subannual'
|
126
|
+
: undefined;
|
127
|
+
const idCols = [
|
82
128
|
'model',
|
83
129
|
'scenario',
|
84
130
|
'version',
|
85
131
|
'region',
|
86
132
|
'variable',
|
87
133
|
'unit',
|
88
|
-
|
134
|
+
'type',
|
135
|
+
stepCategoryCol,
|
136
|
+
].filter(Boolean);
|
137
|
+
const idIdxs = idCols.map((c) => colIdx[c]);
|
138
|
+
// data mapping
|
89
139
|
const dataMap = new Map();
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
140
|
+
const yearIdx = colIdx['step_year'];
|
141
|
+
const dtIdx = colIdx['step_datetime'];
|
142
|
+
const valueIdx = colIdx['value'];
|
143
|
+
for (const dfRow of df.values) {
|
144
|
+
const key = getIamcRowIndex(dfRow, idIdxs);
|
145
|
+
let wideRow = dataMap.get(key);
|
146
|
+
if (!wideRow) {
|
147
|
+
wideRow = takeOverIdx
|
148
|
+
.map((i) => dfRow[i])
|
149
|
+
.concat(Array(allTimes.length).fill(null));
|
150
|
+
dataMap.set(key, wideRow);
|
95
151
|
}
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
152
|
+
const year = yearIdx !== undefined ? dfRow[yearIdx] : undefined;
|
153
|
+
const dt = dtIdx !== undefined ? dfRow[dtIdx] : undefined;
|
154
|
+
let targetIdx;
|
155
|
+
if (year !== undefined && year !== null)
|
156
|
+
targetIdx = yearColIdx.get(year);
|
157
|
+
else if (dt !== undefined && dt !== null)
|
158
|
+
targetIdx = dtColIdx.get(dt);
|
159
|
+
if (targetIdx !== undefined) {
|
160
|
+
wideRow[targetIdx] = dfRow[valueIdx];
|
102
161
|
}
|
103
162
|
}
|
104
|
-
const wideIamcData =
|
105
|
-
for (const wideRow of dataMap.values()) {
|
106
|
-
wideIamcData.push(wideRow);
|
107
|
-
}
|
163
|
+
const wideIamcData = Array.from(dataMap.values());
|
108
164
|
return new dataframe_1.DataFrame(wideIamcData, { columns, dtypes });
|
109
165
|
}
|
110
|
-
|
166
|
+
/**
|
167
|
+
* Generates a unique row index for IAMC data based on the row's identifiers.
|
168
|
+
* @param row The row data as an array
|
169
|
+
* @param rowIdentifiers The indices of the identifiers in the row
|
170
|
+
* @returns A string that uniquely identifies the row
|
171
|
+
*/
|
111
172
|
function getIamcRowIndex(row, rowIdentifiers) {
|
112
173
|
return rowIdentifiers.map((i) => row[i]).join('_');
|
113
174
|
}
|
@@ -131,4 +192,75 @@ function withIamcDefault(filter) {
|
|
131
192
|
}
|
132
193
|
return filter;
|
133
194
|
}
|
134
|
-
|
195
|
+
function sortTimesWithYearFirst(years, dateTimes) {
|
196
|
+
// Create a combined array with type information
|
197
|
+
const combined = [];
|
198
|
+
// Add years with their metadata
|
199
|
+
for (const year of years) {
|
200
|
+
combined.push({ value: year, isYear: true, year });
|
201
|
+
}
|
202
|
+
// Add datetimes with their extracted year
|
203
|
+
for (const dateTime of dateTimes) {
|
204
|
+
// Extract year from datetime string (format: 2005-03-01T01:00:00)
|
205
|
+
const year = parseInt(dateTime.substring(0, 4), 10);
|
206
|
+
combined.push({ value: dateTime, isYear: false, year });
|
207
|
+
}
|
208
|
+
// Sort by year first, then by type (years before datetimes), then by value
|
209
|
+
combined.sort((a, b) => {
|
210
|
+
// First sort by year
|
211
|
+
if (a.year !== b.year) {
|
212
|
+
return a.year - b.year;
|
213
|
+
}
|
214
|
+
// Within the same year, years come before datetimes
|
215
|
+
if (a.isYear && !b.isYear) {
|
216
|
+
return -1;
|
217
|
+
}
|
218
|
+
if (!a.isYear && b.isYear) {
|
219
|
+
return 1;
|
220
|
+
}
|
221
|
+
// If both are the same type, sort by value
|
222
|
+
if (a.value < b.value) {
|
223
|
+
return -1;
|
224
|
+
}
|
225
|
+
if (a.value > b.value) {
|
226
|
+
return 1;
|
227
|
+
}
|
228
|
+
return 0;
|
229
|
+
});
|
230
|
+
// Return just the values
|
231
|
+
return combined.map((item) => item.value);
|
232
|
+
}
|
233
|
+
/**
|
234
|
+
* Splits a DataFrame into separate DataFrames based on DataPointType.
|
235
|
+
* @param df The DataFrame to split
|
236
|
+
* @returns An object containing DataFrames for each type present in the data
|
237
|
+
*/
|
238
|
+
function splitDataFrameByType(df) {
|
239
|
+
const result = {};
|
240
|
+
// If no type column exists, return the original dataframe as annual
|
241
|
+
if (!df.columns.includes('type')) {
|
242
|
+
result.annual = df;
|
243
|
+
return result;
|
244
|
+
}
|
245
|
+
// Get unique types in the dataframe
|
246
|
+
const typeValues = df.columnValues('type');
|
247
|
+
const uniqueTypes = [...new Set(typeValues)];
|
248
|
+
// Filter dataframe for each type present
|
249
|
+
for (const type of uniqueTypes) {
|
250
|
+
const filteredDf = df.query({
|
251
|
+
conditions: { column: 'type', predicate: (value) => value === type },
|
252
|
+
});
|
253
|
+
switch (type) {
|
254
|
+
case datapoint_1.DataPointType.ANNUAL:
|
255
|
+
result.annual = filteredDf;
|
256
|
+
break;
|
257
|
+
case datapoint_1.DataPointType.CATEGORICAL:
|
258
|
+
result.categorical = filteredDf;
|
259
|
+
break;
|
260
|
+
case datapoint_1.DataPointType.DATETIME:
|
261
|
+
result.datetime = filteredDf;
|
262
|
+
break;
|
263
|
+
}
|
264
|
+
}
|
265
|
+
return result;
|
266
|
+
}
|
package/dist/cjs/data/base.js
CHANGED
@@ -26,8 +26,8 @@ class BaseRepository {
|
|
26
26
|
this.enumerationMethod = (_a = this.constructor.enumerationMethod) !== null && _a !== void 0 ? _a : 'PATCH';
|
27
27
|
}
|
28
28
|
_request(url, method, params, body) {
|
29
|
-
var _a;
|
30
29
|
return __awaiter(this, void 0, void 0, function* () {
|
30
|
+
var _a;
|
31
31
|
const config = {};
|
32
32
|
config.url = url;
|
33
33
|
config.method = method;
|
@@ -80,8 +80,8 @@ class BaseRepository {
|
|
80
80
|
/**
|
81
81
|
* Convenience method for requests to the enumeration endpoint.
|
82
82
|
*/
|
83
|
-
_requestEnumeration(
|
84
|
-
return __awaiter(this,
|
83
|
+
_requestEnumeration() {
|
84
|
+
return __awaiter(this, arguments, void 0, function* (params = {}, body = {}, table = false) {
|
85
85
|
params = (0, utils_1.convertToSnakeCase)(params);
|
86
86
|
if (body !== undefined && Object.keys(body).length === 0) {
|
87
87
|
body = undefined;
|
@@ -116,8 +116,8 @@ class BaseRepository {
|
|
116
116
|
}
|
117
117
|
});
|
118
118
|
}
|
119
|
-
_list(
|
120
|
-
return __awaiter(this,
|
119
|
+
_list(_a) {
|
120
|
+
return __awaiter(this, arguments, void 0, function* ({ filter, params, }) {
|
121
121
|
if (this.enumerationMethod === 'GET') {
|
122
122
|
params = Object.assign(Object.assign({}, params), filter);
|
123
123
|
filter = undefined;
|
@@ -133,8 +133,8 @@ class BaseRepository {
|
|
133
133
|
}
|
134
134
|
});
|
135
135
|
}
|
136
|
-
_tabulate(
|
137
|
-
return __awaiter(this,
|
136
|
+
_tabulate(_a) {
|
137
|
+
return __awaiter(this, arguments, void 0, function* ({ filter, params, }) {
|
138
138
|
// TODO: test what happens if we get a number that cannot be represented as float32 (or int32)
|
139
139
|
const data = yield this._requestEnumeration(params, filter, true);
|
140
140
|
const pagination = data.pagination;
|
@@ -156,6 +156,24 @@ class BaseRepository {
|
|
156
156
|
}
|
157
157
|
});
|
158
158
|
}
|
159
|
+
_count(_a) {
|
160
|
+
return __awaiter(this, arguments, void 0, function* ({ filter, params, }) {
|
161
|
+
if (this.enumerationMethod === 'GET') {
|
162
|
+
params = Object.assign(Object.assign(Object.assign({}, params), filter), { limit: 0 });
|
163
|
+
filter = undefined;
|
164
|
+
}
|
165
|
+
else {
|
166
|
+
params = Object.assign(Object.assign({}, params), { limit: 0 });
|
167
|
+
}
|
168
|
+
const data = yield this._requestEnumeration(params, filter, true);
|
169
|
+
if (data === undefined || data.total === undefined) {
|
170
|
+
throw new exceptions_1.UnknownApiError({
|
171
|
+
message: 'Count result does not contain total count.',
|
172
|
+
});
|
173
|
+
}
|
174
|
+
return data.total;
|
175
|
+
});
|
176
|
+
}
|
159
177
|
_bulkUpsert(df, params) {
|
160
178
|
return __awaiter(this, void 0, void 0, function* () {
|
161
179
|
return yield this._request(`${this.prefix}bulk/`, 'POST', params, (0, utils_1.dfToJson)(df));
|