All pages
Powered by GitBook
1 of 25

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

squirrel vs BIDS

Understanding the differences between package formats

BIDS and squirrel are both file formats designed to store neuroimaging data. They are similar, but different in implementation. If you are familiar with BIDS, squirrel will be easy to understand.

squirrel vs BIDS objects

squirrel
BIDS
Notes

subject

sub- directory

The subject object. BIDS sub-* directories contain the ID. squirrel objects are identified by the ID.

study

ses- directory *_sessions.tsv

Session/imaging study object.

series

*.nii.gz files *.nii files anat directory func directory fmap directory ieeg directory perf directory eeg directory *events.json file *events.tsv file <modality>.json file

Mapping series within BIDS can be tricky. There is limited mapping between squirrel and BIDS for this object.

analysis

derivatives directory figures directory motion directory *_scans.tsv file

The analysis results object/directory.

pipeline

code directory

Code, pipelines, scripts to perform analysis on raw data.

experiment

task-*.json task-*.tsv

Details on the experiment.

root -> description

dataset_description.json

Details about the dataset.

root -> changes

CHANGES

Any information about changes from to this dataset from a previous version.

root -> readme

README README.md

More details about the dataset.

subject -> demographics

participants.tsv participants.json

Details about subject demographics.

Specification v1.0

Format specification for v1.0

Overview

A squirrel contains a JSON file with meta-data about all of the data in the package, and a directory structure to store files. While many data items are optional, a squirrel package must contain a JSON file and a data directory.

JSON File

JSON is JavaScript object notation, and many tutorials are available for how to read and write JSON files. Within the squirrel format, keys are camel-case; for example dayNumber or dateOfBirth, where each word in the key is capitalized except the first word. The JSON file should be manually editable. JSON resources:

Data types

The JSON specification includes several data types, but squirrel uses some derivative data types: string, number, date, datetime, char. Date, datetime, and char are stored as the JSON string datatype and should be enclosed in double quotes.

Type

Notes

Example

string

Regular string

“My string of text”

number

Any JSON acceptable number

3.14159 or 1000000

datetime

Datetime is formatted as YYYY-MM-DD HH:MI:SSwhere all numbers are zero-padded and use a 24-hour clock. Datetime is stored as a JSON string datatype

“2022-12-03 15:34:56”

date

Date is formatted as YYYY-MM-DD

“1990-01-05”

char

A single character

F

bool

true or false

true

JSON array

Item is a JSON array of any data type

JSON object

Item is a JSON object

Directory Structure

The JSON file squirrel.json is stored in the root directory. A directory called data contains any data described in the JSON file. Files can be of any type, with file any extension. Because of the broad range of environments in which squirrel files are used, filenames must only contain alphanumeric characters. Filenames cannot contain special characters or spaces and must be less than 255 characters in length.

Squirrel Package

A squirrel package becomes a package once the entire directory structure is combined into a zip file. The compression level does not matter, as long as the file is a .zip archive. Once created, this package can be distributed to other instances of NiDB, squirrel readers, or simply unzipped and manually extracted. Packages can be created manually or exported using NiDB or squirrel converters.

Package Specification

JSON tutorial -

Wiki -

JSON specification -

https://www.w3schools.com/js/js_json_intro.asp
https://en.wikipedia.org/wiki/JSON
https://www.json.org/json-en.html

Using the squirrel library

Overview of how to use the squirrel C++ library

The squirrel library is built using the Qt framework and gdcm. Both are available as open-source, and make development of the squirrel library much more efficient.

The Qt and gdcm libraries (or DLLs on Windows) will need to be redistributed along with any programs that use the squirrel library.

Including squirrel

The squirrel library can be included at the top of your program. Make sure the path to the squirrel library is in the INCLUDE path for your compiler.

#include "squirrel.h"

Reading

Create an object and read an existing squirrel package

squirrel *sqrl = new squirrel();
sqrl->SetPackagePath("/path/to/data.sqrl");
if (sqrl->Read()) {
    cout << "Successfuly read squirrel package" << endl;
else
    cout << "Error reading squirrel package. Log [" << sqrl->GetLog() << "]" << endl;

/* print the entire package */
sqrl->Print();

/* access individual package meta-data */
cout << sqrl->name;

/* delete squirrel object */
delete sqrl;

Iterating subject/study/series data

Functions are provided to retrieve lists of objects.

/* iterate through the subjects */
QList<squirrelSubject> subjects = sqrl->GetSubjectList();
foreach (squirrelSubject subject, subjects) {
    cout <<"Found subject [" + subject.ID + "]");

    /* get studies */
    QList<squirrelStudy> studies = sqrl->GetStudyList(subject.GetObjectID());
    foreach (squirrelStudy study, studies) {
        n->Log(QString("Found study [%1]").arg(study.StudyNumber));

        /* get series */
        QList<squirrelSeries> serieses = sqrl->GetSeriesList(study.GetObjectID());
        foreach (squirrelSeries series, serieses) {
            n->Log(QString("Found series [%1]").arg(series.SeriesNumber));
            int numfiles = series.files.size();
        }
    }
}

Finding data

How to get a copy of an object, for reading or searching a squirrel package.

/* get a subject by ID, the returned object is read-only */
qint64 subjectObjectID = FindSubject("12345");
squirrelSubject subject = GetSubject(subjectObjectID);
QString guid = subject.GUID;
subject.PrintDetails();

/* get a subject by SubjectUID (DICOM field) */
squirrelStudy study = GetStudy(FindSubjectByUID("08.03.21-17:51:10-STD-1.3.12.2.1107.5.3.7.20207"));
QString studyDesc = study.Description;
study.PrintDetails();

/* get study by subject ID, and study number */
squirrelStudy study = GetStudy(FindStudy("12345", 2));
QString studyEquipment = study.Equipment;
study.PrintDetails();

/* get series by seriesUID (DICOM field) */
squirrelSeries series = GetStudy(FindSeriesByUID("09.03.21-17:51:10-STD-1.3.12.2.1107.5.3.7.20207"));
QDateTime seriesDate = series.DateTime;
series.PrintDetails();

/* get series by subjectID 12345, study number 2, and series number 15 */
squirrelSeries series = GetStudy(FindSeries("12345", 2, 15));
QString seriesProtocol = series.Protocol;
series.PrintDetails();

/* get an analysis by subject ID 12345, study 2, and analysis 'freesurfer' */
squirrelAnalysis GetAnalysis(FindAnalysis("12345", 2, "freesurfer"));

/* get other objects by their names */
squirrelDataDictionary dataDictionary = GetDataDictionary(FindDataDictionary("MyDataDict"));
squirrelExperiment experiment = GetExperiment(FindExperiment("MyExperiment"));
squirrelGroupAnalysis groupAnalysis = GetGroupAnalysis(FindGroupAnalysis("MyGroupAnalysis"));
squirrelPipeline pipeline = GetPipeline(FindPipeline("MyPipeline"));

How to modify existing objects in a package.

/* find a subject */

Experiments and Pipelines

Access to these objects is similar to accessing subjects

/* iterate by list to access copies of the objects(read only) */
foreach (squirrelExperiment exp, sqrl->experimentList) {
    cout << exp.experimentName << endl;
}
foreach (squirrelPipeline pipe, sqrl->pipelineList) {
    cout << pipe.pipelineName << endl;
}

/* iterate by index to change the original object (read/write) */
for (int i=0; i < sqrl->experimentList.size(); i++) {
    sqrl->experimentList[i].numFiles = 0;
}
for (int i=0; i < sqrl->pipelineList.size(); i++) {
    sqrl->pipelineList[i].numFiles = 0;
}

Writing

Create a new squirrel package and add a subject

squirrel *sqrl = new squirrel();

/* set the package details */
sqrl->name = "LotsOfData";
sqrl->description = "My First squirrel package;
sqrl->datetime = QDateTime()::currentDateTime();
sqrl->subjectDirFormat = "orig";
sqrl->studyDirFormat = "orig";
sqrl->seriesDirFormat = "orig;
sqrl->dataFormat = "nifti";

/* create a subject */
squirrelSubject sqrlSubject;
sqrlSubject.ID = "123456";
sqrlSubject.alternateIDs = QString("Alt1, 023043").split(",");
sqrlSubject.GUID = "NDAR12345678";
sqrlSubject.dateOfBirth.fromString("2000-01-01", "yyyy-MM-dd");
sqrlSubject.sex = "O";
sqrlSubject.gender = "O";
sqrlSubject.ethnicity1 = subjectInfo->GetValue("ethnicity1");
sqrlSubject.ethnicity2 = subjectInfo->GetValue("ethnicity2");

/* add the subject. This subject has only demographics, there are no studies or  */
sqrl->addSubject(sqrlSubject);

Add a study to existing subject

/* see if we can find a subject by ID */
int subjIndex = sqrl->GetSubjectIndex("123456");
if (subjIndex >= 0) {

    /* build the study object */
    squirrelStudy sqrlStudy;
    sqrlStudy.number = 1;
    sqrlStudy.dateTime.fromString("2023-06-19 15:34:56", "yyyy-MM-dd hh:mm:ss");
    sqrlStudy.ageAtStudy = 34.5;
    sqrlStudy.height = 1.5; // meters
    sqrlStudy.weight = 75.9; // kg
    sqrlStudy.modality = "MR";
    sqrlStudy.description = "MJ and driving";
    sqrlStudy.studyUID = "";
    sqrlStudy.visitType = "FirstVisit";
    sqrlStudy.dayNumber = 1;
    sqrlStudy.timePoint = 1;
    sqrlStudy.equipment = "Siemens 3T Prisma;
    
    sqrl->subjectList[subjIndex].addStudy(sqrlStudy);
}
else {
    cout << "Unable to find subject by ID [123456]" << endl;
}

Write package

QString outdir = "/home/squirrel/thedata" /* output directory of the squirrel package */
QString zippath; /* the full filepath of the written zip file */

sqrl->write(outdir, zippath);++

data

JSON object

This data object contains information about the subjects, and potential future data.

JSON variables

Variable
Type
Default
Description

GroupAnalysisCount

number

Number of group analyses.

SubjectCount

number

Number of subjects in the package.

JSON array

Array containing the subjects.

JSON array

Array containing group analyses.

Directory structure

Files associated with this section are stored in the following directory, but actual binary data should be stored in the subjects or group-analysis sub directories.

/data

Computed (squirrel writer/reader should handle these variables)

🟡
🟡
🟡
subjects
group-analysis

Package root

JSON object

The package root contains all data and files for the package. The JSON root contains all JSON objects for the package.

JSON variables

Variable
Type
Default
Description

JSON object

Package information.

JSON object

Raw and analyzed data.

JSON object

Methods used to analyze the data.

JSON object

Experimental methods used to collect the data.

JSON object

Data dictionary containing descriptions, mappings, and key/value information for any variables in the package.

NumPipelines

number

Number of pipelines.

NumExperiments

number

Number of experiments.

TotalFileCount

number

Total number of data files in the package, excluding .json files.

TotalSize

number

Total size, in bytes, of the data files.

Directory structure

Files associated with this object are stored in the following directory.

/

Computed (squirrel writer/reader should handles these variables)

🟡
🟡
🟡
🟡
🟡
package
data
pipelines
experiments
data-dictionary

series

JSON array

An array of series. Basic series information is stored in the main squirrel.json file. Extended information including series parameters such as DICOM tags are stored in a params.json file in the series directory.

JSON variables

Variable
Type
Default
Description

BidsEntity

string

BidsSuffix

string

BIDS suffix

BIDSTask

string

BIDS Task name

BIDSRun

number

BIDS run number

BIDSPhaseEncodingDirection

string

BIDS PE direction

Description

string

Description of the series

ExperimentName

string

Protocol

string

Protocol name

Run

number

The run identifies order of acquisition in cases of multiple identical series.

SeriesDatetime

date

Date of the series, usually taken from the DICOM header

SeriesNumber

number

Series number. May be sequential, correspond to NiDB assigned series number, or taken from DICOM header

SeriesUID

string

From the SeriesUID DICOM tag

BehavioralFileCount

number

Total number of beh files (including files in subdirs)

BehavioralSize

number

Size of beh data, in bytes

FileCount

number

Total number of files (including files in subdirs)

Size

number

Size of the data, in bytes

JSON file

data/subjectID/studyNum/seriesNum/params.json

JSON object

Directory structure

Files associated with this section are stored in the following directory. subjectID, studyNum, seriesNum are the actual subject ID, study number, and series number. For example /data/S1234ABC/1/1.

/data/<SubjectID>/<StudyNum>/<SeriesNum>

Behavioral data is stored in

/data/<SubjectID>/<StudyNum>/<SeriesNum>/beh

Primary key Required Computed (squirrel writer/reader should handle these variables)

entity (anat, fmri, dwi, etc)

Experiment name associated with this series. Experiments link to the section of the squirrel package

🔵
🔴
🟡

Example package

Package contents (file and directory structure)

/
/squirrel.json
/data
/data/6028
/data/6028/1
/data/6028/1/1
/data/6028/1/1/6028_1_1_00001.nii.gz
/data/6028/1/2
/data/6028/1/2/6028_1_2_00001.nii.gz
/data/6028/1/3
/data/6028/1/3/6028_1_3_00001.nii.gz
/data/6028/1/4
/data/6028/1/4/6028_1_4_00001.nii.gz

... <break> ...

/data/7998/1/11
/data/7998/1/11/7998_1_11_00001.nii.gz
/data/7998/1/12
/data/7998/1/12/7998_1_12_00001.nii.gz

squirrel.json

{
    "TotalFileCount": 3342,
    "TotalSize": 25072523595,
    "data": {
        "SubjectCount": 217,
        "subjects": [
            {
                "AlternateIDs": [
                    ""
                ],
                "DateOfBirth": "",
                "Ethnicity1": "nothispanic",
                "Ethnicity2": "black",
                "GUID": "",
                "Gender": "F",
                "Notes": "",
                "Sex": "F",
                "StudyCount": 1,
                "SubjectID": "6028",
                "VirtualPath": "data/6028",
                "studies": [
                    {
                        "AgeAtStudy": 0,
                        "DayNumber": 0,
                        "Description": "Scan",
                        "Equipment": "MR-101",
                        "Height": 0,
                        "Modality": "MR",
                        "Notes": "",
                        "SeriesCount": 11,
                        "StudyDatetime": "2012-02-13 12:54:05",
                        "StudyNumber": 1,
                        "StudyUID": "",
                        "TimePoint": 0,
                        "VirtualPath": "data/6028/1",
                        "VisitType": "",
                        "Weight": 96.6151871001,
                        "series": [
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "localizer",
                                "FileCount": 2,
                                "Protocol": "localizer",
                                "Run": 1,
                                "SequenceNumber": 1,
                                "SeriesDatetime": "2012-02-13 12:54:37",
                                "SeriesNumber": 1,
                                "SeriesUID": "",
                                "Size": 57512,
                                "VirtualPath": "data/6028/1/1"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "ep2d_REST210",
                                "FileCount": 1,
                                "Protocol": "ep2d_REST210",
                                "Run": 1,
                                "SequenceNumber": 2,
                                "SeriesDatetime": "2012-02-13 12:55:47",
                                "SeriesNumber": 3,
                                "SeriesUID": "",
                                "Size": 27891631,
                                "VirtualPath": "data/6028/1/3"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "bas_MoCoSeries",
                                "FileCount": 1,
                                "Protocol": "ep2d_REST210",
                                "Run": 1,
                                "SequenceNumber": 3,
                                "SeriesDatetime": "2012-02-13 12:55:47",
                                "SeriesNumber": 4,
                                "SeriesUID": "",
                                "Size": 27951359,
                                "VirtualPath": "data/6028/1/4"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "intermediate t-Map",
                                "FileCount": 1,
                                "Protocol": "ep2d_REST210",
                                "Run": 1,
                                "SequenceNumber": 4,
                                "SeriesDatetime": "2012-02-13 12:56:20",
                                "SeriesNumber": 5,
                                "SeriesUID": "",
                                "Size": 28907911,
                                "VirtualPath": "data/6028/1/5"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "Mean_&_t-Maps",
                                "FileCount": 1,
                                "Protocol": "ep2d_REST210",
                                "Run": 1,
                                "SequenceNumber": 5,
                                "SeriesDatetime": "2012-02-13 13:01:47",
                                "SeriesNumber": 8,
                                "SeriesUID": "",
                                "Size": 234775,
                                "VirtualPath": "data/6028/1/8"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "MPRAGE",
                                "FileCount": 2,
                                "Protocol": "MPRAGE",
                                "Run": 1,
                                "SequenceNumber": 6,
                                "SeriesDatetime": "2012-02-13 13:11:32",
                                "SeriesNumber": 9,
                                "SeriesUID": "",
                                "Size": 21844580,
                                "VirtualPath": "data/6028/1/9"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "MPRAGE_repeat",
                                "FileCount": 2,
                                "Protocol": "MPRAGE_repeat",
                                "Run": 1,
                                "SequenceNumber": 7,
                                "SeriesDatetime": "2012-02-13 13:21:35",
                                "SeriesNumber": 10,
                                "SeriesUID": "",
                                "Size": 21587804,
                                "VirtualPath": "data/6028/1/10"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "MPRAGE",
                                "FileCount": 2,
                                "Protocol": "MPRAGE",
                                "Run": 1,
                                "SequenceNumber": 8,
                                "SeriesDatetime": "2012-02-13 13:31:08",
                                "SeriesNumber": 11,
                                "SeriesUID": "",
                                "Size": 21621118,
                                "VirtualPath": "data/6028/1/11"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "B1-Callibration Head",
                                "FileCount": 2,
                                "Protocol": "B1-Callibration Head",
                                "Run": 1,
                                "SequenceNumber": 9,
                                "SeriesDatetime": "2012-02-13 13:32:00",
                                "SeriesNumber": 12,
                                "SeriesUID": "",
                                "Size": 2223871,
                                "VirtualPath": "data/6028/1/12"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "B1-Calibration Body",
                                "FileCount": 2,
                                "Protocol": "B1-Calibration Body",
                                "Run": 1,
                                "SequenceNumber": 10,
                                "SeriesDatetime": "2012-02-13 13:33:32",
                                "SeriesNumber": 13,
                                "SeriesUID": "",
                                "Size": 3048390,
                                "VirtualPath": "data/6028/1/13"
                            },
                            {
                                "BIDSEntity": "",
                                "BIDSPhaseEncodingDirection": "",
                                "BIDSRun": "",
                                "BIDSSuffix": "",
                                "BIDSTask": "",
                                "BehavioralFileCount": 0,
                                "BehavioralSize": 0,
                                "Description": "Axial PD-T2 TSE",
                                "FileCount": 3,
                                "Protocol": "Axial PD-T2 TSE",
                                "Run": 1,
                                "SequenceNumber": 11,
                                "SeriesDatetime": "2012-02-13 13:35:29",
                                "SeriesNumber": 14,
                                "SeriesUID": "",
                                "Size": 9712437,
                                "VirtualPath": "data/6028/1/14"
                            }
                        ]
                    }
                ]
            },
            
... <break> ...

    },
    "package": {
        "Changes": "",
        "DataFormat": "nifti4dgz",
        "Datetime": "2025-03-11 17:24:26",
        "Description": "MR data from the major city site for the large project",
        "License": "",
        "Notes": "",
        "PackageFormat": "nifti4dgz",
        "PackageName": "Large dataset from major city",
        "Readme": "",
        "SeriesDirectoryFormat": "orig",
        "SquirrelBuild": "2025.2.350",
        "SquirrelVersion": "1.0",
        "StudyDirectoryFormat": "orig",
        "SubjectDirectoryFormat": "orig"
    }
}

Squirrel data sharing format

The squirrel data format allows sharing of all information necessary to recreate an experiment and its results, from raw to analyzed data, and experiment parameters to analysis pipelines.

The squirrel format specification is implemented in NiDB. A DICOM-to-squirrel converter, and squirrel validator are available.

🔴
🔴
🔴
🔵
🟡
🟡
🟡
🟡
BIDS
experiments
params
analysis

squirrel utilities

The squirrel command line program

The squirrel command line program allows converstion of DICOM to squirrel, BIDS to squirrel, modification of existing squirrel packages, and listing of information from packages.

Installing squirrel utilities

sudo yum localinstall --nogpgcheck squirrel-xxx.xx.xxx-1.elx.x86_64.rpm
sudo apt install p7zip # p7zip required by squirrel
sudo dpkg -i squirrel_xxxx.xx.xxx.deb

Too many open files error

If you encounter an error "too many open files", or you are unable to write squirrel packages, try increasing the open files limit within Linux

# increase open file limit (temporarily for the current session)
ulimit -n 2048

# increase open file limit (permanently)
# append these lines to /etc/security/limits.conf
*               soft    nofile            2048
*               hard    nofile            2048

Basic Command Line Usage

Convert DICOM to squirrel

# Default DICOM to squirrel conversion
squirrel dicom2squirrel /path/to/dicoms outPackgeName.sqrl

# Specify the output format
squirrel dicom2squirrel /path/to/dicoms outPackge.sqrl --dataformat niti4gz

# Specify the package directory format
squirrel dicom2squirrel /path/to/dicoms outPackage.sqrl --dirformat seq

Convert BIDS to squirrel

squirrel bids2squirrel /path/to/bids outPackage.sqrl

Modify existing squirrel package

# add a subject to a package
squirrel modify /path/to/package.sqrl --add subject --datapath /path/to/new/data --objectdata 'SubjectID=S1234ABC&DateOfBorth=199-12-31&Sex=M&Gender=M'

# remove a study (remove study 1 from subject S1234ABC)
squirrel modify /path/to/package.sqrl --remove study --subjectid S1234ABC --objectid 1

List information about a squirrel package

#list package information
[user@hostname]$ squirrel info ~/testing.sqrl
Squirrel Package: /home/nidb/testing.sqrl
  DataFormat: orig
  Date: Thu May 23 16:16:16 2024
  Description: Dataset description
  DirectoryFormat (subject, study, series): orig, orig, orig
  FileMode: ExistingPackage
  Files:
    314 files
    19181701506 bytes (unzipped)
  PackageName: Squirrel package
  SquirrelBuild: 2024.5.218
  SquirrelVersion: 1.0
  Objects:
    ├── 8 subjects
    │  ├── 8 measures
    │  ├── 0 drugs
    │  ├── 11 studies
    │  ├──── 314 series
    │  └──── 0 analyses
    ├── 0 experiments
    ├── 0 pipelines
    ├── 0 group analyses
    └── 0 data dictionary
    
# list subjects
[user@hostname]$ squirrel info ~/testing.sqrl --object subject
Subjects: sub-ASDS3050KAE sub-ASDS6316BWH sub-ASDS6634GJK sub-ASDS7478SKA sub-ASDS8498GQDCBT sub-HCS8276XPS sub-S4328FSC sub-S7508DDH

# list studies for a specific subject
[user@hostname]$ squirrel info ~/testing.sqrl --object study --subjectid sub-ASDS3050KAE
Studies: 1 2

#list all subjects as CSV format
[user@hostname]$ squirrel info ~/testing.sqrl --object subject --csv
ID, AlternateIDs, DateOfBirth, Ethnicity1, Ethnicity2, GUID, Gender, Sex
"sub-ASDS3050KAE","","","","","","U","U"
"sub-ASDS6316BWH","","","","","","U","U"
"sub-ASDS6634GJK","","","","","","U","U"
"sub-ASDS7478SKA","","","","","","U","U"
"sub-ASDS8498GQDCBT","","","","","","U","U"
"sub-HCS8276XPS","","","","","","U","U"
"sub-S4328FSC","","","","","","",""
"sub-S7508DDH","","","","","","",""

package

JSON object

This object contains information about the squirrel package.

JSON variables

Variable
Type
Default
Description

Changes

string

Any CHANGE files.

DataFormat

string

orig

Data format for imaging data to be written. Squirrel should attempt to convert to the specified format if possible. orig, anon, anonfull, nifti3d, nifti3dgz, nifti4d, nifti4dgz (see details below).

Datetime

datetime

Datetime the package was created.

Description

string

Longer description of the package.

License

string

Any sharing or license notes, or LICENSE files.

NiDBVersion

string

The NiDB version which wrote the package.

Notes

JSON object

See details below.

PackageName

string

Short name of the package.

PackageFormat

string

squirrel

Always squirrel.

Readme

string

Any README files.

SeriesDirectoryFormat

string

orig

orig, seq (see details below).

SquirrelVersion

string

Squirrel format version.

SquirrelBuild

string

Build version of the squirrel library and utilities.

StudyDirectoryFormat

string

orig

orig, seq (see details below).

SubjectDirectoryFormat

string

orig

orig, seq (see details below).

Variable options

subjectDirFormat, studyDirFormat, seriesDirFormat

  • orig - Original subject, study, series directory structure format. Example S1234ABC/1/1

  • seq - Sequential. Zero-padded sequential numbers. Example 00001/0001/00001

dataFormat

  • nifti3d - Nifti 3D format

    • Example file001.nii, file002.nii, file003.nii

  • nifti3dgz - gzipped Nifti 3D format

    • Example file001.nii.gz, file002.nii.gz, file003.nii.gz

  • nifti4d - Nifti 4D format

    • Example file.nii

  • nifti4dgz - gzipped Nifti 4D format

    • Example file.nii.gz

Notes

Notes about the package are stored here. This includes import and export logs, and notes from imported files. This is generally a freeform object, but notes can be divided into sections.

Section
Description

import

Any notes related to import. BIDS files such as README and CHANGES are stored here.

merge

Any notes related to the merging of datasets. Such as information about renumbering of subject IDs

export

Any notes related to the export process

Directory structure

Files associated with this section are stored in the following directory

/

params

Separate JSON file - params.json

Series collection parameters are stored in a separate JSON file called params.json stored in the series directory. The JSON object is an array of key-value pairs. This can be used to store data collection parameters.

JSON variables

Variable
Description
Example

{Key:Value}

A unique key, sometimes derived from the DICOM header

Protocol, T1w FieldStrength, 3.0

Directory structure

Files associated with this section are stored in the following directory. subjectID, studyNum, seriesNum are the actual subject ID, study number, and series number. For example /data/S1234ABC/1/1.

/data/<SubjectID>/<StudyNum>/<SeriesNum>/params.json

observations

JSON array

Observations are collected from a participant in response to an experiment.

JSON variables

Variable
Type
Default
Description

DateEnd

datetime

End datetime of the observation.

DateRecordCreate

datetime

Date the record was created in the current database. The original record may have been imported from another database.

DateRecordEntry

datetime

Date the record was first entered into a database.

DateRecordModify

datetime

Date the record was modified in the current database.

DateStart

datetime

Start datetime of the observation.

Description

string

Longer description of the measure.

Duration

number

Duration of the measure in seconds, if known.

InstrumentName

string

Name of the instrument associated with this measure.

ObservationName

string

Name of the observation.

Notes

string

Detailed notes.

Rater

string

Name of the rater.

Value

string

Value (string or number).

studies

JSON array

An array of imaging studies, with information about each study. An imaging study (or imaging session) is defined as a set of related series collected on a piece of equipment during a time period. An example is a research participant receiving an MRI exam. The participant goes into the scanner, has several MR images collected, and comes out. The time spent in the scanner and all of the data collected from it is considered to be a study.

JSON variables

Directory structure

Files associated with this section are stored in the following directory. SubjectID and StudyNum are the actual subject ID and study number, for example /data/S1234ABC/1.

/data/<SubjectID>/<StudyNum>

Download squirrel from

Primary key Required

orig - Original, raw data format. If the original format was DICOM, the output format should be DICOM. See for details.

anon - If original format is DICOM, write anonymized DICOM, removing most PHI, except dates. See for details.

anonfull - If original format is DICOM, the files will be fully anonymized, by removing dates, times, locations in addition to PHI. See for details.

All DICOM tags are acceptable parameters. See this list for available DICOM tags . Variable keys can be either the hexadecimal format (ID) or string format (Name). For example 0018:1030 or ProtocolName. The params object contains any number of key/value pairs.

Primary key Required

Valid squirrel modalities are derived from the DICOM standard and from NiDB modalities. Modality can be any string, but some squirrel readers may not correctly interpret the modality or may convert it to “other” or “unknown”. See full list of .

Primary key Required Computed (squirrel writer/reader should handle these variables)

Variable
Type
Default
Description
🔵
🔴
🔵
🔴
https://github.com/gbook/squirrel/releases
DICOM anonymization levels
DICOM anonymization levels
DICOM anonymization levels
https://exiftool.org/TagNames/DICOM.html
🔴
🔴
🔵
🔴
🔴
🔵
🔴
🔵
🔴
🟡
modalities

AgeAtStudy

number

Subject’s age in years at the time of the study.

Datetime

datetime

Date of the study.

DayNumber

number

For repeated studies and clinical trials, this indicates the day number of this study in relation to time 0.

Description

string

Study description.

Equipment

string

Equipment name, on which the imaging session was collected.

Height

number

Height in meters of the subject at the time of the study.

Modality

string

Notes

string

Any notes about the study

StudyNumber

number

Study number. May be sequential or correspond to NiDB assigned study number.

StudyUID

string

DICOM field StudyUID.

TimePoint

number

Similar to day number, but this should be an ordinal number.

VisitType

string

Type of visit. ex: Pre, Post.

Weight

number

Weight in kilograms of the subject at the time of the study.

AnalysisCount

number

Number of analyses for this study.

SeriesCount

number

Number of series for this study.

VirtualPath

string

Relative path to the data within the package.

JSON array

Array of series.

JSON array

Array of analyses.

subjects

JSON array

This object is an array of subjects, with information about each subject.

JSON variables

Variable
Type
Default
Description (and possible values)

AlternateIDs

JSON array

List of alternate IDs. Comma separated.

DateOfBirth

date

Subject’s date of birth. Used to calculate age-at-study. Value can be YYYY-00-00 to store year only, or YYYY-MM-00 to store year and month only.

Gender

char

Gender.

GUID

string

Ethnicity1

string

NIH defined ethnicity: Usually hispanic, non-hispanic

Ethnicity2

string

NIH defined race: americanindian, asian, black, hispanic, islander, white

Notes

string

Notes about this subject

Sex

char

Sex at birth (F,M,O,U).

SubjectID

string

Unique ID of this subject. Each subject ID must be unique within the package.

InterventionCount

number

Number of intervention objects.

ObservationCount

number

Number of observation objects.

StudyCount

number

Number of studies.

VirtualPath

string

Relative path to the data within the package.

JSON array

Array of imaging studies/sessions.

JSON array

Array of observations.

JSON array

Array of interventions.

Directory structure

Files associated with this section are stored in the following directory

/data/<SubjectID>

interventions

JSON array

Interventions represent any substances or procedures administered to a participant; through a clinical trial or the participant’s use of prescription or recreational drugs. Detailed variables are available to record exactly how much and when a drug is administered. This allows searching by dose amount, or other variable.

JSON variables

Recording drug administration

The following examples convert between common language and the squirrel storage format

esomeprazole 20mg capsule by mouth daily

2 puffs atrovent inhaler every 6 hours

analysis

JSON array

Analysis results, run on an imaging study level. Can contain files, directories, and variables.

JSON variables

Defines the type of data. See table of supported .

Primary key Required Computed (squirrel writer/reader should handle these variables)

Globally unique identifier, from the NIMH Data Archive ().

Primary key Required

Variable
Type
Default
Description
Variable
Value
Variable
Value

Primary key Required Computed (squirrel writer/reader should handle these variables)

🔴
🔴
🔴
🔴
🔴
🔵
🟡
🟡
🟡
🔵
🔴
🟡
modalities
series
analyses

DrugClass

PPI

DrugName

esomeprazole

DoseAmount

20mg

DoseFrequency

daily

Route

oral

DoseUnit

mg

DrugName

ipratropium

DrugClass

bronchodilator

DoseAmount

2

DoseFrequency

every 6 hours

AdministrationRoute

inhaled

DoseUnit

puffs

🔴
🔴
🔴
🔵
🟡
🟡
🟡
🟡
🔵
🔴
🔵
🔴
🟡
NDA
studies
observations
interventions

AdministrationRoute

string

Drug entry route (oral, IV, unknown, etc).

DateRecordCreate

string

Date the record was created in the current database. The original record may have been imported from another database.

DateRecordEntry

string

Date the record was first entered into a database.

DateRecordModify

string

Date the record was modified in the current database.

DateEnd

datetime

Datetime the intervention was stopped.

DateStart

datetime

Datetime the intervention was started.

Description

string

Longer description.

DoseString

string

Full dosing string. Examples tylenol 325mg twice daily by mouth, or 5g marijuana inhaled by volcano

DoseAmount

number

In combination with other dose variables, the quantity of the drug.

DoseFrequency

string

Description of the frequency of administration.

DoseKey

string

For clinical trials, the dose key.

DoseUnit

string

mg, g, ml, tablets, capsules, etc.

InterventionClass

string

Drug class.

InterventionName

string

Name of the intervention.

Notes

string

Notes about drug.

Rater

string

Rater/experimenter name.

Variable

Type

Default

Description

DateStart

date

Datetime of the start of the analysis.

DateEnd

date

Datetime of the end of the analysis.

DateClusterStart

date

Datetime the job began running on the cluster.

DateClusterEnd

date

Datetime the job finished running on the cluster.

Hostname

string

If run on a cluster, the hostname of the node on which the analysis run.

PipelineName

string

Name of the pipeline used to generate these results.

PipelineVersion

number

1

Version of the pipeline used.

RunTime

number

0

Elapsed wall time, in seconds, to run the analysis after setup.

SeriesCount

number

0

Number of series downloaded/used to perform analysis.

SetupTime

number

0

Elapsed wall time, in seconds, to copy data and set up analysis.

Status

string

Status, should always be ‘complete’.

StatusMessage

string

Last running status message.

Successful

bool

Analysis ran to completion without error and expected files were created.

Size

number

Size in bytes of the analysis.

VirtualPath

string

Relative path to the data within the package.

group-analysis

JSON array

This object is an array of group analyses. A group analysis is considered an analysis involving more than one subject.

JSON variables

Variable
Type
Default
Description

Datetime

datetime

Datetime of the group analysis.

Description

string

Description.

GroupAnalysisName

string

Name of this group analysis.

Notes

string

Notes about the group analysis.

FileCount

number

Number of files in the group analysis.

Size

number

Size in bytes of the analysis.

VirtualPath

string

Path to the group analysis data within the squirrel package.

Directory structure

Files associated with this section are stored in the following directory, where <GroupAnalysisName> is the name of the analysis.

/group-analysis/<GroupAnalysisName>/

pipelines

JSON array

Pipelines are the methods used to analyze data after it has been collected. In other words, the experiment provides the methods to collect the data and the pipelines provide the methods to analyze the data once it has been collected.

JSON Variables

Variable
Type
Default
Description

ClusterType

string

Compute cluster engine (sge or slurm).

ClusterUser

string

Submit username.

ClusterQueue

string

Queue to submit jobs.

ClusterSubmitHost

string

Hostname to submit jobs.

CompleteFiles

JSON array

JSON array of complete files, with relative paths to analysisroot.

CreateDate

datetime

Date the pipeline was created.

DataCopyMethod

string

How the data is copied to the analysis directory: cp, softlink, hardlink.

DependencyDirectory

string

DependencyLevel

string

DependencyLinkType

string

Description

string

Longer pipeline description.

DirectoryStructure

string

Directory

string

Directory where the analyses for this pipeline will be stored. Leave blank to use the default location.

Group

string

ID or name of a group on which this pipeline will run

GroupType

string

Either subject or study

Level

number

subject-level analysis (1) or group-level analysis (2).

MaxWallTime

number

Maximum allowed clock (wall) time in minutes for the analysis to run.

ClusterMemory

number

Amount of memory in GB requested for a running job.

PipelineName

string

Pipeline name.

Notes

string

Extended notes about the pipeline

NumberConcurrentAnalyses

number

1

Number of analyses allowed to run at the same time. This number if managed by NiDB and is different than grid engine queue size.

ClusterNumberCores

number

1

Number of CPU cores requested for a running job.

ParentPipelines

string

Comma separated list of parent pipelines.

ResultScript

string

Executable script to be run at completion of the analysis to find and insert results back into NiDB.

SubmitDelay

number

Delay in hours, after the study datetime, to submit to the cluster. Allows time to upload behavioral data.

TempDirectory

string

The path to a temporary directory if it is used, on a compute node.

UseProfile

bool

true if using the profile option, false otherwise.

UseTempDirectory

bool

true if using a temporary directory, false otherwise.

Version

number

1

Version of the pipeline.

PrimaryScript

string

SecondaryScript

string

DataStepCount

number

Number of data steps.

VirtualPath

string

Path of this pipeline within the squirrel package.

JSON array

Directory structure

Files associated with this section are stored in the following directory. PipelineName is the unique name of the pipeline.

/pipelines/<PipelineName>

experiments

JSON array

Experiments describe how data was collected from the participant. In other words, the methods used to get the data. This does not describe how to analyze the data once it’s collected.

JSON variables

Variable
Type
Default
Description

ExperimentName

string

Unique name of the experiment.

FileCount

number

Number of files contained in the experiment.

Size

number

Size, in bytes, of the experiment files.

VirtualPath

string

Path to the experiment within the squirrel package.

Directory structure

Files associated with this section are stored in the following directory. Where ExperimentName is the unique name of the experiment.

/experiments/<ExperimentName>

data-dictionary

JSON object

The data-dictionary object stores information describing mappings or any other descriptive information about the data. This can also contain any information that doesn't fit elsewhere in the squirrel package, such as project descriptions.

Examples include mapping numeric values (1,2,3,...) to descriptions (F, M, O, ...)

JSON variables

data-dictionary

Variable
Type
Default
Description

DataDictionaryName

string

Name of this data dictionary.

NumFiles

number

Number of files contained in the experiment.

Size

number

Size, in bytes, of the experiment files.

VirtualPath

string

Path to the data-dictionary within the squirrel package.

data-dictionary-item

JSON array

Array of data dictionary items. See next table.

data-dictionary-item

Variable
Type
Default
Description

VariableType

string

Type of variable.

VariableName

string

Name of the variable.

Description

string

Description of the variable.

KeyValueMapping

string

List of possible key/value mappings in the format key1=value1, key2=value2. Example 1=Female, 2=Male

ExpectedTimepoints

number

Number of expected timepoints. Example, the study is expected to have 5 records of a variable.

RangeLow

number

For numeric values, the lower limit.

RangeHigh

number

For numeric values, the upper limit.

Directory structure

Files associated with this section are stored in the following directory.

/data-dictionary

Building Python Wrapper

How to build a Python wrapper for the squirrel library

Prerequisites

On RHEL8 Linux

Create the wrapper

data-steps

JSON array

dataSpec describes the criteria used to find data if searching a database (NiDB for example, since this pipeline is usually connected to a database). The dataSpec is a JSON array of the following variables. Search variables specify how to find data in a database, and Export variables specify how the data is exported.

JSON variables

Modalities

This is a list of common modalities available within squirrel. However, squirrel does not restrict modality codes, so any modality could be used in a dataset.

Pipeline scripts

Details about how pipeline scripts are formatted for squirrel and NiDB

Pipeline scripts are meant to run in bash. They are traditionally formatted to run with a RHEL distribution such as CentOS or Rocky Linux. The scripts are bash compliant, but have some nuances that allow them to run more effectively under an NiDB pipeline setup.

The bash script is interpreted to run on a cluster. Some commands are added to your script to allow it to check in and give status to NiDB as it is running.

The script

Example script...

Before being submitted to the cluster, the script is passed through the NiDB interpreter, and the actual bash script will look like below. This script is running on subject S2907GCS, study 8, under the freesurferUnified6 pipeline. This script will then be submitted to the cluster.

... script is submitted to the cluster

How to interpret the altered script

  1. Details for the grid engine are added at the beginning

    • This includes max wall time, output directories, run-as user, etc

  2. Each command is changed to include logging and check-ins

    • nidb cluster -u pipelinecheckin checks in to the database the current step. This is displayed on the Pipelines --> Analysis webpage

    • Each command is also echoed to the grid engine log file so you can check the log file for the status

    • The output of each command is echoed to a separate log file in the last line using the >>

Pipeline Variables

There are a few pipeline variables that are interpreted by NiDB when running. The variable is replaced with the value before the final script is written out. Each study on which a pipeline runs will have a different script, with different paths, IDs, and other variables listed below.

Primary key Required Computed (squirrel writer/reader should handle these variables)

Primary key Required Computed (squirrel writer/reader should handle these variables)

See details of

See details of .

See

Primary key Required Computed (squirrel writer/reader should handle these variables)

Primary key Required Computed (squirrel writer/reader should handle these variables)

Primary key Required

Variable
Type
Default
Description
Modality Code
Description
DICOM Standard

There is no need for a at the beginning (for example #!/bin/sh) because this script is only interested in the commands being run.

Variable
Description
🔴
🔴
🔴
🔵
🔴
🔴
🔵
🟡
🟡
🔵
🔴
🟡
🔵
🔴
🟡
🔵
🔴
🟡
🔵
🔴
🟡
sudo yum install swig python3-devel
swig -python gfg.i
gcc -c -fpic squirrel_wrap.c squirrel.cpp -I/usr/include/python3.6m

AR

Autorefraction

ASMT

Content Assessment Results

AU

Audio

AUDIO

Audio

BDUS

Bone Densitometry (ultrasound)

BI

Biomagnetic Imaging

BMD

Bone Densitometry (X-ray)

CONSENT

Scanned image of a consent form

CR

Computed Radiography

CT

Computed Tomography

CTPROTOCOL

CT Protocol (Performed)

DG

Diaphanography

DOC

Document

DX

Digital Radiography

ECG

Electrocardiography

EEG

Electroencephelograhy

EPS

Cardiac Electrophysiology

ES

Endoscopy

ET

Eye tracking

FID

Fiducials

GM

General Microscopy

GSR

Galvanic skin response

HC

Hard Copy

HD

Hemodynamic Waveform

IO

Intra-Oral Radiography

IOL

Intraocular Lens Data

IVOCT

Intravascular Optical Coherence Tomography

IVUS

Intravascular Ultrasound

KER

Keratometry

KO

Key Object Selection

LEN

Lensometry

LS

Laser Surface Scan

MEG

Magnetoencephalography

MG

Mammography

MR

Magnetic Resonance

M3D

Model for 3D Manufacturing

NM

Nuclear Medicine

OAM

Ophthalmic Axial Measurements

OCT

Optical Coherence Tomography (non-Ophthalmic)

OP

Ophthalmic Photography

OPT

Ophthalmic Tomography

OPTBSV

Ophthalmic Tomography B-scan Volume Analysis

OPTENF

Ophthalmic Tomography En Face

OPV

Ophthalmic Visual Field

OSS

Optical Surface Scan

OT

Other

PLAN

Plan

PR

Presentation State

PT

Positron Emission Tomography (PET)

PX

Panoramic X-Ray

REG

Registration

RESP

Respiratory Waveform

RF

Radio Fluoroscopy

RG

Radiographic Imaging (conventional film/screen)

RTDOSE

Radiotherapy Dose

RTIMAGE

Radiotherapy Image

RTINTENT

Radiotherapy Intent

RTPLAN

Radiotherapy Plan

RTRAD

RT Radiation

RTRECORD

RT Treatment Record

RTSEGANN

Radiotherapy Segment Annotation

RTSTRUCT

Radiotherapy Structure Set

RWV

Real World Value Map

SEG

Segmentation

SM

Slide Microscopy

SMR

Stereometric Relationship

SR

Structured reporting (SR) Document

SRF

Subjective Refraction

STAIN

Automated Slide Stainer

SURGERY

Pre-surgical mapping plan

TG

Thermography

US

Ultrasound

VA

Visual Acuity

VIDEO

Video

XA

X-Ray Angiography

XC

External-camera Photography

export FREESURFER_HOME=/opt/freesurfer-6.0     #  The Freesurfer home directory (version) you want to use
export FSFAST_HOME=/opt/freesurfer-6.0/fsfast     #  Not sure if these next two are needed but keep them just in case
export MNI_DIR=/opt/freesurfer-6.0/mni     #  Not sure if these next two are needed but keep them just in case
source $FREESURFER_HOME/SetUpFreeSurfer.sh     #  MGH's shell script that sets up Freesurfer to run
export SUBJECTS_DIR={analysisrootdir}     #  Point to the subject directory you plan to use - all FS data will go there
freesurfer > {analysisrootdir}/version.txt     # {NOLOG} get the freesurfer version
perl /opt/pipeline/ImportFreesurferData.pl {analysisrootdir}/data analysis     #  import data. the perl program allows importing of multiple T1s
recon-all -hippocampal-subfields-T1 -no-isrunning -all -notal-check -subjid analysis     #  Autorecon all {PROFILE}
if tail -n 1 {analysisrootdir}/analysis/scripts/recon-all-status.log | grep 'finished without error' ; then touch {analysisrootdir}/reconallsuccess.txt; fi     # {NOLOG} {NOCHECKIN}
recon-all -subjid analysis -qcache     #  do the qcache step {PROFILE}
#!/bin/sh
#$ -N freesurferUnified6
#$ -S /bin/bash
#$ -j y
#$ -o /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/
#$ -V
#$ -u onrc
#$ -l h_rt=72:00:00
LD_LIBRARY_PATH=/opt/pipeline/nidb/; export LD_LIBRARY_PATH;
echo Hostname: `hostname`
echo Username: `whoami`

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s started -m 'Cluster processing started'
cd /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6;

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 1 of 10'
# The Freesurfer home directory (version) you want to use
echo Running export FREESURFER_HOME=/opt/freesurfer-6.0
export FREESURFER_HOME=/opt/freesurfer-6.0 >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step1

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 2 of 10'
# Not sure if these next two are needed but keep them just in case
echo Running export FSFAST_HOME=/opt/freesurfer-6.0/fsfast
export FSFAST_HOME=/opt/freesurfer-6.0/fsfast >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step2

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 3 of 10'
# Not sure if these next two are needed but keep them just in case
echo Running export MNI_DIR=/opt/freesurfer-6.0/mni
export MNI_DIR=/opt/freesurfer-6.0/mni >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step3

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 4 of 10'
# MGH's shell script that sets up Freesurfer to run
echo Running source $FREESURFER_HOME/SetUpFreeSurfer.sh
source $FREESURFER_HOME/SetUpFreeSurfer.sh >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step4

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 5 of 10'
# Point to the subject directory you plan to use - all FS data will go there
echo Running export SUBJECTS_DIR=/home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6
export SUBJECTS_DIR=/home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6 >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step5

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 6 of 10'
# get the freesurfer version
echo Running freesurfer > /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/version.txt
freesurfer > /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/version.txt

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 7 of 10'
# import data. the perl program allows importing of multiple T1s
echo Running perl /opt/pipeline/ImportFreesurferData.pl /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/data analysis
perl /opt/pipeline/ImportFreesurferData.pl /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/data analysis >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step7

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 8 of 10'
# Autorecon all {PROFILE}
echo Running recon-all -hippocampal-subfields-T1 -no-isrunning -all -notal-check -subjid analysis
/usr/bin/time -v recon-all -hippocampal-subfields-T1 -no-isrunning -all -notal-check -subjid analysis >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step8
if tail -n 1 /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/analysis/scripts/recon-all-status.log | grep 'finished without error' ; then touch /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/reconallsuccess.txt; fi

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 10 of 10'
# do the qcache step {PROFILE}
echo Running recon-all -subjid analysis -qcache
/usr/bin/time -v recon-all -subjid analysis -qcache >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step10

/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'Processing result script'
# Running result script
echo Running perl /opt/pipeline/ParseFreesurferResults.pl -r /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6 -p /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/analysis/stats -a 3151385     #  dump results back into ado2 > /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/stepResults.log 2>&1
perl /opt/pipeline/ParseFreesurferResults.pl -r /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6 -p /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/analysis/stats -a 3151385     #  dump results back into ado2 > /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/stepResults.log 2>&1
chmod -Rf 777 /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6
/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'Updating analysis files'
/opt/pipeline/nidb/nidb cluster -u updateanalysis -a 3151385
/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'Checking for completed files'
/opt/pipeline/nidb/nidb cluster -u checkcompleteanalysis -a 3151385
/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s complete -m 'Cluster processing complete'
chmod -Rf 777 /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6
#!/bin/sh
#$ -N freesurferUnified6
#$ -S /bin/bash
#$ -j y
#$ -o /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/
#$ -V
#$ -u onrc
#$ -l h_rt=72:00:00
/opt/pipeline/nidb/nidb cluster -u pipelinecheckin -a 3151385 -s processing -m 'processing step 1 of 10'
# The Freesurfer home directory (version) you want to use
echo Running export FREESURFER_HOME=/opt/freesurfer-6.0
export FREESURFER_HOME=/opt/freesurfer-6.0 >> /home/pipeline/onrc/data/pipeline/S2907GCS/8/freesurferUnified6/pipeline/Step1

{NOLOG}

This does not append >> to the end of a command to log the output

{NOCHECKIN}

This does not prepend a command with a check in, and does not echo the command being run. This is useful (necessary) when running multi-line commands like for loops and if/then statements

{PROFILE}

This prepends the command with a profiler to output information about CPU and memory usage.

{analysisrootdir}

The full path to the analysis root directory. ex /home/user/thePipeline/S1234ABC/1/

{subjectuid}

The UID of the subject being analyzed. Ex S1234ABC

{studynum}

The study number of the study being analyzed. ex 2

{uidstudynum}

UID and studynumber together. ex S1234ABC2

{pipelinename}

The pipeline name

{studydatetime}

The study datetime. ex 2022-07-04 12:34:56

{first_ext_file}

Replaces the variable with the first file (alphabetically) found with the ext extension

{first_n_ext_files}

Replaces the variable with the first N files (alphabetically) found with the ext extension

{last_ext_file}

Replaces the variable with the last file (alphabetically) found with the ext extension

{all_ext_files}

Replaces the variable with all files (alphabetically) found with the ext extension

{command}

The command being run. ex ls -l

{workingdir}

The current working directory

{description}

The description of the command. This is anything following the #, also called a comment

{analysisid}

The analysisID of the analysis. This is useful when inserting analysis results, as the analysisID is required to do that

{subjectuids}

[Second level analysis] List of subjectIDs

{studydatetimes}

[Second level analysis] List of studyDateTimes in the group

{analysisgroupid}

[Second level analysis] The analysisID

{uidstudynums}

[Second level analysis] List of UIDStudyNums

{numsubjects}

[Second level analysis] Total number of subjects in the group analysis

{groups}

[Second level analysis] List of group names contributing to the group analysis. Sometimes this can be used when comparing groups

{numsubjects_groupname}

[Second level analysis] Number of subjects within the specified groupname

{uidstudynums_groupname}

[Second level analysis] Number of studies within the specified groupname

🔴
🔵
🟡
🟡
🟡
🔴
🔴
🔴
🔵
🔴
🟡
🟡
🔴
🔵
🟡
🟡
🟡
🔴
🟡
🟡
🟡
🔴
🔴
🔵
🔵
🔴
pipeline scripts
pipeline scripts
data-steps
data specifications
shebang line

AssociationType

string

[Search] study, or subject.

BehavioralDirectory

string

[Export] if BehFormat writes data to a sub directory, the directory should be named this.

BehavioralDirectoryFormat

string

[Export] nobeh, behroot, behseries, behseriesdir

DataFormat

string

[Export] native, dicom, nifti3d, nifti4d, analyze3d, analyze4d, bids.

Enabled

bool

[Search] true if the step is enabled, false otherwise

Gzip

bool

[Export] true if converted Nift data should be g-zipped, false otherwise.

ImageType

string

[Search] Comma separated list of image types, often derived from the DICOM ImageType tag, (0008:0008).

DataLevel

string

[Search] nearestintime, samestudy. Where is the data coming from.

Location

string

[Export] Directory, relative to the analysisroot, where this data item will be written.

Modality

string

[Search] Modality to search for.

NumberBOLDreps

string

[Search] If SeriesCriteria is set to usecriteria, then search based on this option.

NumberImagesCriteria

string

[Search]

Optional

bool

[Search] true if this data step is option. false if this step is required and the analysis will not run if the data step is not found.

Order

number

The numerical order of this data step.

PreserveSeries

bool

[Export] true to preserve series numbers or false to assign new ordinal numbers.

PrimaryProtocol

bool

[Search] true if this data step determines the primary study, from which subsequent analyses are run.

Protocol

string

[Search] Comma separated list of protocol name(s).

SeriesCriteria

string

[Search] Criteria for which series are downloaded if more than one matches criteria: all, first, last, largest, smallest, usecriteria.

UsePhaseDirectory

bool

[Export] true to write data to a sub directory based on the phase encoding direction.

UseSeriesDirectory

bool

[Export] true to write each series to its own directory, false to write data to the root export directory.

Building squirrel library and utils

Overview

The following OS configurations have been tested to build squirrel with Qt 6.5

  • Compatible

    • RHEL compatible Linux 8 (not 8.6)

    • CentOS 8 (not CentOS 8 Stream)

    • CentOS 7

    • Windows 10/11

squirrel library and utils cannot be built on CentOS Stream 8 or Rocky Linux 8.6. There are kernel bugs which do not work correctly with Qt's QProcess library. This can lead to inconsistencies when running shell commands, and qmake build errors.

Other OS configurations may work to build squirrel, but have not been tested.

Prepare Build Environment

Building the squirrel Library

Once the build environment is setup, the build process can be performed by script. The build.sh script will build the squirrel library files and the squirrel utils.

The first time building squirrel on this machine, perform the following

cd ~
wget https://github.com/gbook/squirrel/archive/main.zip
unzip main.zip
mv squirrel-main squirrel
cd squirrel
./build.sh

This will build gdcm (squirrel depends on GDCM for reading DICOM headers), squirrel lib, and squirrel-gui.

All subsequent builds on this machine can be done with the following

cd ~/squirrel
./build.sh

  • Using Github Desktop, clone the squirrel repository to C:\squirrel

  • Build GDCM

    • Open CMake

    • Set source directory to C:\squirrel\src\gdcm

    • Set build directory to C:\squirrel\bin\gdcm

    • Click Configure (click Yes to create the build directory)

    • Select Visual Studio 16 2019. Click Finish

    • After it's done generating, make sure GDCM_BUILD_SHARED_LIBS is checked

    • Click Configure again

    • Click Generate. This will create the Visual Studio solution and project files

    • Open the C:\squirrel\bin\gdcm\GDCM.sln file in Visual Studio

    • Change the build to Release

    • Right-click ALL_BUILD and click Build

  • Build squirrel library

    • Double-click C:\squirrel\src\squirrel\squirrellib.pro

    • Configure the project for Qt 6.4.2 as necessary

    • Switch the build to Release and build it

    • squirrel.dll and squirrel.lib will now be in C:\squirrel\bin\squirrel

  • Build squirrel-gui

    • Configure the project for Qt 6.4.2 as necessary

    • Double-click C:\squirrel\src\squirrel-gui\squirrel-gui.pro

    • Switch the build to Release and build it

Contributing to the squirrel Library

Setting up a development environment

Once you've been granted access to the squirrel project on github, you'll need to add your server's SSH key to your github account (github.com --> click your username --> Settings --> SSH and GPG keys). There are directions on the github site for how to do this. Then you can clone the current source code into your server.

Cloning a new repository with SSH

cd ~
git clone git@github.com:gbook/squirrel.git squirrel

This will create a git repository called squirrel in your home directory.

Committing changes

cd ~/squirrel
git commit -am "Comments about the changes"
git push origin main

Updating your repository

To keep your local copy of the repository up to date, you'll need to pull any changes from github.

cd ~/squirrel
git pull origin main

Troubleshooting

Build freezes

This may happen if the build machine does not have enough RAM or processors. More likely this is happening inside of a VM in which the VM does not have enough RAM or processors allocated.

Build fails with "QMAKE_CXX.COMPILER_MACROS not defined"

This error happens because of a kernel bug in RHEL 8.6. Downgrade to 8.5 or upgrade to 8.7.

Library error

This example is from the nidb example. If you get an error similar to the following, you'll need to install the missing library

./nidb: error while loading shared libraries: libsquirrel.so.1: cannot open shared object file: No such file or directory./nidb: error while loading shared libraries: libsquirrel.so.1: cannot open shared object file: No such file or directory

You can check which libraries are missing by running ldd on the nidb executable

[nidb@ado2dev bin]$ ldd nidb
        linux-vdso.so.1 (0x00007ffd07fe4000)
        libSMTPEmail.so.1 => /lib/libSMTPEmail.so.1 (0x00007fdb4e2b0000)
        libsquirrel.so.1 => not found
        libgdcmMSFF.so.3.0 => /lib/libgdcmMSFF.so.3.0 (0x00007fdb4dd88000)
        libgdcmCommon.so.3.0 => /lib/libgdcmCommon.so.3.0 (0x00007fdb4db60000)
        libgdcmDICT.so.3.0 => /lib/libgdcmDICT.so.3.0 (0x00007fdb4d688000)
        libgdcmDSED.so.3.0 => /lib/libgdcmDSED.so.3.0 (0x00007fdb4d348000)

Copy the missing library file(s) to /lib as root. Then run ldconfig to register any new libraries.

Virtual Machine Has No Network

If you are using a virtual machine to build, there are a couple of weird bugs in VMWare Workstation Player (possibly other VMWare products as well) where the network adapters on a Linux guest simply stop working. You can't activate them, you can't do anything with them, they just are offline and can't be activated. Or it's connected and network connection is present, but your VM is inaccessible from the outside.

Try these fixes to get the network back:

  1. While the VM is running, suspend the guest OS. Wait for it to suspend and close itself. Then resume the guest OS. No idea why, but this should fix the lack of network adapter in Linux.

  2. Open the VM settings. Go to network, and click the button to edit the bridged adapters. Uncheck the VM adapter. This is if you are using bridged networking only.

  3. Switch to NAT networking. This may be better if you are connected to a public wifi.

Using the squirrel Library

Copy the squirrel library files to the lib directory. The libs will then be available for the whole system.

cd ~/squirrel/bin/squirrel
sudo cp -uv libsquirrel* /lib/

Install the following as root

dnf group install 'Development Tools'
dnf install cmake3
dnf install xcb*
dnf install libxcb*

Install Qt

  1. Download Qt open-source from

  2. Make the installer executable chmod 777 qt-unified-linux-x64-x.x.x-online.run

  3. Run ./qt-unified-linux-x64-x.x.x-online.run

  4. The Qt Maintenance Tool will start. An account is required to download Qt open source.

  5. On the components screen, select the checkbox for Qt 6.5.3 → Desktop gcc 64-bit

Install the following as root

yum group install 'Development Tools'
yum install cmake3
yum install xcb*
yum install libxcb*
yum install gcc-toolset-10

Install Qt

  1. Download Qt open-source from

  2. Make the installer executable chmod 777 qt-unified-linux-x64-x.x.x-online.run

  3. Run ./qt-unified-linux-x64-x.x.x-online.run

  4. The Qt Maintenance Tool will start. An account is required to download Qt open source.

  5. On the components screen, select the checkbox for Qt 6.5.3 → Desktop gcc 64-bit

Install the following as root

yum install epel-release
yum group install 'Development Tools'
yum install cmake3

Install Qt

  1. Make the installer executable chmod 777 qt-unified-linux-x64-x.x.x-online.run

  2. Run ./qt-unified-linux-x64-x.x.x-online.run

  3. The Qt Maintenance Tool will start. An account is required to download Qt open source.

  4. On the components screen, select the checkbox for Qt 6.5.3 → Desktop gcc 64-bit

Install the following as root

apt install build-essential
apt install libxcb*
apt install make
apt install cmake

Install Qt

  1. Make the installer executable chmod 777 qt-unified-linux-x64-x.x.x-online.run

  2. Run ./qt-unified-linux-x64-x.x.x-online.run

  3. The Qt Maintenance Tool will start. An account is required to download Qt open source.

  4. On the components screen, select the checkbox for Qt 6.5.3 → Desktop gcc 64-bit

Install build environment

  1. Install Qt 6.4.2 for MSVC2019 x64

Install Qt

  1. Run the setup program.

  2. The Qt Maintenance Tool will start. An account is required to download Qt open source.

  3. On the components screen, select the checkbox for Qt 6.5.3 → MSVC 2019 64-bit

Download Qt open-source from

Download Qt open-source from

Install edition, available from Microsoft. Install the C++ extensions.

Install

Install , or TortoiseGit, or other Git interface

Download Qt open-source from

🔴
🔴
🔴
🔴
🔴
🔴
🔴
🔴
🔴
https://www.qt.io/download-open-source
https://www.qt.io/download-open-source
https://www.qt.io/download-open-source
https://www.qt.io/download-open-source
Visual Studio 2019 Community
CMake3
Github Desktop
https://www.qt.io/download-open-source