43
56
//-------------------------------------------------------------
46
@page TOPP_MapAlignerBase MapAlignerBase
59
@page TOPP_MapAlignerBase MapAlignerBase
48
@brief Base class for different MapAligner TOPP tools.
61
@brief Base class for different MapAligner TOPP tools.
51
64
// We do not want this class to show up in the docu:
52
65
/// @cond TOPPCLASSES
54
class TOPPMapAlignerBase
67
class TOPPMapAlignerBase :
59
TOPPMapAlignerBase(String name, String description, bool official=true)
60
: TOPPBase(name, description, official)
64
// "public" so it can be used in DefaultParamHandlerDocumenter to get docu
65
static Param getModelDefaults(const String& default_model)
68
params.setValue("type", default_model, "Type of model");
69
// TODO: avoid referring to each TransformationModel subclass explicitly
70
StringList model_types = StringList::create("linear,b_spline,interpolated");
71
if (!model_types.contains(default_model))
73
model_types.insert(model_types.begin(), default_model);
75
params.setValidStrings("type", model_types);
78
TransformationModelLinear::getDefaultParameters(model_params);
79
params.insert("linear:", model_params);
80
params.setSectionDescription("linear", "Parameters for 'linear' model");
81
TransformationModelBSpline::getDefaultParameters(model_params);
82
params.insert("b_spline:", model_params);
83
params.setSectionDescription("b_spline", "Parameters for 'b_spline' model");
84
TransformationModelInterpolated::getDefaultParameters(model_params);
85
// "polynomial" interpolation is not suitable for RT data, so remove it:
86
const Param::ParamEntry& entry =
87
model_params.getEntry("interpolation_type");
88
StringList interpolation_types = entry.valid_strings;
89
StringList::Iterator pos = find(interpolation_types.begin(),
90
interpolation_types.end(), "polynomial");
91
interpolation_types.erase(pos);
92
model_params.setValidStrings("interpolation_type", interpolation_types);
93
params.insert("interpolated:", model_params);
94
params.setSectionDescription("interpolated",
95
"Parameters for 'interpolated' model");
72
TOPPMapAlignerBase(String name, String description, bool official = true) :
73
TOPPBase(name, description, official)
77
// "public" so it can be used in DefaultParamHandlerDocumenter to get docu
78
static Param getModelDefaults(const String & default_model)
81
params.setValue("type", default_model, "Type of model");
82
// TODO: avoid referring to each TransformationModel subclass explicitly
83
StringList model_types = StringList::create("linear,b_spline,interpolated");
84
if (!model_types.contains(default_model))
86
model_types.insert(model_types.begin(), default_model);
88
params.setValidStrings("type", model_types);
91
TransformationModelLinear::getDefaultParameters(model_params);
92
params.insert("linear:", model_params);
93
params.setSectionDescription("linear", "Parameters for 'linear' model");
94
TransformationModelBSpline::getDefaultParameters(model_params);
95
params.insert("b_spline:", model_params);
96
params.setSectionDescription("b_spline", "Parameters for 'b_spline' model");
97
TransformationModelInterpolated::getDefaultParameters(model_params);
98
// "polynomial" interpolation is not suitable for RT data, so remove it:
99
const Param::ParamEntry & entry =
100
model_params.getEntry("interpolation_type");
101
StringList interpolation_types = entry.valid_strings;
102
StringList::Iterator pos = find(interpolation_types.begin(),
103
interpolation_types.end(), "polynomial");
104
interpolation_types.erase(pos);
105
model_params.setValidStrings("interpolation_type", interpolation_types);
106
params.insert("interpolated:", model_params);
107
params.setSectionDescription("interpolated",
108
"Parameters for 'interpolated' model");
100
void registerOptionsAndFlags_(const String& file_formats)
102
registerInputFileList_("in", "<files>", StringList(), "Input files separated by blanks (all must have the same file type)", true);
103
setValidFormats_("in", StringList::create(file_formats));
104
registerOutputFileList_("out", "<files>", StringList(), "Output files separated by blanks", false);
105
setValidFormats_("out", StringList::create(file_formats));
106
registerOutputFileList_("trafo_out", "<files>", StringList(), "Transformation output files separated by blanks", false);
107
setValidFormats_("trafo_out", StringList::create("trafoXML"));
113
void registerOptionsAndFlags_(const String & file_formats, const bool add_reference = false)
115
registerInputFileList_("in", "<files>", StringList(), "Input files separated by blanks (all must have the same file type)", true);
116
setValidFormats_("in", StringList::create(file_formats));
117
registerOutputFileList_("out", "<files>", StringList(), "Output files separated by blanks. Either 'out' or 'trafo_out' has to be provided. They can be used together.", false);
118
setValidFormats_("out", StringList::create(file_formats));
119
registerOutputFileList_("trafo_out", "<files>", StringList(), "Transformation output files separated by blanks. Either 'out' or 'trafo_out' has to be provided. They can be used together.", false);
120
setValidFormats_("trafo_out", StringList::create("trafoXML"));
109
addText_("This tool takes a number of input files, aligns them and writes the results to the output files.");
110
addText_("Either 'out' or 'trafo_out' has to be provided. They can be used together.");
113
void handleReference_(MapAlignmentAlgorithm* alignment)
115
// note: this function is in the base class to avoid code duplication, but
116
// it only makes sense for some derived classes - don't call the function
117
// in a class that doesn't support a reference!
119
// check reference parameters:
120
Size reference_index = getIntOption_("reference:index");
121
String reference_file = getStringOption_("reference:file");
122
if (reference_index > getStringList_("in").size())
124
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
126
if (reference_index && !reference_file.empty())
128
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
131
// pass the reference parameters on to the algorithm:
132
alignment->setReference(reference_index, reference_file);
135
ExitCodes commonMain_(MapAlignmentAlgorithm* alignment)
137
//-------------------------------------------------------------
138
// parameter handling
139
//-------------------------------------------------------------
140
StringList ins = getStringList_("in");
141
StringList outs = getStringList_("out");
142
StringList trafos = getStringList_("trafo_out");
143
Param model_params = getParam_().copy("model:", true);
144
String model_type = model_params.getValue("type");
145
model_params = model_params.copy(model_type + ":", true);
147
ProgressLogger progresslogger;
148
progresslogger.setLogType(log_type_);
150
//-------------------------------------------------------------
151
// check for valid input
152
//-------------------------------------------------------------
153
// check whether some kind of output file is given:
154
if (outs.empty() && trafos.empty())
156
writeLog_("Error: Either data output or transformation output files have to be provided!");
157
return ILLEGAL_PARAMETERS;
159
// check whether number of input files equals number of output files:
160
if (!outs.empty() && (ins.size() != outs.size()))
162
writeLog_("Error: The number of input and output files has to be equal!");
163
return ILLEGAL_PARAMETERS;
165
if (!trafos.empty() && (ins.size() != trafos.size()))
167
writeLog_("Error: The number of input and transformation output files has to be equal!");
168
return ILLEGAL_PARAMETERS;
170
// check whether all input files have the same type (this type is used to store the output type too):
171
FileTypes::Type in_type = FileHandler::getType(ins[0]);
172
for (Size i = 1; i < ins.size(); ++i)
174
if (FileHandler::getType(ins[i]) != in_type)
176
writeLog_("Error: All input files have to be in the same format!");
177
return ILLEGAL_PARAMETERS;
124
registerTOPPSubsection_("reference", "Options to define a reference file (use either 'file' or 'index', not both; if neither is given 'index' is used).");
125
registerInputFile_("reference:file", "<file>", "", "File to use as reference (same file format as input files required)", false);
126
setValidFormats_("reference:file", StringList::create(file_formats));
127
registerIntOption_("reference:index", "<number>", 0, "Use one of the input files as reference ('1' for the first file, etc.).\nIf '0', no explicit reference is set - the algorithm will select a reference.", false);
128
setMinInt_("reference:index", 0);
132
/// deprecated? (not used in PoseClustering... and moved to initialize_() )
133
void handleReference_(MapAlignmentAlgorithm * alignment)
135
// note: this function is in the base class to avoid code duplication, but
136
// it only makes sense for some derived classes - don't call the function
137
// in a class that doesn't support a reference!
139
// check reference parameters:
140
Size reference_index = getIntOption_("reference:index");
141
String reference_file = getStringOption_("reference:file");
142
if (reference_index > getStringList_("in").size())
144
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
146
if (reference_index && !reference_file.empty())
148
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
151
// pass the reference parameters on to the algorithm:
152
alignment->setReference(reference_index, reference_file);
155
ExitCodes initialize_(MapAlignmentAlgorithm * alignment, bool check_ref = false)
157
//-------------------------------------------------------------
158
// parameter handling
159
//-------------------------------------------------------------
160
StringList ins = getStringList_("in");
161
StringList outs = getStringList_("out");
162
StringList trafos = getStringList_("trafo_out");
164
//-------------------------------------------------------------
165
// check for valid input
166
//-------------------------------------------------------------
167
// check whether some kind of output file is given:
168
if (outs.empty() && trafos.empty())
170
writeLog_("Error: Either data output or transformation output files have to be provided!");
171
return ILLEGAL_PARAMETERS;
173
// check whether number of input files equals number of output files:
174
if (!outs.empty() && (ins.size() != outs.size()))
176
writeLog_("Error: The number of input and output files has to be equal!");
177
return ILLEGAL_PARAMETERS;
179
if (!trafos.empty() && (ins.size() != trafos.size()))
181
writeLog_("Error: The number of input and transformation output files has to be equal!");
182
return ILLEGAL_PARAMETERS;
184
// check whether all input files have the same type (this type is used to store the output type too):
185
FileTypes::Type in_type = FileHandler::getType(ins[0]);
186
for (Size i = 1; i < ins.size(); ++i)
188
if (FileHandler::getType(ins[i]) != in_type)
190
writeLog_("Error: All input files have to be in the same format!");
191
return ILLEGAL_PARAMETERS;
195
if (check_ref) // a valid index OR file should be given
197
Size reference_index = getIntOption_("reference:index");
198
String reference_file = getStringOption_("reference:file");
199
if (reference_index > getStringList_("in").size())
201
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
203
if (reference_index && !reference_file.empty())
205
throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
208
// file should have same type as other input
209
if (!reference_file.empty())
211
if (FileHandler::getType(reference_file) != in_type)
213
writeLog_("Error: Reference file has not the same format as other input files!");
214
return ILLEGAL_PARAMETERS;
181
219
//-------------------------------------------------------------
182
220
// set up alignment algorithm
183
221
//-------------------------------------------------------------
184
Param alignment_param = getParam_().copy("algorithm:", true);
186
writeDebug_("Used alignment parameters", alignment_param, 3);
187
alignment->setParameters(alignment_param);
188
alignment->setLogType(log_type_);
190
std::vector<TransformationDescription> transformations;
222
Param alignment_param = getParam_().copy("algorithm:", true);
224
writeDebug_("Used alignment parameters", alignment_param, 3);
225
alignment->setParameters(alignment_param);
226
alignment->setLogType(log_type_);
231
/// deprecated? (not used in PoseClustering... and moved to initialize_() )
232
ExitCodes commonMain_(MapAlignmentAlgorithm * alignment)
234
ExitCodes ret = initialize_(alignment);
235
if (ret != EXECUTION_OK) return ret;
237
ProgressLogger progresslogger;
238
progresslogger.setLogType(log_type_);
241
StringList ins = getStringList_("in");
242
StringList outs = getStringList_("out");
243
StringList trafos = getStringList_("trafo_out");
244
Param model_params = getParam_().copy("model:", true);
245
String model_type = model_params.getValue("type");
246
model_params = model_params.copy(model_type + ":", true);
247
FileTypes::Type in_type = FileHandler::getType(ins[0]);
248
std::vector<TransformationDescription> transformations;
192
250
//-------------------------------------------------------------
193
251
// perform peak alignment
194
252
//-------------------------------------------------------------
195
if (in_type == FileTypes::MZML)
198
std::vector< MSExperiment<> > peak_maps(ins.size());
200
f.setLogType(log_type_);
201
for (Size i = 0; i < ins.size(); ++i)
203
f.load(ins[i], peak_maps[i]);
209
alignment->alignPeakMaps(peak_maps, transformations);
211
catch (Exception::NotImplemented&)
213
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peak data!");
214
return INTERNAL_ERROR;
216
if (model_type != "none")
218
alignment->fitModel(model_type, model_params, transformations);
220
alignment->transformPeakMaps(peak_maps, transformations);
223
progresslogger.startProgress(0, outs.size(), "writing output files");
224
for (Size i = 0; i < outs.size(); ++i)
226
progresslogger.setProgress(i);
228
//annotate output with data processing info
229
addDataProcessing_(peak_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
231
f.store(outs[i], peak_maps[i]);
233
progresslogger.endProgress();
253
if (in_type == FileTypes::MZML)
256
std::vector<MSExperiment<> > peak_maps(ins.size());
258
f.setLogType(log_type_);
259
for (Size i = 0; i < ins.size(); ++i)
261
f.load(ins[i], peak_maps[i]);
267
alignment->alignPeakMaps(peak_maps, transformations);
269
catch (Exception::NotImplemented &)
271
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peak data!");
272
return INTERNAL_ERROR;
274
if (model_type != "none")
276
alignment->fitModel(model_type, model_params, transformations);
278
MapAlignmentTransformer::transformPeakMaps(peak_maps, transformations);
281
progresslogger.startProgress(0, outs.size(), "writing output files");
282
for (Size i = 0; i < outs.size(); ++i)
284
progresslogger.setProgress(i);
286
//annotate output with data processing info
287
addDataProcessing_(peak_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
289
f.store(outs[i], peak_maps[i]);
291
progresslogger.endProgress();
235
293
//-------------------------------------------------------------
236
294
// perform feature alignment
237
295
//-------------------------------------------------------------
238
else if (in_type == FileTypes::FEATUREXML)
241
std::vector< FeatureMap<> > feat_maps(ins.size());
243
// f.setLogType(log_type_); // TODO
244
progresslogger.startProgress(0, ins.size(), "loading input files");
245
for (Size i = 0; i < ins.size(); ++i)
247
progresslogger.setProgress(i);
248
f.load(ins[i], feat_maps[i]);
250
progresslogger.endProgress();
255
alignment->alignFeatureMaps(feat_maps, transformations);
257
catch (Exception::NotImplemented&)
259
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for feature data!");
260
return INTERNAL_ERROR;
262
if (model_type != "none")
264
alignment->fitModel(model_type, model_params, transformations);
266
alignment->transformFeatureMaps(feat_maps, transformations);
269
progresslogger.startProgress(0, outs.size(), "writing output files");
270
for (Size i = 0; i < outs.size(); ++i)
272
progresslogger.setProgress(i);
274
//annotate output with data processing info
275
addDataProcessing_(feat_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
277
f.store(outs[i], feat_maps[i]);
279
progresslogger.endProgress();
296
else if (in_type == FileTypes::FEATUREXML)
299
std::vector<std::vector<Peak2D> > feat_maps(ins.size());
301
// f.setLogType(log_type_); // TODO
302
progresslogger.startProgress(0, ins.size(), "loading input files");
303
for (Size i = 0; i < ins.size(); ++i)
305
progresslogger.setProgress(i);
306
FeatureMap<> feature_map;
307
f.load(ins[i], feature_map);
308
feat_maps[i].resize(feature_map.size());
310
FeatureMap<>::const_iterator it = feature_map.begin();
311
std::vector<Peak2D>::iterator c_it = feat_maps[i].begin();
312
for (; it != feature_map.end(); ++it, ++c_it)
314
*c_it = reinterpret_cast<const Peak2D &>(*it);
317
progresslogger.endProgress();
322
alignment->alignCompactFeatureMaps(feat_maps, transformations);
324
catch (Exception::NotImplemented &)
326
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for feature data!");
327
return INTERNAL_ERROR;
329
if (model_type != "none")
331
alignment->fitModel(model_type, model_params, transformations);
333
// alignment->transformFeatureMaps(feat_maps, transformations);
336
progresslogger.startProgress(0, outs.size(), "writing output files");
337
for (Size i = 0; i < outs.size(); ++i)
339
progresslogger.setProgress(i);
341
FeatureMap<> feature_map;
342
f.load(ins[i], feature_map);
344
MapAlignmentTransformer::transformSingleFeatureMap(feature_map, transformations[i]);
346
//annotate output with data processing info
347
addDataProcessing_(feature_map, getProcessingInfo_(DataProcessing::ALIGNMENT));
349
f.store(outs[i], feature_map);
351
progresslogger.endProgress();
281
353
//-------------------------------------------------------------
282
354
// perform consensus alignment
283
355
//-------------------------------------------------------------
284
else if (in_type == FileTypes::CONSENSUSXML)
287
std::vector<ConsensusMap> cons_maps(ins.size());
289
// f.setLogType(log_type_); // TODO
290
progresslogger.startProgress(0, ins.size(), "loading input files");
291
for (Size i = 0; i < ins.size(); ++i)
293
progresslogger.setProgress(i);
294
f.load(ins[i], cons_maps[i]);
296
progresslogger.endProgress();
301
alignment->alignConsensusMaps(cons_maps, transformations);
303
catch (Exception::NotImplemented&)
305
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for consensus feature data!");
306
return INTERNAL_ERROR;
308
if (model_type != "none")
310
alignment->fitModel(model_type, model_params, transformations);
312
alignment->transformConsensusMaps(cons_maps, transformations);
315
progresslogger.startProgress(0, outs.size(), "writing output files");
316
for (Size i = 0; i < outs.size(); ++i)
318
progresslogger.setProgress(i);
320
//annotate output with data processing info
321
addDataProcessing_(cons_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
323
f.store(outs[i], cons_maps[i]);
325
progresslogger.endProgress();
356
else if (in_type == FileTypes::CONSENSUSXML)
359
std::vector<ConsensusMap> cons_maps(ins.size());
361
// f.setLogType(log_type_); // TODO
362
progresslogger.startProgress(0, ins.size(), "loading input files");
363
for (Size i = 0; i < ins.size(); ++i)
365
progresslogger.setProgress(i);
366
f.load(ins[i], cons_maps[i]);
368
progresslogger.endProgress();
373
alignment->alignConsensusMaps(cons_maps, transformations);
375
catch (Exception::NotImplemented &)
377
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for consensus feature data!");
378
return INTERNAL_ERROR;
380
if (model_type != "none")
382
alignment->fitModel(model_type, model_params, transformations);
384
MapAlignmentTransformer::transformConsensusMaps(cons_maps, transformations);
387
progresslogger.startProgress(0, outs.size(), "writing output files");
388
for (Size i = 0; i < outs.size(); ++i)
390
progresslogger.setProgress(i);
392
//annotate output with data processing info
393
addDataProcessing_(cons_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
395
f.store(outs[i], cons_maps[i]);
397
progresslogger.endProgress();
327
399
//-------------------------------------------------------------
328
400
// perform peptide alignment
329
401
//-------------------------------------------------------------
330
else if (in_type == FileTypes::IDXML)
333
std::vector< std::vector<ProteinIdentification> > protein_ids_vec(ins.size());
334
std::vector< std::vector<PeptideIdentification> > peptide_ids_vec(ins.size());
337
// f.setLogType_(log_type_);
339
progresslogger.startProgress(0, ins.size(), "loading input files");
340
for (Size i = 0; i < ins.size(); ++i)
342
progresslogger.setProgress(i);
343
f.load(ins[i], protein_ids_vec[i], peptide_ids_vec[i]);
345
progresslogger.endProgress();
350
alignment->alignPeptideIdentifications(peptide_ids_vec, transformations);
352
catch (Exception::NotImplemented&)
354
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peptide data!");
355
return INTERNAL_ERROR;
357
if (model_type != "none")
359
alignment->fitModel(model_type, model_params, transformations);
361
alignment->transformPeptideIdentifications(peptide_ids_vec,
365
progresslogger.startProgress(0, outs.size(), "writing output files");
366
for (Size i = 0; i < outs.size(); ++i)
368
progresslogger.setProgress(i);
369
f.store(outs[i], protein_ids_vec[i], peptide_ids_vec[i]);
371
progresslogger.endProgress();
375
// TODO can this really happen? I think it is tested above. Otherwise
376
// throw an appropriate exception?
377
return ILLEGAL_PARAMETERS;
382
for (Size i = 0; i < transformations.size(); ++i)
384
TransformationXMLFile().store(trafos[i], transformations[i]);
402
else if (in_type == FileTypes::IDXML)
405
std::vector<std::vector<ProteinIdentification> > protein_ids_vec(ins.size());
406
std::vector<std::vector<PeptideIdentification> > peptide_ids_vec(ins.size());
409
// f.setLogType_(log_type_);
411
progresslogger.startProgress(0, ins.size(), "loading input files");
412
for (Size i = 0; i < ins.size(); ++i)
414
progresslogger.setProgress(i);
415
f.load(ins[i], protein_ids_vec[i], peptide_ids_vec[i]);
417
progresslogger.endProgress();
422
alignment->alignPeptideIdentifications(peptide_ids_vec, transformations);
424
catch (Exception::NotImplemented &)
426
writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peptide data!");
427
return INTERNAL_ERROR;
429
if (model_type != "none")
431
alignment->fitModel(model_type, model_params, transformations);
433
MapAlignmentTransformer::transformPeptideIdentifications(peptide_ids_vec,
437
progresslogger.startProgress(0, outs.size(), "writing output files");
438
for (Size i = 0; i < outs.size(); ++i)
440
progresslogger.setProgress(i);
441
f.store(outs[i], protein_ids_vec[i], peptide_ids_vec[i]);
443
progresslogger.endProgress();
447
// TODO can this really happen? I think it is tested above. Otherwise
448
// throw an appropriate exception?
449
return ILLEGAL_PARAMETERS;
454
for (Size i = 0; i < transformations.size(); ++i)
456
TransformationXMLFile().store(trafos[i], transformations[i]);
467
#endif // OPENMS_APPLICATIONS_MAPALIGNERBASE_H