diff --git a/bids-validator/src/deps/path.ts b/bids-validator/src/deps/path.ts index a19d88058..de21eb5e6 100644 --- a/bids-validator/src/deps/path.ts +++ b/bids-validator/src/deps/path.ts @@ -9,3 +9,6 @@ export { parse, SEPARATOR, } from 'https://deno.land/std@0.217.0/path/mod.ts' +export { + globToRegExp, +} from 'https://deno.land/std@0.217.0/path/glob_to_regexp.ts' diff --git a/bids-validator/src/schema/associations.ts b/bids-validator/src/schema/associations.ts index db42a6732..e6ccaabaf 100644 --- a/bids-validator/src/schema/associations.ts +++ b/bids-validator/src/schema/associations.ts @@ -82,11 +82,12 @@ const associationLookup = { inherit: true, load: async (file: BIDSFile): Promise => { const contents = await file.text() - const columns = parseBvalBvec(contents) + const rows = parseBvalBvec(contents) return { path: file.path, - n_cols: columns ? columns[0].length : 0, - n_rows: columns ? columns.length : 0, + n_cols: rows ? rows[0].length : 0, + n_rows: rows ? rows.length : 0, + values: rows[0], } }, }, @@ -96,11 +97,11 @@ const associationLookup = { inherit: true, load: async (file: BIDSFile): Promise => { const contents = await file.text() - const columns = parseBvalBvec(contents) + const rows = parseBvalBvec(contents) return { path: file.path, - n_cols: columns ? columns[0].length : 0, - n_rows: columns ? columns.length : 0, + n_cols: rows ? rows[0].length : 0, + n_rows: rows ? rows.length : 0, } }, }, diff --git a/bids-validator/src/setup/loadSchema.ts b/bids-validator/src/setup/loadSchema.ts index ed862e70b..65d015649 100644 --- a/bids-validator/src/setup/loadSchema.ts +++ b/bids-validator/src/setup/loadSchema.ts @@ -1,6 +1,6 @@ import { Schema } from '../types/schema.ts' import { objectPathHandler } from '../utils/objectPathHandler.ts' -import * as schemaDefault from 'https://bids-specification.readthedocs.io/en/latest/schema.json' assert { type: 'json' } +import * as schemaDefault from 'https://bids-specification--1672.org.readthedocs.build/en/1672/schema.json' assert { type: 'json' } /** * Load the schema from the specification @@ -15,7 +15,8 @@ export async function loadSchema(version = 'latest'): Promise { if (bidsSchema !== undefined) { schemaUrl = bidsSchema } else if (version === 'latest' || versionRegex.test(version)) { - schemaUrl = `https://bids-specification.readthedocs.io/en/${version}/schema.json` + schemaUrl = 'https://bids-specification--1672.org.readthedocs.build/en/1672/schema.json' + // schemaUrl = `https://bids-specification.readthedocs.io/en/${version}/schema.json` } try { const schemaModule = await import(/* @vite-ignore */ schemaUrl, { diff --git a/bids-validator/src/summary/summary.ts b/bids-validator/src/summary/summary.ts index 1112079ab..62622a437 100644 --- a/bids-validator/src/summary/summary.ts +++ b/bids-validator/src/summary/summary.ts @@ -69,7 +69,7 @@ export class Summary { schemaVersion: string constructor() { this.dataProcessed = false - this.totalFiles = -1 + this.totalFiles = 0 this.size = 0 this.sessions = new Set() this.subjects = new Set() diff --git a/bids-validator/src/types/context.ts b/bids-validator/src/types/context.ts index 4b03fcbee..de2c1ac69 100644 --- a/bids-validator/src/types/context.ts +++ b/bids-validator/src/types/context.ts @@ -44,6 +44,7 @@ export interface ContextAssociationsBval { path: string n_cols: number n_rows: number + values: number[] } export interface ContextAssociationsBvec { path: string diff --git a/bids-validator/src/validators/filenameIdentify.test.ts b/bids-validator/src/validators/filenameIdentify.test.ts index c765311a0..64a78adfc 100644 --- a/bids-validator/src/validators/filenameIdentify.test.ts +++ b/bids-validator/src/validators/filenameIdentify.test.ts @@ -74,7 +74,7 @@ Deno.test('test hasMatch', async (t) => { hasMatch(schema, context) }) - await t.step('No match', async () => { + await t.step('No match', async () => { const fileName = Deno.makeTempFileSync().split('/')[2] const file = new BIDSFileDeno('/tmp', fileName, ignore) @@ -87,7 +87,7 @@ Deno.test('test hasMatch', async (t) => { true, ) }) - await t.step('1+ matched, datatype match', async () => { + await t.step('2 matches, no pruning', async () => { const path = `${PATH}/../bids-examples/fnirs_automaticity` const fileName = 'events.json' const file = new BIDSFileDeno(path, fileName, ignore) @@ -97,7 +97,6 @@ Deno.test('test hasMatch', async (t) => { 'rules.files.raw.task.events__pet', ] await hasMatch(schema, context) - assertEquals(context.filenameRules.length, 1) - assertEquals(context.filenameRules[0], 'rules.files.raw.task.events__mri') + assertEquals(context.filenameRules.length, 2) }) }) diff --git a/bids-validator/src/validators/filenameIdentify.ts b/bids-validator/src/validators/filenameIdentify.ts index 5cfbdc6cc..0816cf638 100644 --- a/bids-validator/src/validators/filenameIdentify.ts +++ b/bids-validator/src/validators/filenameIdentify.ts @@ -12,7 +12,7 @@ * object in the schema for reference. */ // @ts-nocheck -import { SEPARATOR } from '../deps/path.ts' +import { SEPARATOR, globToRegExp } from '../deps/path.ts' import { GenericSchema, Schema } from '../types/schema.ts' import { BIDSContext } from '../schema/context.ts' import { lookupModality } from '../schema/modalities.ts' @@ -56,7 +56,7 @@ function findRuleMatches(schema, context) { export function _findRuleMatches(node, path, context) { if ( ('path' in node && context.file.name.endsWith(node.path)) || - ('stem' in node && context.file.name.startsWith(node.stem)) || + ('stem' in node && context.file.name.match(globToRegExp(node.stem + '*'))) || ('suffixes' in node && node.suffixes.includes(context.suffix)) ) { context.filenameRules.push(path) @@ -74,27 +74,18 @@ export function _findRuleMatches(node, path, context) { export async function datatypeFromDirectory(schema, context) { const subEntity = schema.objects.entities.subject.name - const subFormat = schema.objects.formats[subEntity.format] const sesEntity = schema.objects.entities.session.name - const sesFormat = schema.objects.formats[sesEntity.format] const parts = context.file.path.split(SEPARATOR) - let datatypeIndex = 2 - if (parts[0] !== '') { - // we assume paths have leading '/' - } - // Ignoring associated data for now - const subParts = parts[1].split('-') - if (!(subParts.length === 2 && subParts[0] === subEntity)) { - // first directory must be subject - } - if (parts.length < 3) { + let datatypeIndex = parts.length - 2 + if (datatypeIndex < 1) { return Promise.resolve() } - const sesParts = parts[2].split('-') - if (sesParts.length === 2 && sesParts[0] === sesEntity) { - datatypeIndex = 3 - } const dirDatatype = parts[datatypeIndex] + if (dirDatatype === 'phenotype') { + // Phenotype is a pseudo-datatype for now. + context.datatype = dirDatatype + return Promise.resolve() + } for (let key in schema.rules.modalities) { if (schema.rules.modalities[key].datatypes.includes(dirDatatype)) { context.modality = key @@ -154,9 +145,9 @@ function entitiesExtensionsInRule( ): boolean { const rule = schema[path] const fileEntities = Object.keys(context.entities) - const ruleEntities = Object.keys(rule.entities).map((key) => + const ruleEntities = rule.entities ? Object.keys(rule.entities).map((key) => lookupEntityLiteral(key, schema), - ) + ) : [] const extInRule = !rule.extensions || (rule.extensions && rule.extensions.includes(context.extension))