From 675262a4a11f864a2090665ba824872697c3fb3c Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Fri, 3 Jan 2025 12:43:31 -0800 Subject: [PATCH] feat: added download and snapshot --- compose/neurosynth-frontend/index.html | 2 +- .../Visualizer/NiiVueVisualizer.tsx | 87 +++++-- .../Visualizer/__mocks__/NiiVueVisualizer.tsx | 10 + .../src/hooks/__mocks__/index.ts | 16 ++ .../neurosynth-frontend/src/hooks/index.ts | 5 + .../hooks/metaAnalyses/useGetNeurovault.tsx | 74 ------ .../metaAnalyses/useGetNeurovaultImages.tsx | 74 ++++++ .../pages/MetaAnalysis/MetaAnalysisPage.tsx | 3 +- .../src/pages/MetaAnalysis/Nimare.helpers.ts | 82 +++++++ .../DisplayMetaAnalysisResults.spec.tsx | 36 +++ .../components/DisplayMetaAnalysisResults.tsx | 85 +++---- .../components/DisplayParsedNiMareFile.tsx | 87 +------ .../__mocks__/DisplayParsedNiMareFile.tsx | 5 + .../components/__mocks__/DynamicForm.tsx | 5 +- .../MetaAnalysisResultStatusAlert.tsx | 5 + .../components/ProjectViewMetaAnalysis.tsx | 18 +- ...ctsPageCardSummaryMetaAnalysesListItem.tsx | 28 +-- .../src/testing/mockData.ts | 212 ++++++++++++++++-- compose/neurosynth-frontend/tsconfig.json | 2 +- 19 files changed, 543 insertions(+), 293 deletions(-) create mode 100644 compose/neurosynth-frontend/src/components/Visualizer/__mocks__/NiiVueVisualizer.tsx delete mode 100644 compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovault.tsx create mode 100644 compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovaultImages.tsx create mode 100644 compose/neurosynth-frontend/src/pages/MetaAnalysis/Nimare.helpers.ts create mode 100644 compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.spec.tsx create mode 100644 compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DisplayParsedNiMareFile.tsx create mode 100644 compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/MetaAnalysisResultStatusAlert.tsx diff --git a/compose/neurosynth-frontend/index.html b/compose/neurosynth-frontend/index.html index 9e94730b1..57127d6c1 100644 --- a/compose/neurosynth-frontend/index.html +++ b/compose/neurosynth-frontend/index.html @@ -17,7 +17,7 @@ - + = ({ imageURL }) => { - const canvasRef = useRef(null); +const NiiVueVisualizer: React.FC<{ file: string; filename: string; neurovaultLink?: string }> = ({ + file, + filename, + neurovaultLink, +}) => { + const canvasRef = useRef(null); const [softThreshold, setSoftThresold] = useState(true); const [showNegatives, setShowNegatives] = useState(false); const [showCrosshairs, setShowCrosshairs] = useState(true); @@ -84,7 +90,7 @@ const NiiVueVisualizer: React.FC<{ imageURL: string }> = ({ imageURL }) => { opacity: 1, }, { - url: imageURL, + url: file, // url: 'https://niivue.github.io/niivue/images/fslt.nii.gz', colorMap: 'warm', cal_min: 0, // default @@ -128,12 +134,17 @@ const NiiVueVisualizer: React.FC<{ imageURL: string }> = ({ imageURL }) => { niivue.setInterpolation(true); niivue.updateGLVolume(); }); - }, [imageURL]); + }, [file]); + + const handleDownloadImage = () => { + if (!niivue) return; + niivue.saveScene(filename + '.png'); + }; return ( - + Threshold = ({ imageURL }) => { value={threshold.value} > - - Soft Threshold - - - - Show Negatives - - - - Show Crosshairs - + + + Soft Threshold + + + + Show Negatives + + + + Show Crosshairs + + + + + + + + {neurovaultLink && ( + + )} + ); }; diff --git a/compose/neurosynth-frontend/src/components/Visualizer/__mocks__/NiiVueVisualizer.tsx b/compose/neurosynth-frontend/src/components/Visualizer/__mocks__/NiiVueVisualizer.tsx new file mode 100644 index 000000000..51c0213e5 --- /dev/null +++ b/compose/neurosynth-frontend/src/components/Visualizer/__mocks__/NiiVueVisualizer.tsx @@ -0,0 +1,10 @@ +const MockNiiVueVisualizer: React.FC<{ imageURL: string }> = ({ imageURL }) => { + return ( +
+

Mocked NiiVue Visualizer

+ {imageURL} +
+ ); +}; + +export default MockNiiVueVisualizer; diff --git a/compose/neurosynth-frontend/src/hooks/__mocks__/index.ts b/compose/neurosynth-frontend/src/hooks/__mocks__/index.ts index 5d051028f..6cecb8e6c 100644 --- a/compose/neurosynth-frontend/src/hooks/__mocks__/index.ts +++ b/compose/neurosynth-frontend/src/hooks/__mocks__/index.ts @@ -4,6 +4,8 @@ import { mockAnnotations, mockBaseStudy, mockConditions, + mockMetaAnalysisResult, + mockNeurovault, mockProject, mockStudy, mockStudysetNested, @@ -179,6 +181,18 @@ const useIsMounted = () => { const useUserCanEdit = vi.fn().mockReturnValue(true); +const useGetMetaAnalysisResultById = vi.fn().mockReturnValue({ + isLoading: false, + isError: false, + data: mockMetaAnalysisResult(), +}); + +const useGetNeurovaultImages = vi.fn().mockReturnValue({ + isLoading: false, + isError: false, + data: mockNeurovault(), +}); + export { useCreateAnalysis, useCreateCondition, @@ -207,4 +221,6 @@ export { useUpdateStudyset, useUserCanEdit, useGetProjectById, + useGetMetaAnalysisResultById, + useGetNeurovaultImages, }; diff --git a/compose/neurosynth-frontend/src/hooks/index.ts b/compose/neurosynth-frontend/src/hooks/index.ts index 68900a659..6a7a9d873 100644 --- a/compose/neurosynth-frontend/src/hooks/index.ts +++ b/compose/neurosynth-frontend/src/hooks/index.ts @@ -9,6 +9,7 @@ import useCreateAlgorithmSpecification from './metaAnalyses/useCreateAlgorithmSp import useGetMetaAnalysesByIds from './metaAnalyses/useGetMetaAnalysesByIds'; import useGetMetaAnalysisById from './metaAnalyses/useGetMetaAnalysisById'; import useGetMetaAnalysesPublic from './metaAnalyses/useGetMetaAnalysesPublic'; +import useGetMetaAnalysisResultById from './metaAnalyses/useGetMetaAnalysisResultById'; import useGetAnnotationsByStudysetId from './analyses/useGetAnnotationsByStudysetId'; import useCreatePoint from './analyses/useCreatePoint'; import useUpdateStudy from './studies/useUpdateStudy'; @@ -38,6 +39,7 @@ import useGetFullText from './external/useGetFullText'; import useUserCanEdit from './useUserCanEdit'; import useGetBaseStudyById from './studies/useGetBaseStudyById'; import useGetProjectById from './projects/useGetProjectById'; +import useGetNeurovaultImages from './metaAnalyses/useGetNeurovaultImages'; export { useGetCurationSummary, @@ -51,6 +53,7 @@ export { useGetFullText, useUserCanEdit, useGetBaseStudyById, + useGetNeurovaultImages, // STUDIES useGetBaseStudies, useGetStudyById, @@ -61,6 +64,8 @@ export { useGetMetaAnalysesByIds, useGetMetaAnalysisById, useGetMetaAnalysesPublic, + // META-ANALYSIS RESULTS + useGetMetaAnalysisResultById, // STUDYSETS useGetStudysets, useGetStudysetById, diff --git a/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovault.tsx b/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovault.tsx deleted file mode 100644 index ab49dd159..000000000 --- a/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovault.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import axios, { AxiosResponse } from 'axios'; -import { useQuery } from 'react-query'; - -export interface INeurovault { - url: string; - id: number; - file: string; - collection: string; - collection_id: string; - file_size: string; - cognitive_paradigm_cogatlas: string; - cognitive_paradigm_cogatlas_id: string; - cognitive_contrast_cogatlas: string; - cognitive_contrast_cogatlas_id: string; - map_type: string; - analysis_level: string; - name: string; - description: string; - add_date: string; - modify_date: string; - is_valid: boolean; - surface_left_file: string; - surface_right_file: string; - data_origin: string; - target_template_image: string; - subject_species: string; - figure: string; - handedness: string; - age: string; - gender: string; - race: string; - ethnicity: string; - BMI: string; - fat_percentage: string; - waist_hip_ratio: string; - mean_PDS_score: string; - tanner_stage: string; - days_since_menstruation: string; - hours_since_last_meal: string; - bis_bas_score: string; - spsrq_score: string; - bis11_score: string; - thumbnail: string; - reduced_representation: string; - is_thresholded: boolean; - perc_bad_voxels: number; - not_mni: boolean; - brain_coverage: number; - perc_voxels_outside: number; - number_of_subjects: string; - modality: string; - statistic_parameters: string; - smoothness_fwhm: string; - contrast_definition: string; - contrast_definition_cogatlas: string; - cognitive_paradigm_description_url: string; - image_type: string; -} - -function useGetNeurovaultImages(neurovaultImages: string[]) { - return useQuery({ - queryKey: ['neurovault-images', ...neurovaultImages], - queryFn: async () => { - const res = await Promise.all>(neurovaultImages.map((url) => axios.get(url))); - return res.map((x) => ({ - ...x.data, - file: x.data.file.replace(/http/, 'https'), - })); - }, - enabled: neurovaultImages.length > 0, - }); -} - -export default useGetNeurovaultImages; diff --git a/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovaultImages.tsx b/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovaultImages.tsx new file mode 100644 index 000000000..a9e6bd954 --- /dev/null +++ b/compose/neurosynth-frontend/src/hooks/metaAnalyses/useGetNeurovaultImages.tsx @@ -0,0 +1,74 @@ +import axios, { AxiosResponse } from 'axios'; +import { useQuery } from 'react-query'; + +export interface INeurovault { + url: string | null; + id: number | null; + file: string | null; + collection: string | null; + collection_id: number | null; + file_size: number | null; + cognitive_paradigm_cogatlas: string | null; + cognitive_paradigm_cogatlas_id: string | null; + cognitive_contrast_cogatlas: string | null; + cognitive_contrast_cogatlas_id: string | null; + map_type: string | null; + analysis_level: string | null; + name: string | null; + description: string | null; + add_date: string | null; + modify_date: string | null; + is_valid: boolean; + surface_left_file: string | null; + surface_right_file: string | null; + data_origin: string | null; + target_template_image: string | null; + subject_species: string | null; + figure: string | null; + handedness: string | null; + age: string | null; + gender: string | null; + race: string | null; + ethnicity: string | null; + BMI: string | null; + fat_percentage: string | null; + waist_hip_ratio: string | null; + mean_PDS_score: string | null; + tanner_stage: string | null; + days_since_menstruation: string | null; + hours_since_last_meal: string | null; + bis_bas_score: string | null; + spsrq_score: string | null; + bis11_score: string | null; + thumbnail: string | null; + reduced_representation: string | null; + is_thresholded: boolean | null; + perc_bad_voxels: number | null; + not_mni: boolean | null; + brain_coverage: number | null; + perc_voxels_outside: number | null; + number_of_subjects: string | null; + modality: string | null; + statistic_parameters: string | null; + smoothness_fwhm: string | null; + contrast_definition: string | null; + contrast_definition_cogatlas: string | null; + cognitive_paradigm_description_url: string | null; + image_type: string | null; +} + +function useGetNeurovaultImages(neurovaultImages: string[]) { + return useQuery({ + queryKey: ['neurovault-images', ...neurovaultImages], + queryFn: async () => { + const res = await Promise.all>(neurovaultImages.map((url) => axios.get(url))); + return res.map((x) => ({ + ...x.data, + file: (x.data.file || '').replace(/http/, 'https'), // without this, link will redirect but result in an error + })); + }, + enabled: neurovaultImages.length > 0, + }); +} + +export default useGetNeurovaultImages; diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/MetaAnalysisPage.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/MetaAnalysisPage.tsx index bc4132143..b706ca2ff 100644 --- a/compose/neurosynth-frontend/src/pages/MetaAnalysis/MetaAnalysisPage.tsx +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/MetaAnalysisPage.tsx @@ -2,8 +2,7 @@ import { Box, Chip, Typography } from '@mui/material'; import NeurosynthBreadcrumbs from 'components/NeurosynthBreadcrumbs'; import StateHandlerComponent from 'components/StateHandlerComponent/StateHandlerComponent'; import TextEdit from 'components/TextEdit/TextEdit'; -import { useGetMetaAnalysisById } from 'hooks'; -import useGetMetaAnalysisResultById from 'hooks/metaAnalyses/useGetMetaAnalysisResultById'; +import { useGetMetaAnalysisById, useGetMetaAnalysisResultById } from 'hooks'; import useGetSpecificationById from 'hooks/metaAnalyses/useGetSpecificationById'; import useUpdateMetaAnalysis from 'hooks/metaAnalyses/useUpdateMetaAnalysis'; import useUserCanEdit from 'hooks/useUserCanEdit'; diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/Nimare.helpers.ts b/compose/neurosynth-frontend/src/pages/MetaAnalysis/Nimare.helpers.ts new file mode 100644 index 000000000..4bf52d32e --- /dev/null +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/Nimare.helpers.ts @@ -0,0 +1,82 @@ +// this is organized as an array to make it orderable. Order is obtained from: https://nimare.readthedocs.io/en/stable/outputs.html#file-names +export const NimareOutputs = [ + // possible value types + { type: 'z', isValueType: true, description: 'Z-statistic' }, + { type: 't', isValueType: true, description: 'T-statistic' }, + { type: 'p', isValueType: true, description: 'p-value' }, + { type: 'logp', isValueType: true, description: 'Negative base-ten logarithm of p-value' }, + { type: 'chi2', isValueType: true, description: 'Chi-squared value' }, + { type: 'prob', isValueType: true, description: 'Probability value' }, + { + type: 'stat', + isValueType: true, + description: 'Test value of meta-analytic algorithm (e.g., ALE values for ALE, OF values for MKDA)', + }, + { type: 'est', isValueType: true, description: 'Parameter estimate (IBMA only)' }, + { type: 'se', isValueType: true, description: 'Standard error of the parameter estimate (IBMA only)' }, + { type: 'tau2', isValueType: true, description: 'Estimated between-study variance (IBMA only)' }, + { type: 'sigma2', isValueType: true, description: 'Estimated within-study variance (IBMA only)' }, + { type: 'label', isValueType: true, description: 'Label map' }, + // KVPs that describe the methods applied to generate the meta analysis + { + type: 'desc', + isValueType: false, + description: + 'Description of the data type. Only used when multiple maps with the same data type are produced by the same method.', + }, + { + type: 'level', + isValueType: false, + description: 'Level of multiple comparisons correction. Either cluster or voxel.', + }, + { + type: 'corr', + isValueType: false, + description: + 'Type of multiple comparisons correction. Either FWE (familywise error rate) or FDR (false discovery rate).', + }, + { + type: 'method', + isValueType: false, + description: + 'Name of the method used for multiple comparisons correction (e.g., “montecarlo” for a Monte Carlo procedure).', + }, + { + type: 'diag', + isValueType: false, + description: + 'Type of diagnostic. Either Jackknife (jackknife analysis) or FocusCounter (focus-count analysis).', + }, + { + type: 'tab', + isValueType: false, + description: 'Type of table. Either clust (clusters table) or counts (contribution table).', + }, + { type: 'tail', isValueType: false, description: 'Sign of the tail for label maps. Either positive or negative.' }, +]; + +export const parseNimareFileName = (fileName: string | undefined | null) => { + // we expect filenames of the form: z_desc-somedescription_level-voxel_corr-fwe_method-montecarlo.nii.gz + if (!fileName) return []; + const segments = fileName.replace('.nii.gz', '').split('_'); + return segments.map((segment) => { + const [key, value] = segment.split('-'); + const nimareOutput = NimareOutputs.find((output) => output.type === key); + if (value === undefined) { + // value type, not a meta analysis method or descriptor + return { + key: 'type', + isValueType: nimareOutput?.isValueType || false, + keyDesc: 'The type of data in the map.', + value: nimareOutput?.type || '', + }; + } else { + return { + key: key, + isValueType: nimareOutput?.isValueType || false, + keyDesc: nimareOutput?.description || '', + value: value, + }; + } + }); +}; diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.spec.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.spec.tsx new file mode 100644 index 000000000..a9f3d6cf2 --- /dev/null +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.spec.tsx @@ -0,0 +1,36 @@ +import { render } from '@testing-library/react'; +import DisplayMetaAnalysisResults from './DisplayMetaAnalysisResults'; +import { useGetMetaAnalysisResultById } from 'hooks'; +import { Mock } from 'vitest'; +import { INeurovault } from 'hooks/metaAnalyses/useGetNeurovaultImages'; + +vi.mock('hooks'); +vi.mock('pages/MetaAnalysis/components/MetaAnalysisResultStatusAlert'); +vi.mock('pages/MetaAnalysis/components/DisplayParsedNiMareFile'); +vi.mock('components/Visualizer/NiiVueVisualizer'); + +const caseA: INeurovault[] = []; +const caseB: INeurovault[] = []; +const caseC: INeurovault[] = []; +const caseD: INeurovault[] = []; + +describe('DisplayMetaAnalysisResults', () => { + it('should render', () => { + render(); + }); + + it('should show the correctly sorted list (1)', () => { + (useGetMetaAnalysisResultById as Mock).mockReturnValue({ + data: caseA, + isLoading: false, + isError: false, + }); + + // Passing in a met-analysis is not important as we mock the hook that provides the important data + render(); + + expect(); + }); + + it('should show the correctly sorted list (2)', () => {}); +}); diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.tsx index f674703d1..d020411f0 100644 --- a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.tsx +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayMetaAnalysisResults.tsx @@ -1,20 +1,17 @@ -import { Download, OpenInNew } from '@mui/icons-material'; -import { Box, Button, Link, List, ListItemButton, ListItemText, Typography } from '@mui/material'; +import { Box, List, ListItemButton, ListItemText, Typography } from '@mui/material'; +import StateHandlerComponent from 'components/StateHandlerComponent/StateHandlerComponent'; import NiiVueVisualizer from 'components/Visualizer/NiiVueVisualizer'; +import { useGetMetaAnalysisResultById, useGetNeurovaultImages } from 'hooks'; +import { INeurovault } from 'hooks/metaAnalyses/useGetNeurovaultImages'; import { MetaAnalysisReturn, NeurovaultFile, ResultReturn } from 'neurosynth-compose-typescript-sdk'; -import MetaAnalysisResultStatusAlert from './MetaAnalysisResultStatusAlert'; -import useGetMetaAnalysisResultById from 'hooks/metaAnalyses/useGetMetaAnalysisResultById'; import { useEffect, useMemo, useState } from 'react'; -import StateHandlerComponent from 'components/StateHandlerComponent/StateHandlerComponent'; -import useGetNeurovaultImages, { INeurovault } from 'hooks/metaAnalyses/useGetNeurovault'; -import DisplayParsedNiMareFile, { NimareOutputs, parseNimareFileName } from './DisplayParsedNiMareFile'; -import ImageIcon from '@mui/icons-material/Image'; +import { NimareOutputs, parseNimareFileName } from '../Nimare.helpers'; +import DisplayParsedNiMareFile from './DisplayParsedNiMareFile'; +import MetaAnalysisResultStatusAlert from './MetaAnalysisResultStatusAlert'; const DisplayMetaAnalysisResults: React.FC<{ metaAnalysis: MetaAnalysisReturn | undefined; }> = (props) => { - // const [] = useState(); - // Each result represents a run. We just need to get the last item to get the latest run const metaAnalysisResults = (props.metaAnalysis?.results || []) as ResultReturn[]; const { data, isLoading, isError } = useGetMetaAnalysisResultById( @@ -32,19 +29,21 @@ const DisplayMetaAnalysisResults: React.FC<{ } = useGetNeurovaultImages(neurovaultFileURLs); const [selectedNeurovaultImage, setSelectedNeurovaultImage] = useState(); - useEffect(() => { - if (!neurovaultFiles) return; - setSelectedNeurovaultImage(neurovaultFiles[0]); - }, [neurovaultFiles]); - const sortedNeurovaultFiles = useMemo(() => { const orderMap = new Map(NimareOutputs.map((output, index) => [output.type, index])); - const sorted = neurovaultFiles?.sort((a, b) => { + // We want the order of the files to be very specific: + // if algorithm is MKDAChi2, then set 1st image to be desc-associationMass + // set 2nd image to be desc-uniformityMass + // otherwise, sort all file names by value type as hardcoded in the NimareOutputs array + // if multiple of the same value type, prioritize corr-cluster, then corr-voxel + // note that generally, this is just alphabetical order + + const sorted = (neurovaultFiles || []).sort((a, b) => { const filenameA = parseNimareFileName(a.name); const filenameB = parseNimareFileName(b.name); - const longerFilename = filenameA.length > filenameB.length ? filenameA : filenameB; - for (let i = 0; i < longerFilename.length; i++) { + const filenameWithMoreSegments = filenameA.length > filenameB.length ? filenameA : filenameB; + for (let i = 0; i < filenameWithMoreSegments.length; i++) { if (!filenameA[i]) return -1; if (!filenameB[i]) return 1; @@ -64,9 +63,13 @@ const DisplayMetaAnalysisResults: React.FC<{ return 0; }); return sorted?.reverse(); - // if (props.metaAnalysis?.specification) // check for meta analysis mkdachi2 }, [neurovaultFiles]); + useEffect(() => { + if (!sortedNeurovaultFiles) return; + setSelectedNeurovaultImage(sortedNeurovaultFiles[0]); + }, [sortedNeurovaultFiles]); + return ( {selectedNeurovaultImage?.file ? ( <> - - - - - - - - + ) : ( No image selected diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayParsedNiMareFile.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayParsedNiMareFile.tsx index c33c6f8ef..9cfb38b82 100644 --- a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayParsedNiMareFile.tsx +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/DisplayParsedNiMareFile.tsx @@ -1,90 +1,9 @@ import { HelpOutline } from '@mui/icons-material'; import { Box, Icon, Paper, Tooltip, Typography } from '@mui/material'; import { useMemo } from 'react'; +import { parseNimareFileName } from '../Nimare.helpers'; -// must turn this into an array to make it orderable -export const NimareOutputs = [ - // possible value types - { type: 'z', isValueType: true, description: 'Z-statistic' }, - { type: 't', isValueType: true, description: 'T-statistic' }, - { type: 'p', isValueType: true, description: 'p-value' }, - { type: 'logp', isValueType: true, description: 'Negative base-ten logarithm of p-value' }, - { type: 'chi2', isValueType: true, description: 'Chi-squared value' }, - { type: 'prob', isValueType: true, description: 'Probability value' }, - { - type: 'stat', - isValueType: true, - description: 'Test value of meta-analytic algorithm (e.g., ALE values for ALE, OF values for MKDA)', - }, - { type: 'est', isValueType: true, description: 'Parameter estimate (IBMA only)' }, - { type: 'se', isValueType: true, description: 'Standard error of the parameter estimate (IBMA only)' }, - { type: 'tau2', isValueType: true, description: 'Estimated between-study variance (IBMA only)' }, - { type: 'sigma2', isValueType: true, description: 'Estimated within-study variance (IBMA only)' }, - { type: 'label', isValueType: true, description: 'Label map' }, - // methods of meta analysis - { - type: 'desc', - isValueType: false, - description: - 'Description of the data type. Only used when multiple maps with the same data type are produced by the same method.', - }, - { - type: 'level', - isValueType: false, - description: 'Level of multiple comparisons correction. Either cluster or voxel.', - }, - { - type: 'corr', - isValueType: false, - description: - 'Type of multiple comparisons correction. Either FWE (familywise error rate) or FDR (false discovery rate).', - }, - { - type: 'method', - isValueType: false, - description: - 'Name of the method used for multiple comparisons correction (e.g., “montecarlo” for a Monte Carlo procedure).', - }, - { - type: 'diag', - isValueType: false, - description: - 'Type of diagnostic. Either Jackknife (jackknife analysis) or FocusCounter (focus-count analysis).', - }, - { - type: 'tab', - isValueType: false, - description: 'Type of table. Either clust (clusters table) or counts (contribution table).', - }, - { type: 'tail', isValueType: false, description: 'Sign of the tail for label maps. Either positive or negative.' }, -]; - -export const parseNimareFileName = (fileName: string | undefined) => { - if (!fileName) return []; - const segments = fileName.replace('.nii.gz', '').split('_'); - return segments.map((segment) => { - const [key, value] = segment.split('-'); - const nimareOutput = NimareOutputs.find((output) => output.type === key); - if (value === undefined) { - // not a method - return { - key: 'type', - isValueType: nimareOutput?.isValueType || false, - keyDesc: 'The type of data in the map.', - value: nimareOutput?.type || '', - }; - } else { - return { - key: key, - isValueType: nimareOutput?.isValueType || false, - keyDesc: nimareOutput?.description || '', - value: value, - }; - } - }); -}; - -const DisplayParsedNiMareFile: React.FC<{ nimareFileName: string | undefined }> = (props) => { +const DisplayParsedNiMareFile: React.FC<{ nimareFileName: string | undefined | null }> = (props) => { const fileNameSegments = useMemo(() => { return parseNimareFileName(props.nimareFileName); }, [props.nimareFileName]); @@ -98,7 +17,7 @@ const DisplayParsedNiMareFile: React.FC<{ nimareFileName: string | undefined }> variant="elevation" display="flex" flexDirection="column" - width="29%" + width="15%" marginRight="2%" marginBottom="0.5rem" padding="0.5rem" diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DisplayParsedNiMareFile.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DisplayParsedNiMareFile.tsx new file mode 100644 index 000000000..177a77ab5 --- /dev/null +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DisplayParsedNiMareFile.tsx @@ -0,0 +1,5 @@ +const MockDisplayParsedNiMareFile: React.FC<{ nimareFileName: string | undefined }> = ({ nimareFileName }) => { + return
{nimareFileName}
; +}; + +export default MockDisplayParsedNiMareFile; diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DynamicForm.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DynamicForm.tsx index 0c804a5fa..d166baf45 100644 --- a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DynamicForm.tsx +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/DynamicForm.tsx @@ -6,10 +6,7 @@ const MockDynamicForm: React.FC = (props) => { {specificationKeys.map((key) => ( {key} ))} - diff --git a/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/MetaAnalysisResultStatusAlert.tsx b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/MetaAnalysisResultStatusAlert.tsx new file mode 100644 index 000000000..6ce833b52 --- /dev/null +++ b/compose/neurosynth-frontend/src/pages/MetaAnalysis/components/__mocks__/MetaAnalysisResultStatusAlert.tsx @@ -0,0 +1,5 @@ +const MockMetaAnalysisResultStatusAlert: React.FC = (props) => { + return
; +}; + +export default MockMetaAnalysisResultStatusAlert; diff --git a/compose/neurosynth-frontend/src/pages/Project/components/ProjectViewMetaAnalysis.tsx b/compose/neurosynth-frontend/src/pages/Project/components/ProjectViewMetaAnalysis.tsx index 2450c5993..9fa1c56b8 100644 --- a/compose/neurosynth-frontend/src/pages/Project/components/ProjectViewMetaAnalysis.tsx +++ b/compose/neurosynth-frontend/src/pages/Project/components/ProjectViewMetaAnalysis.tsx @@ -1,16 +1,7 @@ -import { - Alert, - Box, - Button, - Card, - CardActions, - CardContent, - Chip, - Typography, -} from '@mui/material'; +import { Alert, Box, Button, Card, CardActions, CardContent, Chip, Typography } from '@mui/material'; import StateHandlerComponent from 'components/StateHandlerComponent/StateHandlerComponent'; import { getResultStatus } from 'helpers/MetaAnalysis.helpers'; -import useGetMetaAnalysisResultById from 'hooks/metaAnalyses/useGetMetaAnalysisResultById'; +import { useGetMetaAnalysisResultById } from 'hooks'; import useUserCanEdit from 'hooks/useUserCanEdit'; import { MetaAnalysisReturn, ResultReturn } from 'neurosynth-compose-typescript-sdk'; import { useProjectUser } from 'pages/Project/store/ProjectStore'; @@ -78,10 +69,7 @@ const ProjectViewMetaAnalysis: React.FC = (props) => { {name || ''} - + {description || ''}
diff --git a/compose/neurosynth-frontend/src/pages/Projects/components/ProjectsPageCardSummaryMetaAnalysesListItem.tsx b/compose/neurosynth-frontend/src/pages/Projects/components/ProjectsPageCardSummaryMetaAnalysesListItem.tsx index 3a8edd7af..add4a6c76 100644 --- a/compose/neurosynth-frontend/src/pages/Projects/components/ProjectsPageCardSummaryMetaAnalysesListItem.tsx +++ b/compose/neurosynth-frontend/src/pages/Projects/components/ProjectsPageCardSummaryMetaAnalysesListItem.tsx @@ -1,28 +1,20 @@ -import { - ListItem, - ListItemButton, - ListItemIcon, - ListItemProps, - ListItemText, - Skeleton, -} from '@mui/material'; +import { ListItem, ListItemButton, ListItemIcon, ListItemProps, ListItemText, Skeleton } from '@mui/material'; import { getResultStatus } from 'helpers/MetaAnalysis.helpers'; -import useGetMetaAnalysisResultById from 'hooks/metaAnalyses/useGetMetaAnalysisResultById'; +import { useGetMetaAnalysisResultById } from 'hooks'; import { MetaAnalysisReturn, ResultReturn } from 'neurosynth-compose-typescript-sdk'; import { useMemo } from 'react'; import { Link } from 'react-router-dom'; -const ProjectsPageCardSummaryMetaAnalysesListItem: React.FC< - ListItemProps & { metaAnalysis: MetaAnalysisReturn } -> = (props) => { +const ProjectsPageCardSummaryMetaAnalysesListItem: React.FC = ( + props +) => { const { metaAnalysis, ...listItemProps } = props; - const { data: metaAnalysisResult, isLoading: getMetaAnalysisResultIsLoading } = - useGetMetaAnalysisResultById( - metaAnalysis?.results && metaAnalysis.results.length - ? (metaAnalysis.results[metaAnalysis.results.length - 1] as ResultReturn).id - : undefined - ); + const { data: metaAnalysisResult, isLoading: getMetaAnalysisResultIsLoading } = useGetMetaAnalysisResultById( + metaAnalysis?.results && metaAnalysis.results.length + ? (metaAnalysis.results[metaAnalysis.results.length - 1] as ResultReturn).id + : undefined + ); const resultStatus = useMemo(() => { return getResultStatus(metaAnalysis, metaAnalysisResult); diff --git a/compose/neurosynth-frontend/src/testing/mockData.ts b/compose/neurosynth-frontend/src/testing/mockData.ts index 7400e7993..44b0502c6 100644 --- a/compose/neurosynth-frontend/src/testing/mockData.ts +++ b/compose/neurosynth-frontend/src/testing/mockData.ts @@ -1,4 +1,4 @@ -import { MetaAnalysisReturn, ProjectReturn } from 'neurosynth-compose-typescript-sdk'; +import { MetaAnalysisReturn, ProjectReturn, ResultReturn } from 'neurosynth-compose-typescript-sdk'; import { StudysetReturn, StudyReturn, @@ -9,6 +9,7 @@ import { } from 'neurostore-typescript-sdk'; import { NeurostoreAnnotation } from 'utils/api'; import { IStoreStudy } from 'pages/Study/store/StudyStore.helpers'; +import { INeurovault } from 'hooks/metaAnalyses/useGetNeurovaultImages'; const mockConditions: () => ConditionReturn[] = () => [ { @@ -230,8 +231,7 @@ const mockAnnotations: () => NeurostoreAnnotation[] = () => [ created_at: '2022-04-28T16:25:16.431054+00:00', notes: [ { - authors: - 'Dierks T, Linden DE, Jandl M, Formisano E, Goebel R, Lanfermann H, Singer W', + authors: 'Dierks T, Linden DE, Jandl M, Formisano E, Goebel R, Lanfermann H, Singer W', analysis: '7eEjbzRmX6wv', study_name: "Activation of Heschl's gyrus during auditory hallucinations.", note: { @@ -245,8 +245,7 @@ const mockAnnotations: () => NeurostoreAnnotation[] = () => [ analysis_name: '35712', }, { - authors: - 'Dierks T, Linden DE, Jandl M, Formisano E, Goebel R, Lanfermann H, Singer W', + authors: 'Dierks T, Linden DE, Jandl M, Formisano E, Goebel R, Lanfermann H, Singer W', analysis: '5V3pSFxGqYFm', study_name: "Activation of Heschl's gyrus during auditory hallucinations.", note: { @@ -260,8 +259,7 @@ const mockAnnotations: () => NeurostoreAnnotation[] = () => [ analysis_name: '35713', }, { - authors: - 'Jueptner M, Stephan KM, Frith CD, Brooks DJ, Frackowiak RS, Passingham RE', + authors: 'Jueptner M, Stephan KM, Frith CD, Brooks DJ, Frackowiak RS, Passingham RE', analysis: '5CUdzgAYKk5h', study_name: 'Anatomy of motor learning. I. Frontal cortex and attention to action.', note: { @@ -275,8 +273,7 @@ const mockAnnotations: () => NeurostoreAnnotation[] = () => [ analysis_name: '26997', }, { - authors: - 'Jueptner M, Stephan KM, Frith CD, Brooks DJ, Frackowiak RS, Passingham RE', + authors: 'Jueptner M, Stephan KM, Frith CD, Brooks DJ, Frackowiak RS, Passingham RE', analysis: '3eoGBDLj43ih', study_name: 'Anatomy of motor learning. I. Frontal cortex and attention to action.', note: { @@ -308,9 +305,7 @@ const mockAnnotations: () => NeurostoreAnnotation[] = () => [ }, ]; -const mockStudy: (studyPropOverride?: Partial) => StudyReturn = ( - studyPropOverride -) => ({ +const mockStudy: (studyPropOverride?: Partial) => StudyReturn = (studyPropOverride) => ({ source: 'neurostore', source_id: '7f66YLxzjPKk', doi: 'NaN', @@ -320,8 +315,7 @@ const mockStudy: (studyPropOverride?: Partial) => StudyReturn = ( user: 'github|26612023', updated_at: null, source_updated_at: '2022-04-28T16:23:11.548030+00:00', - publication: - 'The Journal of neuroscience : the official journal of the Society for Neuroscience', + publication: 'The Journal of neuroscience : the official journal of the Society for Neuroscience', created_at: '2022-05-18T19:38:15.262996+00:00', analyses: mockAnalyses(), description: null, @@ -332,9 +326,7 @@ const mockStudy: (studyPropOverride?: Partial) => StudyReturn = ( ...(studyPropOverride || {}), }); -const mockStoreStudy: (studyPropOverride?: Partial) => IStoreStudy = ( - studyPropOverride -) => ({ +const mockStoreStudy: (studyPropOverride?: Partial) => IStoreStudy = (studyPropOverride) => ({ source: 'neurostore', source_id: '7f66YLxzjPKk', doi: 'NaN', @@ -344,8 +336,7 @@ const mockStoreStudy: (studyPropOverride?: Partial) => IStoreStudy user: 'github|26612023', updated_at: null, source_updated_at: '2022-04-28T16:23:11.548030+00:00', - publication: - 'The Journal of neuroscience : the official journal of the Society for Neuroscience', + publication: 'The Journal of neuroscience : the official journal of the Society for Neuroscience', created_at: '2022-05-18T19:38:15.262996+00:00', analyses: [], description: null, @@ -807,6 +798,187 @@ const mockProject: () => ProjectReturn = () => ({ username: 'Nicholas Lee', }); +const mockMetaAnalysisResult: () => ResultReturn = () => ({ + cli_args: null, + cli_version: null, + created_at: '2024-12-06T01:14:37.069129+00:00', + diagnostic_table: + 'id\tPositiveTail 1\tPositiveTail 2\tPositiveTail 3\tPositiveTail 4\tPositiveTail 5\tPositiveTail 6\tPositiveTail 7\tPositiveTail 8\tPositiveTail 9\tPositiveTail 10\tPositiveTail 11\tPositiveTail 12\tPositiveTail 13\tPositiveTail 14\tPositiveTail 15\tPositiveTail 16\tPositiveTail 17\tPositiveTail 18\tPositiveTail 19\tPositiveTail 20\tPositiveTail 21\tPositiveTail 22\tPositiveTail 23\tPositiveTail 24\tPositiveTail 25\tPositiveTail 26\tPositiveTail 27\tPositiveTail 28\nA_Preliminary_Study_of_Functional_Brain_Activation_among_Marijuana_Users_during_Performance_of_a_Virtual_Water_Maze_Task-tab3;_tab4\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAberrant_Orbitofrontal_Connectivity_in_Marijuana_Smoking_Youths-T4;_T2;_T3;_T5\t4\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\nAbnormal_brain_activity_in_prefrontal_brain_regions_in_abstinent_marijuana_users-tbl2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAbstinent_adolescent_marijuana_users_show_altered_fMRI_response_during_spatial_working_memory-tbl2;_T2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAge_of_onset_of_marijuana_use_impacts_inhibitory_processing.-37953;_111;_222;_333\t13\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAltered_affective_response_in_marijuana_smokers:_an_FMRI_study.-21259;_21262;_21260;_21261;_21263\t4\t0\t0\t0\t0\t0\t0\t4\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAltered_brain_tissue_composition_in_heavy_marijuana_users.-21242;_21243\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nAltered_prefrontal_and_insular_cortical_thickness_in_adolescent_marijuana_users.-14325;_some_new_analysis\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nBrain_activation_to_negative_stimuli_mediates_a_relationship_between_adolescent_marijuana_use_and_later_emotional_functioning.-POS:_Heavy_Users_>_Controls;_POS:_Controls_>_Heavy_Users;_NEG:_Controls_>_Heavy_Users\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nCiticoline_Treatment_Improves_Measures_of_Impulsivity_and_Task_Performance_in_Chronic_Marijuana_Smokers:_A_Pilot_BOLD_fMRI_Study-T3;_T2\t6\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nCortico-cerebellar_abnormalities_in_adolescents_with_heavy_marijuana_use.-41239\t1\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nEffects_of_prenatal_marijuana_on_visuospatial_working_memory:_An_fMRI_study_in_young_adults-tbl3\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nFunctional_Activation_and_Effective_Connectivity_Differences_in_Adolescent_Marijuana_Users_Performing_a_Simulated_Gambling_Task-tab3;_tab4\t3\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nFunctional_imaging_of_implicit_marijuana_associations_during_performance_on_an_Implicit_Association_Test_(IAT).-14429;_14430\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nIndividual_and_Additive_Effects_of_the_CNR1_and_FAAH_Genes_on_Brain_Response_to_Marijuana_Cues-tbl3;_tbl2\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nMarijuana_craving_in_the_brain.-40708;_40709\t3\t2\t0\t1\t0\t0\t0\t2\t0\t0\t2\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nMarijuana_use_is_associated_with_a_reorganized_visual-attention_network_and_cerebellar_hypoactivation.-15660;_15661\t2\t2\t0\t1\t1\t1\t0\t1\t0\t0\t0\t1\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nNeural_Correlates_of_Verbal_Learning_in_Adolescent_Alcohol_and_Marijuana_Users-T3;_T2\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nNeural_Effects_of_Positive_and_Negative_Incentives_during_Marijuana_Withdrawal-pone-0061470-t005;_pone-0061470-t004;_pone-0061470-t003;_pone-0061470-t002\t7\t2\t0\t1\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nNeural_mechanisms_of_risky_decision_making_in_adolescents_reporting_frequent_alcohol_and/or_marijuana_use.-Linear_Control_>_Linear_Risk;_Mean_Control_>_Mean_Risk;_Linear_Risk_>_Linear_Control;_Mean_risk_>_Mean_control;_Mean_Risk_>_Mean_Control;_Linear_risk_>_Linear_control\t1\t2\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nNeural_substrates_of_faulty_decision-making_in_abstinent_marijuana_users-tbl4;_tbl3;_tbl5;_tbl2\t0\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nNeuroimaging_of_marijuana_smokers_during_inhibitory_processing:_a_pilot_investigation.-20295;_111;_222;_333;_20294;_20293\t8\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nPoor_decision-making_by_chronic_marijuana_users_is_associated_with_decreased_functional_responsiveness_to_negative_consequences-LOSS_EVALUATION;_ALL_EVALUATION\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\nPreliminary_findings_demonstrating_latent_effects_of_early_adolescent_marijuana_use_onset_on_cortical_architecture.-21176;_my_new_analysis\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nThe_impact_of_initiation:_Early_onset_marijuana_smokers_demonstrate_altered_Stroop_performance_and_brain_activation-tbl0025;_T5\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nWhite_matter_characterization_of_adolescent_binge_drinking_with_and_without_co-occurring_marijuana_use:_A_3-year_investigation-t0010\t0\t0\t0\t0\t0\t0\t0\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nfMRI_BOLD_Response_in_High-risk_College_Students_(Part_1):_During_Exposure_to_Alcohol,_Marijuana,_Polydrug_and_Emotional_Picture_Cues-AGQ042TB1;_AGQ042TB2\t3\t0\t2\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nfMRI_BOLD_Response_of_High-risk_College_Students_(Part_2):_During_Memory_Priming_of_Alcohol,_Marijuana_and_Polydrug_Picture_Cues-Marijuana_non-studied_>_marijuana_studied;_Polydrug_non-studied_>_polydrug_studied;_Alcohol_non-studied_>_alcohol_studied\t0\t2\t0\t0\t1\t0\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\nfMRI_response_to_spatial_working_memory_in_adolescents_with_comorbid_marijuana_and_alcohol_use_disorders.-21243\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n', + id: 'PyftC25kGRm5', + meta_analysis_id: 'WfCnGvpZxXi4', + neurovault_collection: { + collection_id: '19125', + created_at: '2024-12-06T01:14:37.119322+00:00', + files: [ + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894952', + status: 'OK', + updated_at: '2024-12-06T01:14:38.571618+00:00', + url: 'https://neurovault.org/api/images/894952', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894953', + status: 'OK', + updated_at: '2024-12-06T01:14:38.560317+00:00', + url: 'https://neurovault.org/api/images/894953', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894954', + status: 'OK', + updated_at: '2024-12-06T01:14:38.583886+00:00', + url: 'https://neurovault.org/api/images/894954', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894955', + status: 'OK', + updated_at: '2024-12-06T01:14:38.572714+00:00', + url: 'https://neurovault.org/api/images/894955', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894956', + status: 'OK', + updated_at: '2024-12-06T01:14:38.626910+00:00', + url: 'https://neurovault.org/api/images/894956', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894959', + status: 'OK', + updated_at: '2024-12-06T01:14:38.572475+00:00', + url: 'https://neurovault.org/api/images/894959', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894963', + status: 'OK', + updated_at: '2024-12-06T01:14:38.593230+00:00', + url: 'https://neurovault.org/api/images/894963', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894964', + status: 'OK', + updated_at: '2024-12-06T01:14:38.616257+00:00', + url: 'https://neurovault.org/api/images/894964', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894958', + status: 'OK', + updated_at: '2024-12-06T01:14:38.622045+00:00', + url: 'https://neurovault.org/api/images/894958', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894957', + status: 'OK', + updated_at: '2024-12-06T01:14:38.593275+00:00', + url: 'https://neurovault.org/api/images/894957', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894960', + status: 'OK', + updated_at: '2024-12-06T01:14:38.581951+00:00', + url: 'https://neurovault.org/api/images/894960', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894962', + status: 'OK', + updated_at: '2024-12-06T01:14:38.614241+00:00', + url: 'https://neurovault.org/api/images/894962', + }, + { + created_at: '2024-12-06T01:14:38.323194+00:00', + exception: null, + image_id: '894961', + status: 'OK', + updated_at: '2024-12-06T01:14:38.617741+00:00', + url: 'https://neurovault.org/api/images/894961', + }, + ], + updated_at: null, + url: 'https://neurovault.org/api/collections/19125', + }, + updated_at: '2024-12-06T01:14:38.323194+00:00', +}); + +const mockNeurovault: () => INeurovault[] = () => [ + { + url: 'http://neurovault.org/images/894952/', + id: 894952, + file: 'http://neurovault.org/media/images/19125/p_desc-uniformity.nii.gz', + collection: 'http://neurovault.org/collections/19125/', + collection_id: 19125, + file_size: 177268, + cognitive_paradigm_cogatlas: null, + cognitive_paradigm_cogatlas_id: null, + cognitive_contrast_cogatlas: null, + cognitive_contrast_cogatlas_id: null, + map_type: 'P map (given null hypothesis)', + analysis_level: 'meta-analysis', + name: 'p_desc-uniformity.nii.gz', + description: '', + add_date: '2024-12-06T02:14:39.317726+01:00', + modify_date: '2024-12-06T02:14:43.836661+01:00', + is_valid: true, + surface_left_file: 'http://neurovault.org/media/images/19125/894952.L.func.gii', + surface_right_file: 'http://neurovault.org/media/images/19125/894952.R.func.gii', + data_origin: 'volume', + target_template_image: 'GenericMNI', + subject_species: 'homo sapiens', + figure: null, + handedness: null, + age: null, + gender: null, + race: null, + ethnicity: null, + BMI: null, + fat_percentage: null, + waist_hip_ratio: null, + mean_PDS_score: null, + tanner_stage: null, + days_since_menstruation: null, + hours_since_last_meal: null, + bis_bas_score: null, + spsrq_score: null, + bis11_score: null, + thumbnail: 'http://neurovault.org/media/images/19125/glass_brain_894952.jpg', + reduced_representation: null, + is_thresholded: false, + perc_bad_voxels: 74.68694225423734, + not_mni: false, + brain_coverage: 100.0, + perc_voxels_outside: 0.0, + number_of_subjects: null, + modality: 'Other', + statistic_parameters: null, + smoothness_fwhm: null, + contrast_definition: null, + contrast_definition_cogatlas: null, + cognitive_paradigm_description_url: null, + image_type: 'statistic_map', + }, +]; + export { mockConditions, mockWeights, @@ -823,4 +995,6 @@ export { mockStorePoints, mockStoreStudy, mockProject, + mockMetaAnalysisResult, + mockNeurovault, }; diff --git a/compose/neurosynth-frontend/tsconfig.json b/compose/neurosynth-frontend/tsconfig.json index 66e049d8c..1c2c5f273 100644 --- a/compose/neurosynth-frontend/tsconfig.json +++ b/compose/neurosynth-frontend/tsconfig.json @@ -18,5 +18,5 @@ "jsx": "react-jsx", "types": ["cypress", "node", "vite/client", "vitest/globals"] }, - "include": ["src", "cypress", "vite-env.d.ts", "*.config.ts", "__mocks__", "eslint.config.js"] + "include": ["src", "hooks", "cypress", "vite-env.d.ts", "*.config.ts", "__mocks__", "eslint.config.js"] }