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