journal/tool/journalLib.jq

203 lines
7 KiB
Plaintext
Raw Normal View History

2024-11-09 00:49:08 +00:00
import "utils" as utils;
def calculateIngestionDose($customUnits):
. as $ingestion |
if .customUnitId != null then
($customUnits | map(select(.id == $ingestion.customUnitId))[0]) as $customUnit |
.dose * $customUnit.dose | . as $dose |
$dose * 100 | round / 100
else
.dose
end;
def ingestionUnit($customUnits):
. as $ingestion |
if .customUnitId != null then
($customUnits | map(select(.id == $ingestion.customUnitId))[0]) as $customUnit |
$customUnit.originalUnit
else
.units
end;
def ingestionConsumerName:
. as $ingestion |
$ingestion.consumerName // "default";
def filterIngestions($substanceFilter; $consumerFilter):
. as $ingestions |
if (($substanceFilter // [] | length) > 0) then
[
$ingestions[] as $ingestion |
if
([$substanceFilter[] | . == $ingestion.substanceName] | any)
and
([$consumerFilter[] | . == ($ingestion | ingestionConsumerName)] | any)
then $ingestion
else null end
] | map(select(. != null))
else $ingestions end;
def ingestionsSubstanceNames:
. as $ingestions |
[$ingestions[].substanceName] | utils::orderedUnique;
def ingestionsConsumerNames:
. as $ingestions |
[$ingestions[] | ingestionConsumerName] | utils::orderedUnique;
def ingestionsByConsumer:
. as $ingestions |
($ingestions | ingestionsConsumerNames) as $consumerNames |
[
$consumerNames[] as $consumerName |
{
key: $consumerName,
value: [$ingestions | map(select(
. | ingestionConsumerName == $consumerName
))],
}
] | from_entries;
def experienceStats($customUnits):
. as $experience |
$experience.ingestions as $ingestions |
(reduce $ingestions[] as $ingestion ({}; . as $stats |
$ingestion |
.substanceName as $name |
.administrationRoute as $administrationRoute |
. | calculateIngestionDose($customUnits) as $dose |
. | ingestionUnit($customUnits) as $unit |
. | ingestionConsumerName as $consumerName |
$stats | .[$consumerName].[$name].[$administrationRoute] |=
($stats.[$consumerName].[$name].[$administrationRoute] // {
unit: "",
# null because null+null = null for ingestions with unknown dose which .dose is null
dose: null
}) |
.[$consumerName].[$name].[$administrationRoute].unit |= $unit |
.[$consumerName].[$name].[$administrationRoute].dose += $dose
));
def statsCalculateCombinedDose($substanceName; $consumerName):
. as $stats |
(.[$consumerName].[$substanceName] | [to_entries[] | .value.dose] | add) as $combinedDose |
(.[$consumerName].[$substanceName] | to_entries[0] | .value.unit) as $combinedDoseUnit |
{dose: $combinedDose, unit: $combinedDoseUnit};
def experiencesWithExtraData($customUnits):
. as $experiences |
(reduce $experiences[] as $experience ([];
($experience | experienceStats($customUnits)) as $stats |
. += [{
$stats,
$experience
}]
));
def filterSortExperiences($customUnits; $substanceFilter; $consumerFilter; $sortMethod; $sortOptions):
. as $experiences |
($consumerFilter // ["default"]) as $consumerFilter |
$sortOptions |
# If filtering results by substances but no sortOptions.substanceName is defined, use the first one as a default
(.substanceName |=
if
$sortOptions.substanceName == null
and
(($substanceFilter | length) >= 1)
then
$substanceFilter[0]
else
null
end
) | . as $sortOptions |
$sortOptions | (.ingestionMethod |= ($sortOptions.ingestionMethod // "ORAL")) | . as $sortOptions |
$sortOptions | (.consumerName |= ($sortOptions.consumerName // "default")) | . as $sortOptions |
def sortFilter:
def oldToNewSort: .experience.sortDate;
def highestCombinedDoseSort: .stats.[$sortOptions.consumerName].[$sortOptions.substanceName] | [to_entries[] | .value.dose] | add;
def highestMethodDoseSort: .stats.[$sortOptions.consumerName].[$sortOptions.substanceName].[$sortOptions.ingestionMethod // "ORAL"].dose;
def filterBySubstanceFilter:
. as $experiencesData |
[
$experiencesData[] as $experienceData |
($experienceData.experience.ingestions) as $ingestions |
if ($experienceData.experience.ingestions |
any(
. as $ingestion |
$substanceFilter |
any(index($ingestion.substanceName))
)
) then $experienceData else null end
] | map(select(. != null));
def filterByConsumerFilter:
. as $experiencesData |
(reduce $experiencesData[] as $experienceData ([];
($experienceData.experience.ingestions) as $ingestions |
. +=
if ($experienceData.experience.ingestions |
any(
(. | ingestionConsumerName) as $consumerName |
$consumerFilter |
any(index($consumerName))
)
) then [$experienceData] else [] end
));
def filterBySubstanceAndConsumer:
. as $experiencesData |
(reduce $experiencesData[] as $experienceData ([];
($experienceData.experience.ingestions) as $ingestions |
. +=
if
($experienceData.experience.ingestions |
any(
.substanceName == $sortOptions.substanceName
and
(. | ingestionConsumerName) == $sortOptions.consumerName
))
then [$experienceData] else [] end
));
def filterByIngestionMethodForSubstance:
. as $experiencesData | filterBySubstanceAndConsumer as $experiencesData |
(reduce $experiencesData[] as $experienceData ([];
($experienceData.experience.ingestions) as $ingestions |
. += if ($experienceData.experience.ingestions | any(.substanceName == $sortOptions.substanceName and .administrationRoute == $sortOptions.ingestionMethod))
then [$experienceData] else [] end
));
# speeds up by excluding everything not containing substances & consumers not in filters, wouldn't show any data anyway
if $substanceFilter != null then filterBySubstanceFilter end |
filterByConsumerFilter |
if
$sortMethod == "old-to-new" or $sortMethod == null
then
sort_by(oldToNewSort)
elif
$sortMethod == "highest-combined-dose"
then
utils::assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") |
filterBySubstanceAndConsumer |
sort_by(highestCombinedDoseSort, oldToNewSort) |
reverse
elif
$sortMethod == "highest-dose-for-method"
then
utils::assert($sortOptions.substanceName != null; "substanceName not provided as sortOption") |
filterByIngestionMethodForSubstance |
sort_by(highestMethodDoseSort, oldToNewSort) |
reverse
end;
$experiences |
experiencesWithExtraData($customUnits) |
sortFilter;
def experienceByTitle($name):
utils::assert((. | type) == "array"; "experienceByTitle takes a array of experiences as input") |
map(select(.title == $name))[0];