Skip to content

Commit

Permalink
feat: multiple tomogram use api v2 (#1234)
Browse files Browse the repository at this point in the history
Follow up of #1190 to complete the remaining integration items from
#624 (comment)

This does not fully migrate the run query to use API v2, it only uses
some of the data for MT related features (`isPortalStandard`,
`isAuthorSubmitted`, etc.)

---------

Co-authored-by: Bryan Chu <[email protected]>
  • Loading branch information
codemonkey800 and bchu1 authored Oct 16, 2024
1 parent d5a73ac commit 858d815
Show file tree
Hide file tree
Showing 17 changed files with 429 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,30 @@ export function AnnotationAlignmentCallout({
{t('alignmentId')}
</p>
<CopyBox content={alignmentId} />
<p className="text-sds-body-xs leading-sds-body-xs mt-[10px]">
<I18n i18nKey="thisAnnotationRequiresTransformation" />
</p>
<div className="bg-[#ffdb97] flex flex-col gap-[12px] mt-sds-xxs p-sds-s rounded-[2px]">
{misalignedTomograms?.map((tomogram) => (
<div className="text-sds-body-xxs !leading-[18px]">
<div className="font-semibold">{getTomogramName(tomogram)}</div>
<div>
Tomogram ID: {IdPrefix.Tomogram}-{tomogram.id}
</div>
{tomogram.alignment != null && (
<div>
Alignment ID: {IdPrefix.Alignment}-{tomogram.alignment.id}

{misalignedTomograms.length > 0 && (
<>
<p className="text-sds-body-xs leading-sds-body-xs mt-[10px]">
<I18n i18nKey="thisAnnotationRequiresTransformation" />
</p>

<div className="bg-[#ffdb97] flex flex-col gap-[12px] mt-sds-xxs p-sds-s rounded-[2px]">
{misalignedTomograms.map((tomogram) => (
<div className="text-sds-body-xxs !leading-[18px]">
<div className="font-semibold">{getTomogramName(tomogram)}</div>
<div>
Tomogram ID: {IdPrefix.Tomogram}-{tomogram.id}
</div>
{tomogram.alignment != null && (
<div>
Alignment ID: {IdPrefix.Alignment}-{tomogram.alignment.id}
</div>
)}
</div>
)}
))}
</div>
))}
</div>
</>
)}
</Callout>
)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { useMemo } from 'react'
import { DeepPartial } from 'utility-types'

import { AnnotationFileEdge } from 'app/__generated_v2__/graphql'
import { useDownloadModalContext } from 'app/context/DownloadModal.context'
import { useDownloadModalQueryParamState } from 'app/hooks/useDownloadModalQueryParamState'
import { useRunById } from 'app/hooks/useRunById'

import { AnnotationAlignmentCallout } from './AnnotationAlignmentCallout'
import { FileFormatDropdown } from './FileFormatDropdown'

export function ConfigureAnnotationDownloadContent() {
const { objectShapeType } = useDownloadModalQueryParamState()
const { objectShapeType, fileFormat } = useDownloadModalQueryParamState()
const { annotationToDownload, allTomograms } = useDownloadModalContext()

const fileFormats = useMemo<string[]>(
Expand All @@ -18,15 +21,30 @@ export function ConfigureAnnotationDownloadContent() {
[annotationToDownload?.files, objectShapeType],
)

const { annotationShapes } = useRunById()

const isMatchingFormat = (file: DeepPartial<AnnotationFileEdge>) =>
file?.node?.format === fileFormat

const alignmentId =
annotationShapes
.find(
(shape) =>
shape.annotation?.id === annotationToDownload?.id &&
shape.shapeType === objectShapeType &&
shape.annotationFiles.edges.some(isMatchingFormat),
)
?.annotationFiles.edges.find(isMatchingFormat)?.node.alignmentId ?? 0

return (
<>
<FileFormatDropdown className="pt-sds-l" fileFormats={fileFormats} />
<AnnotationAlignmentCallout
// TODO(bchu): Use alignment ID when annotation query is migrated.
alignmentId={0}
alignmentId={alignmentId}
initialState="open"
// TODO(bchu): Filter by tomograms that do not have the same annotation ID.
misalignedTomograms={allTomograms ?? []}
misalignedTomograms={(allTomograms ?? []).filter(
(tomogram) => tomogram.alignment?.id !== alignmentId,
)}
/>
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import { ConfigureTomogramDownloadContent } from './ConfigureTomogramDownloadCon

export function ConfigureDownloadContent() {
const { t } = useI18n()
const { datasetTitle, runName, objectName } = useDownloadModalContext()

const { annotationName, annotationId, objectShapeType } =
useDownloadModalQueryParamState()

const { annotationToDownload, datasetTitle, runName, objectName } =
useDownloadModalContext()

return (
<>
<ModalSubtitle label={t('datasetName')} value={datasetTitle} />
Expand All @@ -32,6 +35,12 @@ export function ConfigureDownloadContent() {
{objectShapeType && (
<ModalSubtitle label={t('objectShapeType')} value={objectShapeType} />
)}
{annotationToDownload !== undefined && (
<ModalSubtitle
label={t('alignmentId')}
value={`${IdPrefix.Alignment}-${annotationToDownload.id}`}
/>
)}

<p className="mt-sds-xl text-sds-body-m leading-sds-body-m font-semibold">
{t('selectDownload')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ export function DownloadOptionsContent() {
value={tomogramProcessing}
/>
)}
{multipleTomogramsEnabled &&
annotationToDownload &&
tomogramToDownload?.alignment && (
<ModalSubtitle
label={t('alignmentId')}
value={tomogramToDownload.alignment.id}
/>
)}
{fileFormat && (
<ModalSubtitle
label={t('fileFormat')}
Expand Down Expand Up @@ -168,13 +176,13 @@ export function DownloadOptionsContent() {

<DownloadTabContent />

{multipleTomogramsEnabled && annotationToDownload !== undefined ? (
{multipleTomogramsEnabled &&
annotationToDownload !== undefined &&
tomogramToDownload?.alignment ? (
<AnnotationAlignmentCallout
// TODO(bchu): Use alignment ID when annotation query is migrated.
alignmentId={0}
alignmentId={tomogramToDownload.alignment.id}
initialState="closed"
// TODO(bchu): Filter by tomograms that do not have the same annotation ID.
misalignedTomograms={allTomograms ?? []}
misalignedTomograms={[]}
/>
) : (
<Callout intent="notice" className="!w-full !mt-sds-xl">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function TomogramSelectorInputLabel({
{t('unitAngstrom', { value: tomogram.voxelSpacing })}
</span>
{tomogram.isPortalStandard && <TomogramTypeBadge type="standard" />}
{tomogram.isAuthorSubmitted && <TomogramTypeBadge type="author" />}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export function TomogramSelectorOption({
{tomogram.isPortalStandard && (
<TomogramTypeBadge type="standard" size="small" />
)}
{tomogram.isAuthorSubmitted && (
<TomogramTypeBadge type="author" size="small" />
)}
</div>
<div className="text-sds-body-xxs text-sds-color-primitive-gray-500 font-normal">
{t('tomogramSampling')}:{' '}
Expand Down
32 changes: 30 additions & 2 deletions frontend/packages/data-portal/app/components/Run/RunHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Button, Icon } from '@czi-sds/components'
import { match, P } from 'ts-pattern'

import { Breadcrumbs } from 'app/components/Breadcrumbs'
import { CollapsibleList } from 'app/components/CollapsibleList'
Expand Down Expand Up @@ -51,14 +52,28 @@ export function RunHeader() {
annotationFilesAggregates,
tomogramsCount,
alignmentsCount,
tomograms,
} = useRunById()
const { toggleDrawer } = useMetadataDrawer()
const { t } = useI18n()

const tiltSeries = run.tiltseries[0]

const tomogram = run.tomogram_voxel_spacings.at(0)?.tomograms.at(0)
const keyPhotoURL = tomogram?.key_photo_url ?? undefined

// Use author submitted tomogram if available, otherwise default to the first one
const tomogramV2 =
tomograms.find(
(currentTomogram) =>
currentTomogram.isVisualizationDefault ??
currentTomogram.isAuthorSubmitted,
) ?? tomograms.at(0)

const keyPhotoURL =
(multipleTomogramsEnabled
? tomogramV2?.keyPhotoUrl
: tomogram?.key_photo_url) ?? undefined

const neuroglancerConfig = tomogram?.neuroglancer_config

const { openRunDownloadModal } = useDownloadModalQueryParamState()
Expand All @@ -72,7 +87,20 @@ export function RunHeader() {
actions={
<div className="flex items-center gap-2.5">
<ViewTomogramButton
tomogramId={tomogram?.id?.toString()}
tomogramId={match({
multipleTomogramsEnabled,
tomogramV2Id: tomogramV2?.id,
tomogramV1Id: tomogram?.id,
})
.with(
{ multipleTomogramsEnabled: true, tomogramV2Id: P.number },
({ tomogramV2Id }) => tomogramV2Id.toString(),
)
.with(
{ multipleTomogramsEnabled: false, tomogramV1Id: P.number },
({ tomogramV1Id }) => tomogramV1Id.toString(),
)
.otherwise(() => undefined)}
neuroglancerConfig={neuroglancerConfig}
buttonProps={{
sdsStyle: 'rounded',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useAtom } from 'jotai'
import { IdPrefix } from 'app/constants/idPrefixes'
import { useI18n } from 'app/hooks/useI18n'
import { MetadataDrawerId } from 'app/hooks/useMetadataDrawer'
import { useRunById } from 'app/hooks/useRunById'
import { metadataDrawerTomogramAtom } from 'app/state/metadataDrawerTomogram'
import { getTableData } from 'app/utils/table'
import { getTomogramName, isFiducial } from 'app/utils/tomograms'
Expand All @@ -21,6 +22,7 @@ import { IDENTITY_MATRIX_4X4, Matrix4x4 } from './Matrix4x4'
export function TomogramMetadataDrawer() {
const { t } = useI18n()
const [tomogram] = useAtom(metadataDrawerTomogramAtom)
const { run } = useRunById()

if (tomogram === undefined) {
return null
Expand Down Expand Up @@ -59,7 +61,7 @@ export function TomogramMetadataDrawer() {
},
{
label: t('publications'),
values: [], // TODO
values: [run.dataset.dataset_publications ?? ''],
renderValue: (value: string) => (
<DatabaseEntryList entries={value} />
),
Expand All @@ -73,9 +75,7 @@ export function TomogramMetadataDrawer() {
},
{
label: t('depositionName'),
// TODO(bchu): Uncomment after API field name change is in prod.
// values: [tomogram.deposition?.title ?? ''],
values: [],
values: [tomogram.deposition?.title ?? ''],
renderValue: (value: string) => (
<Link
className="text-sds-color-primitive-blue-400"
Expand Down
31 changes: 27 additions & 4 deletions frontend/packages/data-portal/app/components/Run/TomogramTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import {
import { useRunById } from 'app/hooks/useRunById'
import { metadataDrawerTomogramAtom } from 'app/state/metadataDrawerTomogram'
import { TomogramV2 } from 'app/types/gqlResponseTypes'
import { cnsNoMerge } from 'app/utils/cns'
import { getTomogramName } from 'app/utils/tomograms'

import { AuthorList } from '../AuthorList'
import { I18n } from '../I18n'
import { KeyPhoto } from '../KeyPhoto'
import { TomogramTypeBadge } from '../TomogramTypeBadge'
import { Tooltip } from '../Tooltip'
import { ViewTomogramButton } from '../ViewTomogramButton'

export function TomogramsTable() {
Expand Down Expand Up @@ -72,9 +75,14 @@ export function TomogramsTable() {
</div>
<div className="flex items-center flex-wrap gap-sds-xs text-sds-body-xxs">
{`${t('tomogramId')}: ${IdPrefix.Tomogram}-${original.id}`}

{original.isPortalStandard && (
<TomogramTypeBadge type="standard" showTooltip />
)}

{original.isAuthorSubmitted && (
<TomogramTypeBadge type="author" showTooltip />
)}
</div>
<div className=" text-sds-color-primitive-gray-600 text-sds-body-xxs leading-sds-header-xxs">
<AuthorList
Expand Down Expand Up @@ -106,11 +114,24 @@ export function TomogramsTable() {
{t('alignmentId')}
</CellHeader>
),
cell: ({ getValue }) => (
cell: ({ getValue, row: { original: tomogram } }) => (
<TableCell width={TomogramTableWidths.alignment}>
<div>
<p>
{IdPrefix.Alignment}-{getValue()}
</div>
</p>

{tomogram.isPortalStandard && (
<Tooltip tooltip={<I18n i18nKey="alignmentIdCanonicalTooltip" />}>
<p
className={cnsNoMerge(
'text-sds-body-xxs leading-sds-body-xxs text-sds-color-semantic-text-base-secondary',
'underline underline-offset-4 decoration-dashed',
)}
>
{t('canonical')}
</p>
</Tooltip>
)}
</TableCell>
),
}),
Expand Down Expand Up @@ -159,7 +180,9 @@ export function TomogramsTable() {
cell: ({ row: { original } }) => (
<TableCell width={TomogramTableWidths.actions}>
<div className="flex flex-col gap-sds-xs items-start">
{original.neuroglancerConfig != null && ( // TODO(bchu): Check it's either isPortalStandard or isAuthorSubmitted
{/* TODO Use only `isVisualizationDefault` when data is available */}
{(original.isVisualizationDefault ??
original.isAuthorSubmitted) && (
<ViewTomogramButton
tomogramId={original.id.toString()}
neuroglancerConfig={original.neuroglancerConfig}
Expand Down
Loading

0 comments on commit 858d815

Please sign in to comment.