Skip to content

Commit 00f3d24

Browse files
authored
Fix/recipe json cleanup (#181)
* remove irrelevant gradient data from final recipe string * round radius to 2 decimal points * update test file to remove unnecessary gradients * copilot suggestions
1 parent 37f3e55 commit 00f3d24

6 files changed

Lines changed: 36 additions & 59 deletions

File tree

src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState } from "react";
22
import { Layout, Typography } from "antd";
33
import { getJobStatus, updateJobStatusTimestamp } from "./utils/firebase";
4-
import { getFirebaseRecipe, jsonToString } from "./utils/recipeLoader";
4+
import { getFirebaseRecipe, recipeToString } from "./utils/recipeLoader";
55
import { getSubmitPackingUrl, JOB_STATUS } from "./constants/aws";
66
import {
77
useJobId,
@@ -43,7 +43,7 @@ function App() {
4343
recipeString: string
4444
): Promise<boolean> => {
4545
const originalRecipe = await getFirebaseRecipe(recipeId);
46-
return !(jsonToString(originalRecipe) == recipeString);
46+
return !(recipeToString(originalRecipe) == recipeString);
4747
};
4848

4949
const submitRecipe = async (

src/components/InputSwitch/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const InputSwitch = (props: InputSwitchProps): JSX.Element => {
4949
}
5050
if (typeof value == "number") {
5151
value = value * conversion;
52-
value = Number(value.toFixed(4));
52+
value = Number(value.toFixed(2));
5353
}
5454
return value;
5555
}, [getCurrentValue, id, min, conversion, dataType]);

src/state/store.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { create } from "zustand";
22
import { subscribeWithSelector } from "zustand/middleware";
33
import { isEmpty, isEqual, get as lodashGet } from "lodash-es";
44
import { PackingResult, RecipeData, RecipeManifest } from "../types";
5-
import { jsonToString } from "../utils/recipeLoader";
5+
import { recipeToString } from "../utils/recipeLoader";
66
import {
77
getRecipeDataFromFirebase,
88
getRecipeManifestFromFirebase,
@@ -236,7 +236,7 @@ export const useRecipeStore = create<RecipeStore>()(
236236
edits
237237
);
238238
if (!recipeObject) return;
239-
const recipeString = jsonToString(recipeObject);
239+
const recipeString = recipeToString(recipeObject);
240240
set({ isPacking: true });
241241
try {
242242
await callback(s.selectedRecipeId, configId, recipeString);

src/test/recipeLoader.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect, test } from 'vitest';
22
import fs from 'fs';
3-
import { isFirebaseRef, getFirebaseRecipe, jsonToString } from '../utils/recipeLoader';
3+
import { isFirebaseRef, getFirebaseRecipe, recipeToString } from '../utils/recipeLoader';
44

55
test('isFirebaseRef detects Firebase references correctly', () => {
66
expect(isFirebaseRef('firebase:recipes/some_id')).toBe(true);
@@ -14,7 +14,7 @@ test('isFirebaseRef detects Firebase references correctly', () => {
1414
test('getFirebaseRecipe works as expected for ER_peroxisome_v_struct_gradient_370574', async () => {
1515
const recipeId = 'ER_peroxisome_v_struct_gradient_370574';
1616
const recipeJson = await getFirebaseRecipe(recipeId);
17-
const recipeString = jsonToString(recipeJson);
17+
const recipeString = recipeToString(recipeJson);
1818

1919
expect(recipeString).toBeDefined();
2020
expect(typeof recipeString).toBe('string');
@@ -30,7 +30,7 @@ test('getFirebaseRecipe works as expected for ER_peroxisome_v_struct_gradient_37
3030
test('getFirebaseRecipe works as expected for one_sphere', async () => {
3131
const recipeId = 'one_sphere_v_1.0.0';
3232
const recipeJson = await getFirebaseRecipe(recipeId);
33-
const recipeString = jsonToString(recipeJson);
33+
const recipeString = recipeToString(recipeJson);
3434

3535
expect(recipeString).toBeDefined();
3636
expect(typeof recipeString).toBe('string');

src/test/test-files/ER_peroxisome.json

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -132,54 +132,6 @@
132132
}
133133
},
134134
"gradients": {
135-
"apical_gradient": {
136-
"description": "gradient based on distance from a plane",
137-
"invert": null,
138-
"mode": "vector",
139-
"mode_settings": {
140-
"center": [0, 0, 106.875],
141-
"direction": [0, 0, 1]
142-
},
143-
"name": "apical_gradient",
144-
"pick_mode": "linear",
145-
"reversed": false,
146-
"weight_mode": "exponential",
147-
"weight_mode_settings": {
148-
"decay_length": 0.1
149-
}
150-
},
151-
"membrane_gradient": {
152-
"description": "gradient based on distance from the surface of the membrane mesh",
153-
"invert": null,
154-
"mode": "surface",
155-
"mode_settings": {
156-
"object": "membrane",
157-
"scale_to_next_surface": false
158-
},
159-
"name": "membrane_gradient",
160-
"pick_mode": "linear",
161-
"reversed": false,
162-
"weight_mode": "exponential",
163-
"weight_mode_settings": {
164-
"decay_length": 0.01
165-
}
166-
},
167-
"nucleus_gradient": {
168-
"description": "gradient based on distance from the surface of the nucleus mesh",
169-
"invert": null,
170-
"mode": "surface",
171-
"mode_settings": {
172-
"object": "nucleus",
173-
"scale_to_next_surface": false
174-
},
175-
"name": "nucleus_gradient",
176-
"pick_mode": "linear",
177-
"reversed": false,
178-
"weight_mode": "exponential",
179-
"weight_mode_settings": {
180-
"decay_length": 0.1
181-
}
182-
},
183135
"struct_gradient": {
184136
"name": "struct_gradient",
185137
"invert": null,

src/utils/recipeLoader.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,34 @@ const getFirebaseRecipe = async (name: string): Promise<ViewableRecipe> => {
328328
return unpackedRecipe;
329329
}
330330

331-
const jsonToString = (json: ViewableRecipe): string => {
332-
return JSON.stringify(json, null, 2);
331+
const recipeToString = (rec: ViewableRecipe): string => {
332+
// Deep copy recipe to avoid mutating original object
333+
const recipe: ViewableRecipe = structuredClone(rec);
334+
335+
// Collect a list of gradients that are referenced by objects the recipe
336+
const referencedGradients: Set<string> = new Set();
337+
if (recipe.objects) {
338+
for (const obj of Object.values(recipe.objects)) {
339+
if (obj.packing_mode === "gradient" && obj.gradient) {
340+
referencedGradients.add(obj.gradient);
341+
} else if (obj.packing_mode === "random" && obj.gradient) {
342+
// If packing mode is random, gradient field is irrelevant
343+
// and should be cleared
344+
delete obj.gradient;
345+
}
346+
}
347+
}
348+
349+
// If the recipe has gradients that aren't referenced in any objects, delete them
350+
if (recipe.gradients) {
351+
for (const gradientName of Object.keys(recipe.gradients)) {
352+
if (!referencedGradients.has(gradientName)) {
353+
delete recipe.gradients[gradientName];
354+
}
355+
}
356+
}
357+
return JSON.stringify(recipe, null, 2);
333358
}
334359

335360

336-
export { getFirebaseRecipe, isFirebaseRef, jsonToString };
361+
export { getFirebaseRecipe, isFirebaseRef, recipeToString };

0 commit comments

Comments
 (0)