Package: d2b
d2bOrganize data in the BIDS format.Compatible withdcm2bidsconfig files.Installationpipinstalld2bUsageThe singular CLI entrypoint:$d2b--help
usage:d2b[-h][-v]{run,scaffold}...

d2b-OrganizedataintheBIDSformat

positionalarguments:{run,scaffold}optionalarguments:-h,--helpshowthishelpmessageandexit-v,--versionshowprogram'sversionnumberandexitScaffold a BIDS dataset:$d2bscaffold--help
usage:d2bscaffold[-h]out_dir

ScaffoldaBIDSdatasetdirectorystructure

positionalarguments:out_dirOutputBIDSdirectory

optionalarguments:-h,--helpshowthishelpmessageandexitOrganize nifti data (sidecars required) into a BIDS-compliant structure:$d2brun--help
usage:d2brun[-h]-cCONFIG_FILE-pPARTICIPANT-oOUT_DIR[-sSESSION][-l{DEBUG,INFO,WARNING,ERROR,CRITICAL}]in_dir[in_dir...]OrganizedataintheBIDSformat

positionalarguments:in_dirDirectory(ies)containingfilestoorganize

requiredarguments:-cCONFIG_FILE,--configCONFIG_FILEJSONconfigurationfile(seeexample/config.json)-pPARTICIPANT,--participantPARTICIPANTParticipantID-oOUT_DIR,--out-dirOUT_DIROutputBIDSdirectory

optionalarguments:-sSESSION,--sessionSESSIONSessionID-l{DEBUG,INFO,WARNING,ERROR,CRITICAL},--log-level{DEBUG,INFO,WARNING,ERROR,CRITICAL}SetlogginglevelMotivationThis package offers a pluggable BIDS-ification workflow which attempts to mirror parts of thedcm2bidsCLI.One of the most important goals of this package is to support existingdcm2bidsconfig files.A notable difference betweend2banddcm2bidsis that the default assumption made byd2bis that you'reNOTgiving it DICOM data as input (although, if this is your use-case, there's a plugin to enable going straight from DICOM -> BIDS).Out of the box,d2bassumes that you're working with NIfTI + NIfTI sidecar data.The general premise of thedcm2bidsworkflow is very nice:describe the files your interested in (in config) and the software will take the descriptions, find matching files, and organize those files accordingly.d2b(together with plugins powered bypluggy) tries to offer all functionality thatdcm2bidsoffers, with an aim toward beingextensible.We wanteddcm2bidsto do things that it wasnever intended to do, henced2bwas born.d2banddcm2bidsSimilarities:Config files used withdcm2bidsare compatible withd2bThed2b runcommand corresponds todcm2bidsThed2b scaffoldcommand corresponds todcm2bids_scaffoldDifferences:d2bhas a plugin system so that users can extend the core functionality to fit the needs of their specific use-case.Thed2bcode architecture is meant to make the BIDS dataset generation process less error prone.Out of the box,d2bdoesn't try to convert DICOM files and in factdcm2niixdoesn't even need to be installed. To do DICOM -> BIDS conversions install thed2b-dcm2niixpluginOut of the boxdefaceTplis no longer supported.Writing config filesTo make writingd2bconfig files easier, we've included aJSON schemaspecification file (schema.json). You can use this file in editors that support JSON Schema definitions to provide autocompletion:as well as validation while you edit your config files:For example, with vscode you might create/add to your.vscode/settings.jsonfile in the workspace to include:{
  // ... other settings ...

  "json.schemas": [
    {
      "fileMatch": ["*d2b-config*.json"],
      "url": "https://raw.githubusercontent.com/d2b-dev/d2b/master/json-schemas/schema.json"
    }
  ]
}Having this setting enabled would mean that any file matching*d2b-config*.jsonwould be validated against the latest JSON schema in thed2brepoThe plugin systemd2busespluggyto faciliate the discorvery and integration of plugins, as such familiarity with thepluggy documentationis helpful.That said, here's a small example:Let's write a plugin that adds the commandd2b hello <name>tod2b.The convention is to name the package implementing the plugind2b-[plugin-name], so we'll name our packaged2b-hello.Let's add the plugin implementationd2b-hello/d2b_hello.py:from__future__importannotationsimportargparsefromd2b.hookspecsimporthookimpl@hookimpldefregister_commands(subparsers:argparse._SubParsersAction):parser=subparsers.add_parser("hello")parser.add_argument("name",help="Greet this person")parser.add_argument("--shout",action="store_true",help="Shout it!")parser.set_defaults(handler=handler)defhandler(args:argparse.Namespace):name:str=args.nameshout:bool|None=args.shoutgreeting=f"Hello,{name}!"print(greeting.upper()ifshoutelsegreeting)The script above is tapping into one of the various pluggable locations (hookspecs in pluggy speak) by providing and implementation (hookimpl) of one of the desired hookspecs (register_commands) exposed byd2b.There are many spots ind2bwhich allow for a user to extend or change the core functionality. Check out the modulehookspecs.pyto see which hooks are available.In the case aboveregister_commandsis one of the hookspecs defined byd2benabling for plugins to add subcommands to thed2bCLI.How do we telld2babout our plugin?To discover the plugind2b(viapluggy) usesentrypoints. So we'll add a basicsetup.pymodule:d2b-hello/setup.py:fromsetuptoolsimportfind_packagesfromsetuptoolsimportsetupsetup(name="d2b-hello",install_requires="d2b>=0.2.3,<1.0",entry_points={"d2b":["d2b-hello=d2b_hello"]},packages=find_packages(),)And now we can install our plugin:pipinstall-e./d2b-hello/After which we have:$d2b--help
usage:d2b[-h][-v]{run,scaffold,hello}...

d2b-OrganizedataintheBIDSformat

positionalarguments:{run,scaffold,hello}optionalarguments:-h,--helpshowthishelpmessageandexit-v,--versionshowprogram'sversionnumberandexitOurd2b hellosubcommand is there!$d2bhello--help
usage:d2bhello[-h][--shout]name

positionalarguments:nameGreetthisperson

optionalarguments:-h,--helpshowthishelpmessageandexit--shoutShoutit!And, trying it out:$d2bhelloAndrew--shout
HELLO,ANDREW!Success! 🏆ContributingHave or install a recent version ofpoetry(version >= 1.1)Fork the repoSetup a virtual environment (however you prefer)Runpoetry installRunpre-commit installAdd your changes (adding/updating tests is always nice too)Commit your changes + push to your forkOpen a PR