Skip to content

Commit

Permalink
Merge pull request #843 from bids-standard/revise-subjectmetadata
Browse files Browse the repository at this point in the history
change subjectMetadata to array
  • Loading branch information
nellh authored Sep 24, 2019
2 parents f552be1 + 4ca3000 commit 2c0a610
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 37 deletions.
9 changes: 5 additions & 4 deletions bids-validator/tests/bids.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ describe('BIDS example datasets ', function() {
var warnings = issues.warnings
assert(summary.sessions.length === 0)
assert(summary.subjects.length === 1)
assert.deepEqual(summary.subjectMetadata, {
'01': {
sex: 'M',
assert.deepEqual(summary.subjectMetadata, [
{
participantId: '01',
age: 25,
sex: 'M',
},
})
])
assert.deepEqual(summary.tasks, ['rhyme judgment'])
assert.isFalse(summary.dataProcessed)
assert(summary.modalities.includes('T1w'))
Expand Down
14 changes: 5 additions & 9 deletions bids-validator/utils/__tests__/collectSubjectMetadata.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ sub-01 34 F
sub-02 38 M
`
const subjectMetadata = collectSubjectMetadata(tsvFile)
assert.deepEqual(subjectMetadata, {
'01': {
age: 34,
sex: 'F',
},
'02': {
age: 38,
sex: 'M',
},
assert.lengthOf(subjectMetadata, 2)
assert.deepEqual(subjectMetadata[0], {
participantId: '01',
age: 34,
sex: 'F',
})
})
it('extracts tsv string to subjectMetadata object', () => {
Expand Down
67 changes: 43 additions & 24 deletions bids-validator/utils/summary/collectSubjectMetadata.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
const PARTICIPANT_ID = 'participantId'
const AGE = 'age'
/**
* Go from tsv format string with participant_id as a required header to object of form
* {
* participant_id_1: {
* Go from tsv format string with participant_id as a required header to array of form
* [
* {
* participantId: 'participant_id_1'
* foo: 'x',
* ...
* },
* participant_id_2: {
* {
* participantId: 'participant_id_2'
* foo: 'y',
* ...
* }
* ...
* }
* ]
*
* returns null if participant_id is not a header or file contents do not exist
* @param {string} participantsTsvContent
Expand All @@ -21,29 +25,44 @@ const collectSubjectMetadata = participantsTsvContent => {
.split('\n')
.filter(row => row !== '')
.map(row => row.split('\t'))
const [headers, ...subjectData] = contentTable
const participant_idIndex = headers.findIndex(
header => header === 'participant_id',
const [snakeCaseHeaders, ...subjectData] = contentTable
const headers = snakeCaseHeaders.map(header =>
header === 'participant_id' ? PARTICIPANT_ID : header,
)
if (participant_idIndex === -1) return null
const targetKeys = [PARTICIPANT_ID, 'age', 'sex', 'group']
.map(key => ({
key,
index: headers.findIndex(targetKey => targetKey === key),
}))
.filter(({ index }) => index !== -1)
const participantIdKey = targetKeys.find(
({ key }) => key === PARTICIPANT_ID,
)
const ageKey = targetKeys.find(({ key }) => key === AGE)
if (participantIdKey === undefined) return null
else
return subjectData.reduce(
(subjectMetadata, data) => ({
...subjectMetadata,
[data[participant_idIndex].replace(/^sub-/, '')]: data.reduce(
(subjectMetadata, datum, i) =>
i === participant_idIndex
? subjectMetadata
: {
...subjectMetadata,
[headers[i]]:
headers[i] === 'age' ? parseInt(datum) : datum,
},
return subjectData
.map(data => {
// this first map is for transforming any data coming out of participants.tsv:
// strip subject ids to match metadata.subjects: 'sub-01' -> '01'
data[participantIdKey.index] = data[participantIdKey.index].replace(
/^sub-/,
'',
)
// make age an integer
if (ageKey) data[ageKey.index] = parseInt(data[ageKey.index])
return data
})
.map(data =>
//extract all target metadata for each subject
targetKeys.reduce(
(subject, { key, index }) => ({
...subject,
[key]: data[index],
}),
{},
),
}),
{},
)
)
}
}

Expand Down

0 comments on commit 2c0a610

Please sign in to comment.