Skip to content

Commit

Permalink
Merge pull request #564 from arayabrain/feature/cell_numbering
Browse files Browse the repository at this point in the history
Feature/cell numbering
  • Loading branch information
milesAraya authored Jan 23, 2025
2 parents d54ab2a + 6251ba5 commit ac7f304
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
selectImageItemRoiAlpha,
selectImageItemFilePath,
selectImageItemAlpha,
selectImageItemShowRoiLabels,
} from "store/slice/VisualizeItem/VisualizeItemSelectors"
import {
setImageItemShowGrid,
Expand All @@ -48,6 +49,7 @@ import {
resetImageActiveIndex,
setImageItemRoiAlpha,
setImageItemAlpha,
setImageItemShowRoiLabels,
} from "store/slice/VisualizeItem/VisualizeItemSlice"
import { ColorType } from "store/slice/VisualizeItem/VisualizeItemType"
import { selectCurrentWorkspaceId } from "store/slice/Workspace/WorkspaceSelector"
Expand All @@ -71,6 +73,7 @@ export const ImageItemEditor: FC = () => {
<ShowLine />
<ShowGrid />
<ShowScale />
<ShowRoiLabels />
<Zsmooth />
<Grid container component="label" alignItems="center">
<Grid item xs={8}>
Expand Down Expand Up @@ -225,6 +228,24 @@ const RoiAlpha: FC = () => {
)
}

const ShowRoiLabels: FC = () => {
const itemId = useContext(SelectedItemIdContext)
const showRoiLabels = useSelector(selectImageItemShowRoiLabels(itemId))
const dispatch = useDispatch()
const toggleChecked = () => {
dispatch(
setImageItemShowRoiLabels({ itemId, showRoiLabels: !showRoiLabels }),
)
}
return (
<ParamSwitch
label={"Show ROI labels"}
value={showRoiLabels}
onChange={toggleChecked}
/>
)
}

const StartEndIndex: FC = () => {
const workspaceId = useSelector(selectCurrentWorkspaceId)
const itemId = useContext(SelectedItemIdContext)
Expand Down
67 changes: 62 additions & 5 deletions frontend/src/components/Workspace/Visualize/Plot/ImagePlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
PlotData,
PlotMouseEvent,
PlotSelectionEvent,
Annotations,
} from "plotly.js"

import { Button, LinearProgress, TextField, Typography } from "@mui/material"
Expand Down Expand Up @@ -77,6 +78,7 @@ import {
selectImageItemAlpha,
selectRoiItemOutputKeys,
selectVisualizeItems,
selectImageItemShowRoiLabels,
} from "store/slice/VisualizeItem/VisualizeItemSelectors"
import {
incrementImageActiveIndex,
Expand Down Expand Up @@ -227,6 +229,7 @@ const ImagePlotChart = memo(function ImagePlotChart({
const [startDragAddRoi, setStartDragAddRoi] = useState(false)
const [action, setAction] = useState("")
const [positionDrag, setChangeSize] = useState<PositionDrag | undefined>()
const showRoiLabels = useSelector(selectImageItemShowRoiLabels(itemId))

const outputKey: string | null = useSelector(selectRoiItemOutputKeys(itemId))

Expand Down Expand Up @@ -300,7 +303,7 @@ const ImagePlotChart = memo(function ImagePlotChart({
z: roiDataState,
type: "heatmap",
name: "roi",
hovertemplate: action === ADD_ROI ? "none" : "cell id: %{z}",
hovertemplate: action === ADD_ROI ? "none" : "ROI: %{z}",
// hoverinfo: isAddRoi || pointClick.length ? "none" : undefined,
colorscale: [...Array(timeDataMaxIndex + 1)].map((_, i) => {
const new_i = Math.floor(((i % 10) * 10 + i / 10) % 100)
Expand Down Expand Up @@ -389,6 +392,57 @@ const ImagePlotChart = memo(function ImagePlotChart({
dispatch(selectingImageArea({ itemId, range: event.range }))
}
})

const roiLabels = useMemo(() => {
if (!showRoiLabels) return []
const labels: Annotations[] = []
const seen = new Set()

roiDataState.forEach((row, _y) => {
row.forEach((value, _x) => {
if (value !== null && !seen.has(value)) {
seen.add(value)
const points = {
x: [] as number[],
y: [] as number[],
count: 0,
}
roiDataState.forEach((r, yi) => {
r.forEach((v, xi) => {
if (v === value) {
points.x.push(xi)
points.y.push(yi)
points.count++
}
})
})

const centerX = points.x.reduce((a, b) => a + b, 0) / points.count
const centerY = points.y.reduce((a, b) => a + b, 0) / points.count

const annotation: Partial<Annotations> = {
x: centerX,
y: centerY,
text: `${value}`,
xref: "x",
yref: "y",
showarrow: false,
font: {
color: "black", // Black text
size: 10,
weight: 700, // Bold text
},
bgcolor: "rgba(255, 255, 255, 0.6)", // Soft white semi-transparent background (60% opacity)
borderpad: 0.5, // Padding around the text
}

labels.push(annotation as Annotations)
}
})
})
return labels
}, [roiDataState, showRoiLabels])

const layout = useMemo(
() => ({
title: {
Expand All @@ -412,6 +466,7 @@ const ImagePlotChart = memo(function ImagePlotChart({
autotick: true,
ticks: "",
showticklabels: showticklabels,
annotations: roiLabels,
},
yaxis: {
title: meta?.ylabel,
Expand All @@ -420,10 +475,11 @@ const ImagePlotChart = memo(function ImagePlotChart({
showgrid: showgrid,
showline: showline,
zeroline: false,
autotick: true, // todo
autotick: true,
ticks: "",
showticklabels: showticklabels, // todo
showticklabels: showticklabels,
},
annotations: roiLabels,
}),
//eslint-disable-next-line react-hooks/exhaustive-deps
[
Expand All @@ -435,6 +491,7 @@ const ImagePlotChart = memo(function ImagePlotChart({
height,
selectMode,
action,
roiLabels,
],
)

Expand Down Expand Up @@ -709,8 +766,8 @@ const ImagePlotChart = memo(function ImagePlotChart({
action === DELETE_ROI
? "#F84E1B"
: action === MERGE_ROI
? "#6619A9"
: "default",
? "#6619A9"
: "default",
display: "flex",
gap: 1,
textDecoration: "none",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const RoiPlotImple = memo(function RoiPlotImple() {
// zsmooth: zsmooth, // ['best', 'fast', false]
zsmooth: false,
showlegend: true,
hovertemplate: "ROI: %{z}",
},
],
[imageData, colorscale],
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/store/slice/VisualizeItem/VisualizeItemSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,3 +608,13 @@ export const selectImageItemRangeUnit =
throw new Error("invalid VisualaizeItemType")
}
}

export const selectImageItemShowRoiLabels =
(itemId: number) => (state: RootState) => {
const item = selectVisualizeItemById(itemId)(state)
if (isImageItem(item)) {
return item.showRoiLabels
} else {
throw new Error("invalid VisualaizeItemType")
}
}
14 changes: 14 additions & 0 deletions frontend/src/store/slice/VisualizeItem/VisualizeItemSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const imageItemInitialValue: ImageItem = {
roiItem: null,
roiAlpha: 1.0,
duration: 500,
showRoiLabels: false,
}
const timeSeriesItemInitialValue: TimeSeriesItem = {
...displayDataCommonInitialValue,
Expand Down Expand Up @@ -857,6 +858,18 @@ export const visualaizeItemSlice = createSlice({
targetItem.selectedIndex = action.payload.selectedIndex
}
},
setImageItemShowRoiLabels: (
state,
action: PayloadAction<{
itemId: number
showRoiLabels: boolean
}>,
) => {
const targetItem = state.items[action.payload.itemId]
if (isImageItem(targetItem)) {
targetItem.showRoiLabels = action.payload.showRoiLabels
}
},
},
extraReducers: (builder) => {
builder
Expand Down Expand Up @@ -1025,6 +1038,7 @@ export const {
setHistogramItemBins,
setLineItemSelectedIndex,
setPolartemItemSelectedIndex,
setImageItemShowRoiLabels,
resetAllOrderList,
reset,
} = visualaizeItemSlice.actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export interface ImageItem extends DisplayDataItemBaseType {
roiAlpha: number
duration: number
clickedDataId?: string
showRoiLabels: boolean
}

export interface TimeSeriesItem extends DisplayDataItemBaseType {
Expand Down
6 changes: 3 additions & 3 deletions studio/app/optinist/wrappers/caiman/cnmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ def get_roi(A, roi_thr, thr_method, swap_dim, dims):
# we compute the cumulative sum of the energy of the Ath component
# that has been ordered from least to highest
patch_data = A.data[A.indptr[i] : A.indptr[i + 1]]
indx = np.argsort(patch_data)[::-1]
idx = np.argsort(patch_data)[::-1]

if thr_method == "nrg":
cumEn = np.cumsum(patch_data[indx] ** 2)
cumEn = np.cumsum(patch_data[idx] ** 2)
if len(cumEn) == 0:
pars = dict(
coordinates=np.array([]),
Expand All @@ -48,7 +48,7 @@ def get_roi(A, roi_thr, thr_method, swap_dim, dims):
cumEn /= cumEn[-1]
Bvec = np.ones(d)
# we put it in a similar matrix
Bvec[A.indices[A.indptr[i] : A.indptr[i + 1]][indx]] = cumEn
Bvec[A.indices[A.indptr[i] : A.indptr[i + 1]][idx]] = cumEn
else:
Bvec = np.zeros(d)
Bvec[A.indices[A.indptr[i] : A.indptr[i + 1]]] = (
Expand Down

0 comments on commit ac7f304

Please sign in to comment.