Skip to content

Commit

Permalink
Move outputs back into experiments store
Browse files Browse the repository at this point in the history
Partially reverts 0dff547
sverhoeven committed Nov 12, 2024
1 parent 00180dd commit aac745a
Showing 3 changed files with 34 additions and 87 deletions.
59 changes: 22 additions & 37 deletions apps/class-solid/src/components/Analysis.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { For, Match, Show, Switch, createMemo, createUniqueId } from "solid-js";
import { getVerticalProfiles } from "~/lib/profiles";
import {
type Analysis,
deleteAnalysis,
experiments,
outputForExperiment,
outputForPermutation,
} from "~/lib/store";
import { type Analysis, deleteAnalysis, experiments } from "~/lib/store";
import LinePlot from "./LinePlot";
import { MdiCog, MdiContentCopy, MdiDelete, MdiDownload } from "./icons";
import { Button } from "./ui/button";
@@ -37,21 +31,22 @@ export function TimeSeriesPlot() {
return experiments
.filter((e) => e.running === false) // Skip running experiments
.flatMap((e, i) => {
const experimentOutput = outputForExperiment(e);
const permutationRuns = e.permutations.map((perm, j) => {
const permOutput = outputForPermutation(experimentOutput, j);
return {
label: `${e.name}/${perm.name}`,
y: permOutput.h ?? [],
x: permOutput.t ?? [],
color: colors[(j + 1) % 10],
linestyle: linestyles[i % 5],
};
});
const experimentOutput = e.reference.output;
const permutationRuns = e.permutations
.filter((perm) => perm.output !== undefined)
.map((perm, j) => {
return {
label: `${e.name}/${perm.name}`,
y: perm.output?.h ?? [],
x: perm.output?.t ?? [],
color: colors[(j + 1) % 10],
linestyle: linestyles[i % 5],
};
});
return [
{
y: experimentOutput?.reference.h ?? [],
x: experimentOutput?.reference.t ?? [],
y: experimentOutput?.h ?? [],
x: experimentOutput?.t ?? [],
label: e.name,
color: colors[0],
linestyle: linestyles[i],
@@ -77,16 +72,14 @@ export function VerticalProfilePlot() {
return experiments
.filter((e) => e.running === false) // Skip running experiments
.flatMap((e, i) => {
const experimentOutput = outputForExperiment(e);
const permutations = e.permutations.map((p, j) => {
// TODO get additional config info from reference
// permutations probably usually don't have gammaq/gammatetha set?
const permOutput = outputForPermutation(experimentOutput, j);
return {
color: colors[(j + 1) % 10],
linestyle: linestyles[i % 5],
label: `${e.name}/${p.name}`,
...getVerticalProfiles(permOutput, p.config, variable, time),
...getVerticalProfiles(p.output, p.config, variable, time),
};
});

@@ -96,7 +89,7 @@ export function VerticalProfilePlot() {
color: colors[0],
linestyle: linestyles[i],
...getVerticalProfiles(
experimentOutput?.reference ?? {
e.reference.output ?? {
t: [],
h: [],
theta: [],
@@ -127,27 +120,19 @@ function FinalHeights() {
<For each={experiments}>
{(experiment) => {
const h = () => {
const experimentOutput = outputForExperiment(experiment);
return (
experimentOutput?.reference.h[
experimentOutput.reference.h.length - 1
] || 0
);
const experimentOutput = experiment.reference.output;
return experimentOutput?.h[experimentOutput?.h.length - 1] || 0;
};
return (
<Show when={!experiment.running}>
<li class="mb-2" title={experiment.name}>
{experiment.name}: {h().toFixed()} m
</li>
<For each={experiment.permutations}>
{(perm, permIndex) => {
{(perm) => {
const h = () => {
const experimentOutput = outputForExperiment(experiment);
const permOutput = outputForPermutation(
experimentOutput,
permIndex(),
);
return permOutput.h?.length
const permOutput = perm.output;
return permOutput?.h?.length
? permOutput.h[permOutput.h.length - 1]
: 0;
};
21 changes: 7 additions & 14 deletions apps/class-solid/src/lib/download.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ClassOutput } from "@classmodel/class/runner";
import type { ExperimentConfigSchema } from "@classmodel/class/validate";
import { BlobReader, BlobWriter, ZipWriter } from "@zip.js/zip.js";
import { type Experiment, outputForExperiment } from "./store";
import type { Experiment } from "./store";

export function toConfig(experiment: Experiment): ExperimentConfigSchema {
return {
@@ -40,29 +40,22 @@ export async function createArchive(experiment: Experiment) {
type: "application/json",
});
await zipWriter.add("config.json", new BlobReader(configBlob));
const output = outputForExperiment(experiment);
if (!output) {
return;
}

if (output.reference) {
const csvBlob = new Blob([outputToCsv(output.reference)], {
if (experiment.reference.output) {
const csvBlob = new Blob([outputToCsv(experiment.reference.output)], {
type: "text/csv",
});
await zipWriter.add(`${experiment.name}.csv`, new BlobReader(csvBlob));
}

let permIndex = 0;
for (const perm of experiment.permutations) {
const name = perm.name;
const permutationOutput = output.permutations[permIndex];
if (output && name) {
for (const permutation of experiment.permutations) {
const permutationOutput = permutation.output;
if (permutationOutput) {
const csvBlob = new Blob([outputToCsv(permutationOutput)], {
type: "text/csv",
});
await zipWriter.add(`${name}.csv`, new BlobReader(csvBlob));
await zipWriter.add(`${permutation.name}.csv`, new BlobReader(csvBlob));
}
permIndex++;
}
await zipWriter.close();
return await zipFileWriter.getData();
41 changes: 5 additions & 36 deletions apps/class-solid/src/lib/store.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import { runClass } from "./runner";
export interface Permutation<C extends PartialConfig = PartialConfig> {
name: string;
config: C;
output?: ClassOutput | undefined;
// TODO Could use per run state to show progress of run of reference and each permutation
// running: boolean;
}
@@ -23,6 +24,7 @@ export interface Experiment {
reference: {
// TODO change reference.config to config, as there are no other keys in reference
config: PartialConfig;
output?: ClassOutput | undefined;
};
permutations: Permutation[];
running: number | false;
@@ -31,34 +33,6 @@ export interface Experiment {
export const [experiments, setExperiments] = createStore<Experiment[]>([]);
export const [analyses, setAnalyses] = createStore<Analysis[]>([]);

interface ExperimentOutput {
reference: ClassOutput;
permutations: ClassOutput[];
}

// Outputs must store outside store as they are too big to wrap in proxy
export const outputs: ExperimentOutput[] = [];

export function outputForExperiment(
index: number | Experiment,
): ExperimentOutput | undefined {
if (typeof index === "object") {
const i = experiments.indexOf(index);
return outputs[i];
}
return outputs[index];
}

export function outputForPermutation(
experiment: ExperimentOutput | undefined,
permutationIndex: number,
) {
if (!experiment || experiment.permutations.length <= permutationIndex) {
return { t: [], h: [], theta: [], dtheta: [] };
}
return experiment.permutations[permutationIndex];
}

// biome-ignore lint/suspicious/noExplicitAny: recursion is hard to type
function mergeConfigurations(reference: any, permutation: any) {
const merged = { ...reference };
@@ -81,7 +55,7 @@ function mergeConfigurations(reference: any, permutation: any) {
export async function runExperiment(id: number) {
const exp = experiments[id];

setExperiments(id, "running", 0);
setExperiments(id, "running", 0.0001);

// TODO make lazy, if config does not change do not rerun
// or make more specific like runReference and runPermutation
@@ -90,18 +64,15 @@ export async function runExperiment(id: number) {
const referenceConfig = unwrap(exp.reference.config);
const newOutput = await runClass(referenceConfig);

outputs[id] = {
reference: newOutput,
permutations: [],
};
setExperiments(id, "reference", "output", newOutput);

// Run permutations
let permCounter = 0;
for (const proxiedPerm of exp.permutations) {
const permConfig = unwrap(proxiedPerm.config);
const combinedConfig = mergeConfigurations(referenceConfig, permConfig);
const newOutput = await runClass(combinedConfig);
outputs[id].permutations[permCounter] = newOutput;
setExperiments(id, "permutations", permCounter, "output", newOutput);
permCounter++;
}

@@ -172,7 +143,6 @@ export function duplicateExperiment(id: number) {

export function deleteExperiment(index: number) {
setExperiments(experiments.filter((_, i) => i !== index));
outputs.splice(index, 1);
}

export async function modifyExperiment(
@@ -226,7 +196,6 @@ export async function deletePermutationFromExperiment(
setExperiments(experimentIndex, "permutations", (perms) =>
perms.filter((_, i) => i !== permutationIndex),
);
outputs[experimentIndex].permutations.splice(permutationIndex, 1);
}

export function findPermutation(exp: Experiment, permutationName: string) {

0 comments on commit aac745a

Please sign in to comment.