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

PoseClusteringShiftSuperimposer.h (Maintainer: Clemens Groepl, Eva Lange)

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // --------------------------------------------------------------------------
00005 //                   OpenMS Mass Spectrometry Framework
00006 // --------------------------------------------------------------------------
00007 //  Copyright (C) 2003-2008 -- Oliver Kohlbacher, Knut Reinert
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Lesser General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //  This library is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //  Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with this library; if not, write to the Free Software
00021 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // --------------------------------------------------------------------------
00024 // $Maintainer: Clemens Groepl, Eva Lange $
00025 // --------------------------------------------------------------------------
00026 
00027 
00028 #ifndef OPENMS_ANALYSIS_MAPMATCHING_POSECLUSTERINGSHIFTSUPERIMPOSER_H
00029 #define OPENMS_ANALYSIS_MAPMATCHING_POSECLUSTERINGSHIFTSUPERIMPOSER_H
00030 
00031 #include <OpenMS/ANALYSIS/MAPMATCHING/BaseSuperimposer.h>
00032 #include <OpenMS/DATASTRUCTURES/DBoundingBox.h>
00033 #include <OpenMS/DATASTRUCTURES/Matrix.h>
00034 #include <OpenMS/DATASTRUCTURES/String.h>
00035 #include <OpenMS/ANALYSIS/MAPMATCHING/LinearMapping.h>
00036 
00037 
00038 #include <fstream>
00039 
00040 #define V_PoseClusteringShiftSuperimposer(bla) // std::cout << bla << std::endl;
00041 
00042 namespace OpenMS
00043 {
00044 
00060   template < typename MapT = FeatureMap<> >
00061   class PoseClusteringShiftSuperimposer
00062         : public BaseSuperimposer< MapT >
00063   {
00064   public:
00065 
00069     enum Maps
00070     {
00071       MODEL = 0,
00072       SCENE = 1
00073     };
00074 
00075     typedef BaseSuperimposer< MapT > Base;
00076 
00077   //protected:
00084 /*
00085   struct IntensityBoundingBoxTraits : Base::TraitsType
00086     {
00087       typedef typename Base::TraitsType::IntensityType CoordinateType;
00088     };
00089 */
00090   
00091 
00092   public:
00093 
00094     typedef 
00095 
00101     class Shift
00102     {
00103     public:
00104       typedef DoubleReal QualityType;
00105             
00106       Shift()
00107           : position_(0),
00108           quality_(0)
00109       {}
00110 
00111       Shift(Shift const & source)
00112           : position_(source.position_),
00113           quality_(source.quality_)
00114       {}
00115 
00116       Shift & operator= (Shift const & source)
00117       {
00118         position_ = source.position_;
00119         quality_ = source.quality_;
00120         return *this;
00121       }
00122 
00123       virtual ~Shift()
00124       {}
00125 
00126       typedef DPosition<2> PositionType;
00127       // typedef typename TraitsType::QualityType QualityType;
00128 
00130       const PositionType& getPosition() const
00131       {
00132         return position_;
00133       }
00134 
00136       PositionType& getPosition()
00137       {
00138         return position_;
00139       }
00140 
00142       void setPosition(const PositionType& position)
00143       {
00144         position_ = position;
00145       }
00146 
00148       QualityType getQuality() const
00149       {
00150         return quality_;
00151       }
00152 
00154       QualityType& getQuality()
00155       {
00156         return quality_;
00157       }
00158 
00160       void setQuality(QualityType quality)
00161       {
00162         quality_ = quality;
00163       }
00164 
00165       /*
00166 
00167       not used currently
00168 
00170       struct QualityLess : std::binary_function < Shift, Shift, bool >
00171       {
00172       bool operator () ( Shift const & left, Shift const & right ) const {return ( left.getQuality() < right.getQuality() );}
00173       bool operator () ( Shift const & left, QualityType const & right ) const {return ( left.getQuality() < right );}
00174       bool operator () ( QualityType const & left, Shift const & right ) const {return ( left< right.getQuality() );}
00175       bool operator () ( QualityType const & left, QualityType const & right ) const {return ( left < right );}
00176       };
00177       */
00178 
00179     protected:
00180       PositionType position_;
00181       QualityType quality_;
00182     };
00183 
00184     typedef typename Base::QualityType QualityType;
00185     typedef typename Base::PositionType PositionType;
00186     typedef typename Base::IntensityType IntensityType;
00187     typedef typename Base::PointType PointType;
00188     typedef typename Base::PointMapType PointMapType;
00189     typedef typename PositionType::CoordinateType CoordinateType;
00190     typedef DBoundingBox<2>  PositionBoundingBoxType;
00191     typedef DBoundingBox<1> IntensityBoundingBoxType;
00192     typedef std::vector <UInt> ElementBucketType;
00193     typedef Matrix < ElementBucketType > ElementBucketMatrixType;
00194     typedef Shift ShiftType;
00195     typedef Matrix < typename ShiftType::QualityType > ShiftQualityMatrixType;
00196     typedef Matrix < ShiftType > ShiftMatrixType;
00197     typedef LinearMapping FinalShiftType;
00198 
00199     using Base::setParameters;
00200     using Base::getParameters;
00201     using Base::subsections_;
00202     using Base::defaultsToParam_;
00203     using Base::param_;
00204     using Base::defaults_;
00205     using Base::setElementMap;
00206     using Base::getElementMap;
00207     using Base::final_transformation_;
00208 
00210     PoseClusteringShiftSuperimposer()
00211         : Base()
00212     {
00213       Base::setName(getProductName());
00214       
00215       defaults_.setValue("feature_map:bucket_size:RT",150.0,"Number of surrounding buckets of element indices to be considered when computing shifts.",true);
00216       defaults_.setValue("feature_map:bucket_size:MZ",4.0,"Number of surrounding buckets of element indices to be considered when computing shifts.",true);
00217       defaults_.setValue("transformation_space:shift_bucket_size:RT",5.0,"Defines the shift parameter's bucket size during histograming.");
00218       defaults_.setValue("transformation_space:shift_bucket_size:MZ",0.1,"Defines the shift parameter's bucket size during histograming.");
00219       defaults_.setValue("feature_map:bucket_window:RT",2,"Number of surrounding buckets of element indices to be considered when computing shifts.",true);
00220       defaults_.setValue("feature_map:bucket_window:MZ",1,"Number of surrounding buckets of element indices to be considered when computing shifts.",true);
00221       defaults_.setValue("transformation_space:bucket_window_shift:RT",2,"Number of surrounding buckets of shift indices to be considered when computing shifts.",true);
00222       defaults_.setValue("transformation_space:bucket_window_shift:MZ",1,"Number of surrounding buckets of shift indices to be considered when computing shifts.",true);
00223       subsections_.push_back("debug");
00224       
00225       defaultsToParam_();
00226     }
00227 
00229     virtual ~PoseClusteringShiftSuperimposer()
00230     {
00231       V_PoseClusteringShiftSuperimposer("~PoseClusteringShiftSuperimposer");
00232     }
00233 
00235     virtual void run()
00236     {
00237       // clear the member
00238       element_bucket_[RawDataPoint2D::RT].clear();
00239       element_bucket_[RawDataPoint2D::MZ].clear();
00240       shift_bucket_.clear();
00241 
00242       if ( !this->element_map_[MODEL]->empty() && !this->element_map_[SCENE]->empty() )
00243       {
00244         computeElementBuckets_();
00245         computeShiftBuckets_();
00246         computeShift_();
00247       }
00248       else
00249       {
00250         std::cerr << "PoseClusteringShiftSuperimposer::run():  Oops, one of the element maps is empty!\n";
00251       }
00252     }
00253 
00255     static BaseSuperimposer<PointMapType>* create()
00256     {
00257       return new PoseClusteringShiftSuperimposer();
00258     }
00259 
00261     static const String getProductName()
00262     {
00263       return "poseclustering_shift";
00264     }
00265 
00267     void setShiftBucketSize(UInt dim, double shift_bucket_size)
00268     {
00269       shift_bucket_size_[dim] = shift_bucket_size;
00270       param_.setValue( String("transformation_space:shift_bucket_size:") + RawDataPoint2D::shortDimensionName(dim), (float)shift_bucket_size);
00271     }
00272 
00274     double getShiftBucketSize(UInt dim) const
00275     {
00276       return shift_bucket_size_[dim];
00277     }
00278 
00280     void setElementBucketWindow(UInt dim, UInt element_bucket_window)
00281     {
00282       element_bucket_window_[dim] = element_bucket_window;
00283       param_.setValue(String("feature_map:bucket_window:") + RawDataPoint2D::shortDimensionName(dim), (int)element_bucket_window);
00284     }
00285 
00287     UInt getElementBucketWindow(UInt dim) const
00288     {
00289       return element_bucket_window_[dim];
00290     }
00291 
00293     void setShiftBucketWindow(UInt dim, UInt shift_bucket_window)
00294     {
00295       shift_bucket_window_[dim] = shift_bucket_window;
00296       param_.setValue(String("transformation_space:bucket_window_shift:") + RawDataPoint2D::shortDimensionName(dim), (int)shift_bucket_window);
00297     }
00298 
00300     UInt getShiftBucketWindow(UInt dim) const
00301     {
00302       return shift_bucket_window_[dim];
00303     }
00304   protected:
00305     virtual void updateMembers_()
00306     {
00307       shift_bucket_size_[0] = (CoordinateType)param_.getValue("transformation_space:shift_bucket_size:RT");
00308       shift_bucket_size_[1] = (CoordinateType)param_.getValue("transformation_space:shift_bucket_size:MZ");
00309       element_bucket_window_[0] = (UInt)param_.getValue("feature_map:bucket_window:RT");
00310       element_bucket_window_[1] = (UInt)param_.getValue("feature_map:bucket_window:MZ");
00311       shift_bucket_window_[0] = (UInt)param_.getValue("transformation_space:bucket_window_shift:RT");
00312       shift_bucket_window_[1] = (UInt)param_.getValue("transformation_space:bucket_window_shift:MZ");
00313       element_bucket_size_[0] = (CoordinateType)param_.getValue("feature_map:bucket_size:RT");
00314       element_bucket_size_[1] = (CoordinateType)param_.getValue("feature_map:bucket_size:MZ");
00315     }
00316 
00318     void computeElementBuckets_()
00319     {
00320 #define V_computeElementBuckets_(bla) V_PoseClusteringShiftSuperimposer(bla)
00321       V_computeElementBuckets_("@@@ computeElementBuckets_()");
00322 
00323       // Shorthands ...
00324       PositionType & fbs = element_bucket_size_;
00325 
00326       for ( UInt map_index = 0; map_index < 2; ++map_index )
00327       {
00328         // Shorthands ...
00329         V_computeElementBuckets_("\n--- map_index: "<<map_index);
00330         PointMapType const     & fm     = getElementMap(map_index);
00331         PositionBoundingBoxType  & fmpbb  = element_map_position_bounding_box_[map_index] ;
00332         IntensityBoundingBoxType & fmibb  = element_map_intensity_bounding_box_[map_index];
00333 
00334         fmpbb.clear();
00335         fmibb.clear();
00336 
00337         // Compute the bounding box for the element map, with respect to
00338         // position and intensity.
00339         for ( typename PointMapType::ConstIterator fm_iter = fm.begin();
00340               fm_iter != fm.end();
00341               ++fm_iter
00342             )
00343         {
00344           fmpbb.enlarge(fm_iter->getPosition());
00345           fmibb.enlarge(fm_iter->getIntensity());
00346         }
00347         V_computeElementBuckets_("fmpbb: "<<fmpbb<<"fmibb: "<<fmibb);
00348       }
00349 
00350       // Next we will enlarge each element_map_position_bounding_box_ such
00351       // that all buckets will have the same diagonal.  To provide against
00352       // rounding errors, we allocate one bucket more than needed (in each
00353       // dimension) and shift the grid by one-half of the difference.
00354       for ( UInt map_index = 0; map_index < 2; ++map_index )
00355       {
00356         // Shorthands ...
00357         V_computeElementBuckets_("\n--- map_index: "<<map_index);
00358         PointMapType          const & fm     = getElementMap(map_index);
00359         PositionBoundingBoxType const & fmpbb  = element_map_position_bounding_box_[map_index] ;
00360         PositionBoundingBoxType       & fmpbbe = element_map_position_bounding_box_enlarged_[map_index] ;
00361         ElementBucketMatrixType       & fb     = element_bucket_[map_index];
00362 
00363         // Compute num_buckets.  Compute extra margin to make bounding box a
00364         // multiple of element buckets.
00365         PositionType const diagonal = fmpbb.diagonal();
00366         PositionType diagonal_enlarged;
00367         V_computeElementBuckets_("diagonal: " << diagonal);
00368         int num_buckets[2];
00369         for ( UInt dimension = 0; dimension < 2; ++dimension)
00370         {
00371           num_buckets[dimension] = int(1.1 + diagonal[dimension]/fbs[dimension]);
00372           diagonal_enlarged[dimension] = fbs[dimension] * num_buckets[dimension];
00373         }
00374         V_computeElementBuckets_("num_buckets: "<<num_buckets[RawDataPoint2D::RT]<<' '<<num_buckets[RawDataPoint2D::MZ]);
00375         V_computeElementBuckets_("diagonal_enlarged: "<<diagonal_enlarged);
00376 
00377         // The extra margin.
00378         PositionType extra_element_bucket_size_(diagonal_enlarged-diagonal);
00379         extra_element_bucket_size_ /= 2;
00380         V_computeElementBuckets_("efbs: " << extra_element_bucket_size_);
00381 
00382         // Compute the enlarged element map bounding box accordingly.
00383         fmpbbe.clear();
00384         fmpbbe.enlarge( fmpbb.min() - extra_element_bucket_size_ );
00385         fmpbbe.enlarge( fmpbb.max() + extra_element_bucket_size_ );
00386         V_computeElementBuckets_("fmpbbe: "<<fmpbbe);
00387 
00388         // Resize element_bucket_[map_index] accordingly.
00389         fb.resize(num_buckets[RawDataPoint2D::RT],num_buckets[RawDataPoint2D::MZ]);
00390         V_computeElementBuckets_("rows: "<<fb.rows()<<"  cols: "<<fb.cols());
00391 
00392         // Now, finally, we store the indices of the elements in their
00393         // corresponding buckets.
00394         PositionType const & fmpbbe_min = fmpbbe.min();
00395         for ( UInt index= 0; index < fm.size(); ++index )
00396         {
00397           PositionType position = fm[index].getPosition() - fmpbbe_min;
00398           fb ( UInt(position[RawDataPoint2D::RT]/fbs[RawDataPoint2D::RT]), UInt(position[RawDataPoint2D::MZ]/fbs[RawDataPoint2D::MZ]) ).push_back(index);
00399         }
00400 
00401         // Optionally, write debug output as specified in param.
00402         if ( getParameters().exists("debug:feature_buckets_file") )
00403         {
00404           String const element_buckets_file = (String)getParameters().getValue("debug:feature_buckets_file") + String(map_index?"_SCENE":"_MODEL");
00405           std::ofstream dump_file(element_buckets_file.c_str());
00406           std::cerr << "### Writing "<<element_buckets_file<<std::endl;
00407           dump_file << "# " << element_buckets_file << " generated " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString() << std::endl;
00408           dump_file << "# Positions of elements in non-empty element buckets" << std::endl;
00409           for ( ElementBucketMatrixType::ConstIterator iter = fb.begin(); iter != fb.end(); ++iter)
00410           {
00411             if (iter->empty())
00412               continue;
00413             std::pair<UInt,UInt> row_col = fb.indexPair(iter-fb.begin());
00414             dump_file << row_col.first << ' ' << row_col.second << " #bucket" << std::endl;
00415             for ( ElementBucketType::const_iterator viter = iter->begin(); viter != iter->end(); ++viter)
00416             {
00417               dump_file << fm[*viter].getRT() <<' '<<fm[*viter].getMZ() << std::endl;
00418             }
00419             dump_file << std::endl;
00420           }
00421           dump_file << "# " << element_buckets_file << " EOF " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString() << std::endl;
00422         }
00423       }
00424 
00425       return;
00426 #undef V_computeElementBuckets_
00427 
00428     } // computeElementBuckets_
00429 
00430 
00436     void computeShiftBuckets_()
00437     {
00438 #define V_computeShiftBuckets_(bla) V_PoseClusteringShiftSuperimposer(bla)
00439       V_computeShiftBuckets_("\n");
00440       V_computeShiftBuckets_("@@@ computeShiftBuckets_()");
00441 
00442       // Shorthands ...
00443       ShiftQualityMatrixType & tb      = shift_bucket_;
00444       PositionType                 & tbs     = shift_bucket_size_;
00445       PositionBoundingBoxType      & tbb     = shift_bounding_box_ ;
00446       PositionBoundingBoxType      & tbbe    = shift_bounding_box_enlarged_ ;
00447       UInt                   const (&fbw)[2] = element_bucket_window_;
00448       //         ShiftMatrixType        & tm      = shift_matrix_;
00449 
00450       // Compute the bounding box for the shift map
00451       {
00452         tbb.clear();
00453         tbb.enlarge ( element_map_position_bounding_box_[SCENE].min() - element_map_position_bounding_box_[MODEL].min() );
00454         tbb.enlarge ( element_map_position_bounding_box_[SCENE].min() - element_map_position_bounding_box_[MODEL].max() );
00455         tbb.enlarge ( element_map_position_bounding_box_[SCENE].max() - element_map_position_bounding_box_[MODEL].min() );
00456         tbb.enlarge ( element_map_position_bounding_box_[SCENE].max() - element_map_position_bounding_box_[MODEL].max() );
00457       }
00458       V_computeShiftBuckets_("tbb: "<<tbb);
00459 
00460       // Next we will enlarge each bucket_size_ such that all buckets will
00461       // have the same diagonal.  To provide against rounding errors, we
00462       // allocate one bucket more than needed (in each dimension) and shift
00463       // the grid by one-half.
00464 
00465       PositionType half_of_shift_bucket_size_(tbs);
00466       half_of_shift_bucket_size_ /= 2;
00467       V_computeShiftBuckets_("hotbs: " << half_of_shift_bucket_size_);
00468 
00469       // Adjust the enlarged shift map bounding box accordingly.
00470       {
00471         tbbe.clear();
00472         tbbe.enlarge( tbb.min() - half_of_shift_bucket_size_ );
00473         tbbe.enlarge( tbb.max() + half_of_shift_bucket_size_ );
00474       }
00475       V_computeShiftBuckets_("tbbe: "<<tbbe);
00476 
00477       // Compute shift_bucket_size_ and num_buckets.
00478       PositionType diagonal = tbbe.diagonal();
00479       V_computeShiftBuckets_("diagonal: " << diagonal);
00480       int num_buckets[2];
00481       for ( UInt dimension = 0; dimension < 2; ++dimension)
00482       {
00483         num_buckets[dimension] = int(diagonal[dimension]/tbs[dimension]);
00484         tbs[dimension] = diagonal[dimension] / num_buckets[dimension];
00485       }
00486       V_computeShiftBuckets_("tbs: "<<tbs);
00487 
00488       // Resize shift_bucket_ accordingly.
00489       tb.resize(num_buckets[RawDataPoint2D::RT]+1,num_buckets[RawDataPoint2D::MZ]+1);
00490       V_computeShiftBuckets_("rows: "<<tb.rows()<<"  cols: "<<tb.cols());
00491 
00492       // Clear the shift buckets.
00493       std::fill(tb.begin(),tb.end(),QualityType(0));
00494 
00495 
00496       // Resize shift_matrix_ according to element_bucket_[RawDataPoint2D::MZ]
00497       //         tm.resize(element_bucket_[RawDataPoint2D::MZ].sizePair());
00498 
00499       // Now we store the shifts for all relevant element pairs in their
00500       // corresponding buckets.  Each shift is distributed among its
00501       // four neighboring "buckets", with weights according to the distances
00502       // from these corner points.  Note that the outer two loops (over i and
00503       // j) enumerate the "image" (element_bucket_[RawDataPoint2D::MZ]), then we search for
00504       // "pre-images" (element_bucket_[0}) in the two inner loops (over k and
00505       // l).  (And of course, finally, we enumerate all element pairs.)  This
00506       // way we can associate the shifts vectors to buckets of the
00507       // image, and when we will later apply it, we will not change the
00508       // pre-image, which might be a consensus or so.
00509 #define V_computeShiftBuckets_enumeration(bla) V_computeShiftBuckets_(bla)
00510 
00511       // progress dots
00512       Int progress_dots = 0;
00513       if (this->param_.exists("debug::progress_dots"))
00514       {
00515         progress_dots = (Int)this->param_.getValue("debug:progress_dots");
00516       }
00517 
00518       PositionType const & tbbe_min = tbbe.min();
00519 
00520       // Compute the index shift of corresponding element buckets of model and scene.
00521       PositionType const fmpbbe_min_offset =
00522         element_map_position_bounding_box_enlarged_[SCENE].min() -
00523         element_map_position_bounding_box_enlarged_[MODEL].min();
00524       int const element_buckets_index_offset_RT = int ( fmpbbe_min_offset[RawDataPoint2D::RT] / element_bucket_size_[RawDataPoint2D::RT] );
00525       int const element_buckets_index_offset_MZ = int ( fmpbbe_min_offset[RawDataPoint2D::MZ] / element_bucket_size_[RawDataPoint2D::MZ] );
00526 
00527       // iterate over buckets of scene
00528       for ( UInt scene_bucket_index_RT = 0;
00529             scene_bucket_index_RT < element_bucket_[SCENE].rows();
00530             ++scene_bucket_index_RT
00531           )
00532       {
00533         for ( UInt scene_bucket_index_MZ = 0;
00534               scene_bucket_index_MZ < element_bucket_[SCENE].cols();
00535               ++scene_bucket_index_MZ
00536             )
00537         {
00538 
00539           // compute the corresponding bucket in the model
00540           int const model_bucket_index_center_RT = scene_bucket_index_RT + element_buckets_index_offset_RT;
00541           int const model_bucket_index_center_MZ = scene_bucket_index_MZ + element_buckets_index_offset_MZ;
00542 
00543           // iterate over buckets of model
00544           for ( int model_bucket_index_RT
00545                 =  std::max<int>( model_bucket_index_center_RT - fbw[RawDataPoint2D::RT], 0 );
00546                 model_bucket_index_RT
00547                 <= std::min<int>( model_bucket_index_center_RT + fbw[RawDataPoint2D::RT], element_bucket_[MODEL].rows()-1 );
00548                 ++model_bucket_index_RT
00549               )
00550           {
00551             for ( int model_bucket_index_MZ
00552                   =  std::max<int>( model_bucket_index_center_MZ - fbw[RawDataPoint2D::MZ], 0 );
00553                   model_bucket_index_MZ
00554                   <= std::min<int>( model_bucket_index_center_MZ + fbw[RawDataPoint2D::MZ], element_bucket_[MODEL].cols()-1 );
00555                   ++model_bucket_index_MZ
00556                 )
00557             {
00558               // iterate over pairs of elements for this pair of buckets
00559               int number_of_considered_element_pairs_for_this_pair_of_buckets = 0;
00560               ElementBucketType const & model_element_bucket
00561               = element_bucket_[MODEL]
00562                 ( model_bucket_index_RT, model_bucket_index_MZ );
00563               for ( ElementBucketType::const_iterator model_iter = model_element_bucket.begin();
00564                     model_iter != model_element_bucket.end();
00565                     ++model_iter
00566                   )
00567               {
00568                 ElementBucketType const & scene_element_bucket
00569                 = element_bucket_[SCENE]( scene_bucket_index_RT, scene_bucket_index_MZ );
00570                 for ( ElementBucketType::const_iterator scene_iter = scene_element_bucket.begin();
00571                       scene_iter != scene_element_bucket.end();
00572                       ++scene_iter
00573                     )
00574                 {
00575                   // Compute the shift corresponding to a pair of elements.
00576                   ShiftType shift = shift_( getElementMap(0)[*model_iter],
00577                                             getElementMap(1)[*scene_iter] );
00578                   //                     V_computeShiftBuckets_enumeration("shift: "<< shift.getPosition());
00579                   //                     V_computeShiftBuckets_enumeration("shift: "<< shift.getQuality());
00580 
00581                   PositionType tpwm = shift.getPosition();
00582                   tpwm -= tbbe_min;
00583                   // V_computeShiftBuckets_enumeration("trans.pos wrt tbbe_min: "<< shift.getPosition());
00584 
00585                   QualityType  const & tq = shift.getQuality();
00586 
00587                   // Compute the bucket index (the lowest of the four) for
00588                   // this shift.  Also compute the fractional part of
00589                   // the position within the bucket.
00590                   UInt bucket_index[2];
00591                   PositionType bucket_fraction;
00592                   for ( UInt dimension = 0; dimension < 2; ++dimension )
00593                   {
00594                     bucket_fraction[dimension] = tpwm[dimension] / tbs[dimension];  // floating point division
00595                     bucket_index[dimension]    = (UInt) bucket_fraction[dimension]; // round down (yes we are >= 0)
00596                     bucket_fraction[dimension] -= bucket_index[dimension];          // fractional part
00597                   }
00598                   PositionType bucket_fraction_complement(1,1);
00599                   bucket_fraction_complement -= bucket_fraction;
00600 
00601                   // Distribute the quality of the shift among the four neighboring buckets.
00602                   QualityType factor;
00603 
00604                   factor = bucket_fraction_complement[RawDataPoint2D::RT] * bucket_fraction_complement[RawDataPoint2D::MZ];
00605                   tb( bucket_index[RawDataPoint2D::RT], bucket_index[RawDataPoint2D::MZ] ) += tq * factor;
00606 
00607                   factor = bucket_fraction_complement[RawDataPoint2D::RT] * bucket_fraction[RawDataPoint2D::MZ];
00608                   tb( bucket_index[RawDataPoint2D::RT], bucket_index[RawDataPoint2D::MZ] + 1 ) += tq * factor;
00609 
00610                   factor = bucket_fraction[RawDataPoint2D::RT] * bucket_fraction_complement[RawDataPoint2D::MZ];
00611                   tb( bucket_index[RawDataPoint2D::RT] + 1, bucket_index[RawDataPoint2D::MZ] ) += tq * factor;
00612 
00613                   factor = bucket_fraction[RawDataPoint2D::RT] * bucket_fraction[RawDataPoint2D::MZ];
00614                   tb( bucket_index[RawDataPoint2D::RT] + 1, bucket_index[RawDataPoint2D::MZ] + 1 ) += tq * factor;
00615 
00616                   ++number_of_considered_element_pairs_for_this_pair_of_buckets;
00617 
00618                   if ( progress_dots &&
00619                        ! (number_of_considered_element_pairs_for_this_pair_of_buckets % progress_dots)
00620                      )
00621                   {
00622                     std::cout << 'H' << std::flush;
00623                   }
00624 
00625                 } // for scene_iter
00626               } // for model_iter
00627 
00628 #if 0 // debug output
00629               if ( number_of_considered_element_pairs_for_this_pair_of_buckets )
00630               {
00631                 std::cout <<
00632                 "s_b_i_RT, _MZ, m_b_i_c_RT, _MZ, m_b_i_RT, _MZ, number_pairs: " <<
00633                 scene_bucket_index_RT<<' '<<scene_bucket_index_MZ<<' '<<
00634                 model_bucket_index_center_RT<<' '<<model_bucket_index_center_MZ<<' '<<
00635                 model_bucket_index_RT<<' '<<model_bucket_index_MZ<<' '<<
00636                 number_of_considered_element_pairs_for_this_pair_of_buckets
00637                 ;
00638               }
00639 #endif
00640 
00641             } // for model_bucket_index_MZ
00642           } // for model_bucket_index_RT
00643         } // for scene_bucket_index_MZ
00644       } // for scene_bucket_index_RT
00645 
00646 #undef V_computeShiftBuckets_enumeration
00647 
00648       // Optionally, write debug output as specified in param.
00649       if ( getParameters().exists("debug:dump_shift_buckets") )
00650       {
00651         String dump_filename = getParameters().getValue("debug:dump_shift_buckets");
00652         std::ofstream dump_file(dump_filename.c_str());
00653         V_computeShiftBuckets_("### Writing "<<dump_filename);
00654         dump_file << "# " << dump_filename << " generated " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString() << std::endl;
00655         dump_file << "# Shift buckets: xcoord ycoord quality xindex yindex" << std::endl;
00656 
00657         for ( typename ShiftQualityMatrixType::ConstIterator iter = tb.begin(); iter != tb.end(); ++iter)
00658         {
00659           std::pair<UInt,UInt> row_col = tb.indexPair(iter-tb.begin());
00660           if ( *iter )
00661           {
00662             dump_file << tbbe_min[RawDataPoint2D::RT] + tbs[RawDataPoint2D::RT] * row_col.first << ' '
00663             << tbbe_min[RawDataPoint2D::MZ] + tbs[RawDataPoint2D::MZ] * row_col.second << ' '
00664             << *iter << ' '
00665             << row_col.first << ' '
00666             << row_col.second
00667             << " #tb" << std::endl ;
00668           }
00669         }
00670         dump_file << "# " << dump_filename << " EOF " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString() << std::endl;
00671       }
00672 
00673 #undef V_computeShiftBuckets_
00674 
00675     } // computeShiftBuckets_
00676 
00677 
00678 
00683     void computeShift_()
00684     {
00685 #define V_computeShift_(bla) V_PoseClusteringShiftSuperimposer(bla)
00686       V_computeShift_("@@@ computeShift_()");
00687 
00688       ShiftType shift;
00689 
00690       // Shorthands ...
00691       ShiftQualityMatrixType const & tb = shift_bucket_;
00692       PositionType const & tbs = shift_bucket_size_;
00693       UInt const (&tbw)[2] = shift_bucket_window_;
00694 
00695       // Find the transformation bucket with highest impact (quality).
00696       UInt tb_max_element_index = std::max_element(tb.begin(),tb.end()) - tb.begin();
00697       UInt tb_max_indices[2];
00698       tb_max_indices[RawDataPoint2D::RT] = tb.rowIndex(tb_max_element_index);
00699       tb_max_indices[RawDataPoint2D::MZ] = tb.colIndex(tb_max_element_index);
00700       V_computeShift_("tb_max: "<<tb_max_indices[RawDataPoint2D::RT]<<' '<<tb_max_indices[RawDataPoint2D::MZ]<<" quality="<<tb(tb_max_indices[RawDataPoint2D::RT],tb_max_indices[RawDataPoint2D::MZ]));
00701 
00702       // Compute a weighted average of the shifts nearby the tb_max_element.
00703       //ShiftType result; // initially zero
00704 
00705       PositionType const& tbbe_min = shift_bounding_box_enlarged_.min();
00706       int tb_run_indices[2];
00707       for ( tb_run_indices[RawDataPoint2D::RT]  = std::max ( int (tb_max_indices[RawDataPoint2D::RT] - tbw[RawDataPoint2D::RT]), 0 );
00708             tb_run_indices[RawDataPoint2D::RT] <= std::min ( int (tb_max_indices[RawDataPoint2D::RT] + tbw[RawDataPoint2D::RT]), int (tb.rows()) - 1 );
00709             ++tb_run_indices[RawDataPoint2D::RT]
00710           )
00711       {
00712         for ( tb_run_indices[RawDataPoint2D::MZ]  = std::max ( int (tb_max_indices[RawDataPoint2D::MZ] - tbw[RawDataPoint2D::MZ]), 0 );
00713               tb_run_indices[RawDataPoint2D::MZ] <= std::min ( int (tb_max_indices[RawDataPoint2D::MZ] + tbw[RawDataPoint2D::MZ]), int (tb.cols()) - 1 );
00714               ++tb_run_indices[RawDataPoint2D::MZ]
00715             )
00716         {
00717           PositionType contribution_position(tbs);
00718           for ( UInt dimension = 0; dimension < 2; ++dimension)
00719           {
00720             contribution_position[dimension] *= tb_run_indices[dimension];
00721           }
00722           contribution_position += tbbe_min;
00723           QualityType contribution_quality = tb( tb_run_indices[RawDataPoint2D::RT], tb_run_indices[RawDataPoint2D::MZ] );
00724           shift.getQuality() += contribution_quality;
00725           contribution_position *= contribution_quality;
00726           shift.getPosition() += contribution_position;
00727         }
00728       }
00729       if ( shift.getQuality() != 0 )
00730       {
00731         // ???? we need to shift the opposite way!  Found that out by try-and-error.  Clemens
00732         shift.getPosition() /= -shift.getQuality() ;
00733       }
00734       else
00735       {
00736         // result.getPosition() is irrelevant anyway
00737       }
00738 
00739       // Assign the result.
00740       for ( int dim = 0; dim < 2; ++dim )
00741       {
00742         // set slope and intercept
00743         final_transformation_[dim].setSlope(1.0);
00744         final_transformation_[dim].setIntercept(shift.getPosition()[dim]);
00745         V_computeShift_("computeShift_() hat geklappt: " << shift.getPosition()[dim]);
00746       }
00747 
00748 
00749 #undef V_computeShift_
00750 
00751     } // computeShift_
00752 
00753 
00766     ShiftType shift_( PointType const & left, PointType const & right ) const
00767     {
00768       ShiftType shift;
00769       shift.setPosition(right.getPosition() - left.getPosition());
00770       if ( right.getIntensity() == 0 )
00771         shift.setQuality(0);
00772       QualityType result = left.getIntensity() / right.getIntensity();
00773       shift.setQuality( result <= 1. ? result : 1. / result );
00774       return shift;
00775     }
00776 
00778     PositionBoundingBoxType  element_map_position_bounding_box_[2];
00779 
00782     PositionBoundingBoxType  element_map_position_bounding_box_enlarged_[2];
00783 
00785     IntensityBoundingBoxType element_map_intensity_bounding_box_[2];
00786 
00788     ElementBucketMatrixType element_bucket_[2];
00789 
00791     PositionType element_bucket_size_;
00792 
00794     ShiftQualityMatrixType shift_bucket_;
00795 
00797     PositionBoundingBoxType shift_bounding_box_;
00798 
00801     PositionBoundingBoxType shift_bounding_box_enlarged_;
00802 
00804     PositionType shift_bucket_size_;
00805 
00808     UInt element_bucket_window_[2];
00809 
00812     UInt shift_bucket_window_[2];
00813   }
00814   ; // PoseClusteringShiftSuperimposer
00815 
00816 } // namespace OpenMS
00817 
00818 #endif  // OPENMS_ANALYSIS_MAPMATCHING_PoseClusteringShiftSuperimposer_H

Generated Tue Apr 1 15:36:37 2008 -- using doxygen 1.5.4 OpenMS / TOPP 1.1