Skip to content

Commit

Permalink
use @fi-sci/figurl-interface and protocol p1
Browse files Browse the repository at this point in the history
  • Loading branch information
magland committed Dec 18, 2023
1 parent 99c5ece commit 45c37a5
Show file tree
Hide file tree
Showing 24 changed files with 103 additions and 76 deletions.
9 changes: 9 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
"clear": true
},
"detail": "Run black formatter"
},
{
"label": "Publish npm",
"type": "shell",
"command": "bash -ic .vscode/tasks/publish-npm.sh",
"presentation": {
"clear": true
},
"detail": "Publish GUI package to npm"
}
]
}
17 changes: 17 additions & 0 deletions .vscode/tasks/publish-npm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -ex

cd gui
rm -rf dist
yarn install
yarn build
npm publish --access public --dry-run

echo "Proceed with publishing to npm? (y/n)"
read answer
if [ "$answer" != "${answer#[Yy]}" ] ;then
npm publish --access public
else
echo "Aborted."
fi
22 changes: 17 additions & 5 deletions gui/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "spikesortingview",
"private": true,
"version": "0.2.0",
"name": "@fi-sci/figurl-sortingview",
"private": false,
"version": "12.0.1",
"scripts": {
"dev": "vite --port 3000",
"build": "tsc && vite build",
Expand All @@ -12,7 +12,7 @@
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@figurl/interface": "^0.3.0",
"@fi-sci/figurl-interface": "^0.3.0",
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@fortawesome/free-regular-svg-icons": "^6.1.2",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
Expand Down Expand Up @@ -57,5 +57,17 @@
"source-map-explorer": "^2.5.3",
"typescript": "^5.0.2",
"vite": "^4.3.2"
}
},
"files": [
"src/",
"dist/",
".eslintrc.js",
"index.html",
"LICENSE",
"package.json",
"README.md",
"tsconfig.json",
"tsconfig.node.json",
"vite.config.ts"
]
}
2 changes: 1 addition & 1 deletion gui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useWindowDimensions } from './libraries/core-utils';
import { getFigureData, SetupUrlState } from '@figurl/interface';
import { getFigureData, SetupUrlState } from '@fi-sci/figurl-interface';
import { defaultUnitSelection, SetupSortingCuration, UnitMetricSelectionContext, unitMetricSelectionReducer, UnitSelectionContext, unitSelectionReducer } from './libraries/spike-sorting-views/index';
import { SetupAnnotations, SetupTimeseriesSelection } from './libraries/timeseries-views';
import { MuiThemeProvider } from '@material-ui/core';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { load } from '@loaders.gl/core';
import { ImageLoader } from '@loaders.gl/images';
import { clamp } from '@math.gl/core';
import { COORDINATE_SYSTEM, OrthographicView } from 'deck.gl';
import { getFileDataUrl } from '@figurl/interface';
import { getFileDataUrl } from '@fi-sci/figurl-interface';
import React, { FunctionComponent, useMemo } from 'react';


Expand Down Expand Up @@ -76,7 +76,7 @@ const DeckGLComponent: FunctionComponent<Props> = ({layers, layerIndex}) => {
renderSubLayers: (props: {tile: any, data: any}) => {
const {
bbox: {left, bottom, right, top}
} = props.tile;
} = props.tile as any;
// const {width, height} = dimensions;
return new BitmapLayer(props, {
data: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from "@figurl/interface";
import { useFileData } from "@fi-sci/figurl-interface";
import { ProgressComponent } from "../component-progress";
import { FunctionComponent, useEffect, useMemo, useState } from "react";
import { LayoutItem, MLView } from "./MainLayoutViewData";
Expand All @@ -20,7 +20,7 @@ const IndividualLayoutItemView: FunctionComponent<Props> = ({layoutItem, ViewCom
const view = views.filter(v => (v.viewId === viewId))[0]
if (!view) throw Error(`View not found ${viewId}`)

const { fileData: figureData, progress, errorMessage } = useFileData(view.dataUri)
const { fileData: figureData, progress, errorMessage } = useFileData(view.dataUri, 'json-deserialized')
const [progressValue, setProgressValue] = useState<{loaded: number, total: number} | undefined>(undefined)
useEffect(() => {
progress.onProgress(({loaded, total}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from '@figurl/interface';
import { useFileData } from '@fi-sci/figurl-interface';
import { FunctionComponent, useEffect, useMemo, useState } from 'react';
import { ViewComponentProps } from '../../core-view-component-props';

Expand All @@ -13,7 +13,7 @@ type Props = {
const ViewWrapper: FunctionComponent<Props> = ({ figureDataSha1, figureDataUri, ViewComponent, width, height }) => {
const sha1OrUri = figureDataSha1 ? figureDataSha1.toString() : figureDataUri
if (!sha1OrUri) throw Error('No figureDataSha1 or figureDataUri in ViewWrapper')
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri)
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri, 'json-deserialized')
const [progressValue, setProgressValue] = useState<{loaded: number, total: number} | undefined>(undefined)
useEffect(() => {
progress.onProgress(({loaded, total}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useUrlState } from '@figurl/interface'
import { useUrlState } from '@fi-sci/figurl-interface'
import React, { useCallback } from 'react'
import { AnimationState, AnimationStateAction } from '../../util-animation'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFileData, readDir } from "@figurl/interface"
import { getFileData, readDir } from "@fi-sci/figurl-interface"

const chunkSize = 1000 * 1000 * 4 // 4MB chunks. Is this a good choice?

Expand Down Expand Up @@ -49,10 +49,10 @@ class EphysTracesClient {
async initialize() {
const dir = await readDir(this.ephysTracesUri)
const binaryJsonUri = `${this.ephysTracesUri}/binary.json`
this.#binaryJson = await getFileData(binaryJsonUri, () => {}, {responseType: 'json'})
this.#binaryJson = await getFileData(binaryJsonUri, 'json', () => {})
if (!this.#binaryJson) throw Error('Unable to load binary.json')
const probeJsonUri = `${this.ephysTracesUri}/probe.json`
this.#probeJson = await getFileData(probeJsonUri, () => {}, {responseType: 'json'})
this.#probeJson = await getFileData(probeJsonUri, 'json', () => {})
if (!this.#probeJson) throw Error('Unable to load probe.json')
const binaryFname = this.#binaryJson.kwargs.file_paths[0]
const ff = dir.files.find(f => (f.name === binaryFname))
Expand Down Expand Up @@ -131,7 +131,7 @@ class EphysTracesClient {
try {
const i1 = chunkSize * i
const i2 = Math.min(chunkSize * (i + 1), this.#fileSize)
const content = await getFileData(this.#binaryUri, () => {}, {startByte: i1, endByte: i2, responseType: 'binary'})
const content = await getFileData(this.#binaryUri, 'binary', () => {}, {startByte: i1, endByte: i2})
this.#chunks[i] = content
return this.#chunks[i]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useSignedIn } from "@figurl/interface";
import { useSignedIn } from "@fi-sci/figurl-interface";
import { Button, Input } from "@material-ui/core";
import { FunctionComponent, useCallback, useEffect, useMemo, useState } from "react";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { randomAlphaString } from '../../core-utils';
import { Hyperlink } from '../../core-views';
import { getFileData, storeFileData, storeGithubFileData, useSignedIn } from "@figurl/interface";
import { getFileData, storeFileData, storeGithubFileData, useSignedIn } from "@fi-sci/figurl-interface";
import { Button } from "@material-ui/core";
import { FunctionComponent, useCallback, useEffect, useMemo, useRef, useState } from "react";
import EditGithubUriControl from './EditGithubUriControl';
Expand Down Expand Up @@ -128,7 +128,7 @@ const SaveControl: FunctionComponent<Props> = ({fallbackUri, uri, setUri, object
useEffect(() => {
if (!first.current) return
if (uri) {
getFileData(uri, () => {}).then((x) => {
getFileData(uri, 'json-deserialized', () => {}).then((x) => {
if (!x) {
console.warn('Empty state')
return
Expand All @@ -140,7 +140,7 @@ const SaveControl: FunctionComponent<Props> = ({fallbackUri, uri, setUri, object
})
}).catch((err: Error) => {
if (fallbackUri) {
getFileData(fallbackUri, () => {}).then((y) => {
getFileData(fallbackUri, 'json-deserialized', () => {}).then((y) => {
if (!y) {
console.warn('Empty state 2')
return
Expand Down Expand Up @@ -297,16 +297,16 @@ const SaveControl: FunctionComponent<Props> = ({fallbackUri, uri, setUri, object
}

// Thanks: https://stackoverflow.com/questions/16167581/sort-object-properties-and-json-stringify
export const JSONStringifyDeterministic = ( obj: Object, space: string | number | undefined =undefined ) => {
var allKeys: string[] = [];
export const JSONStringifyDeterministic = ( obj: object, space: string | number | undefined =undefined ) => {
const allKeys: string[] = [];
JSON.stringify( obj, function( key, value ){ allKeys.push( key ); return value; } )
allKeys.sort();
return JSON.stringify( obj, allKeys, space );
}

// Thanks: https://stackoverflow.com/questions/3665115/how-to-create-a-file-in-memory-for-user-to-download-but-not-through-server
function downloadTextFile(filename: string, text: string) {
var element = document.createElement('a');
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSelectedUnitIds } from "..";
import { FunctionComponent, useCallback, useEffect, useMemo } from "react";
import { SortingCuration2ViewData } from "./SortingCuration2ViewData";
import SaveControl from "./SaveControl";
import { useUrlState } from "@figurl/interface";
import { useUrlState } from "@fi-sci/figurl-interface";

type Props = {
data: SortingCuration2ViewData
Expand Down Expand Up @@ -148,15 +148,15 @@ const unitsAreInMergeGroups = (unitIds: (number | string)[], sortingCuration: So
if (!sortingCuration) return false
const mg = sortingCuration.mergeGroups || []
const all = mg.reduce((prev, g) => [...prev, ...g], []) // all units in merge groups
for (let unitId of unitIds) {
for (const unitId of unitIds) {
if (!all.includes(unitId)) return false
}
return true
}

const getLabelCheckboxStates = (labelChoices: string[], sortingCuration: SortingCuration | undefined, selectedUnitIds: (string | number)[], disabled: boolean) => {
const ret: {[label: string]: 'checked' | 'unchecked' | 'indeterminant' | 'disabled'} = {}
for (let label of labelChoices) {
for (const label of labelChoices) {
const idsWithLabel = selectedUnitIds.filter(id => (sortingCuration && ((sortingCuration.labelsByUnit || {})[id] || []).includes(label)))
ret[label] = disabled ? 'disabled' :
selectedUnitIds.length === 0 ? 'disabled' :
Expand All @@ -170,8 +170,8 @@ const getLabelCheckboxStates = (labelChoices: string[], sortingCuration: Sorting
export const getAllLabelChoices = (curation: SortingCuration | undefined, labelChoicesFromData: string[] | undefined) => {
const ret = labelChoicesFromData ? [...labelChoicesFromData] : [...standardLabelChoices]
if (curation !== undefined) {
for (let a of Object.values(curation.labelsByUnit || {})) {
for (let label of a) {
for (const a of Object.values(curation.labelsByUnit || {})) {
for (const label of a) {
if (!ret.includes(label)) ret.push(label)
}
}
Expand All @@ -180,8 +180,8 @@ export const getAllLabelChoices = (curation: SortingCuration | undefined, labelC
}

export const getAbbreviatedUnitIdsString = (unitIds: (string | number)[], maxLength: number) => {
let ret: string = ''
for (let id of unitIds) {
let ret = ''
for (const id of unitIds) {
if (ret.length > maxLength - 3) {
ret = ret + '...'
break
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFileData, useUrlState } from "@figurl/interface";
import { getFileData, useUrlState } from "@fi-sci/figurl-interface";
import { FunctionComponent, PropsWithChildren, useEffect, useMemo, useReducer, useRef } from "react";
import AnnotationsContext, { annotationReducer, defaultAnnotationState } from "./AnnotationContext";

Expand All @@ -11,7 +11,7 @@ const SetupAnnotations: FunctionComponent<PropsWithChildren> = (props) => {
if (!first.current) return
const uri = urlState.annotations
if (uri) {
getFileData(uri, () => {}).then((x) => {
getFileData(uri, 'json-deserialized', () => {}).then((x) => {
annotationDispatch({type: 'setAnnotationState', annotationState: x})
}).catch((err: Error) => {
console.warn('Problem getting annotation state')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useUrlState } from '@figurl/interface'
import { useUrlState } from '@fi-sci/figurl-interface'
import React, { FunctionComponent, PropsWithChildren, useEffect, useMemo, useReducer, useRef } from 'react'
import TimeseriesSelectionContext, { timeseriesSelectionReducer, defaultTimeseriesSelection } from './TimeseriesSelectionContext'

Expand Down
4 changes: 2 additions & 2 deletions gui/src/libraries/view-composite/ViewWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from '@figurl/interface';
import { useFileData } from '@fi-sci/figurl-interface';
import { FunctionComponent, useEffect, useMemo, useState } from 'react';
import { ViewComponentProps } from '../../libraries/core-view-component-props';

Expand All @@ -13,7 +13,7 @@ type Props = {
const ViewWrapper: FunctionComponent<Props> = ({ figureDataSha1, figureDataUri, ViewComponent, width, height }) => {
const sha1OrUri = figureDataSha1 ? figureDataSha1.toString() : figureDataUri
if (!sha1OrUri) throw Error('No figureDataSha1 or figureDataUri in ViewWrapper')
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri)
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri, 'json-deserialized')
const [progressValue, setProgressValue] = useState<{loaded: number, total: number} | undefined>(undefined)
useEffect(() => {
progress.onProgress(({loaded, total}) => {
Expand Down
10 changes: 5 additions & 5 deletions gui/src/libraries/view-ephys-traces-dev/EphysTracesClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFileData, readDir } from "@figurl/interface"
import { getFileData, readDir } from "@fi-sci/figurl-interface"

const chunkSize = 1000 * 1000 * 4 // 4MB chunks. Is this a good choice?

Expand Down Expand Up @@ -49,18 +49,18 @@ class EphysTracesClient {
async initialize() {
const dir = await readDir(this.ephysTracesUri)
const binaryJsonUri = `${this.ephysTracesUri}/binary.json`
this.#binaryJson = await getFileData(binaryJsonUri, () => {}, {responseType: 'json'})
this.#binaryJson = await getFileData(binaryJsonUri, 'json', () => {})
if (!this.#binaryJson) throw Error('Unable to load binary.json')
const probeJsonUri = `${this.ephysTracesUri}/probe.json`
this.#probeJson = await getFileData(probeJsonUri, () => {}, {responseType: 'json'})
this.#probeJson = await getFileData(probeJsonUri, 'json', () => {})
if (!this.#probeJson) throw Error('Unable to load probe.json')
const binaryFname = this.#binaryJson.kwargs.file_paths[0]
const ff = dir.files.find(f => (f.name === binaryFname))
if (!ff) {
throw Error(`Unable to find: ${binaryFname} in remote directory`)
}
this.#dataType = this.#binaryJson.kwargs.dtype
this.#bytesPerEntry = this.#dataType === '<i2' ? 2 : '<f4' ? 4 : 2
this.#bytesPerEntry = this.#dataType === '<i2' ? 2 : this.#dataType === '<f4' ? 4 : 2
this.#fileSize = ff.size
const channelIds = this.#binaryJson.kwargs.channel_ids
this.#info = {
Expand Down Expand Up @@ -139,7 +139,7 @@ class EphysTracesClient {
try {
const i1 = chunkSize * i
const i2 = Math.min(chunkSize * (i + 1), this.#fileSize)
const content = await getFileData(this.#binaryUri, () => {}, {startByte: i1, endByte: i2, responseType: 'binary'})
const content = await getFileData(this.#binaryUri, 'binary', () => {}, {startByte: i1, endByte: i2})
this.#chunks[i] = content
return this.#chunks[i]
}
Expand Down
4 changes: 2 additions & 2 deletions gui/src/libraries/view-ephys-traces-dev/EphysTracesView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from '@figurl/interface';
import { useFileData } from '@fi-sci/figurl-interface';
import { TimeseriesSelectionContext } from '../timeseries-views';
import { FunctionComponent, useContext, useEffect, useMemo, useState } from "react";
import EphysTracesClient, { EphysTracesInfo } from "./EphysTracesClient";
Expand All @@ -21,7 +21,7 @@ const EphysTracesView: FunctionComponent<Props> = ({data, width, height}) => {
ephysTracesClient.getInfo().then(setEphysTracesInfo)
}, [ephysTracesClient])

const {fileData: sortingData} = useFileData(sortingUri || '')
const {fileData: sortingData} = useFileData(sortingUri || '', 'json-deserialized')

const {timeseriesSelectionDispatch} = useContext(TimeseriesSelectionContext)
// const {timeseriesStartTimeSec, timeseriesEndTimeSec} = timeseriesSelection
Expand Down
4 changes: 2 additions & 2 deletions gui/src/libraries/view-mountain-layout/ViewWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from '@figurl/interface';
import { useFileData } from '@fi-sci/figurl-interface';
import { FunctionComponent, useEffect, useMemo, useState } from 'react';
import { ViewComponentProps } from '../../libraries/core-view-component-props';

Expand All @@ -13,7 +13,7 @@ type Props = {
const ViewWrapper: FunctionComponent<Props> = ({ figureDataSha1, figureDataUri, ViewComponent, width, height }) => {
const sha1OrUri = figureDataSha1 ? figureDataSha1.toString() : figureDataUri
if (!sha1OrUri) throw Error('No figureDataSha1 or figureDataUri in ViewWrapper')
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri)
const { fileData: figureData, progress, errorMessage } = useFileData(sha1OrUri, 'json-deserialized')
const [progressValue, setProgressValue] = useState<{loaded: number, total: number} | undefined>(undefined)
useEffect(() => {
progress.onProgress(({loaded, total}) => {
Expand Down
4 changes: 2 additions & 2 deletions gui/src/libraries/view-multi-timeseries/ViewWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ViewComponentProps } from '../../libraries/core-view-component-props';
import { useFileData } from '@figurl/interface';
import { useFileData } from '@fi-sci/figurl-interface';
import React, { FunctionComponent, useMemo } from 'react';
import { TimeseriesLayoutOpts } from '../../View';
import './MultiTimeseriesView.css';
Expand All @@ -17,7 +17,7 @@ type Props = {
const ViewWrapper: FunctionComponent<Props> = ({ label, figureDataSha1, figureDataUri, ViewComponent, isBottomPanel, width, height }) => {
const sha1OrUri = figureDataSha1 ? figureDataSha1.toString() : figureDataUri
if (!sha1OrUri) throw Error('No figureDataSha1 or figureDataUri in ViewWrapper')
const { fileData: figureData, errorMessage } = useFileData(sha1OrUri)
const { fileData: figureData, errorMessage } = useFileData(sha1OrUri, 'json-deserialized')

const opts: TimeseriesLayoutOpts = useMemo(() => {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useFileData } from "@figurl/interface";
import { useFileData } from "@fi-sci/figurl-interface";
import { FunctionComponent, useEffect, useMemo, useState } from "react";
import { ProgressComponent } from "../core-views";
import { LayoutItem, SLView } from "./SortingLayoutViewData";
Expand All @@ -20,7 +20,7 @@ const IndividualLayoutItemView: FunctionComponent<Props> = ({layoutItem, ViewCom
const view = views.filter(v => (v.viewId === viewId))[0]
if (!view) throw Error(`View not found ${viewId}`)

const { fileData: figureData, progress, errorMessage } = useFileData(view.dataUri)
const { fileData: figureData, progress, errorMessage } = useFileData(view.dataUri, 'json-deserialized')
const [progressValue, setProgressValue] = useState<{loaded: number, total: number} | undefined>(undefined)
useEffect(() => {
progress.onProgress(({loaded, total}) => {
Expand Down
Loading

0 comments on commit 45c37a5

Please sign in to comment.