Regoranize generator code
This commit is contained in:
+119
-114
@@ -412,128 +412,65 @@ export class Standards {
|
|||||||
? this.activityStandards[activity].metadata.generators
|
? this.activityStandards[activity].metadata.generators
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const ageGenerators = allGenerators.filter(
|
for (const generator of allGenerators) {
|
||||||
(g) => g.metric === "age",
|
if (generator.metric === "age") {
|
||||||
);
|
for (const gender of Object.values(Gender)) {
|
||||||
for (const ageGenerator of ageGenerators) {
|
const peakAge = this.cfg.activity[activity].peakAge;
|
||||||
for (const gender of Object.values(Gender)) {
|
const ageStep = 10;
|
||||||
const peakAge = this.cfg.activity[activity].peakAge;
|
|
||||||
const ageStep = 10;
|
|
||||||
|
|
||||||
const minAge = 0;
|
const minAge = 0;
|
||||||
const maxAge = 100;
|
const maxAge = 100;
|
||||||
|
|
||||||
const referenceStandard = this.byActivity(activity)
|
|
||||||
.byMetrics({
|
|
||||||
weight: getAvgWeight(gender, peakAge),
|
|
||||||
gender,
|
|
||||||
age: peakAge,
|
|
||||||
})
|
|
||||||
.getOneInterpolated();
|
|
||||||
|
|
||||||
let currAge = minAge;
|
|
||||||
while (currAge <= maxAge) {
|
|
||||||
const newStandard: Standard = {
|
|
||||||
metrics: {
|
|
||||||
weight: getAvgWeight(gender, currAge),
|
|
||||||
age: currAge,
|
|
||||||
gender,
|
|
||||||
},
|
|
||||||
levels: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const lvl in referenceStandard.levels) {
|
|
||||||
const base = referenceStandard.levels[lvl];
|
|
||||||
if (!base) continue;
|
|
||||||
|
|
||||||
const s = this.cfg.activity[activity].ageModifier;
|
|
||||||
|
|
||||||
const youngFloor0 = 0.5;
|
|
||||||
const oldFloor0 = 0.5;
|
|
||||||
|
|
||||||
const youngFloor = 1 - (1 - youngFloor0) * s;
|
|
||||||
const oldFloor = 1 - (1 - oldFloor0) * s;
|
|
||||||
|
|
||||||
const cy =
|
|
||||||
(s * (1 - youngFloor0)) /
|
|
||||||
Math.pow(peakAge - minAge, 2);
|
|
||||||
const co =
|
|
||||||
(s * (1 - oldFloor0)) /
|
|
||||||
Math.pow(maxAge - peakAge, 2);
|
|
||||||
|
|
||||||
let f =
|
|
||||||
currAge <= peakAge
|
|
||||||
? 1 - cy * Math.pow(peakAge - currAge, 2)
|
|
||||||
: 1 - co * Math.pow(currAge - peakAge, 2);
|
|
||||||
|
|
||||||
const floor = Math.min(youngFloor, oldFloor);
|
|
||||||
const fCurr = Math.max(floor, Math.min(1, f));
|
|
||||||
|
|
||||||
newStandard.levels[lvl] = base * fCurr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefer real data over generated data
|
|
||||||
const overlappingStandard = this.byActivity(activity)
|
|
||||||
.byMetrics(newStandard.metrics)
|
|
||||||
.getOne();
|
|
||||||
if (!overlappingStandard)
|
|
||||||
this.activityStandards[activity].standards.push(
|
|
||||||
newStandard,
|
|
||||||
);
|
|
||||||
|
|
||||||
currAge += ageStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now that we generated metric data, remove the old data
|
|
||||||
this.activityStandards[activity].standards =
|
|
||||||
this.activityStandards[activity].standards.filter(
|
|
||||||
(s) => s.metrics.weight,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const weightGenerators = allGenerators.filter(
|
|
||||||
(g) => g.metric === "weight",
|
|
||||||
);
|
|
||||||
for (const weightGenerator of weightGenerators) {
|
|
||||||
for (const gender of Object.values(Gender)) {
|
|
||||||
for (const age of this.agesFor(activity, gender)) {
|
|
||||||
const weightStep = 12;
|
|
||||||
const referenceWeight = getAvgWeight(gender, age);
|
|
||||||
|
|
||||||
const minWeight = Math.max(
|
|
||||||
referenceWeight - 3 * weightStep,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
const maxWeight = referenceWeight + 3 * weightStep;
|
|
||||||
|
|
||||||
const referenceStandard = this.byActivity(activity)
|
const referenceStandard = this.byActivity(activity)
|
||||||
.byMetrics({ weight: referenceWeight, gender, age })
|
.byMetrics({
|
||||||
|
weight: getAvgWeight(gender, peakAge),
|
||||||
|
gender,
|
||||||
|
age: peakAge,
|
||||||
|
})
|
||||||
.getOneInterpolated();
|
.getOneInterpolated();
|
||||||
|
|
||||||
let currWeight = minWeight;
|
let currAge = minAge;
|
||||||
while (currWeight <= maxWeight) {
|
while (currAge <= maxAge) {
|
||||||
const newStandard: Standard = {
|
const newStandard: Standard = {
|
||||||
metrics: {
|
metrics: {
|
||||||
weight: currWeight,
|
weight: getAvgWeight(gender, currAge),
|
||||||
age,
|
age: currAge,
|
||||||
gender,
|
gender,
|
||||||
},
|
},
|
||||||
levels: {},
|
levels: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// apply allometric scaling to generate levels
|
|
||||||
for (const lvl in referenceStandard.levels) {
|
for (const lvl in referenceStandard.levels) {
|
||||||
if (!referenceStandard.levels[lvl]) continue;
|
const base = referenceStandard.levels[lvl];
|
||||||
|
if (!base) continue;
|
||||||
|
|
||||||
const scalingExponent =
|
const s =
|
||||||
this.cfg.activity[activity].weightModifier;
|
this.cfg.activity[activity].ageModifier;
|
||||||
const coefficient =
|
|
||||||
currWeight / referenceWeight;
|
|
||||||
|
|
||||||
newStandard.levels[lvl] =
|
const youngFloor0 = 0.5;
|
||||||
referenceStandard.levels[lvl] *
|
const oldFloor0 = 0.5;
|
||||||
coefficient ** scalingExponent;
|
|
||||||
|
const youngFloor = 1 - (1 - youngFloor0) * s;
|
||||||
|
const oldFloor = 1 - (1 - oldFloor0) * s;
|
||||||
|
|
||||||
|
const cy =
|
||||||
|
(s * (1 - youngFloor0)) /
|
||||||
|
Math.pow(peakAge - minAge, 2);
|
||||||
|
const co =
|
||||||
|
(s * (1 - oldFloor0)) /
|
||||||
|
Math.pow(maxAge - peakAge, 2);
|
||||||
|
|
||||||
|
let f =
|
||||||
|
currAge <= peakAge
|
||||||
|
? 1 -
|
||||||
|
cy * Math.pow(peakAge - currAge, 2)
|
||||||
|
: 1 -
|
||||||
|
co * Math.pow(currAge - peakAge, 2);
|
||||||
|
|
||||||
|
const floor = Math.min(youngFloor, oldFloor);
|
||||||
|
const fCurr = Math.max(floor, Math.min(1, f));
|
||||||
|
|
||||||
|
newStandard.levels[lvl] = base * fCurr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefer real data over generated data
|
// prefer real data over generated data
|
||||||
@@ -547,16 +484,84 @@ export class Standards {
|
|||||||
newStandard,
|
newStandard,
|
||||||
);
|
);
|
||||||
|
|
||||||
currWeight += weightStep;
|
currAge += ageStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// now that we generated metric data, remove the old data
|
// now that we generated metric data, remove the old data
|
||||||
this.activityStandards[activity].standards =
|
this.activityStandards[activity].standards =
|
||||||
this.activityStandards[activity].standards.filter(
|
this.activityStandards[activity].standards.filter(
|
||||||
(s) => s.metrics.weight,
|
(s) => s.metrics.weight,
|
||||||
);
|
);
|
||||||
|
} else if (generator.metric === "weight") {
|
||||||
|
for (const gender of Object.values(Gender)) {
|
||||||
|
for (const age of this.agesFor(activity, gender)) {
|
||||||
|
const weightStep = 12;
|
||||||
|
const referenceWeight = getAvgWeight(gender, age);
|
||||||
|
|
||||||
|
const minWeight = Math.max(
|
||||||
|
referenceWeight - 3 * weightStep,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
const maxWeight = referenceWeight + 3 * weightStep;
|
||||||
|
|
||||||
|
const referenceStandard = this.byActivity(activity)
|
||||||
|
.byMetrics({
|
||||||
|
weight: referenceWeight,
|
||||||
|
gender,
|
||||||
|
age,
|
||||||
|
})
|
||||||
|
.getOneInterpolated();
|
||||||
|
|
||||||
|
let currWeight = minWeight;
|
||||||
|
while (currWeight <= maxWeight) {
|
||||||
|
const newStandard: Standard = {
|
||||||
|
metrics: {
|
||||||
|
weight: currWeight,
|
||||||
|
age,
|
||||||
|
gender,
|
||||||
|
},
|
||||||
|
levels: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
// apply allometric scaling to generate levels
|
||||||
|
for (const lvl in referenceStandard.levels) {
|
||||||
|
if (!referenceStandard.levels[lvl])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const scalingExponent =
|
||||||
|
this.cfg.activity[activity]
|
||||||
|
.weightModifier;
|
||||||
|
const coefficient =
|
||||||
|
currWeight / referenceWeight;
|
||||||
|
|
||||||
|
newStandard.levels[lvl] =
|
||||||
|
referenceStandard.levels[lvl] *
|
||||||
|
coefficient ** scalingExponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prefer real data over generated data
|
||||||
|
const overlappingStandard = this.byActivity(
|
||||||
|
activity,
|
||||||
|
)
|
||||||
|
.byMetrics(newStandard.metrics)
|
||||||
|
.getOne();
|
||||||
|
if (!overlappingStandard)
|
||||||
|
this.activityStandards[
|
||||||
|
activity
|
||||||
|
].standards.push(newStandard);
|
||||||
|
|
||||||
|
currWeight += weightStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now that we generated metric data, remove the old data
|
||||||
|
this.activityStandards[activity].standards =
|
||||||
|
this.activityStandards[activity].standards.filter(
|
||||||
|
(s) => s.metrics.weight,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.activityStandards[activity].standards = this.activityStandards[
|
this.activityStandards[activity].standards = this.activityStandards[
|
||||||
|
|||||||
Reference in New Issue
Block a user