Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fresh-dots-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@sophys-web/spu-ui": patch
---

Update common schemas for better handling sampleTag fields (adding support for being used in unix filenames) and acquireTime fields (removing minimum value restriction of 0.1 seconds supporting positive numbers).
20 changes: 20 additions & 0 deletions apps/spu-ui/src/app/_components/plans/schemas/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,23 @@ export const proposalSchema = z
regexPatterns.proposal,
"Proposal must be exactly 8 digits long and contain only numbers",
);

export const acquireTimeSchema = z.coerce.number().positive();

/**
* sampleTag is a common field used in acquisition related forms and
* can be used to generate filenames for acquired data.
*/
export const sampleTagSchema = z
.string()
.min(1, "Sample tag must not be empty")
.max(100, "Sample tag must not exceed 100 characters")
.regex(
regexPatterns.noEmptySpaces,
"Sample tag must not contain empty spaces",
)
.regex(regexPatterns.noDots, "Sample tag must not contain dots")
.regex(
regexPatterns.invalidChars,
'Sample tag must not contain any of the following characters: \\ / : * ? " < > |',
);
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ import {
trayRows,
} from "~/app/_components/store/setup1/constants";
import { useSampleStore } from "../store/setup1/use-sample-store";
import { proposalSchema } from "./schemas/common";
import {
acquireTimeSchema,
proposalSchema,
sampleTagSchema,
} from "./schemas/common";

export const planName = "setup1_complete_standard_acquisition";

export const planSchema = z.object({
acquireTime: z.coerce.number().positive(),
acquireTime: acquireTimeSchema,
numExposures: z.coerce.number().int().positive(),
row: z
.string()
Expand Down Expand Up @@ -70,9 +74,7 @@ export const planSchema = z.object({
),
volume: z.coerce.number().positive(),
proposal: proposalSchema,
sampleTag: z
.string()
.min(1, "Sample name or other form of identification is required"),
sampleTag: sampleTagSchema,
sampleType: z
.string()
.transform((val) => val.trimStart().trimEnd())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,22 @@ import {
import { Switch } from "@sophys-web/ui/switch";
import type { LastSampleParams } from "~/app/_hooks/use-capillary-state";
import { sampleTypeOptions } from "~/app/_components/store/setup1/constants";
import { proposalSchema } from "./schemas/common";
import {
acquireTimeSchema,
proposalSchema,
sampleTagSchema,
} from "./schemas/common";

const planName = "setup1_acquisition";
const planSchema = z.object({
acquireTime: z.coerce
.number()
.min(0.1, "Acquire time (in seconds) must be at least 0.1"),
acquireTime: acquireTimeSchema,
numExposures: z.coerce
.number()
.min(1, "Number of exposures must be at least 1"),
motionSpeed: z.coerce.number().positive().optional(),
proposal: proposalSchema,
sampleType: z.enum(sampleTypeOptions),
sampleTag: z.string(),
sampleTag: sampleTagSchema,
temperature: z.coerce.number().positive().optional(),
setTemperature: z.boolean().optional(),
usePimega: z.boolean().optional(),
Expand Down
10 changes: 7 additions & 3 deletions apps/spu-ui/src/app/_components/plans/setup2-acquisition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,19 @@ import {
import { Label } from "@sophys-web/ui/label";
import { Switch } from "@sophys-web/ui/switch";
import { InfoTooltip } from "@sophys-web/widgets/form-components/info-tooltip";
import { proposalSchema } from "./schemas/common";
import {
acquireTimeSchema,
proposalSchema,
sampleTagSchema,
} from "./schemas/common";

export const name = "setup2_acquisition";

export const schema = z.object({
acquireTime: z.coerce.number().positive(),
acquireTime: acquireTimeSchema,
numExposures: z.coerce.number().int().positive(),
proposal: proposalSchema,
sampleTag: z.string().min(1),
sampleTag: sampleTagSchema,
usePimega: z.boolean().optional().default(true),
usePicolo: z.boolean().optional().default(true),
detReadout: z.coerce.number().positive().optional().default(0.001),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,17 @@ import {
cardIndexOptions,
cardRows,
} from "../store/setup2/constants";
import { proposalSchema, regexPatterns } from "./schemas/common";

const sampleTagSchema = z
.string()
.min(1)
.max(
100,
"Sample name or other form of identification must be at most 100 characters long",
)
.regex(regexPatterns.invalidChars, {
message:
"Sample tag can only contain letters, numbers, dashes, and underscores",
})
.regex(regexPatterns.noEmptySpaces, {
message: "Sample tag must not contain empty spaces",
})
.regex(regexPatterns.noDots, {
message: "Sample tag must not contain dots",
});
import {
acquireTimeSchema,
proposalSchema,
sampleTagSchema,
} from "./schemas/common";

const schema = z
.object({
proposal: proposalSchema,
sampleTag: sampleTagSchema,
acquireTime: z.coerce
.number()
.min(0.1, "Acquire time (in seconds) must be at least 0.1"),
acquireTime: acquireTimeSchema,
numExposures: z.coerce
.number()
.int()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import {
InputGroupInput,
} from "@sophys-web/ui/input-group";
import { InfoTooltip } from "@sophys-web/widgets/form-components/info-tooltip";
import { proposalSchema } from "./schemas/common";
import { proposalSchema, sampleTagSchema } from "./schemas/common";

export const name = "setup2_find_sample_horizontal_scan";

export const schema = z.object({
proposal: proposalSchema,
sampleTag: z.string().min(1),
sampleTag: sampleTagSchema,
minX: z.coerce.number(),
maxX: z.coerce.number(),
xStepSize: z.coerce.number().positive().default(1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import {
InputGroupInput,
} from "@sophys-web/ui/input-group";
import { InfoTooltip } from "@sophys-web/widgets/form-components/info-tooltip";
import { proposalSchema } from "./schemas/common";
import { proposalSchema, sampleTagSchema } from "./schemas/common";

export const name = "setup2_find_sample_vertical_scan";

export const schema = z.object({
proposal: proposalSchema,
sampleTag: z.string().min(1),
sampleTag: sampleTagSchema,
minY: z.coerce.number(),
maxY: z.coerce.number(),
yStepSize: z.coerce.number().positive().default(1),
Expand Down
10 changes: 7 additions & 3 deletions apps/spu-ui/src/app/_components/plans/setup4-xps-acquisition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ import {
InputGroupInput,
} from "@sophys-web/ui/input-group";
import { InfoTooltip } from "@sophys-web/widgets/form-components/info-tooltip";
import { proposalSchema } from "./schemas/common";
import {
acquireTimeSchema,
proposalSchema,
sampleTagSchema,
} from "./schemas/common";

export const name = "setup4_xpcs_acquisition";

export const schema = z.object({
acquirePeriod: z.coerce.number().positive(),
acquirePeriod: acquireTimeSchema,
numExposures: z.coerce.number().int().positive(),
detReadout: z.coerce.number().min(0.001).positive().optional(),
proposal: proposalSchema,
sampleTag: z.string().min(1),
sampleTag: sampleTagSchema,
});

export function Setup4XpcsAquisitionForm({
Expand Down
11 changes: 0 additions & 11 deletions apps/spu-ui/src/app/_components/store/setup1/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ export const trayColumns = [
] as const;
export const trayRows = ["A", "B", "C", "D", "E", "F", "G", "H"] as const;
export const trayOptions = ["Tray1", "Tray2"] as const;
export const acquireTimeOptions = [
"200",
"100",
"50",
"25",
"12.5",
"6.25",
"3.125",
"1.5625",
"0.5",
] as const;
export const sampleTypeOptions = ["buffer", "sample"] as const;
export const cleaningOptions = ["light", "normal", "heavy", "custom"] as const;
export const standardCleaningOptions = ["light", "normal", "heavy"] as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
trayOptions,
trayRows,
} from "../../store/setup1/constants";
import { proposalSchema } from "./../../plans/schemas/common";
import { proposalSchema, sampleTagSchema } from "./../../plans/schemas/common";
import { useSampleStore } from "./use-sample-store";

export const planName = "setup1_load_procedure";
Expand All @@ -35,7 +35,7 @@ export const planSchema = z.object({
.positive()
.max(100, "Volume must be between 0 and 100 µL"),
proposal: proposalSchema,
sampleTag: z.string(),
sampleTag: sampleTagSchema,
sampleType: z.enum(sampleTypeOptions),
expUvTime: z.coerce.number().nonnegative().optional(),
measureUvNumber: z.coerce.number().int().nonnegative().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ import {
} from "@sophys-web/ui/select";
import type { trayColumns, trayOptions, trayRows } from "./constants";
import type { Sample } from "./use-sample-store";
import { sampleTagSchema } from "../../plans/schemas/common";
import { initialVolume } from "./constants";
import { sampleIdFromPosition, useSampleStore } from "./use-sample-store";

const sampleSchema = z.object({
sampleType: z.enum(["sample", "buffer"]),
sampleTag: z.string().min(2, { message: "Sample tag is required" }),
sampleTag: sampleTagSchema,
volume: z.coerce.number().min(0),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo } from "react";
import { z } from "zod";
import { useStore } from "@sophys-web/api-client/hooks";
import { usePvData } from "@sophys-web/pvws-store";
import { sampleTagSchema } from "../../plans/schemas/common";
import {
cardCapillaryColumns,
cardColumns,
Expand Down Expand Up @@ -134,7 +135,7 @@ export const sampleIdEncoder = z
*/
export const sampleSchema = z.object({
id: z.string(),
sampleTag: z.string(),
sampleTag: sampleTagSchema,
position: z
.object({
x: z.coerce.number(),
Expand Down
Loading