1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
// main.m dcm2niix
// by Chris Rorden on 3/22/14, see license.txt
// Copyright (c) 2014 Chris Rorden. All rights reserved.
// yaml batch support by Benjamin Irving, 2016 - maintains copyright
#include <stdbool.h> //requires VS 2015 or later
#ifdef _MSC_VER
#include <io.h> //access()
#ifndef F_OK
#define F_OK 0 /* existence check */
#endif
#else
#include <unistd.h> //access()
#endif
#include "nii_dicom.h"
#include "nii_dicom_batch.h"
#include <cmath>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h> // clock_t, clock, CLOCKS_PER_SEC
#include <yaml-cpp/yaml.h>
const char *removePath(const char *path) { // "/usr/path/filename.exe" -> "filename.exe"
const char *pDelimeter = strrchr(path, '\\');
if (pDelimeter)
path = pDelimeter + 1;
pDelimeter = strrchr(path, '/');
if (pDelimeter)
path = pDelimeter + 1;
return path;
} // removePath()
int rmainbatch(TDCMopts opts) {
clock_t start = clock();
nii_loadDir(&opts);
printf("Conversion required %f seconds.\n", ((float)(clock() - start)) / CLOCKS_PER_SEC);
return EXIT_SUCCESS;
} // rmainbatch()
void showHelp(const char *argv[]) {
const char *cstr = removePath(argv[0]);
printf("Usage: %s <batch_config.yml>\n", cstr);
printf("\n");
printf("The configuration file must be in yaml format as shown below\n");
printf("\n");
printf("### START YAML FILE ###\n");
printf("Options:\n");
printf(" isGz: false\n");
printf(" isFlipY: false\n");
printf(" isVerbose: false\n");
printf(" isCreateBIDS: false\n");
printf(" isOnlySingleFile: false\n");
printf("Files:\n");
printf(" -\n");
printf(" in_dir: /path/to/first/folder\n");
printf(" out_dir: /path/to/output/folder\n");
printf(" filename: dcemri\n");
printf(" -\n");
printf(" in_dir: /path/to/second/folder\n");
printf(" out_dir: /path/to/output/folder\n");
printf(" filename: fa3\n");
printf("### END YAML FILE ###\n");
printf("\n");
#if defined(_WIN64) || defined(_WIN32)
printf(" Example :\n");
printf(" %s c:\\dir\\yaml.yml\n", cstr);
printf(" %s \"c:\\dir with spaces\\yaml.yml\"\n", cstr);
#else
printf(" Examples :\n");
printf(" %s /Users/chris/yaml.yml\n", cstr);
printf(" %s \"/Users/dir with spaces/yaml.yml\"\n", cstr);
#endif
} // showHelp()
int main(int argc, const char *argv[]) {
#if defined(__APPLE__)
#define kOS "MacOS"
#elif (defined(__linux) || defined(__linux__))
#define kOS "Linux"
#else
#define kOS "Windows"
#endif
printf("dcm2niibatch using Chris Rorden's dcm2niiX version %s (%llu-bit %s)\n", kDCMvers, (unsigned long long)sizeof(size_t) * 8, kOS);
if (argc != 2) {
if (argc < 2)
printf(" Please provide location of config file\n");
else
printf(" Do not include additional inputs with a config file\n");
printf("\n");
showHelp(argv);
return EXIT_FAILURE;
}
if (access(argv[1], F_OK) == -1) {
printf(" Please provide location of config file\n");
printf("\n");
showHelp(argv);
return EXIT_FAILURE;
}
// Process it all via a yaml file
std::string yaml_file = argv[1];
std::cout << "yaml_path: " << yaml_file << std::endl;
YAML::Node config = YAML::LoadFile(yaml_file);
struct TDCMopts opts;
readIniFile(&opts, argv); // setup defaults, e.g. path to pigz
opts.isCreateBIDS = config["Options"]["isCreateBIDS"].as<bool>();
opts.isOnlySingleFile = config["Options"]["isOnlySingleFile"].as<bool>();
opts.isFlipY = config["Options"]["isFlipY"].as<bool>();
opts.isCreateText = false;
opts.isVerbose = 0;
opts.isGz = config["Options"]["isGz"].as<bool>(); // save data as compressed (.nii.gz) or raw (.nii)
/*bool isInternalGz = config["Options"]["isInternalGz"].as<bool>();
if (isInternalGz) {
strcpy(opts.pigzname, "”); //do NOT use pigz: force internal compressor
//in general, pigz is faster unless you have a very slow network, in which case the internal compressor is better
}*/
for (auto i : config["Files"]) {
std::string indir = i["in_dir"].as<std::string>();
strcpy(opts.indir, indir.c_str());
std::string outdir = i["out_dir"].as<std::string>();
strcpy(opts.outdir, outdir.c_str());
std::string filename = i["filename"].as<std::string>();
strcpy(opts.filename, filename.c_str());
rmainbatch(opts);
}
return EXIT_SUCCESS;
} // main()
|