File: miconv.cpp

package info (click to toggle)
odin 2.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,196 kB
  • sloc: cpp: 62,638; sh: 4,541; makefile: 779
file content (223 lines) | stat: -rw-r--r-- 7,153 bytes parent folder | download | duplicates (3)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include <odindata/fileio.h>
#include <odindata/utils.h>
#include <odindata/filter.h>

/**
  * \page miconv Conversion utility for medical images
  * \verbinclude cmdline-utils/miconv.usage
  *
  * \section miconv_examples Some examples how to use miconv:
  *
  * Read a bunch of DICOM files (format 'dcm'), produced by Siemens, from directory 'mosaic' and convert it to NIFTI file 'mosaic.nii'
  * with a dialect suitable for FSL:
  *   \verbatim
       miconv -rf dcm -rdialect siemens -wdialect fsl mosaic mosaic.nii
      \endverbatim
  *
  * Converting a short (16 bit) raw data file '2dseq' of size 256x256 to a DICOM file 'image.dcm':
  *   \verbatim
       miconv -nx 256 -ny 256 -rf short 2dseq image.dcm
      \endverbatim
  */

struct MiConvOpts : LDRblock {

  LDRbool   quiet;
  LDRstring protfile;
  LDRstring parlist;

  MiConvOpts() {

    quiet.set_cmdline_option("q").set_description("Quiet mode: do not print progress");
    append_member(quiet,"quiet");

    protfile.set_cmdline_option("p").set_description("Load this protocol for defaults");
    append_member(protfile,"protfile");

    parlist.set_cmdline_option("l").set_description("Lists space-separated set of protocol parameters and exits. Use '-l help' to get a list of possible parameters and '-l all' to list all parameters. The parameter 'output-file' must be omitted when using this option.");
    append_member(parlist,"parlist");
  }

};

////////////////////////////////////////

void usage(const Protocol& prot) {
  FileReadOpts ropts;
  FileWriteOpts wopts;
  MiConvOpts mopts;
  FilterChain filter;
  STD_cout << "miconv:  Converts medical image data between formats." << STD_endl;
  STD_cout << "         File formats are automatically identified by their file extension." << STD_endl;
  STD_cout << "         It expects at least two filenames/directories (for the input and output file) at the end of the command line." << STD_endl;
  STD_cout << "         An exception is the option '-l' which requires only one filename/directory to list its content." << STD_endl;
  STD_cout << configInfo() << STD_endl;
  STD_cout << STD_endl;
  STD_cout << "Usage: miconv [options] <input-file> [<output-file>]" << STD_endl;
  STD_cout << "General options:" << STD_endl;
  STD_cout << mopts.get_cmdline_usage("\t");
  STD_cout << "Protocol options (overrides parameters in input data):" << STD_endl;
  STD_cout << prot.get_cmdline_usage("\t");
  STD_cout << "File read options (will be applied to input data before processing):" << STD_endl;
  STD_cout << ropts.get_cmdline_usage("\t");
  STD_cout << "File write options (will be applied to output data after processing):" << STD_endl;
  STD_cout << wopts.get_cmdline_usage("\t");
  STD_cout << "Filters/processing, applied in the order they appear on the command line:" << STD_endl;
  STD_cout << filter.get_cmdline_usage("\t");
  STD_cout << "Other options:" << STD_endl;
  STD_cout << "\t" << LogBase::get_usage() << STD_endl;
  STD_cout << "\t" << helpUsage() << STD_endl;
  STD_cout << "Supported file extensions(formats):" << STD_endl;
  STD_cout << FileIO::autoformats_str("\t") << STD_endl;
}


////////////////////////////////////////

int main(int argc, char* argv[]) {
  if(LogBase::set_log_levels(argc,argv)) return 0;

  Log<OdinData> odinlog("miconv","main");

  char optval[ODIN_MAXCHAR];

  Protocol prot_template;
  FileReadOpts  ropts;
  FileWriteOpts wopts;
  MiConvOpts mopts;

  if(hasHelpOption(argc,argv)) {usage(prot_template); return 0;}
  if(argc<3) {usage(prot_template); return 0;}

  // set defaults
  prot_template.seqpars.set_MatrixSize(readDirection,1);
  prot_template.seqpars.set_MatrixSize(phaseDirection,1);
  prot_template.seqpars.set_MatrixSize(sliceDirection,1);

  mopts.parse_cmdline_options(argc,argv);

  if(mopts.quiet) FileIO::set_trace_status(false);

  STD_string infile;
  STD_string outfile;


  if(mopts.parlist!="") {
    infile=argv[argc-1];
  } else {
    infile=argv[argc-2];
    outfile=argv[argc-1];
  }

  if(mopts.parlist=="help") {
    STD_cout << "Possible protocol parameters:" << STD_endl;
    for(unsigned int i=0; i<prot_template.numof_pars(); i++) {
      LDRbase& ldr=prot_template[i];
      if(ldr.get_filemode()!=exclude) {
	STD_cout <<  ldr.get_label() << STD_endl;
      }
    }
    return 0;
  }

  svector pars;
  if(mopts.parlist=="all") {
    for(unsigned int i=0; i<prot_template.numof_pars(); i++) {
      LDRbase& ldr=prot_template[i];
      if(ldr.get_filemode()!=exclude) pars.push_back(ldr.get_label());
    }
  } else {
    pars=tokens(mopts.parlist);
  }

  int npars=pars.size();
  if(npars) FileIO::set_trace_status(false);

  if(mopts.protfile!="") {
    ODINLOG(odinlog,infoLog) << "Loading default protocol " << optval << STD_endl;
    prot_template.load(mopts.protfile);
  }

  // override parameters of protocol file
  prot_template.parse_cmdline_options(argc,argv,false); // do not modify argc/argv on 1st pass

  FileIO::ProtocolDataMap pdmap_in;

  // Read data
  ropts.parse_cmdline_options(argc,argv);

  ProgressDisplayConsole display;
  ProgressMeter progmeter(display);
  ProgressMeter* progmeter_ptr=0;
  if(!mopts.quiet) progmeter_ptr=&progmeter;

  int readresult=FileIO::autoread(pdmap_in, infile, ropts, prot_template, progmeter_ptr);

  if(readresult<0) {
    ODINLOG(odinlog,errorLog) << "autoread failed" << STD_endl;
    return readresult;
  }

  // If requested, print formatted protocol properties and exit
  if(npars) {
    
    int ncols=npars;
    int irow=0;
    int ndsets=pdmap_in.size();
    if(ndsets>1) {
      ncols++;
    }
    int nrows=ndsets;
    if(npars>1) nrows++;
    sarray table(nrows,ncols);
    if(npars>1) {
      for(int ipar=0; ipar<npars; ipar++) {
        table(0,ipar)=pars[ipar];
      }
      table(0,npars)="Dataset";
      irow++;
    }
    for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap_in.begin(); pdit!=pdmap_in.end(); ++pdit) {
      for(int ipar=0; ipar<npars; ipar++) {
        table(irow,ipar)=rmblock(pdit->first.printval(pars[ipar]), "\n", ""); // truncate after first newline
      }
      if(ndsets>1) {
        STD_ostringstream oss;
        oss << pdit->second.shape();
        table(irow,npars)=oss.str();
      }
      irow++;
    }

    STD_cout << print_table(table);

    return 0;
  }

  ODINLOG(odinlog,normalDebug) << "mem(in ): " << Profiler::get_memory_usage() << STD_endl;

  // Create copy of protocol-data map, thereby modify protocol
  FileIO::ProtocolDataMap pdmap_out;
  for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap_in.begin(); pdit!=pdmap_in.end(); ++pdit) {
    Protocol prot(pdit->first);
    prot.parse_cmdline_options(argc,argv); // override parameters of infile
    pdmap_out[prot].reference(pdit->second);
  }

  ODINLOG(odinlog,normalDebug) << "mem(out): " << Profiler::get_memory_usage() << STD_endl;

  // Parse before filters to remove options
  wopts.parse_cmdline_options(argc,argv);

  FilterChain filterchain(argc,argv);

  //apply filters on pdmap_out
  if(!filterchain.apply(pdmap_out)) return -1;


  // Write data
  int result=FileIO::autowrite(pdmap_out, outfile, wopts);

  if(result>0) result=0;
  return result;
}