Skip to content

Commit

Permalink
Move to other file, add comments and a warning for unknown params
Browse files Browse the repository at this point in the history
  • Loading branch information
WardBrian committed Jun 26, 2024
1 parent 7a3e199 commit 919ef45
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 109 deletions.
116 changes: 7 additions & 109 deletions gui/src/app/SPAnalysis/SPAnalysisContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createContext, FunctionComponent, PropsWithChildren, useEffect, useRedu
import { deserializeAnalysis, initialDataModel, serializeAnalysis, SPAnalysisDataModel, modelHasUnsavedChanges } from "./SPAnalysisDataModel"
import { SPAnalysisReducer, SPAnalysisReducerAction, SPAnalysisReducerType } from "./SPAnalysisReducer"
import { useSearchParams } from "react-router-dom"
import { SamplingOpts } from "../StanSampler/StanSampler"
import { fromSearchParams, fetchRemoteAnalysis } from "./SPAnalysisQueryLoading"

type SPAnalysisContextType = {
data: SPAnalysisDataModel
Expand All @@ -18,112 +18,6 @@ export const SPAnalysisContext = createContext<SPAnalysisContextType>({
})


enum QueryParamKeys {
StanFile = "stan",
DataFile = "data",
SamplingOpts = "sampling_opts",
Title = "title",
SONumChains = 'num_chains',
SONumWarmup = 'num_warmup',
SONumSamples = 'num_samples',
SOInitRadius = 'init_radius',
SOSeed = 'seed',
}

type QueryParams = {
[key in QueryParamKeys]: string | null
}

const fromSearchParams = (searchParams: URLSearchParams) => {
const query: QueryParams = {
stan: searchParams.get(QueryParamKeys.StanFile),
data: searchParams.get(QueryParamKeys.DataFile),
sampling_opts: searchParams.get(QueryParamKeys.SamplingOpts),
title: searchParams.get(QueryParamKeys.Title),
num_chains: searchParams.get(QueryParamKeys.SONumChains),
num_warmup: searchParams.get(QueryParamKeys.SONumWarmup),
num_samples: searchParams.get(QueryParamKeys.SONumSamples),
init_radius: searchParams.get(QueryParamKeys.SOInitRadius),
seed: searchParams.get(QueryParamKeys.SOSeed),
}
return query

}


const tryFetch = async (url: string) => {
console.log('Fetching content from', url);
try {
const req = await fetch(url);
if (!req.ok) {
console.error('Failed to fetch from url', url, req.status, req.statusText);
return undefined;
}
return await req.text();
} catch (err) {
console.error('Failed to fetch from url', url, err);
return undefined;
}
}

const deepCopy = (obj: any) => {
return JSON.parse(JSON.stringify(obj))
}

const fetchRemoteAnalysis = async (query: QueryParams) => {

// any special 'project' query could be loaded here at the top
const data: SPAnalysisDataModel = deepCopy(initialDataModel);

if (query.stan) {
const stanFileContent = await tryFetch(query.stan);
if (stanFileContent) {
data.stanFileContent = stanFileContent;
}
}
if (query.data) {
const dataFileContent = await tryFetch(query.data);
if (dataFileContent) {
data.dataFileContent = dataFileContent;
}
}

if (query.sampling_opts) {
const text = await tryFetch(query.sampling_opts);
if (text) {
// TODO(bmw) validate
data.samplingOpts = JSON.parse(text);
}
} else {
if (query.num_chains) {
data.samplingOpts.num_chains = parseInt(query.num_chains);
}
if (query.num_warmup) {
data.samplingOpts.num_warmup = parseInt(query.num_warmup);
}
if (query.num_samples) {
data.samplingOpts.num_samples = parseInt(query.num_samples);
}
if (query.init_radius) {
data.samplingOpts.init_radius = parseFloat(query.init_radius);
}
if (query.seed) {
data.samplingOpts.seed = parseInt(query.seed);
}
}

if (query.title) {
data.meta.title = query.title;
}

// TODO(bmw) create a 'setEphemera' helper?
data.ephemera.stanFileContent = data.stanFileContent;
data.ephemera.dataFileContent = data.dataFileContent;

return data;
}


const SPAnalysisContextProvider: FunctionComponent<PropsWithChildren<SPAnalysisContextProviderProps>> = ({ children }) => {
const [data, update] = useReducer<SPAnalysisReducerType>(SPAnalysisReducer, initialDataModel)

Expand All @@ -145,7 +39,7 @@ const SPAnalysisContextProvider: FunctionComponent<PropsWithChildren<SPAnalysisC
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, [data])

////////////////////////////////////////////////////////////////////////////////////////


useEffect(() => {
Expand All @@ -168,12 +62,16 @@ const SPAnalysisContextProvider: FunctionComponent<PropsWithChildren<SPAnalysisC

}, [data, searchParams])


useEffect(() => {
// whenever the data state is 'dirty', we want to
// clear the URL bar as to indiciate that the viewed content is
// no longer what the link would point to
if (searchParams.size !== 0 && modelHasUnsavedChanges(data)) {
setSearchParams(new URLSearchParams());
}
}, [data, searchParams, setSearchParams])
////////////////////////////////////////////////////////////////////////////////////////


return (
<SPAnalysisContext.Provider value={{ data, update }}>
Expand Down
113 changes: 113 additions & 0 deletions gui/src/app/SPAnalysis/SPAnalysisQueryLoading.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { SPAnalysisDataModel, initialDataModel } from "./SPAnalysisDataModel";


enum QueryParamKeys {
StanFile = "stan",
DataFile = "data",
SamplingOpts = "sampling_opts",
Title = "title",
SONumChains = 'num_chains',
SONumWarmup = 'num_warmup',
SONumSamples = 'num_samples',
SOInitRadius = 'init_radius',
SOSeed = 'seed'
}

type QueryParams = {
[key in QueryParamKeys]: string | null
}

export const fromSearchParams = (searchParams: URLSearchParams) => {
for (const key of searchParams.keys()) {
// warn on unknown keys
if (!Object.values(QueryParamKeys).includes(key as QueryParamKeys)) {
console.warn('Unknown query parameter', key)
}
}

const query: QueryParams = {
stan: searchParams.get(QueryParamKeys.StanFile),
data: searchParams.get(QueryParamKeys.DataFile),
sampling_opts: searchParams.get(QueryParamKeys.SamplingOpts),
title: searchParams.get(QueryParamKeys.Title),
num_chains: searchParams.get(QueryParamKeys.SONumChains),
num_warmup: searchParams.get(QueryParamKeys.SONumWarmup),
num_samples: searchParams.get(QueryParamKeys.SONumSamples),
init_radius: searchParams.get(QueryParamKeys.SOInitRadius),
seed: searchParams.get(QueryParamKeys.SOSeed),
}
return query

}

const tryFetch = async (url: string) => {
console.log('Fetching content from', url)
try {
const req = await fetch(url)
if (!req.ok) {
console.error('Failed to fetch from url', url, req.status, req.statusText)
return undefined
}
return await req.text()
} catch (err) {
console.error('Failed to fetch from url', url, err)
return undefined
}
}

const deepCopy = (obj: any) => {
return JSON.parse(JSON.stringify(obj))
}

export const fetchRemoteAnalysis = async (query: QueryParams) => {

// any special 'project' query could be loaded here at the top
const data: SPAnalysisDataModel = deepCopy(initialDataModel)

if (query.stan) {
const stanFileContent = await tryFetch(query.stan)
if (stanFileContent) {
data.stanFileContent = stanFileContent
}
}
if (query.data) {
const dataFileContent = await tryFetch(query.data)
if (dataFileContent) {
data.dataFileContent = dataFileContent
}
}

if (query.sampling_opts) {
const text = await tryFetch(query.sampling_opts)
if (text) {
// TODO(bmw) validate
data.samplingOpts = JSON.parse(text)
}
} else {
if (query.num_chains) {
data.samplingOpts.num_chains = parseInt(query.num_chains)
}
if (query.num_warmup) {
data.samplingOpts.num_warmup = parseInt(query.num_warmup)
}
if (query.num_samples) {
data.samplingOpts.num_samples = parseInt(query.num_samples)
}
if (query.init_radius) {
data.samplingOpts.init_radius = parseFloat(query.init_radius)
}
if (query.seed) {
data.samplingOpts.seed = parseInt(query.seed)
}
}

if (query.title) {
data.meta.title = query.title
}

// TODO(bmw) create a 'setEphemera' helper?
data.ephemera.stanFileContent = data.stanFileContent
data.ephemera.dataFileContent = data.dataFileContent

return data
}

0 comments on commit 919ef45

Please sign in to comment.