From 67347d39a25096d2a40be3e3029e973741c21510 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Mon, 22 Apr 2024 15:45:59 -0400 Subject: [PATCH 1/7] FIX: Start file count at 0 The -1 seems to have been copied from the legacy validator, which used -1 as an indicator that the value was uninitialized and then later replaced it with a `length()` call. Since we just increment it when processing each file, it makes sense to start at 0. --- bids-validator/src/summary/summary.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() From d24c4cebcc85423b2e78d928e25b0d4877d850b8 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Mon, 22 Apr 2024 16:01:14 -0400 Subject: [PATCH 2/7] FIX: Expect multiple rule matches for events.json This test is a bit weird; it seems to have been relying on arbitrary pruning. There's nothing in the rules or code that now (as of #1940) should prevent multiple rules from being returned. If we do want a test to verify pruning, we should come up with a new one. --- bids-validator/src/validators/filenameIdentify.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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) }) }) From 7a1a22ab300f1742a6e3087cd526a60f4981eed1 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 24 Apr 2024 23:13:35 -0400 Subject: [PATCH 3/7] feat: Add values to associations.bvals, fix misnamed variables --- bids-validator/src/schema/associations.ts | 13 +++++++------ bids-validator/src/types/context.ts | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) 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/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 From 4efab0d1b1f66c182f16b9b8669525da73827540 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 25 Apr 2024 16:59:50 -0400 Subject: [PATCH 4/7] Enable stems to be globs --- bids-validator/src/deps/path.ts | 3 +++ bids-validator/src/validators/filenameIdentify.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) 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/validators/filenameIdentify.ts b/bids-validator/src/validators/filenameIdentify.ts index 5cfbdc6cc..c3a0ac060 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) From 50430b85f84a7d3262495817df94ab008dc6ec77 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 25 Apr 2024 17:00:34 -0400 Subject: [PATCH 5/7] TMP: Use bids-standard/bids-specification#1672 schema --- bids-validator/src/setup/loadSchema.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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, { From 49fcb2d78a0c2f3264a289eaba34516f161907e6 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 25 Apr 2024 21:11:40 -0400 Subject: [PATCH 6/7] feat: Accept phenotype as a pseudo-datatype --- .../src/validators/filenameIdentify.ts | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/bids-validator/src/validators/filenameIdentify.ts b/bids-validator/src/validators/filenameIdentify.ts index c3a0ac060..e19754205 100644 --- a/bids-validator/src/validators/filenameIdentify.ts +++ b/bids-validator/src/validators/filenameIdentify.ts @@ -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 From 36f73704f212fb7499c5b5a32da42f903ecd601c Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 25 Apr 2024 21:46:50 -0400 Subject: [PATCH 7/7] fix: Check if rule.entities exists before accessing keys --- bids-validator/src/validators/filenameIdentify.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bids-validator/src/validators/filenameIdentify.ts b/bids-validator/src/validators/filenameIdentify.ts index e19754205..0816cf638 100644 --- a/bids-validator/src/validators/filenameIdentify.ts +++ b/bids-validator/src/validators/filenameIdentify.ts @@ -145,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))