ODIN
miconv.cpp
1 #include <odindata/fileio.h>
2 #include <odindata/utils.h>
3 #include <odindata/filter.h>
4 
23 struct MiConvOpts : LDRblock {
24 
25  LDRbool quiet;
26  LDRstring protfile;
27  LDRstring parlist;
28 
29  MiConvOpts() {
30 
31  quiet.set_cmdline_option("q").set_description("Quiet mode: do not print progress");
32  append_member(quiet,"quiet");
33 
34  protfile.set_cmdline_option("p").set_description("Load this protocol for defaults");
35  append_member(protfile,"protfile");
36 
37  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.");
38  append_member(parlist,"parlist");
39  }
40 
41 };
42 
44 
45 void usage(const Protocol& prot) {
46  FileReadOpts ropts;
47  FileWriteOpts wopts;
48  MiConvOpts mopts;
49  FilterChain filter;
50  STD_cout << "miconv: Converts medical image data between formats." << STD_endl;
51  STD_cout << " File formats are automatically identified by their file extension." << STD_endl;
52  STD_cout << " It expects at least two filenames/directories (for the input and output file) at the end of the command line." << STD_endl;
53  STD_cout << " An exception is the option '-l' which requires only one filename/directory to list its content." << STD_endl;
54  STD_cout << configInfo() << STD_endl;
55  STD_cout << STD_endl;
56  STD_cout << "Usage: miconv [options] <input-file> [<output-file>]" << STD_endl;
57  STD_cout << "General options:" << STD_endl;
58  STD_cout << mopts.get_cmdline_usage("\t");
59  STD_cout << "Protocol options (overrides parameters in input data):" << STD_endl;
60  STD_cout << prot.get_cmdline_usage("\t");
61  STD_cout << "File read options (will be applied to input data before processing):" << STD_endl;
62  STD_cout << ropts.get_cmdline_usage("\t");
63  STD_cout << "File write options (will be applied to output data after processing):" << STD_endl;
64  STD_cout << wopts.get_cmdline_usage("\t");
65  STD_cout << "Filters/processing, applied in the order they appear on the command line:" << STD_endl;
66  STD_cout << filter.get_cmdline_usage("\t");
67  STD_cout << "Other options:" << STD_endl;
68  STD_cout << "\t" << LogBase::get_usage() << STD_endl;
69  STD_cout << "\t" << helpUsage() << STD_endl;
70  STD_cout << "Supported file extensions(formats):" << STD_endl;
71  STD_cout << FileIO::autoformats_str("\t") << STD_endl;
72 }
73 
74 
76 
77 int main(int argc, char* argv[]) {
78  if(LogBase::set_log_levels(argc,argv)) return 0;
79 
80  Log<OdinData> odinlog("miconv","main");
81 
82  char optval[ODIN_MAXCHAR];
83 
84  Protocol prot_template;
85  FileReadOpts ropts;
86  FileWriteOpts wopts;
87  MiConvOpts mopts;
88 
89  if(hasHelpOption(argc,argv)) {usage(prot_template); return 0;}
90  if(argc<3) {usage(prot_template); return 0;}
91 
92  // set defaults
93  prot_template.seqpars.set_MatrixSize(readDirection,1);
94  prot_template.seqpars.set_MatrixSize(phaseDirection,1);
95  prot_template.seqpars.set_MatrixSize(sliceDirection,1);
96 
97  mopts.parse_cmdline_options(argc,argv);
98 
99  if(mopts.quiet) FileIO::set_trace_status(false);
100 
101  STD_string infile;
102  STD_string outfile;
103 
104 
105  if(mopts.parlist!="") {
106  infile=argv[argc-1];
107  } else {
108  infile=argv[argc-2];
109  outfile=argv[argc-1];
110  }
111 
112  if(mopts.parlist=="help") {
113  STD_cout << "Possible protocol parameters:" << STD_endl;
114  for(unsigned int i=0; i<prot_template.numof_pars(); i++) {
115  LDRbase& ldr=prot_template[i];
116  if(ldr.get_filemode()!=exclude) {
117  STD_cout << ldr.get_label() << STD_endl;
118  }
119  }
120  return 0;
121  }
122 
123  svector pars;
124  if(mopts.parlist=="all") {
125  for(unsigned int i=0; i<prot_template.numof_pars(); i++) {
126  LDRbase& ldr=prot_template[i];
127  if(ldr.get_filemode()!=exclude) pars.push_back(ldr.get_label());
128  }
129  } else {
130  pars=tokens(mopts.parlist);
131  }
132 
133  int npars=pars.size();
134  if(npars) FileIO::set_trace_status(false);
135 
136  if(mopts.protfile!="") {
137  ODINLOG(odinlog,infoLog) << "Loading default protocol " << optval << STD_endl;
138  prot_template.load(mopts.protfile);
139  }
140 
141  // override parameters of protocol file
142  prot_template.parse_cmdline_options(argc,argv,false); // do not modify argc/argv on 1st pass
143 
144  FileIO::ProtocolDataMap pdmap_in;
145 
146  // Read data
147  ropts.parse_cmdline_options(argc,argv);
148 
149  ProgressDisplayConsole display;
150  ProgressMeter progmeter(display);
151  ProgressMeter* progmeter_ptr=0;
152  if(!mopts.quiet) progmeter_ptr=&progmeter;
153 
154  int readresult=FileIO::autoread(pdmap_in, infile, ropts, prot_template, progmeter_ptr);
155 
156  if(readresult<0) {
157  ODINLOG(odinlog,errorLog) << "autoread failed" << STD_endl;
158  return readresult;
159  }
160 
161  // If requested, print formatted protocol properties and exit
162  if(npars) {
163 
164  int ncols=npars;
165  int irow=0;
166  int ndsets=pdmap_in.size();
167  if(ndsets>1) {
168  ncols++;
169  }
170  int nrows=ndsets;
171  if(npars>1) nrows++;
172  sarray table(nrows,ncols);
173  if(npars>1) {
174  for(int ipar=0; ipar<npars; ipar++) {
175  table(0,ipar)=pars[ipar];
176  }
177  table(0,npars)="Dataset";
178  irow++;
179  }
180  for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap_in.begin(); pdit!=pdmap_in.end(); ++pdit) {
181  for(int ipar=0; ipar<npars; ipar++) {
182  table(irow,ipar)=rmblock(pdit->first.printval(pars[ipar]), "\n", ""); // truncate after first newline
183  }
184  if(ndsets>1) {
185  STD_ostringstream oss;
186  oss << pdit->second.shape();
187  table(irow,npars)=oss.str();
188  }
189  irow++;
190  }
191 
192  STD_cout << print_table(table);
193 
194  return 0;
195  }
196 
197  ODINLOG(odinlog,normalDebug) << "mem(in ): " << Profiler::get_memory_usage() << STD_endl;
198 
199  // Create copy of protocol-data map, thereby modify protocol
200  FileIO::ProtocolDataMap pdmap_out;
201  for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap_in.begin(); pdit!=pdmap_in.end(); ++pdit) {
202  Protocol prot(pdit->first);
203  prot.parse_cmdline_options(argc,argv); // override parameters of infile
204  pdmap_out[prot].reference(pdit->second);
205  }
206 
207  ODINLOG(odinlog,normalDebug) << "mem(out): " << Profiler::get_memory_usage() << STD_endl;
208 
209  // Parse before filters to remove options
210  wopts.parse_cmdline_options(argc,argv);
211 
212  FilterChain filterchain(argc,argv);
213 
214  //apply filters on pdmap_out
215  if(!filterchain.apply(pdmap_out)) return -1;
216 
217 
218  // Write data
219  int result=FileIO::autowrite(pdmap_out, outfile, wopts);
220 
221  if(result>0) result=0;
222  return result;
223 }
STD_map< Protocol, Data< float, 4 > > ProtocolDataMap
Definition: fileio.h:89
static int autowrite(const ProtocolDataMap &pdmap, const STD_string &filename, const FileWriteOpts &opts)
static int autoread(ProtocolDataMap &pdmap, const STD_string &filename, const FileReadOpts &opts, const Protocol &protocol_template, ProgressMeter *progmeter=0)
static STD_string autoformats_str(const STD_string &indent="")
STD_string get_cmdline_usage(const STD_string &lineprefix) const
LDRbase & set_description(const STD_string &descr)
Definition: ldrbase.h:382
virtual fileMode get_filemode() const
Definition: ldrbase.h:420
int load(const STD_string &filename, const LDRserBase &serializer=LDRserJDX())
LDRblock & append_member(LDRbase &ldr, const STD_string ldrlabel="")
unsigned int numof_pars() const
const STD_string & get_label() const
Definition: tjlabel.h:48
static bool set_log_levels(int argc, char *argv[], bool trigger_error=true)
static STD_string get_usage()
Definition: tjlog.h:218
static STD_string get_memory_usage()
Protocol proxy.
Definition: protocol.h:33
SeqPars seqpars
Definition: protocol.h:88
SeqPars & set_MatrixSize(direction dir, unsigned int size, parameterMode parmode=edit)
const char * configInfo()
int hasHelpOption(int argc, char *argv[])
STD_string print_table(const sarray &table)
STD_string rmblock(const STD_string &s, const STD_string &blockbegin, const STD_string &blockend, bool rmbegin=true, bool rmend=true, bool rmall=true, bool hierachical=false)
const char * helpUsage()
svector tokens(const STD_string &tokenstring, char custom_separator=0, char escape_begin='"', char escape_end='"')