Skip to content

Commit 68c5f65

Browse files
committed
feat: Enable multi-file associations, load coordsystems
1 parent 0c52020 commit 68c5f65

File tree

1 file changed

+45
-26
lines changed

1 file changed

+45
-26
lines changed

src/schema/associations.ts

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ import { parseBvalBvec } from '../files/dwi.ts'
99
import { walkBack } from '../files/inheritance.ts'
1010
import { evalCheck } from './applyRules.ts'
1111
import { expressionFunctions } from './expressionLanguage.ts'
12+
import { readEntities } from './entities.ts'
1213

1314
import { readText } from '../files/access.ts'
1415

16+
type LoadFunction = (file: BIDSFile, options: any) => Promise<any>
17+
type MultiLoadFunction = (files: BIDSFile[], options: any) => Promise<any>
18+
1519
function defaultAssociation(file: BIDSFile, _options: any): Promise<{ path: string }> {
1620
return Promise.resolve({ path: file.path })
1721
}
@@ -24,7 +28,7 @@ function defaultAssociation(file: BIDSFile, _options: any): Promise<{ path: stri
2428
*
2529
* Many associations only consist of a path; this object is for more complex associations.
2630
*/
27-
const associationLookup = {
31+
const associationLookup: Record<string, LoadFunction> = {
2832
events: async (file: BIDSFile, options: { maxRows: number }): Promise<Events> => {
2933
const columns = await loadTSV(file, options.maxRows)
3034
.catch((e) => {
@@ -86,11 +90,22 @@ const associationLookup = {
8690
sampling_frequency: columns.get('sampling_frequency'),
8791
}
8892
},
89-
coordsystem: async (file: BIDSFile, options: { maxRows: number }): Promise<{path: string, keys: string[]}> => {
90-
const keys = Object.keys(await loadJSON(file).catch((e) => {return {}}))
93+
}
94+
const multiAssociationLookup: Record<string, MultiLoadFunction> = {
95+
coordsystems: async (
96+
files: BIDSFile[],
97+
options: any,
98+
): Promise<{ paths: string[]; spaces: string[]; parents: string[] }> => {
99+
const jsons = await Promise.allSettled(
100+
files.map((f) => loadJSON(f).catch(() => ({} as Record<string, unknown>))),
101+
)
102+
const parents = jsons.map((j) =>
103+
j.status === 'fulfilled' ? j.value?.ParentCoordinateSystem : undefined
104+
).filter((p) => p) as string[]
91105
return {
92-
path: file.path,
93-
keys: keys,
106+
paths: files.map((f) => f.path),
107+
spaces: files.map((f) => readEntities(f.name).entities?.space),
108+
ParentCoordinateSystems: parents,
94109
}
95110
},
96111
}
@@ -131,33 +146,37 @@ export async function buildAssociations(
131146
rule.target.suffix,
132147
rule.target?.entities ?? [],
133148
).next().value
134-
if (Array.isArray(file)) {
135-
file = file[0]
136-
}
137-
} catch (error) {
138-
if (
139-
error && typeof error === 'object' && 'code' in error &&
140-
error.code === 'MULTIPLE_INHERITABLE_FILES'
141-
) {
142-
// @ts-expect-error
149+
} catch (error: any) {
150+
if (error?.code === 'MULTIPLE_INHERITABLE_FILES') {
143151
context.dataset.issues.add(error)
144-
break
152+
continue
145153
} else {
146154
throw error
147155
}
148156
}
149157

150-
if (file) {
151-
// @ts-expect-error
152-
const load = associationLookup[key] ?? defaultAssociation
153-
// @ts-expect-error
154-
associations[key] = await load(file, { maxRows: context.dataset.options?.maxRows }).catch(
155-
(error: any) => {
156-
if (error.code) {
157-
context.dataset.issues.add({ ...error, location: file.path })
158-
}
159-
},
160-
)
158+
if (file && !(Array.isArray(file) && file.length === 0)) {
159+
const options = { maxRows: context.dataset.options?.maxRows }
160+
if (key in multiAssociationLookup) {
161+
const load = multiAssociationLookup[key]
162+
if (!Array.isArray(file)) {
163+
file = [file]
164+
}
165+
associations[key as keyof Associations] = await load(file, options)
166+
} else {
167+
const load = associationLookup[key] ?? defaultAssociation
168+
if (Array.isArray(file)) {
169+
file = file[0]
170+
}
171+
const location = file.path
172+
associations[key as keyof Associations] = await load(file, { maxRows: context.dataset.options?.maxRows }).catch(
173+
(error: any) => {
174+
if (error.code) {
175+
context.dataset.issues.add({ ...error, location })
176+
}
177+
},
178+
)
179+
}
161180
}
162181
}
163182
return Promise.resolve(associations)

0 commit comments

Comments
 (0)