Open Suchiman opened 4 years ago
If you (anyone) would like to fix these issues, please open a pull request against oref0 dev. To verify the fixes don’t have unintended consequences, we can run oref0-backtest with and without the fixes and confirm whether it changes insulin dosing behavior.
@Suchiman 👍 for code review, If you have some advices with my adaptation of Autotune for AAPS (not finished yet) you're wellcome https://github.com/MilosKozak/AndroidAPS/pull/2669 ...
I have 2 other point that surprised me (it's not a deep analysis): oref0/lib/autotune-prep/categorize.js (lines389-395)
if (opts.categorize_uam_as_basal) {
console.error("--categorize-uam-as-basal=true set: categorizing all UAM data as basal.");
basalGlucoseData = basalGlucoseData.concat(UAMGlucoseData);
} else if (CSFLength > 12) {
console.error("Found at least 1h of carb absorption: assuming all meals were announced, and categorizing UAM data as basal.");
basalGlucoseData = basalGlucoseData.concat(UAMGlucoseData);
} else {
To verify if all meals were announced, check if there is at least 1h of CSF values seems to me very strange (if you have just only one meal recorded, it's very difficult to have less than one hour of CSF data...)
During my tests I found some days with more than 3 hours of UAM data considered as basal (this test is allways true on my side) For my part, I would have chosen something like "less than one hour of UAM data" (line 392)
} else if (UAMLength < 12) {
console.error("Found less than 1h of UAM data: assuming all meals were announced, and categorizing UAM data as basal.");
basalGlucoseData = basalGlucoseData.concat(UAMGlucoseData);
oref0/lib/autotune/index.js (lines 361-364)
} else {
deviations += Math.max(0*previousAutotune.min_5m_carbimpact,parseFloat(CSFGlucose[i].deviation));
mealCarbs = Math.max(mealCarbs, parseInt(CSFGlucose[i].mealCarbs));
}
What's the idea behind 0*previousAutotune.min_5m_carbimpact
?
Some GitHub archaeology shows that the 0*previousAutotune thing was from https://github.com/openaps/oref0/commit/5b3ecb3fc4c5be6f455f1d6066ca8b2729d28f6a "disable min deviation for CSF calculation" - it was a leftover from something I attempted during initial autotune development, and just never got cleaned up.
But with this modification you also disable negative deviation in calculation...
For categorize_uam_as_basal setting I never see on my tests any impact on results (I always have more than 1 hour of csf data so test is always true, even with 2 or 3 hours of uam data...). Do you think my proposal is a good idea (UAMLength < 12)?
I'm using AAPS (xDrip+ Libre2 / Accu-Check Insight -> meaning there are some gotchas) and am a windows user so i tried getting it to run locally on which i gave up after some struggling with WSL dependency conflicts around node-gyp. I then did what every self respecting developer would do and did a line by line port to my favorite and totally unbiased best language 😜 C# and tweaked it until it was bug compatible (producing same output) with AutotuneWeb. During this process i noticed quite a few suspicious code snippets where i was unable to tell if it's an atrocious feature of dynamic code or a bug.
currentIOBOnly
flag https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/autotune-prep/categorize.js#L209inputs.clock
isn't passed by all callers and will be undefined here whichtz
turns into the current timestamp https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L174new Date(undefined)
which results in anInvalid date
that returnsNaN
for its instance methods causing https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/basal.js#L19nowMinutes
to becomeNaN
, thus always failing this condition https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/basal.js#L22 and effectively returning https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/basal.js#L14currentItem.rate
is sometimesundefined
/null
causingnetBasalRate
to becomeNaN
here https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L546created_at
but the other code seems to assumestarted_at
(yaay schemaless) https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L556new Date(0).getTime()
is a very elaborate / obfuscated way of saying0
, https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/index.js#L40-L42endOffset
here but in the JSON file it'sendoffset
(although, just thinking about it, that could also be an error from AutotuneWeb) https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/isf.js#L16 https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/isf.js#L41endOffset
even it's already set https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/profile/isf.js#L30-L38current._type
https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/meal/history.js#L58 which is a property that does not exists in my nightscout data unlikeeventType
from the quite similiar looking code here https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L294current.insulin
is sometimes null here https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L301temp.timestamp
withcurrent.created_at
and then try to find duplicates withcurrent.timestamp
that might not exists or be different fromcreated_at
https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/meal/history.js#L74-L78 https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/meal/history.js#L87-L89current.absolute
for AAPS but unless you setalways use absolute values
, which must not be used with insight, AAPS sendsrate
(with the same value as absolute) https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L317-L319 which is the case for the non AAPS case here https://github.com/openaps/oref0/blob/acb0150021e7bf284b6741a9510076a13f690747/lib/iob/history.js#L325-L327 i've personally changed the code to either useabsolute ?? rate
whatever is presentvar
thus creating them in global scope.number = number.toFixed(precision)
to round which actually returns a string and then use that elsewhere to do arithmetic. Also this uses IEEE754 compliant AwayFromZero rounding while other code usesMath.round(x * 1En) / 1En
which uses half-up rounding that will also round differently than IEEE754 compliant code since the multiplying fucks with otherwise irrepresentable numbers like0.15
which is actually0.1499999999999999944488848768742172978818416595458984375
and thus rounds withtoFixed(1)
to0.1
but withMath.round(0.15 * 10) / 10
to0.2
All in all the lack of static type safety and the schemaless design of nightscout with attempted normalization scattered across the entire codebase makes this code a pain to work with and the inconsistent naming doesn't help either (
treatment
might refer to different sorts of objects; the various datetime properties that alternate between unix timestamp, iso8601 string or date instance, the type isn't even guaranteed to be consistent with the same name; all styles are used, lower_snake_case, camelCase, PascalCase). I'd suggest normalizing the data into a single format before the call to prepare even. Most of these things were found by the C# compiler telling me off. I'm sure i've also missed another few cases because i've only started documenting these things halfway through. And after these painful discoveries, here's something to laugh