Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

SpectrumAlignment.h

Go to the documentation of this file.
00001 // --------------------------------------------------------------------------
00002 //                   OpenMS -- Open-Source Mass Spectrometry
00003 // --------------------------------------------------------------------------
00004 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
00005 // ETH Zurich, and Freie Universitaet Berlin 2002-2012.
00006 //
00007 // This software is released under a three-clause BSD license:
00008 //  * Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 //  * Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //  * Neither the name of any author or any participating institution
00014 //    may be used to endorse or promote products derived from this software
00015 //    without specific prior written permission.
00016 // For a full list of authors, refer to the file AUTHORS.
00017 // --------------------------------------------------------------------------
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
00022 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // --------------------------------------------------------------------------
00031 // $Maintainer: Timo Sachsenberg $
00032 // $Authors: Andreas Bertsch $
00033 // --------------------------------------------------------------------------
00034 //
00035 #ifndef OPENMS_COMPARISON_SPECTRA_SPECTRUMALIGNMENT_H
00036 #define OPENMS_COMPARISON_SPECTRA_SPECTRUMALIGNMENT_H
00037 
00038 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00039 
00040 #include <vector>
00041 #include <map>
00042 #include <utility>
00043 #include <algorithm>
00044 
00045 #define ALIGNMENT_DEBUG
00046 #undef  ALIGNMENT_DEBUG
00047 
00048 namespace OpenMS
00049 {
00050 
00062   class OPENMS_DLLAPI SpectrumAlignment :
00063     public DefaultParamHandler
00064   {
00065 public:
00066 
00067     // @name Constructors and Destructors
00068     // @{
00070     SpectrumAlignment();
00071 
00073     SpectrumAlignment(const SpectrumAlignment & source);
00074 
00076     virtual ~SpectrumAlignment();
00077 
00079     SpectrumAlignment & operator=(const SpectrumAlignment & source);
00080     // @}
00081 
00082     template <typename SpectrumType>
00083     void getSpectrumAlignment(std::vector<std::pair<Size, Size> > & alignment, const SpectrumType & s1, const SpectrumType & s2) const
00084     {
00085       if (!s1.isSorted() || !s2.isSorted())
00086       {
00087         throw Exception::IllegalArgument(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Input to SpectrumAlignment is not sorted!");
00088       }
00089       // clear result
00090       alignment.clear();
00091 
00092       double tolerance = (double)param_.getValue("tolerance");
00093       std::map<Size, std::map<Size, std::pair<Size, Size> > > traceback;
00094       std::map<Size, std::map<Size, double> > matrix;
00095 
00096       // init the matrix with "gap costs" tolerance
00097       matrix[0][0] = 0;
00098       for (Size i = 1; i <= s1.size(); ++i)
00099       {
00100         matrix[i][0] = i * tolerance;
00101         traceback[i][0]  = std::make_pair(i - 1, 0);
00102       }
00103       for (Size j = 1; j <= s2.size(); ++j)
00104       {
00105         matrix[0][j] = j * tolerance;
00106         traceback[0][j] = std::make_pair(0, j - 1);
00107       }
00108 
00109       // fill in the matrix
00110       Size left_ptr(1);
00111       Size last_i(0), last_j(0);
00112 
00113       //Size off_band_counter(0);
00114       for (Size i = 1; i <= s1.size(); ++i)
00115       {
00116         double pos1(s1[i - 1].getMZ());
00117 
00118         for (Size j = left_ptr; j <= s2.size(); ++j)
00119         {
00120           bool off_band(false);
00121           // find min of the three possible directions
00122           double pos2(s2[j - 1].getMZ());
00123           double diff_align = fabs(pos1 - pos2);
00124 
00125           // running off the right border of the band?
00126           if (pos2 > pos1 && diff_align > tolerance)
00127           {
00128             if (i < s1.size() && j < s2.size() && s1[i].getMZ() < pos2)
00129             {
00130               off_band = true;
00131             }
00132           }
00133 
00134           // can we tighten the left border of the band?
00135           if (pos1 > pos2 && diff_align > tolerance && j > left_ptr + 1)
00136           {
00137             ++left_ptr;
00138           }
00139 
00140           double score_align = diff_align;
00141 
00142           if (matrix.find(i - 1) != matrix.end() && matrix[i - 1].find(j - 1) != matrix[i - 1].end())
00143           {
00144             score_align += matrix[i - 1][j - 1];
00145           }
00146           else
00147           {
00148             score_align += (i - 1 + j - 1) * tolerance;
00149           }
00150 
00151           double score_up = tolerance;
00152           if (matrix.find(i) != matrix.end() && matrix[i].find(j - 1) != matrix[i].end())
00153           {
00154             score_up += matrix[i][j - 1];
00155           }
00156           else
00157           {
00158             score_up += (i + j - 1) * tolerance;
00159           }
00160 
00161           double score_left = tolerance;
00162           if (matrix.find(i - 1) != matrix.end() && matrix[i - 1].find(j) != matrix[i - 1].end())
00163           {
00164             score_left += matrix[i - 1][j];
00165           }
00166           else
00167           {
00168             score_left += (i - 1 + j) * tolerance;
00169           }
00170 
00171 #ifdef ALIGNMENT_DEBUG
00172           cerr << i << " " << j << " " << left_ptr << " " << pos1 << " " << pos2 << " " << score_align << " " << score_left << " " << score_up << endl;
00173 #endif
00174 
00175           if (score_align <= score_up && score_align <= score_left && diff_align <= tolerance)
00176           {
00177             matrix[i][j] = score_align;
00178             traceback[i][j] = std::make_pair(i - 1, j - 1);
00179             last_i = i;
00180             last_j = j;
00181           }
00182           else
00183           {
00184             if (score_up <= score_left)
00185             {
00186               matrix[i][j] = score_up;
00187               traceback[i][j] = std::make_pair(i, j - 1);
00188             }
00189             else
00190             {
00191               matrix[i][j] = score_left;
00192               traceback[i][j] = std::make_pair(i - 1, j);
00193             }
00194           }
00195 
00196           if (off_band)
00197           {
00198             break;
00199           }
00200         }
00201       }
00202 
00203       //last_i = s1.size() + 1;
00204       //last_j = s2.size() + 1;
00205 
00206       //cerr << last_i << " " << last_j << endl;
00207 
00208 #ifdef ALIGNMENT_DEBUG
00209 #if 0
00210       cerr << "TheMatrix: " << endl << " \t  \t";
00211       for (Size j = 0; j != s2.size(); ++j)
00212       {
00213         cerr << s2[j].getPosition()[0] << " \t";
00214       }
00215       cerr << endl;
00216       for (Size i = 0; i <= s1.size(); ++i)
00217       {
00218         if (i != 0)
00219         {
00220           cerr << s1[i - 1].getPosition()[0] << " \t";
00221         }
00222         else
00223         {
00224           cerr << " \t";
00225         }
00226         for (Size j = 0; j <= s2.size(); ++j)
00227         {
00228           if (matrix.has(i) && matrix[i].has(j))
00229           {
00230             if (traceback[i][j].first == i - 1 && traceback[i][j].second == j - 1)
00231             {
00232               cerr << "\\";
00233             }
00234             else
00235             {
00236               if (traceback[i][j].first == i - 1 && traceback[i][j].second == j)
00237               {
00238                 cerr << "|";
00239               }
00240               else
00241               {
00242                 cerr << "-";
00243               }
00244             }
00245 
00246             cerr << matrix[i][j] << "  \t";
00247           }
00248           else
00249           {
00250             cerr << "-1  \t";
00251           }
00252         }
00253         cerr << endl;
00254       }
00255 #endif
00256 #endif
00257 
00258       // do traceback
00259       Size i = last_i;
00260       Size j = last_j;
00261 
00262       while (i >= 1 && j >= 1)
00263       {
00264         if (traceback[i][j].first == i - 1 && traceback[i][j].second == j - 1)
00265         {
00266           alignment.push_back(std::make_pair(i - 1, j - 1));
00267         }
00268         Size new_i = traceback[i][j].first;
00269         Size new_j = traceback[i][j].second;
00270 
00271         i = new_i;
00272         j = new_j;
00273       }
00274 
00275       std::reverse(alignment.begin(), alignment.end());
00276 
00277 #ifdef ALIGNMENT_DEBUG
00278 #if 0
00279       // print alignment
00280       cerr << "Alignment (size=" << alignment.size() << "): " << endl;
00281 
00282       Size i_s1(0), i_s2(0);
00283       for (vector<pair<Size, Size> >::const_reverse_iterator it = alignment.rbegin(); it != alignment.rend(); ++it, ++i_s1, ++i_s2)
00284       {
00285         while (i_s1 < it->first - 1)
00286         {
00287           cerr << i_s1 << " " << s1[i_s1].getPosition()[0] << " " << s1[i_s1].getIntensity() << endl;
00288           i_s1++;
00289         }
00290         while (i_s2 < it->second - 1)
00291         {
00292           cerr << " \t " <<  i_s2 << " " << s2[i_s2].getPosition()[0] << " " << s2[i_s2].getIntensity() << endl;
00293           i_s2++;
00294         }
00295         cerr << "(" << s1[it->first - 1].getPosition()[0] << " <-> " << s2[it->second - 1].getPosition()[0] << ") ("
00296              << it->first << "|" << it->second << ") (" << s1[it->first - 1].getIntensity() << "|" << s2[it->second - 1].getIntensity() << ")" << endl;
00297       }
00298 #endif
00299 #endif
00300 
00301     }
00302 
00303   };
00304 
00305 }
00306 #endif //OPENMS_COMPARISON_SPECTRA_SPECTRUMALIGNMENT_H

OpenMS / TOPP release 1.10.0 Documentation generated on Thu Mar 7 2013 09:42:44 using doxygen 1.7.1