From e75bcfa29005d16dc6ca9127caee6ccacc73e04b Mon Sep 17 00:00:00 2001 From: JohnCLee7 <79617818+JohnCLee7@users.noreply.github.com> Date: Fri, 29 Nov 2024 23:39:13 +1100 Subject: [PATCH] Hotfix/revert to static temperature estimation (#25) * Removed upload button for temperature estimation data from csv file. * Revert "Fix/temperature estimation implementation (#23)" This reverts commit 827496ca1382784536b9e7b706803f79f2846912. * Locked index's to current order. --- app/calculate/sweep/page.tsx | 2 - app/fridge/graph/page.tsx | 2 - backend | 2 +- components/config/ConfigStage.tsx | 61 +++++++++----------- components/config/GUIconfig.json | 50 ----------------- components/config/context.tsx | 15 +---- components/inputs/importCSVButton.tsx | 6 +- components/pyodide/fridge.d.ts | 3 +- components/pyodide/fridge.ts | 9 +-- components/pyodide/index.tsx | 80 +++++++++++++-------------- components/pyodide/types.d.ts | 20 +------ components/wiremap/map.tsx | 4 +- 12 files changed, 77 insertions(+), 177 deletions(-) diff --git a/app/calculate/sweep/page.tsx b/app/calculate/sweep/page.tsx index b88778a..aaab7db 100644 --- a/app/calculate/sweep/page.tsx +++ b/app/calculate/sweep/page.tsx @@ -636,8 +636,6 @@ function useSweep( const model = useCryogenicModel(); const fridge = useFridge(); - model.loadTemperatureEstimation(fridge.temperatureEstimationData); - const [result1D, setResult1D] = useState([null, "loading"]); const [result2D, setResult2D] = useState([null, "loading"]); diff --git a/app/fridge/graph/page.tsx b/app/fridge/graph/page.tsx index ac75a6c..d09c881 100644 --- a/app/fridge/graph/page.tsx +++ b/app/fridge/graph/page.tsx @@ -94,8 +94,6 @@ function FridgeGraphs() { const model = useCryogenicModel(); const fridge = useFridge(); - model.loadTemperatureEstimation(fridge.temperatureEstimationData); - const dimensions = useDimensions(); const numGraphs = 3; diff --git a/backend b/backend index f586cdb..e13f207 160000 --- a/backend +++ b/backend @@ -1 +1 @@ -Subproject commit f586cdbb372a79216fccbce35d3906d3abeb1108 +Subproject commit e13f20768e5fa7e708f4d39b4b6ae3b623ec5614 diff --git a/components/config/ConfigStage.tsx b/components/config/ConfigStage.tsx index ab7a980..428b9f0 100644 --- a/components/config/ConfigStage.tsx +++ b/components/config/ConfigStage.tsx @@ -7,9 +7,7 @@ import { NumericInputColumn } from "@/components/inputs/numeric"; import { DeleteButtonColumn, FormGroup, FormSection, findNextId } from "@/components/config/common"; import { readCSVFile } from "@/components/config/ConfigCable"; import { useFeatureFlags } from "@/components/config/featureFlagContext"; -import { UploadCSVButton } from "@/components/inputs/importCSVButton"; -import { TempEstimationPoint } from "@/components/pyodide/types"; -import styles from "@/components/config/Config.module.css"; +import { UploadCSVButton } from "../inputs/importCSVButton"; function getNewStage(stages: StageConfig[], lines: LineConfig[]): [StageConfig, SegmentConfig[]] { const nextIndex = stages.length > 0 ? Math.ceil(Math.max(...stages.map((item: StageConfig) => item.index))) + 1 : 0; @@ -50,7 +48,7 @@ type StageConfigProps = { // eslint-disable-next-line max-lines-per-function export default function FridgeStages({ tooltips, setModal }: StageConfigProps): JSX.Element { - const { stages, setStages, lines, segments, setSegments, temperatureEstimationData, setTemperatureEstimationData } = useFridge(); + const { stages, setStages, lines, segments, setSegments } = useFridge(); const updateStageId = (index: number, oldId: string, value: string) => { setSegments(segments.map((item: SegmentConfig) => item.stageId !== oldId ? item : { ...item, stageId: value })); updateStage(index, "id", value); @@ -84,7 +82,7 @@ export default function FridgeStages({ tooltips, setModal }: StageConfigProps): active: true, data: dataString, onSubmit: (dataStr: string) => { - setTemperatureEstimationData(fromStringToArray(dataStr)); + console.log(fromStringToArray(dataStr)); } }) } catch (err) { @@ -100,55 +98,46 @@ export default function FridgeStages({ tooltips, setModal }: StageConfigProps): return ( - label="Index" tooltip={tooltips.index} data={stages} valueGetter={(item: StageConfig) => item.index} valueSetter={(index, item, value) => updateStage(index, "index", value)} /> + label="Index" tooltip={tooltips.index} data={stages} valueGetter={(item: StageConfig) => item.index} valueSetter={(index, item, value) => updateStage(index, "index", value)} disabled={featureFlags.staticStageCount} /> label="Stage Names" tooltip={tooltips.stage_names} data={stages} valueGetter={(item: StageConfig) => item.id} valueSetter={(index, item, value) => updateStageId(index, item.id, value)} isUnique={(value: string) => stages.every((item: StageConfig) => item.id !== value)} /> label="Temperatures (k)" tooltip={tooltips.tempertures} data={stages} valueGetter={(item: StageConfig) => item.temperature} valueSetter={(index, item, value) => updateStage(index, "temperature", value)} /> label="Cooling Budgets (W)" tooltip={tooltips.cooling_powers} data={stages} valueGetter={(item: StageConfig) => item.coolingPower} valueSetter={(index, item, value) => updateStage(index, "coolingPower", value)} /> {!featureFlags.staticStageCount && label="Stage" tooltip={tooltips.remove_stage} data={stages} onClick={removeStage} />} - -
- - -
-
); } +type TempEstimationPoint = { + point_powers: number[], + temperatures: number[] +} + // eslint-disable-next-line max-lines-per-function function interpretTempEstimatePoints(csvData: string[][]): TempEstimationPoint[] { - if (csvData.length < 3) throw new Error(`CSV data needs at least two points (rows).`); + if (csvData.length < 2) throw new Error(`CSV data needs at least two points (rows).`); const data: TempEstimationPoint[] = []; for (let i = 0; i < csvData.length; i++) { // for now, limiting to 5 stages, therefore 5 values for each, totaling 10 values expected - if (csvData[i].length < 2) break; if (csvData[i].length != 10) throw new Error(`CSV data does not have the correct number of columns to represent 5 stages at row ${i}.`); - const powers: number[] = []; + const point_powers: number[] = []; const temperatures: number[] = []; for (let j = 0; j < 5; j++) { - powers.push(parseFloat(csvData[i][j])); + point_powers.push(parseFloat(csvData[i][j])); temperatures.push(parseFloat(csvData[i][j + 5])); } - if (powers.every((p) => isNaN(p))) { - throw new Error(`Some of the Point Powers values: '${powers}' are not a number.`); + if (point_powers.every((p) => isNaN(p))) { + throw new Error(`Some of the Point Powers values: '${point_powers}' are not a number.`); } else if (temperatures.every((t) => isNaN(t))) { throw new Error(`Some of the Temperature values: '${temperatures}' are not a number.`); } else { - const point: TempEstimationPoint = { applied_power: powers, measured_temperature: temperatures }; + const point: TempEstimationPoint = { point_powers, temperatures }; data.push(point); } } @@ -169,13 +158,13 @@ function dataToString(data: TempEstimationPoint[]): string { function getPAndTValueString(dataPoint: TempEstimationPoint, end: boolean): string { let pString: string = ""; let tString: string = ""; - const length = (dataPoint.applied_power.length + dataPoint.measured_temperature.length) / 2; + const length = (dataPoint.point_powers.length + dataPoint.temperatures.length) / 2; for (let j = 0; j < length - 1; j++) { - pString += dataPoint.applied_power[j] + ","; - tString += dataPoint.measured_temperature[j] + ","; + pString += dataPoint.point_powers[j] + ","; + tString += dataPoint.temperatures[j] + ","; } - pString += dataPoint.applied_power[length - 1] + ","; - tString += dataPoint.measured_temperature[length - 1]; + pString += dataPoint.point_powers[length - 1] + ","; + tString += dataPoint.temperatures[length - 1]; return "(" + pString + tString + ((end) ? ")" : "),") } @@ -191,25 +180,25 @@ function fromStringToArray(data: string): TempEstimationPoint[] { const noBrackets = lines[i].replaceAll('(', '').replaceAll(')', ''); const values = noBrackets.split(',') - const powers: number[] = []; + const point_powers: number[] = []; const temperatures: number[] = []; const stageNum = values.length / 2; for (let j = 0; j < stageNum; j++) { - powers.push(parseFloat(values[j])); + point_powers.push(parseFloat(values[j])); temperatures.push(parseFloat(values[j + stageNum])); } - if (powers.every((p) => isNaN(p))) { - throw new Error(`Some of the values ${powers} could not be interpreted as a number.`) + if (point_powers.every((p) => isNaN(p))) { + throw new Error(`Some of the values ${point_powers} could not be interpreted as a number.`) } else if (temperatures.every((t) => isNaN(t))) { throw new Error(`Some of the values ${temperatures} could not be interpreted as a number.`) } // TODO: more handeling for if the error is not in the first non whitespace charcter of f or a. - result.push({ applied_power: powers, measured_temperature: temperatures }); + result.push({ point_powers, temperatures }); } return result; diff --git a/components/config/GUIconfig.json b/components/config/GUIconfig.json index fbf4bab..d3ba422 100644 --- a/components/config/GUIconfig.json +++ b/components/config/GUIconfig.json @@ -342,56 +342,6 @@ "length": 0.14, "attenuation": 0 } - ], - "temperatureEstimationData": [ - { - "applied_power": [ - 1e-10, - 1e-10, - 1e-2, - 1e-10, - 1e-10 - ], - "measured_temperature": [ - 4.20111000e+1, - 3.41026571e+0, - 1.20520821e+0, - 1.63359036e-1, - 1.64774143e-2 - ] - }, - { - "applied_power": [ - 2.5, - 0.5, - 2.5e-2, - 0.5e-3, - 4e-4 - ], - "measured_temperature": [ - 4.20111000e+1, - 3.41026571e+0, - 1.20520821e+0, - 1.63359036e-1, - 1.64774143e-2 - ] - }, - { - "applied_power": [ - 5, - 1, - 5e-2, - 1e-3, - 8e-4 - ], - "measured_temperature": [ - 4.20111000e+1, - 3.41026571e+0, - 1.20520821e+0, - 1.63359036e-1, - 1.64774143e-2 - ] - } ] } } \ No newline at end of file diff --git a/components/config/context.tsx b/components/config/context.tsx index 728ddc8..e191907 100644 --- a/components/config/context.tsx +++ b/components/config/context.tsx @@ -4,14 +4,12 @@ import { FC, PropsWithChildren, createContext, useContext, useEffect, useMemo, u import defaultFridge from "@/components/config/GUIconfig.json" import { FridgeConfig, StageConfig, CableConfig, LineConfig, SegmentConfig } from "@/components/pyodide/fridge.d" import { useFeatureFlags } from "./featureFlagContext" -import { TempEstimationPoint } from "@/components/pyodide/types" export type FridgeContext = FridgeConfig & { setStages: (stages: StageConfig[]) => void, setCables: (cables: CableConfig[]) => void, setLines: (lines: LineConfig[]) => void, setSegments: (segments: SegmentConfig[]) => void, - setTemperatureEstimationData: (setTemperatureEstimationData: TempEstimationPoint[]) => void, import: (fridge: FridgeConfig) => void, export: () => FridgeConfig reset: () => void, @@ -24,12 +22,10 @@ const defaultFridgeContext: FridgeContext = { cables: defaultFridge.FridgeUTS.cables as CableConfig[], lines: defaultFridge.FridgeUTS.lines as LineConfig[], segments: defaultFridge.FridgeUTS.segments as SegmentConfig[], - temperatureEstimationData: defaultFridge.FridgeUTS.temperatureEstimationData as TempEstimationPoint[], setStages: () => { }, setCables: () => { }, setLines: () => { }, setSegments: () => { }, - setTemperatureEstimationData: () => { }, import: () => { }, export: () => defaultFridge.FridgeUTS as FridgeConfig, reset: () => { }, @@ -46,7 +42,6 @@ export const FridgeProvider: FC = ({ children }) => { const [cables, setCables] = useState([]); const [lines, setLines] = useState([]); const [segments, setSegments] = useState([]); - const [tempEstData, setTempEstData] = useState([]); const featureFlags = useFeatureFlags(); @@ -63,12 +58,10 @@ export const FridgeProvider: FC = ({ children }) => { setCables(fridge.cables); setLines(fridge.lines); setSegments(fridge.segments); - setTempEstData(fridge.temperatureEstimationData); - }, [setStages, setCables, setLines, setSegments, setTempEstData]); - + }, [setStages, setCables, setLines, setSegments]); const exportConfig = useMemo(() => () => { - return { stages, cables, lines, segments, temperatureEstimationData: tempEstData }; - }, [stages, cables, lines, segments, tempEstData]); + return { stages, cables, lines, segments }; + }, [stages, cables, lines, segments]); const reset = useMemo(() => () => { importConfig(defaultFridge.FridgeUTS as FridgeConfig); @@ -96,8 +89,6 @@ export const FridgeProvider: FC = ({ children }) => { setLines: setLines, segments: segments, setSegments: setSegments, - temperatureEstimationData: tempEstData, - setTemperatureEstimationData: setTempEstData, import: importConfig, export: exportConfig, reset: reset, diff --git a/components/inputs/importCSVButton.tsx b/components/inputs/importCSVButton.tsx index 9490690..a430c55 100644 --- a/components/inputs/importCSVButton.tsx +++ b/components/inputs/importCSVButton.tsx @@ -24,19 +24,19 @@ export function UploadCSVButton({ label, tooltip, message, onClick, ...props }: } return ( - <> +
- - +
); } \ No newline at end of file diff --git a/components/pyodide/fridge.d.ts b/components/pyodide/fridge.d.ts index 69abb7c..ce6d9b7 100644 --- a/components/pyodide/fridge.d.ts +++ b/components/pyodide/fridge.d.ts @@ -1,11 +1,10 @@ -import { Diameters, ThermalConductivityValue, BivariateCableData, TempEstimationPoint } from "./types"; +import { Diameters, ThermalConductivityValue, BivariateCableData } from "./types"; export type FridgeConfig = { stages: StageConfig[]; cables: CableConfig[]; lines: LineConfig[]; segments: SegmentConfig[]; - temperatureEstimationData: TempEstimationPoint[]; }; export type StageId = string; // e.g. "50K", "MXC" or "Still" diff --git a/components/pyodide/fridge.ts b/components/pyodide/fridge.ts index d6d5dde..c638c9f 100644 --- a/components/pyodide/fridge.ts +++ b/components/pyodide/fridge.ts @@ -400,8 +400,7 @@ function createNewFridge(fridge: FridgeConfig, lineID: string, stages: string[], stages: fridge.stages, cables: fridge.cables, lines: fridge.lines, - segments: newSegments, - temperatureEstimationData: fridge.temperatureEstimationData + segments: newSegments }; } @@ -543,8 +542,7 @@ function updateFridgeStagesTemps(fridge: FridgeConfig, sTemp: number[]): FridgeC stages: newStages, cables: fridge.cables, lines: fridge.lines, - segments: fridge.segments, - temperatureEstimationData: fridge.temperatureEstimationData + segments: fridge.segments }; } @@ -599,8 +597,7 @@ export function sweepModel2D(model: CryoModelInterface, fridge: FridgeConfig, li }) var newFridge = createNewFridge(fridge, lineID, stages, configs); // initial temperature estimates (should instead update configuration file) - // var t_est = [4.20111000e+1, 3.41026571e+0, 1.20520821e+0, 1.63359036e-1, 1.64774143e-2]; - var t_est = fridge.stages.map((stage) => stage.temperature); + var t_est = [4.20111000e+1, 3.41026571e+0, 1.20520821e+0, 1.63359036e-1, 1.64774143e-2];//fridge.stages.map((stage) => stage.temperature); var load_matrix_0: number[][] = lineCount.map(() => stages.map(() => 0)); var delta_load_matrix: number[][] = lineCount.map(() => stages.map(() => 1)); const threshold: number = 0.0005; diff --git a/components/pyodide/index.tsx b/components/pyodide/index.tsx index 1905299..a26009e 100644 --- a/components/pyodide/index.tsx +++ b/components/pyodide/index.tsx @@ -19,9 +19,7 @@ import { SweepModelOuterFn, ConstraintGenerationFn, SpecificConstraintGenerationFn, - BivariateCableData, - ApplyBoundedTStagesFn, - LoadTemperatureEstimationFn + BivariateCableData } from "./types"; import { LineLoadOutput } from "@/components/pyodide/fridge.d" import { PythonRuntime, usePythonRuntime } from "@/lib/pythonrt"; @@ -188,13 +186,38 @@ export class CryoModel extends PythonRuntime implements CryoModelInterface { return this.runJSON(code); } - applyBoundedTStages: ApplyBoundedTStagesFn = (heatLoads: number[]) => { + applyBoundedTStages: ApplyTStagesFn = (heatLoads: number[]) => { + const heatLoadLimits: { stage: string, lowerLimit: number, upperLimit: number }[] = [ + { + stage: "50K", + lowerLimit: 0, + upperLimit: 5 + }, + { + stage: "4K", + lowerLimit: 0, + upperLimit: 1 + }, + { + stage: "Still", + lowerLimit: 1e-2, + upperLimit: 5e-2 + }, + { + stage: "CP", + lowerLimit: 0, + upperLimit: 1e-3 + }, + { + stage: "MXC", + lowerLimit: 0, + upperLimit: 8e-4 + }, + ]; // only works for 5 stage fridge where the middle stage is the still stage. const heatLoadsLocal = heatLoads.map((h, i) => (i == 2) ? Math.max(heatLoads[i], 3e-2) : h); - const { temperatures, heatLoadLimits } = this.applyTStages(heatLoadsLocal) - const errors: string[] = []; for (let i = 0; i < heatLoadLimits.length; i++) { @@ -206,7 +229,7 @@ export class CryoModel extends PythonRuntime implements CryoModelInterface { `Heat Load ${heatLoadsLocal[i]} exceeds the range ` + `[${heatLoadLimits[i].lowerLimit},` + ` ${heatLoadLimits[i].upperLimit}]` + - ` for stage ${i}\n` + ` for stage ${heatLoadLimits[i].stage}\n` ) }; } @@ -216,7 +239,7 @@ export class CryoModel extends PythonRuntime implements CryoModelInterface { return this.nanValueArray(heatLoads); } - return temperatures; + return this.applyTStages(heatLoadsLocal) } // eslint-disable-next-line max-lines-per-function @@ -229,25 +252,15 @@ export class CryoModel extends PythonRuntime implements CryoModelInterface { total = [] heat_loads = ${jsToPy(heatLoads)} - for i in range(len(heat_loads)): - total.append(t_funcs(i, heat_loads)) + total.append(param_functions.T_funcs(0, heat_loads)) + total.append(param_functions.T_funcs(1, heat_loads)) + total.append(param_functions.T_funcs(2, heat_loads)) + total.append(param_functions.T_funcs(3, heat_loads)) + total.append(param_functions.T_funcs(4, heat_loads)) json.dumps(total) ` - - const bounds: number[][] = this.pyodide?.globals.get('bounds').toJs(); - - const heatLoadLimits: { lowerLimit: number, upperLimit: number }[] = bounds.map((b) => { - return { - lowerLimit: b[0], - upperLimit: b[1] - } - }); - - return { - temperatures: this.runJSON(code), - heatLoadLimits - }; + return this.runJSON(code); } // eslint-disable-next-line max-lines-per-function @@ -602,25 +615,6 @@ export class CryoModel extends PythonRuntime implements CryoModelInterface { ` return this.runJSON(code); } - - loadTemperatureEstimation: LoadTemperatureEstimationFn = (data) => { - - const formattedData: number[][] = data.map((row) => [...row.applied_power, ...row.measured_temperature]) - - const jsToPy = javascriptToPython; - const code = ` - from CryowalaCore import param_functions - import numpy as np - import pandas as pd - import json - - data = np.array(${jsToPy(formattedData)}) - - t_funcs, bounds = param_functions.generate_t_funcs(data) - - ` - this.run(code); - } } export function useCryogenicModel(): CryoModel { diff --git a/components/pyodide/types.d.ts b/components/pyodide/types.d.ts index 9679bc1..cbe0bf1 100644 --- a/components/pyodide/types.d.ts +++ b/components/pyodide/types.d.ts @@ -6,7 +6,7 @@ export interface CryoModelInterface { fluxNoise: FluxNoiseFn; cableAttenuation: CableAttenuationFn; applyTStages: ApplyTStagesFn; - applyBoundedTStages: ApplyBoundedTStagesFn; + applyBoundedTStages: ApplyTStagesFn; sweepModelInner: SweepModelInnerFn; cableAttGeneration: CableAttGenerationFn; noisePhotons: NoisePhotonsFn; @@ -15,7 +15,6 @@ export interface CryoModelInterface { sweepModelOuter: SweepModelOuterFn; constraintGeneration: ConstraintGenerationFn; specificConstraintGeneration: SpecificConstraintGenerationFn; - loadTemperatureEstimation: LoadTemperatureEstimationFn; } export type InnerPinDiameter = number; @@ -34,11 +33,6 @@ export type BivariateCableData = { attenuation: number }; -export type TempEstimationPoint = { - applied_power: number[], - measured_temperature: number[] -} - /** * Returns list of `passive` loads of cable from n stages * @@ -136,13 +130,9 @@ export type CableAttenuationFn = ( f: number ) => number; -export type ApplyBoundedTStagesFn = ( - heatLoads: number[] -) => number[]; - export type ApplyTStagesFn = ( heatLoads: number[] -) => { temperatures: number[], heatLoadLimits: { lowerLimit: number, upperLimit: number }[] }; +) => number[]; export type SweepModelInnerOutput = { absHeatValues: number[][], @@ -218,8 +208,4 @@ export type SpecificConstraintGenerationFn = ( constraints: string[], x: number, y: number -) => number[]; - -export type LoadTemperatureEstimationFn = ( - data: TempEstimationPoint[] -) => void; \ No newline at end of file +) => number[]; \ No newline at end of file diff --git a/components/wiremap/map.tsx b/components/wiremap/map.tsx index 882a369..aa881a0 100644 --- a/components/wiremap/map.tsx +++ b/components/wiremap/map.tsx @@ -341,17 +341,15 @@ export type WiringDiagramProps = { }; // eslint-disable-next-line max-lines-per-function export function WiringDiagram({ margin }: WiringDiagramProps) { - const fridge = useFridge(); const model = useCryogenicModel(); const { width: totalWidth, height: totalHeight } = useDimensions(); - model.loadTemperatureEstimation(fridge.temperatureEstimationData); - const width = totalWidth - margin.left - margin.right; const height = totalHeight - margin.top - margin.bottom; const LinkComponent = LinkVerticalStep; + const fridge = useFridge(); const treeBreadth = fridge.lines.length; const treeDepth = fridge.stages.length + 1;