-
Notifications
You must be signed in to change notification settings - Fork 15
BEP042 patches #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
BEP042 patches #268
Changes from all commits
cd976b5
5c32a78
cd30d92
0c52020
68c5f65
e6abc84
60b5168
5757fc0
e6de738
79248e8
9758f91
50337ca
a2fe000
ac68280
6ef750d
188a77e
1fa78a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!-- | ||
A new scriv changelog fragment. | ||
|
||
Uncomment the section that is right (remove the HTML comment wrapper). | ||
For top level release notes, leave all the headers commented out. | ||
--> | ||
|
||
|
||
### Added | ||
|
||
- Implement `associations.coordsystems` to collate multiple `coordsystem.json` files, | ||
as required by BEP 042 (EMG). | ||
|
||
<!-- | ||
### Changed | ||
|
||
- A bullet item for the Changed category. | ||
|
||
--> | ||
<!-- | ||
### Fixed | ||
|
||
- A bullet item for the Fixed category. | ||
|
||
--> | ||
<!-- | ||
### Deprecated | ||
|
||
- A bullet item for the Deprecated category. | ||
|
||
--> | ||
<!-- | ||
### Removed | ||
|
||
- A bullet item for the Removed category. | ||
|
||
--> | ||
<!-- | ||
### Security | ||
|
||
- A bullet item for the Security category. | ||
|
||
--> | ||
<!-- | ||
### Infrastructure | ||
|
||
- A bullet item for the Infrastructure category. | ||
|
||
--> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,14 +3,19 @@ import type { Schema as MetaSchema } from '@bids/schema/metaschema' | |
|
||
import type { BIDSFile } from '../types/filetree.ts' | ||
import type { BIDSContext } from './context.ts' | ||
import { loadJSON } from '../files/json.ts' | ||
import { loadTSV } from '../files/tsv.ts' | ||
import { parseBvalBvec } from '../files/dwi.ts' | ||
import { walkBack } from '../files/inheritance.ts' | ||
import { evalCheck } from './applyRules.ts' | ||
import { expressionFunctions } from './expressionLanguage.ts' | ||
import { readEntities } from './entities.ts' | ||
|
||
import { readText } from '../files/access.ts' | ||
|
||
type LoadFunction = (file: BIDSFile, options: any) => Promise<any> | ||
type MultiLoadFunction = (files: BIDSFile[], options: any) => Promise<any> | ||
|
||
function defaultAssociation(file: BIDSFile, _options: any): Promise<{ path: string }> { | ||
return Promise.resolve({ path: file.path }) | ||
} | ||
|
@@ -23,7 +28,7 @@ function defaultAssociation(file: BIDSFile, _options: any): Promise<{ path: stri | |
* | ||
* Many associations only consist of a path; this object is for more complex associations. | ||
*/ | ||
const associationLookup = { | ||
const associationLookup: Record<string, LoadFunction> = { | ||
events: async (file: BIDSFile, options: { maxRows: number }): Promise<Events> => { | ||
const columns = await loadTSV(file, options.maxRows) | ||
.catch((e) => { | ||
|
@@ -86,6 +91,24 @@ const associationLookup = { | |
} | ||
}, | ||
} | ||
const multiAssociationLookup: Record<string, MultiLoadFunction> = { | ||
coordsystems: async ( | ||
files: BIDSFile[], | ||
options: any, | ||
): Promise<{ paths: string[]; spaces: string[]; ParentCoordinateSystems: string[] }> => { | ||
const jsons = await Promise.allSettled( | ||
files.map((f) => loadJSON(f).catch(() => ({} as Record<string, unknown>))), | ||
) | ||
const parents = jsons.map((j) => | ||
j.status === 'fulfilled' ? j.value?.ParentCoordinateSystem : undefined | ||
).filter((p) => p) as string[] | ||
return { | ||
paths: files.map((f) => f.path), | ||
spaces: files.map((f) => readEntities(f.name).entities?.space), | ||
ParentCoordinateSystems: parents, | ||
} | ||
}, | ||
} | ||
|
||
export async function buildAssociations( | ||
context: BIDSContext, | ||
|
@@ -123,33 +146,37 @@ export async function buildAssociations( | |
rule.target.suffix, | ||
rule.target?.entities ?? [], | ||
).next().value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The EMG examples do not have this case, but with multiple We currently strongly assume (and implement with For now this could be noted as a limitation in the validator implementation. |
||
if (Array.isArray(file)) { | ||
file = file[0] | ||
} | ||
} catch (error) { | ||
if ( | ||
error && typeof error === 'object' && 'code' in error && | ||
error.code === 'MULTIPLE_INHERITABLE_FILES' | ||
) { | ||
// @ts-expect-error | ||
} catch (error: any) { | ||
if (error?.code === 'MULTIPLE_INHERITABLE_FILES') { | ||
context.dataset.issues.add(error) | ||
break | ||
continue | ||
rwblair marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else { | ||
throw error | ||
} | ||
} | ||
|
||
if (file) { | ||
// @ts-expect-error | ||
const load = associationLookup[key] ?? defaultAssociation | ||
// @ts-expect-error | ||
associations[key] = await load(file, { maxRows: context.dataset.options?.maxRows }).catch( | ||
(error: any) => { | ||
if (error.code) { | ||
context.dataset.issues.add({ ...error, location: file.path }) | ||
} | ||
}, | ||
) | ||
if (file && !(Array.isArray(file) && file.length === 0)) { | ||
const options = { maxRows: context.dataset.options?.maxRows } | ||
if (key in multiAssociationLookup) { | ||
const load = multiAssociationLookup[key] | ||
if (!Array.isArray(file)) { | ||
file = [file] | ||
} | ||
associations[key as keyof Associations] = await load(file, options).catch((e: any) => {}) | ||
} else { | ||
const load = associationLookup[key] ?? defaultAssociation | ||
if (Array.isArray(file)) { | ||
file = file[0] | ||
} | ||
const location = file.path | ||
associations[key as keyof Associations] = await load(file, options).catch( | ||
(error: any) => { | ||
if (error.code) { | ||
context.dataset.issues.add({ ...error, location }) | ||
} | ||
}, | ||
) | ||
} | ||
} | ||
} | ||
return Promise.resolve(associations) | ||
|
Uh oh!
There was an error while loading. Please reload this page.