Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
MapAlignerBase.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2015.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Hendrik Weisser $
32 // $Authors: Marc Sturm, Clemens Groepl, Hendrik Weisser $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_APPLICATIONS_MAPALIGNERBASE_H
36 #define OPENMS_APPLICATIONS_MAPALIGNERBASE_H
37 
38 #include <OpenMS/FORMAT/MzMLFile.h>
45 
48 
52 
54 
55 //-------------------------------------------------------------
56 // Doxygen docu
57 //-------------------------------------------------------------
58 
65 // We do not want this class to show up in the docu:
67 
68 namespace OpenMS
69 {
70 
71 class TOPPMapAlignerBase :
72  public TOPPBase
73 {
74 
75 public:
76  TOPPMapAlignerBase(String name, String description, bool official = true) :
77  TOPPBase(name, description, official)
78  {
79  }
80 
81  // "public" so it can be used in DefaultParamHandlerDocumenter to get docu
82  static Param getModelDefaults(const String& default_model)
83  {
84  Param params;
85  params.setValue("type", default_model, "Type of model");
86  // TODO: avoid referring to each TransformationModel subclass explicitly
87  StringList model_types = ListUtils::create<String>("linear,b_spline,interpolated");
88  if (!ListUtils::contains(model_types, default_model))
89  {
90  model_types.insert(model_types.begin(), default_model);
91  }
92  params.setValidStrings("type", model_types);
93 
94  Param model_params;
96  params.insert("linear:", model_params);
97  params.setSectionDescription("linear", "Parameters for 'linear' model");
99  params.insert("b_spline:", model_params);
100  params.setSectionDescription("b_spline", "Parameters for 'b_spline' model");
102  params.insert("interpolated:", model_params);
103  params.setSectionDescription("interpolated",
104  "Parameters for 'interpolated' model");
105  return params;
106  }
107 
108 protected:
109  void registerOptionsAndFlags_(const String& file_formats, const bool add_reference = false)
110  {
111  registerInputFileList_("in", "<files>", StringList(), "Input files separated by blanks (all must have the same file type)", true);
112  setValidFormats_("in", ListUtils::create<String>(file_formats));
113  registerOutputFileList_("out", "<files>", StringList(), "Output files separated by blanks. Either 'out' or 'trafo_out' has to be provided. They can be used together.", false);
114  setValidFormats_("out", ListUtils::create<String>(file_formats));
115  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);
116  setValidFormats_("trafo_out", ListUtils::create<String>("trafoXML"));
117  addEmptyLine_();
118  if (add_reference)
119  {
120  registerTOPPSubsection_("reference", "Options to define a reference file (use either 'file' or 'index', not both; if neither is given 'index' is used).");
121  registerInputFile_("reference:file", "<file>", "", "File to use as reference (same file format as input files required)", false);
122  setValidFormats_("reference:file", ListUtils::create<String>(file_formats));
123  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);
124  setMinInt_("reference:index", 0);
125  }
126  }
127 
129  void handleReference_(MapAlignmentAlgorithm* alignment)
130  {
131  // note: this function is in the base class to avoid code duplication, but
132  // it only makes sense for some derived classes - don't call the function
133  // in a class that doesn't support a reference!
134 
135  // check reference parameters:
136  Size reference_index = getIntOption_("reference:index");
137  String reference_file = getStringOption_("reference:file");
138  if (reference_index > getStringList_("in").size())
139  {
140  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
141  }
142  if (reference_index && !reference_file.empty())
143  {
144  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
145  }
146 
147  // pass the reference parameters on to the algorithm:
148  alignment->setReference(reference_index, reference_file);
149  }
150 
151  ExitCodes initialize_(MapAlignmentAlgorithm* alignment, bool check_ref = false)
152  {
153  //-------------------------------------------------------------
154  // parameter handling
155  //-------------------------------------------------------------
156  StringList ins = getStringList_("in");
157  StringList outs = getStringList_("out");
158  StringList trafos = getStringList_("trafo_out");
159 
160  //-------------------------------------------------------------
161  // check for valid input
162  //-------------------------------------------------------------
163  // check whether some kind of output file is given:
164  if (outs.empty() && trafos.empty())
165  {
166  writeLog_("Error: Either data output or transformation output files have to be provided!");
167  return ILLEGAL_PARAMETERS;
168  }
169  // check whether number of input files equals number of output files:
170  if (!outs.empty() && (ins.size() != outs.size()))
171  {
172  writeLog_("Error: The number of input and output files has to be equal!");
173  return ILLEGAL_PARAMETERS;
174  }
175  if (!trafos.empty() && (ins.size() != trafos.size()))
176  {
177  writeLog_("Error: The number of input and transformation output files has to be equal!");
178  return ILLEGAL_PARAMETERS;
179  }
180  // check whether all input files have the same type (this type is used to store the output type too):
181  FileTypes::Type in_type = FileHandler::getType(ins[0]);
182  for (Size i = 1; i < ins.size(); ++i)
183  {
184  if (FileHandler::getType(ins[i]) != in_type)
185  {
186  writeLog_("Error: All input files have to be in the same format!");
187  return ILLEGAL_PARAMETERS;
188  }
189  }
190 
191  if (check_ref) // a valid index OR file should be given
192  {
193  Size reference_index = getIntOption_("reference:index");
194  String reference_file = getStringOption_("reference:file");
195  if (reference_index > getStringList_("in").size())
196  {
197  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
198  }
199  if (reference_index && !reference_file.empty())
200  {
201  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
202  }
203 
204  // file should have same type as other input
205  if (!reference_file.empty())
206  {
207  if (FileHandler::getType(reference_file) != in_type)
208  {
209  writeLog_("Error: Reference file has not the same format as other input files!");
210  return ILLEGAL_PARAMETERS;
211  }
212  }
213  }
214 
215  //-------------------------------------------------------------
216  // set up alignment algorithm
217  //-------------------------------------------------------------
218  Param alignment_param = getParam_().copy("algorithm:", true);
219 
220  writeDebug_("Used alignment parameters", alignment_param, 3);
221  alignment->setParameters(alignment_param);
222  alignment->setLogType(log_type_);
223 
224  return EXECUTION_OK;
225  }
226 
228  ExitCodes commonMain_(MapAlignmentAlgorithm* alignment)
229  {
230  ExitCodes ret = initialize_(alignment);
231  if (ret != EXECUTION_OK) return ret;
232 
233  ProgressLogger progresslogger;
234  progresslogger.setLogType(log_type_);
235 
236 
237  StringList ins = getStringList_("in");
238  StringList outs = getStringList_("out");
239  StringList trafos = getStringList_("trafo_out");
240  Param model_params = getParam_().copy("model:", true);
241  String model_type = model_params.getValue("type");
242  model_params = model_params.copy(model_type + ":", true);
243  FileTypes::Type in_type = FileHandler::getType(ins[0]);
244  std::vector<TransformationDescription> transformations;
245 
246  //-------------------------------------------------------------
247  // perform peak alignment
248  //-------------------------------------------------------------
249  if (in_type == FileTypes::MZML)
250  {
251  // load input
252  std::vector<MSExperiment<> > peak_maps(ins.size());
253  MzMLFile f;
254  f.setLogType(log_type_);
255  for (Size i = 0; i < ins.size(); ++i)
256  {
257  f.load(ins[i], peak_maps[i]);
258  }
259 
260  // try to align
261  try
262  {
263  alignment->alignPeakMaps(peak_maps, transformations);
264  }
265  catch (Exception::NotImplemented&)
266  {
267  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peak data!");
268  return INTERNAL_ERROR;
269  }
270  if (model_type != "none")
271  {
272  alignment->fitModel(model_type, model_params, transformations);
273  }
274  MapAlignmentTransformer::transformPeakMaps(peak_maps, transformations);
275 
276  // write output
277  progresslogger.startProgress(0, outs.size(), "writing output files");
278  for (Size i = 0; i < outs.size(); ++i)
279  {
280  progresslogger.setProgress(i);
281 
282  //annotate output with data processing info
283  addDataProcessing_(peak_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
284 
285  f.store(outs[i], peak_maps[i]);
286  }
287  progresslogger.endProgress();
288  }
289  //-------------------------------------------------------------
290  // perform feature alignment
291  //-------------------------------------------------------------
292  else if (in_type == FileTypes::FEATUREXML)
293  {
294  // load input
295  std::vector<std::vector<Peak2D> > feat_maps(ins.size());
296  FeatureXMLFile f;
297  // f.setLogType(log_type_); // TODO
298  progresslogger.startProgress(0, ins.size(), "loading input files");
299  for (Size i = 0; i < ins.size(); ++i)
300  {
301  progresslogger.setProgress(i);
302  FeatureMap feature_map;
303  f.load(ins[i], feature_map);
304  feat_maps[i].resize(feature_map.size());
305 
306  FeatureMap::const_iterator it = feature_map.begin();
307  std::vector<Peak2D>::iterator c_it = feat_maps[i].begin();
308  for (; it != feature_map.end(); ++it, ++c_it)
309  {
310  *c_it = reinterpret_cast<const Peak2D&>(*it);
311  }
312  }
313  progresslogger.endProgress();
314 
315  // try to align
316  try
317  {
318  alignment->alignCompactFeatureMaps(feat_maps, transformations);
319  }
320  catch (Exception::NotImplemented&)
321  {
322  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for feature data!");
323  return INTERNAL_ERROR;
324  }
325  if (model_type != "none")
326  {
327  alignment->fitModel(model_type, model_params, transformations);
328  }
329  // alignment->transformFeatureMaps(feat_maps, transformations);
330 
331  // write output
332  progresslogger.startProgress(0, outs.size(), "writing output files");
333  for (Size i = 0; i < outs.size(); ++i)
334  {
335  progresslogger.setProgress(i);
336 
337  FeatureMap feature_map;
338  f.load(ins[i], feature_map);
339 
340  MapAlignmentTransformer::transformSingleFeatureMap(feature_map, transformations[i]);
341 
342  //annotate output with data processing info
343  addDataProcessing_(feature_map, getProcessingInfo_(DataProcessing::ALIGNMENT));
344 
345  f.store(outs[i], feature_map);
346  }
347  progresslogger.endProgress();
348  }
349  //-------------------------------------------------------------
350  // perform consensus alignment
351  //-------------------------------------------------------------
352  else if (in_type == FileTypes::CONSENSUSXML)
353  {
354  // load input
355  std::vector<ConsensusMap> cons_maps(ins.size());
356  ConsensusXMLFile f;
357  // f.setLogType(log_type_); // TODO
358  progresslogger.startProgress(0, ins.size(), "loading input files");
359  for (Size i = 0; i < ins.size(); ++i)
360  {
361  progresslogger.setProgress(i);
362  f.load(ins[i], cons_maps[i]);
363  }
364  progresslogger.endProgress();
365 
366  // try to align
367  try
368  {
369  alignment->alignConsensusMaps(cons_maps, transformations);
370  }
371  catch (Exception::NotImplemented&)
372  {
373  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for consensus feature data!");
374  return INTERNAL_ERROR;
375  }
376  if (model_type != "none")
377  {
378  alignment->fitModel(model_type, model_params, transformations);
379  }
380  MapAlignmentTransformer::transformConsensusMaps(cons_maps, transformations);
381 
382  // write output
383  progresslogger.startProgress(0, outs.size(), "writing output files");
384  for (Size i = 0; i < outs.size(); ++i)
385  {
386  progresslogger.setProgress(i);
387 
388  //annotate output with data processing info
389  addDataProcessing_(cons_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
390 
391  f.store(outs[i], cons_maps[i]);
392  }
393  progresslogger.endProgress();
394  }
395  //-------------------------------------------------------------
396  // perform peptide alignment
397  //-------------------------------------------------------------
398  else if (in_type == FileTypes::IDXML)
399  {
400  // load input
401  std::vector<std::vector<ProteinIdentification> > protein_ids_vec(ins.size());
402  std::vector<std::vector<PeptideIdentification> > peptide_ids_vec(ins.size());
403 
404  IdXMLFile f;
405  // f.setLogType_(log_type_);
406 
407  progresslogger.startProgress(0, ins.size(), "loading input files");
408  for (Size i = 0; i < ins.size(); ++i)
409  {
410  progresslogger.setProgress(i);
411  f.load(ins[i], protein_ids_vec[i], peptide_ids_vec[i]);
412  }
413  progresslogger.endProgress();
414 
415  // try to align
416  try
417  {
418  alignment->alignPeptideIdentifications(peptide_ids_vec, transformations);
419  }
420  catch (Exception::NotImplemented&)
421  {
422  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peptide data!");
423  return INTERNAL_ERROR;
424  }
425  if (model_type != "none")
426  {
427  alignment->fitModel(model_type, model_params, transformations);
428  }
430  transformations);
431 
432  // write output
433  progresslogger.startProgress(0, outs.size(), "writing output files");
434  for (Size i = 0; i < outs.size(); ++i)
435  {
436  progresslogger.setProgress(i);
437  f.store(outs[i], protein_ids_vec[i], peptide_ids_vec[i]);
438  }
439  progresslogger.endProgress();
440  }
441  else
442  {
443  // TODO can this really happen? I think it is tested above. Otherwise
444  // throw an appropriate exception?
445  return ILLEGAL_PARAMETERS;
446  }
447 
448  if (!trafos.empty())
449  {
450  for (Size i = 0; i < transformations.size(); ++i)
451  {
452  TransformationXMLFile().store(trafos[i], transformations[i]);
453  }
454  }
455 
456  return EXECUTION_OK;
457  }
458 
459 };
460 
461 }
462 
464 
465 #endif // OPENMS_APPLICATIONS_MAPALIGNERBASE_H
Type
Actual file types enum.
Definition: FileTypes.h:59
static FileTypes::Type getType(const String &filename)
Tries to determine the file type (by name or content)
OpenMS identification format (.idXML)
Definition: FileTypes.h:67
static void transformConsensusMaps(std::vector< ConsensusMap > &maps, const std::vector< TransformationDescription > &given_trafos)
Applies the given transformations to consensus maps.
static void transformPeakMaps(std::vector< MSExperiment<> > &maps, const std::vector< TransformationDescription > &given_trafos)
Applies the given transformations to peak maps.
OpenMS consensus map format (.consensusXML)
Definition: FileTypes.h:68
static void transformSingleFeatureMap(FeatureMap &fmap, const TransformationDescription &trafo)
Applies the given transformations to a single feature map.
static void getDefaultParameters(Param &params)
Gets the default parameters.
static void transformPeptideIdentifications(std::vector< std::vector< PeptideIdentification > > &maps, const std::vector< TransformationDescription > &given_trafos)
Applies the given transformations to peptide identifications.
Retention time alignment of different maps.
Definition: DataProcessing.h:68
static void getDefaultParameters(Param &params)
Gets the default parameters.
std::vector< String > StringList
Vector of String.
Definition: ListUtils.h:74
OpenMS feature file (.featureXML)
Definition: FileTypes.h:66
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:121
static bool contains(const std::vector< T > &container, const E &elem)
Checks whether the element elem is contained in the given container.
Definition: ListUtils.h:150
MzML file (.mzML)
Definition: FileTypes.h:73
static void getDefaultParameters(Param &params)
Gets the default parameters.

OpenMS / TOPP release 2.0.0 Documentation generated on Wed Mar 30 2016 16:18:39 using doxygen 1.8.5