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-2013.
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: $
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 
50 
51 using namespace OpenMS;
52 using namespace std;
53 
54 //-------------------------------------------------------------
55 // Doxygen docu
56 //-------------------------------------------------------------
57 
64 // We do not want this class to show up in the docu:
66 
67 class TOPPMapAlignerBase :
68  public TOPPBase
69 {
70 
71 public:
72  TOPPMapAlignerBase(String name, String description, bool official = true) :
73  TOPPBase(name, description, official)
74  {
75  }
76 
77  // "public" so it can be used in DefaultParamHandlerDocumenter to get docu
78  static Param getModelDefaults(const String & default_model)
79  {
80  Param params;
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))
85  {
86  model_types.insert(model_types.begin(), default_model);
87  }
88  params.setValidStrings("type", model_types);
89 
90  Param model_params;
92  params.insert("linear:", model_params);
93  params.setSectionDescription("linear", "Parameters for 'linear' model");
95  params.insert("b_spline:", model_params);
96  params.setSectionDescription("b_spline", "Parameters for 'b_spline' model");
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");
109  return params;
110  }
111 
112 protected:
113  void registerOptionsAndFlags_(const String & file_formats, const bool add_reference = false)
114  {
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"));
121  addEmptyLine_();
122  if (add_reference)
123  {
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);
129  }
130  }
131 
133  void handleReference_(MapAlignmentAlgorithm * alignment)
134  {
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!
138 
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())
143  {
144  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
145  }
146  if (reference_index && !reference_file.empty())
147  {
148  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
149  }
150 
151  // pass the reference parameters on to the algorithm:
152  alignment->setReference(reference_index, reference_file);
153  }
154 
155  ExitCodes initialize_(MapAlignmentAlgorithm * alignment, bool check_ref = false)
156  {
157  //-------------------------------------------------------------
158  // parameter handling
159  //-------------------------------------------------------------
160  StringList ins = getStringList_("in");
161  StringList outs = getStringList_("out");
162  StringList trafos = getStringList_("trafo_out");
163 
164  //-------------------------------------------------------------
165  // check for valid input
166  //-------------------------------------------------------------
167  // check whether some kind of output file is given:
168  if (outs.empty() && trafos.empty())
169  {
170  writeLog_("Error: Either data output or transformation output files have to be provided!");
171  return ILLEGAL_PARAMETERS;
172  }
173  // check whether number of input files equals number of output files:
174  if (!outs.empty() && (ins.size() != outs.size()))
175  {
176  writeLog_("Error: The number of input and output files has to be equal!");
177  return ILLEGAL_PARAMETERS;
178  }
179  if (!trafos.empty() && (ins.size() != trafos.size()))
180  {
181  writeLog_("Error: The number of input and transformation output files has to be equal!");
182  return ILLEGAL_PARAMETERS;
183  }
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)
187  {
188  if (FileHandler::getType(ins[i]) != in_type)
189  {
190  writeLog_("Error: All input files have to be in the same format!");
191  return ILLEGAL_PARAMETERS;
192  }
193  }
194 
195  if (check_ref) // a valid index OR file should be given
196  {
197  Size reference_index = getIntOption_("reference:index");
198  String reference_file = getStringOption_("reference:file");
199  if (reference_index > getStringList_("in").size())
200  {
201  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' must not be higher than the number of input files");
202  }
203  if (reference_index && !reference_file.empty())
204  {
205  throw Exception::InvalidParameter(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'reference:index' and 'reference:file' cannot be used together");
206  }
207 
208  // file should have same type as other input
209  if (!reference_file.empty())
210  {
211  if (FileHandler::getType(reference_file) != in_type)
212  {
213  writeLog_("Error: Reference file has not the same format as other input files!");
214  return ILLEGAL_PARAMETERS;
215  }
216  }
217  }
218 
219  //-------------------------------------------------------------
220  // set up alignment algorithm
221  //-------------------------------------------------------------
222  Param alignment_param = getParam_().copy("algorithm:", true);
223 
224  writeDebug_("Used alignment parameters", alignment_param, 3);
225  alignment->setParameters(alignment_param);
226  alignment->setLogType(log_type_);
227 
228  return EXECUTION_OK;
229  }
230 
232  ExitCodes commonMain_(MapAlignmentAlgorithm * alignment)
233  {
234  ExitCodes ret = initialize_(alignment);
235  if (ret != EXECUTION_OK) return ret;
236 
237  ProgressLogger progresslogger;
238  progresslogger.setLogType(log_type_);
239 
240 
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;
249 
250  //-------------------------------------------------------------
251  // perform peak alignment
252  //-------------------------------------------------------------
253  if (in_type == FileTypes::MZML)
254  {
255  // load input
256  std::vector<MSExperiment<> > peak_maps(ins.size());
257  MzMLFile f;
258  f.setLogType(log_type_);
259  for (Size i = 0; i < ins.size(); ++i)
260  {
261  f.load(ins[i], peak_maps[i]);
262  }
263 
264  // try to align
265  try
266  {
267  alignment->alignPeakMaps(peak_maps, transformations);
268  }
269  catch (Exception::NotImplemented &)
270  {
271  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peak data!");
272  return INTERNAL_ERROR;
273  }
274  if (model_type != "none")
275  {
276  alignment->fitModel(model_type, model_params, transformations);
277  }
278  MapAlignmentTransformer::transformPeakMaps(peak_maps, transformations);
279 
280  // write output
281  progresslogger.startProgress(0, outs.size(), "writing output files");
282  for (Size i = 0; i < outs.size(); ++i)
283  {
284  progresslogger.setProgress(i);
285 
286  //annotate output with data processing info
287  addDataProcessing_(peak_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
288 
289  f.store(outs[i], peak_maps[i]);
290  }
291  progresslogger.endProgress();
292  }
293  //-------------------------------------------------------------
294  // perform feature alignment
295  //-------------------------------------------------------------
296  else if (in_type == FileTypes::FEATUREXML)
297  {
298  // load input
299  std::vector<std::vector<Peak2D> > feat_maps(ins.size());
300  FeatureXMLFile f;
301  // f.setLogType(log_type_); // TODO
302  progresslogger.startProgress(0, ins.size(), "loading input files");
303  for (Size i = 0; i < ins.size(); ++i)
304  {
305  progresslogger.setProgress(i);
306  FeatureMap<> feature_map;
307  f.load(ins[i], feature_map);
308  feat_maps[i].resize(feature_map.size());
309 
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)
313  {
314  *c_it = reinterpret_cast<const Peak2D &>(*it);
315  }
316  }
317  progresslogger.endProgress();
318 
319  // try to align
320  try
321  {
322  alignment->alignCompactFeatureMaps(feat_maps, transformations);
323  }
324  catch (Exception::NotImplemented &)
325  {
326  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for feature data!");
327  return INTERNAL_ERROR;
328  }
329  if (model_type != "none")
330  {
331  alignment->fitModel(model_type, model_params, transformations);
332  }
333  // alignment->transformFeatureMaps(feat_maps, transformations);
334 
335  // write output
336  progresslogger.startProgress(0, outs.size(), "writing output files");
337  for (Size i = 0; i < outs.size(); ++i)
338  {
339  progresslogger.setProgress(i);
340 
341  FeatureMap<> feature_map;
342  f.load(ins[i], feature_map);
343 
344  MapAlignmentTransformer::transformSingleFeatureMap(feature_map, transformations[i]);
345 
346  //annotate output with data processing info
347  addDataProcessing_(feature_map, getProcessingInfo_(DataProcessing::ALIGNMENT));
348 
349  f.store(outs[i], feature_map);
350  }
351  progresslogger.endProgress();
352  }
353  //-------------------------------------------------------------
354  // perform consensus alignment
355  //-------------------------------------------------------------
356  else if (in_type == FileTypes::CONSENSUSXML)
357  {
358  // load input
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)
364  {
365  progresslogger.setProgress(i);
366  f.load(ins[i], cons_maps[i]);
367  }
368  progresslogger.endProgress();
369 
370  // try to align
371  try
372  {
373  alignment->alignConsensusMaps(cons_maps, transformations);
374  }
375  catch (Exception::NotImplemented &)
376  {
377  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for consensus feature data!");
378  return INTERNAL_ERROR;
379  }
380  if (model_type != "none")
381  {
382  alignment->fitModel(model_type, model_params, transformations);
383  }
384  MapAlignmentTransformer::transformConsensusMaps(cons_maps, transformations);
385 
386  // write output
387  progresslogger.startProgress(0, outs.size(), "writing output files");
388  for (Size i = 0; i < outs.size(); ++i)
389  {
390  progresslogger.setProgress(i);
391 
392  //annotate output with data processing info
393  addDataProcessing_(cons_maps[i], getProcessingInfo_(DataProcessing::ALIGNMENT));
394 
395  f.store(outs[i], cons_maps[i]);
396  }
397  progresslogger.endProgress();
398  }
399  //-------------------------------------------------------------
400  // perform peptide alignment
401  //-------------------------------------------------------------
402  else if (in_type == FileTypes::IDXML)
403  {
404  // load input
405  std::vector<std::vector<ProteinIdentification> > protein_ids_vec(ins.size());
406  std::vector<std::vector<PeptideIdentification> > peptide_ids_vec(ins.size());
407 
408  IdXMLFile f;
409  // f.setLogType_(log_type_);
410 
411  progresslogger.startProgress(0, ins.size(), "loading input files");
412  for (Size i = 0; i < ins.size(); ++i)
413  {
414  progresslogger.setProgress(i);
415  f.load(ins[i], protein_ids_vec[i], peptide_ids_vec[i]);
416  }
417  progresslogger.endProgress();
418 
419  // try to align
420  try
421  {
422  alignment->alignPeptideIdentifications(peptide_ids_vec, transformations);
423  }
424  catch (Exception::NotImplemented &)
425  {
426  writeLog_("Error: The algorithm '" + alignment->getName() + "' cannot be used for peptide data!");
427  return INTERNAL_ERROR;
428  }
429  if (model_type != "none")
430  {
431  alignment->fitModel(model_type, model_params, transformations);
432  }
434  transformations);
435 
436  // write output
437  progresslogger.startProgress(0, outs.size(), "writing output files");
438  for (Size i = 0; i < outs.size(); ++i)
439  {
440  progresslogger.setProgress(i);
441  f.store(outs[i], protein_ids_vec[i], peptide_ids_vec[i]);
442  }
443  progresslogger.endProgress();
444  }
445  else
446  {
447  // TODO can this really happen? I think it is tested above. Otherwise
448  // throw an appropriate exception?
449  return ILLEGAL_PARAMETERS;
450  }
451 
452  if (!trafos.empty())
453  {
454  for (Size i = 0; i < transformations.size(); ++i)
455  {
456  TransformationXMLFile().store(trafos[i], transformations[i]);
457  }
458  }
459 
460  return EXECUTION_OK;
461  }
462 
463 };
464 
466 
467 #endif // OPENMS_APPLICATIONS_MAPALIGNERBASE_H
Type
Actual file types enum.
Definition: FileTypes.h:59
static void transformSingleFeatureMap(FeatureMap<> &fmap, const TransformationDescription &trafo)
Applies the given transformations to a single feature map.
static FileTypes::Type getType(const String &filename)
Tries to determine the file type (by name or content)
const ParamEntry & getEntry(const String &key) const
Returns the whole parameter entry.
void setValue(const String &key, const DataValue &value, const String &description="", const StringList &tags=StringList())
Sets a value.
A more convenient string class.
Definition: String.h:56
void insert(const String &prefix, const Param &param)
A 2-dimensional raw data point or peak.
Definition: Peak2D.h:55
bool contains(const String &s) const
Returns if a string is contained in the list.
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.
Base class for all map-alignment algorithms.
Definition: MapAlignmentAlgorithm.h:58
Parameter entry used to store the actual information inside of a Param entry.
Definition: Param.h:74
void setSectionDescription(const String &key, const String &description)
Sets a description for an existing section.
static void transformPeakMaps(std::vector< MSExperiment<> > &maps, const std::vector< TransformationDescription > &given_trafos)
Applies the given transformations to peak maps.
void store(String filename, const TransformationDescription &transformation)
Stores the data in an TransformationXML file.
void setParameters(const Param &param)
Sets the parameters.
Base class for TOPP applications.
Definition: TOPPBase.h:130
OpenMS consensus map format (.consensusXML)
Definition: FileTypes.h:68
Param copy(const String &prefix, bool remove_prefix=false) const
Returns a new Param object containing all entries that start with prefix.
File adapter for MzML files.
Definition: MzMLFile.h:58
Used to load and store TransformationXML files.
Definition: TransformationXMLFile.h:57
void endProgress() const
Ends the progress display.
virtual void alignConsensusMaps(std::vector< ConsensusMap > &, std::vector< TransformationDescription > &)
Aligns consensus maps.
virtual void alignPeakMaps(std::vector< MSExperiment<> > &, std::vector< TransformationDescription > &)
Aligns peak maps.
const DataValue & getValue(const String &key) const
Returns a value of a parameter.
const String & getName() const
Non-mutable access to the name.
This class provides Input functionality for ConsensusMaps and Output functionality for alignments and...
Definition: ConsensusXMLFile.h:59
static void getDefaultParameters(Param &params)
Gets the default parameters.
iterator Iterator
Mutable iterator.
Definition: StringList.h:65
static void transformPeptideIdentifications(std::vector< std::vector< PeptideIdentification > > &maps, const std::vector< TransformationDescription > &given_trafos)
Applies the given transformations to peptide identifications.
static StringList create(const String &list, const char splitter= ',')
Returns a list that is created by splitting the given (comma-separated) string (String are not trimme...
Exception indicating that an invalid parameter was handed over to an algorithm.
Definition: Exception.h:348
virtual void alignCompactFeatureMaps(std::vector< std::vector< Peak2D > > &, std::vector< TransformationDescription > &)
Aligns vectors of 2D peaks (memory efficient version of FeatureMap)
Retention time alignment of different maps.
Definition: DataProcessing.h:68
static void getDefaultParameters(Param &params)
Gets the default parameters.
void setValidStrings(const String &key, const std::vector< String > &strings)
Sets the valid strings for the parameter key.
OpenMS feature file (.featureXML)
Definition: FileTypes.h:66
Management and storage of parameters / INI files.
Definition: Param.h:69
This class provides Input/Output functionality for feature maps.
Definition: FeatureXMLFile.h:59
String list.
Definition: StringList.h:56
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:144
Base class for all classes that want to report their progess.
Definition: ProgressLogger.h:56
void startProgress(SignedSize begin, SignedSize end, const String &label) const
Initializes the progress display.
std::vector< String > valid_strings
Default: empty.
Definition: Param.h:104
void setProgress(SignedSize value) const
Sets the current progress.
static void fitModel(const String &model_type, const Param &params, std::vector< TransformationDescription > &trafos)
Fits a model with given parameters to the transformations.
virtual void setReference(Size reference_index=0, const String &reference_file="")
Defines a reference for the alignment.
virtual void alignPeptideIdentifications(std::vector< std::vector< PeptideIdentification > > &, std::vector< TransformationDescription > &)
Aligns peptide identifications.
Not implemented exception.
Definition: Exception.h:437
MzML file (.mzML)
Definition: FileTypes.h:73
void setLogType(LogType type) const
Sets the progress log that should be used. The default type is NONE!
static void getDefaultParameters(Param &params)
Gets the default parameters.
Used to load and store idXML files.
Definition: IdXMLFile.h:63

OpenMS / TOPP release 1.11.1 Documentation generated on Thu Nov 14 2013 11:19:16 using doxygen 1.8.5