00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OPENMS_ANALYSIS_MAPMATCHING_STARALIGNMENT_H
00029 #define OPENMS_ANALYSIS_MAPMATCHING_STARALIGNMENT_H
00030
00031 #include <OpenMS/ANALYSIS/MAPMATCHING/BaseAlignment.h>
00032 #include <OpenMS/ANALYSIS/MAPMATCHING/ElementPair.h>
00033 #include <OpenMS/ANALYSIS/MAPMATCHING/MapMatcherRegression.h>
00034 #include <OpenMS/KERNEL/DPeakConstReferenceArray.h>
00035 #include <OpenMS/KERNEL/ConsensusFeature.h>
00036 #include <OpenMS/KERNEL/StandardTypes.h>
00037
00038
00039 #define DEBUG_ALIGNMENT
00040 #undef DEBUG_ALIGNMENT
00041
00042 namespace OpenMS
00043 {
00066 template < typename ConsensusElementT = ConsensusFeature< FeatureMap < > > >
00067 class StarAlignment : public BaseAlignment< ConsensusElementT >
00068 {
00069 public:
00073 enum Maps
00074 {
00075 MODEL = 0,
00076 SCENE = 1
00077 };
00078
00080 typedef BaseAlignment< ConsensusElementT > Base;
00081 typedef typename Base::ConsensusElementType ConsensusElementType;
00082 typedef typename Base::ElementType ElementType;
00083 typedef typename Base::ElementContainerType ElementContainerType;
00084 typedef typename Base::ConsensusVectorType ConsensusVectorType;
00085
00087 typedef DPeakConstReferenceArray< ElementContainerType > PeakConstReferenceMapType;
00088
00090 typedef DPosition < 2 > PositionType;
00091
00093 typedef DoubleReal QualityType;
00094
00096 typedef DoubleReal IntensityType;
00097
00099 typedef ElementPair < ConsensusElementType > ElementPairType;
00100
00102 typedef std::vector < ConsensusElementType > ConsensusElementPairVectorType;
00103
00105 typedef std::vector < ElementType > ElementPairVectorType;
00106
00107 using Base::param_;
00108 using Base::final_consensus_map_;
00109 using Base::transformations_;
00110 using Base::map_type_;
00111
00113 StarAlignment()
00114 : Base(),
00115 reference_map_index_(0)
00116 {
00117
00118 this->setName("StarAlignment");
00119 Base::subsections_.push_back("matching_algorithm");
00120 Base::subsections_.push_back("consensus_algorithm");
00121
00122 Base::defaultsToParam_();
00123 }
00124
00126 virtual ~StarAlignment()
00127 {}
00128
00130 void setReferenceMapIndex(UInt index) throw (Exception::InvalidValue)
00131 {
00132 if (index > final_consensus_map_.getMapVector().size())
00133 {
00134 throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__,"The index is not contained in the vector of element containers.","") ;
00135 }
00136 else
00137 {
00138 reference_map_index_ = index;
00139 }
00140 }
00142 UInt getReferenceMapIndex() const
00143 {
00144 return reference_map_index_;
00145 }
00146
00148 virtual void run() throw (Exception::InvalidValue)
00149 {
00150 if (final_consensus_map_.getMapVector().size() < 2)
00151 {
00152 throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__,"Take at least 2 maps for alignment.","") ;
00153 }
00154 else
00155 {
00156 assignReferenceMap_();
00157 }
00158 #ifdef DEBUG_ALIGNMENT
00159 std::cout << "*** Reference Map is " << final_consensus_map_.getFilenames()[reference_map_index_] << " ***" << std::endl;
00160 #endif
00161
00162 if (map_type_ == "feature_map")
00163 {
00164 alignMultipleFeatureMaps_();
00165 }
00166 else
00167 {
00168 if (map_type_ == "consensus_map")
00169 {
00170 alignMultipleConsensusMaps_();
00171 }
00172 else
00173 {
00174 if (map_type_ == "peak_map")
00175 {
00176 alignMultiplePeakMaps_();
00177 }
00178 else
00179 {
00180 throw Exception::InvalidValue(__FILE__, __LINE__, __PRETTY_FUNCTION__,"Wrong map type. Choose \"feature_map\", \"peak_map\" or \"consensus_map\".","") ;
00181 }
00182 }
00183
00184 }
00185 }
00186
00187
00189 virtual String getAlignmentTree() const
00190 {
00191 String tree;
00192 UInt n = final_consensus_map_.getMapVector().size();
00193 tree = '(';
00194 UInt j = 0;
00195 for (UInt i = 0; i < n; ++i)
00196 {
00197 if (i != reference_map_index_)
00198 {
00199 tree = tree + '(' + reference_map_index_ + ":0," + i + ':' + (i+1) + "):0";
00200 ++j;
00201
00202 if (j < (n-1))
00203 {
00204 tree = tree + ',';
00205 }
00206 }
00207 }
00208 tree = tree + ')';
00209
00210 return tree;
00211 }
00212
00214 void merge(ConsensusMap < ConsensusElementType >& new_map)
00215 {
00216 final_consensus_map_.merge(new_map);
00217 }
00218
00219 protected:
00221 UInt reference_map_index_;
00222
00223
00225 void assignReferenceMap_()
00226 {
00227 UInt n = final_consensus_map_.getMapVector().size();
00228 UInt ref_index = 0;
00229 UInt max_number = final_consensus_map_.getMapVector()[ref_index]->size();
00230
00231 for (UInt i = 1; i < n; ++i)
00232 {
00233 if (n > max_number)
00234 {
00235 max_number = n;
00236 ref_index = i;
00237 }
00238 }
00239 reference_map_index_ = ref_index;
00240 }
00241
00243 void alignMultipleFeatureMaps_()
00244 {
00245 std::vector < ElementContainerType* >& element_map_vector = final_consensus_map_.getMapVector();
00246
00247 #ifdef DEBUG_ALIGNMENT
00248 std::cout << "*** Build a consensus map of the elements of the reference map (contains only singleton consensus elements) ***" << std::endl;
00249 #endif
00250
00251 ConsensusVectorType cons_ref_map;
00252 const ElementContainerType& map = *(element_map_vector[reference_map_index_]);
00253 UInt n = map.size();
00254 for (UInt i=0; i < n; ++i)
00255 {
00256 ConsensusElementType c(reference_map_index_,i,map[i]);
00257 final_consensus_map_.push_back(c);
00258 cons_ref_map.push_back(c);
00259 }
00260
00261 #ifdef DEBUG_ALIGNMENT
00262
00263
00264
00265
00266
00267
00268
00269 std::cout << "*** Compute the consensus map of all pairwise alignment ***" << std::endl;
00270 #endif
00271
00273 BasePairwiseMapMatcher< ConsensusVectorType >* pairwise_matcher_;
00274 pairwise_matcher_ = Factory<BasePairwiseMapMatcher< ConsensusVectorType > >::create("poseclustering_pairwise");
00275 pairwise_matcher_->setParameters(param_.copy("matching_algorithm:",true));
00276
00277 pairwise_matcher_->setElementMap(MODEL,cons_ref_map);
00278
00279 MapMatcherRegression<ConsensusElementType> lin_regression;
00280 UInt number_maps = element_map_vector.size();
00281 transformations_.resize(number_maps);
00282 #ifdef DEBUG_ALIGNMENT
00283
00284 UInt number_alignments = 0;
00285 #endif
00286
00287 for (UInt i = 0; i < number_maps; ++i)
00288 {
00289 std::cout.precision(10);
00290 if (i != reference_map_index_)
00291 {
00292 #ifdef DEBUG_ALIGNMENT
00293 std::cout << "*** Build a consensus map of map " << i << " *** " << final_consensus_map_.getFilenames()[i] << " ***" << std::endl;
00294 #endif
00295
00296
00297 ConsensusVectorType map;
00298 buildConsensusVectorType_(i,map);
00299
00300 #ifdef DEBUG_ALIGNMENT
00301
00302 std::cout << "*** Compute a transformation for each grid cell and find pairs in the reference_map_ and map " << i << " ***" << std::endl;
00303 #endif
00304
00305 pairwise_matcher_->setElementMap(SCENE, map);
00306 pairwise_matcher_->initGridTransformation(map);
00307 pairwise_matcher_->run();
00308
00309 #ifdef DEBUG_ALIGNMENT
00310
00311 std::cout << "*** Estimate for each grid cell a better transformation using the element pairs. number of pairs: " << pairwise_matcher_->getElementPairs().size() << " ***" << std::endl;
00312 #endif
00313
00314
00315 if (pairwise_matcher_->getElementPairs().size() > 2)
00316 {
00317
00318 lin_regression.setElementPairs(pairwise_matcher_->getElementPairs());
00319 lin_regression.setGrid(pairwise_matcher_->getGrid());
00320 lin_regression.setMinQuality(-1.);
00321 lin_regression.estimateTransform();
00322 std::cout << "Estimated Grid " << i << ": " << lin_regression.getGrid() << std::endl;
00323 transformations_[i] = lin_regression.getGrid();
00324 }
00325
00326 else
00327 {
00328 std::cout << "Superimposer Grid " << i << ": " << pairwise_matcher_->getGrid() << std::endl;
00329 transformations_[i] = pairwise_matcher_->getGrid();
00330 }
00331 #ifdef DEBUG_ALIGNMENT
00332
00333
00334 #endif
00335
00336
00337 UInt n = map.size();
00338 for (UInt j = 0; j < n; ++j)
00339 {
00340
00341
00342
00343 typename Grid::iterator grid_it = transformations_[i].begin();
00344 while ((grid_it != (transformations_[i]).end()))
00345 {
00346 IndexTuple< ElementContainerType > index_tuple(i,j,(*(element_map_vector[i]))[j]);
00347 PositionType pos = (*(element_map_vector[i]))[j].getPosition();
00348 if (grid_it->encloses(map[j].getPosition()))
00349 {
00350
00351 if (grid_it->getMappings().size() != 0)
00352 {
00353 grid_it->getMappings()[RawDataPoint2D::RT].apply(pos[RawDataPoint2D::RT]);
00354 }
00355
00356 index_tuple.setTransformedPosition(pos);
00357 #ifdef DEBUG_ALIGNMENT
00358
00359
00360 #endif
00361
00362 map[j].getPosition() = pos;
00363 map[j].insert(index_tuple);
00364 break;
00365 }
00366 grid_it++;
00367 }
00368 }
00369
00370 #ifdef DEBUG_ALIGNMENT
00371
00372 std::cout << "*** Compute the consensus of the reference map and map " << i << " ***" << std::endl;
00373 #endif
00374
00375
00376
00377 DelaunayPairFinder<ConsensusVectorType, ElementContainerType> pair_finder;
00378 pair_finder.setParameters(param_.copy("consensus_algorithm:",true));
00379 pair_finder.computeConsensusMap(map,final_consensus_map_);
00380
00381 #ifdef DEBUG_ALIGNMENT
00382
00383 std::cout << "*** DONE!! number of consensus elements " << final_consensus_map_.size() << " ***"<< std::endl;
00384 ++number_alignments;
00385
00386
00387
00388
00389
00390 #endif
00391
00392 }
00393 }
00394 #ifdef DEBUG_ALIGNMENT
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 #endif
00486
00487 delete pairwise_matcher_;
00488
00489 }
00490
00492 void alignMultiplePeakMaps_()
00493 {
00494 std::vector < ElementContainerType* >& element_map_vector = final_consensus_map_.getMapVector();
00495
00496
00497
00498 UInt n = 400;
00499 PeakConstReferenceMapType reference_pointer_map((element_map_vector[reference_map_index_])->begin(), (element_map_vector[reference_map_index_])->end());
00500 reference_pointer_map.sortByIntensity();
00501 UInt number = (reference_pointer_map.size() > n) ? n : reference_pointer_map.size();
00502 PeakConstReferenceMapType reference_most_intense(reference_pointer_map.end() - number, reference_pointer_map.end());
00503
00504 BasePairwiseMapMatcher< PeakConstReferenceMapType >* pairwise_matcher_;
00505 pairwise_matcher_ = Factory<BasePairwiseMapMatcher< PeakConstReferenceMapType > >::create("poseclustering_pairwise");
00506 pairwise_matcher_->setParameters(param_.copy("matching_algorithm:",true));
00507
00508 pairwise_matcher_->setElementMap(MODEL,reference_most_intense);
00509
00510 MapMatcherRegression< ElementType > lin_regression;
00511 UInt number_maps = element_map_vector.size();
00512 transformations_.resize(number_maps);
00513
00514 for (UInt i = 0; i < number_maps; ++i)
00515 {
00516 std::cout.precision(10);
00517 if (i != reference_map_index_)
00518 {
00519 PeakConstReferenceMapType pointer_map((element_map_vector[i])->begin(), (element_map_vector[i])->end());
00520
00521 pairwise_matcher_->setElementMap(SCENE, pointer_map);
00522 pairwise_matcher_->initGridTransformation(pointer_map);
00523 pairwise_matcher_->run();
00524
00525 #ifdef DEBUG_ALIGNMENT
00526 std::cout << "*** Estimate for each grid cell a better transformation using the element pairs. number of pairs: " << pairwise_matcher_->getElementPairs().size() << " ***" << std::endl;
00527 #endif
00528
00529 lin_regression.setElementPairs(pairwise_matcher_->getElementPairs());
00530 lin_regression.setGrid(pairwise_matcher_->getGrid());
00531 lin_regression.setMinQuality(-1.);
00532 lin_regression.estimateTransform();
00533
00534 transformations_[i] = lin_regression.getGrid();
00535 }
00536 }
00537
00538 delete pairwise_matcher_;
00539 }
00540
00542 void alignMultipleConsensusMaps_()
00543 {
00544 std::vector < ElementContainerType* >& element_map_vector = final_consensus_map_.getMapVector();
00545
00546 #ifdef DEBUG_ALIGNMENT
00547 std::cout << "*** Build a consensus map of the elements of the reference map (contains only singleton consensus elements) ***" << std::endl;
00548 #endif
00549
00550 ConsensusVectorType cons_ref_map;
00551 const ElementContainerType& map = *(element_map_vector[reference_map_index_]);
00552 UInt m = map.size();
00553 for (UInt i=0; i < m; ++i)
00554 {
00555 ConsensusElementType c(reference_map_index_,i,map[i]);
00556 final_consensus_map_.push_back(c);
00557 cons_ref_map.push_back(c);
00558 }
00559
00560 #ifdef DEBUG_ALIGNMENT
00561
00562 std::ofstream out("reference_map.dat", std::ios::out);
00563 for (UInt i = 0; i < cons_ref_map.size(); ++i)
00564 {
00565 out << cons_ref_map[i].getRT() << ' ' << cons_ref_map[i].getMZ() << '\n';
00566 }
00567 out.flush();
00568
00569 std::cout << "*** Compute the consensus map of all pairwise alignment ***" << std::endl;
00570 #endif
00571
00572
00573 UInt n = 50;
00574 PeakConstReferenceMapType reference_pointer_map((element_map_vector[reference_map_index_])->begin(), (element_map_vector[reference_map_index_])->end());
00575 reference_pointer_map.sortByIntensity();
00576 UInt number = (reference_pointer_map.size() > n) ? n : reference_pointer_map.size();
00577 PeakConstReferenceMapType reference_most_intense(reference_pointer_map.end() - number, reference_pointer_map.end());
00578
00579 BasePairwiseMapMatcher< PeakConstReferenceMapType >* pairwise_matcher_;
00580 pairwise_matcher_ = Factory<BasePairwiseMapMatcher< PeakConstReferenceMapType > >::create("poseclustering_pairwise");
00581 pairwise_matcher_->setParameters(param_.copy("matching_algorithm:",true));
00582
00583 pairwise_matcher_->setElementMap(MODEL,reference_most_intense);
00584
00585 MapMatcherRegression< ElementType > lin_regression;
00586 UInt number_maps = element_map_vector.size();
00587 transformations_.resize(number_maps);
00588 #ifdef DEBUG_ALIGNMENT
00589
00590 UInt number_alignments = 0;
00591 #endif
00592
00593 for (UInt i = 0; i < number_maps; ++i)
00594 {
00595 std::cout.precision(10);
00596 if (i != reference_map_index_)
00597 {
00598 #ifdef DEBUG_ALIGNMENT
00599 std::cout << "*** Build a consensus map of map " << i << " *** " << std::endl;
00600 #endif
00601
00602 ConsensusVectorType map;
00603 buildConsensusVectorType_(i,map);
00604
00605 PeakConstReferenceMapType pointer_map((element_map_vector[i])->begin(), (element_map_vector[i])->end());
00606
00607 pairwise_matcher_->setElementMap(SCENE, pointer_map);
00608 pairwise_matcher_->initGridTransformation(pointer_map);
00609 pairwise_matcher_->run();
00610
00611 #ifdef DEBUG_ALIGNMENT
00612
00613 std::cout << "*** Estimate for each grid cell a better transformation using the element pairs. number of pairs: " << pairwise_matcher_->getElementPairs().size() << " ***" << std::endl;
00614 #endif
00615
00616 lin_regression.setElementPairs(pairwise_matcher_->getElementPairs());
00617 lin_regression.setGrid(pairwise_matcher_->getGrid());
00618 lin_regression.setMinQuality(-1.);
00619 lin_regression.estimateTransform();
00620
00621 transformations_[i] = lin_regression.getGrid();
00622
00623 #ifdef DEBUG_ALIGNMENT
00624
00625 String name = "map_" + (String)number_alignments + ".dat";
00626 std::ofstream out(name.c_str(), std::ios::out);
00627 #endif
00628
00629 UInt n = map.size();
00630 for (UInt j = 0; j < n; ++j)
00631 {
00632
00633
00634 typename Grid::iterator grid_it = (lin_regression.getGrid()).begin();
00635 while (grid_it != (lin_regression.getGrid()).end() )
00636 {
00637 if (grid_it->encloses(map[j].getPosition()) )
00638 {
00639
00640 IndexTuple< ElementContainerType > index_tuple(i,j,(*(element_map_vector[i]))[j]);
00641 PositionType pos = (*(element_map_vector[i]))[j].getPosition();
00642
00643 grid_it->getMappings()[RawDataPoint2D::RT].apply(pos[RawDataPoint2D::RT]);
00644
00645 index_tuple.setTransformedPosition(pos);
00646
00647 #ifdef DEBUG_ALIGNMENT
00648
00649 out << map[j].getRT() << ' ' << map[j].getMZ() << ' ' << pos[RawDataPoint2D::RT] << ' ' << pos[RawDataPoint2D::MZ] << '\n';
00650 #endif
00651
00652 map[j].getPosition() = pos;
00653 map[j].insert(index_tuple);
00654 }
00655 grid_it++;
00656
00657 }
00658 }
00659
00660 #ifdef DEBUG_ALIGNMENT
00661 out.flush();
00662
00663 std::cout << "*** Compute the consensus of the reference map and map " << i << " ***" << std::endl;
00664 #endif
00665
00666 DelaunayPairFinder<ConsensusVectorType, ElementContainerType> pair_finder;
00667 pair_finder.setParameters(param_.copy("consensus_algorithm:",true));
00668 pair_finder.computeConsensusMap(map,final_consensus_map_);
00669
00670 #ifdef DEBUG_ALIGNMENT
00671 std::cout << "*** DONE!! number of consensus elements " << final_consensus_map_.size() << " ***"<< std::endl;
00672 ++number_alignments;
00673 #endif
00674
00675 }
00676 }
00677 #ifdef DEBUG_ALIGNMENT
00678 std::cout << "=========== Final Consensus Map =========" << std::endl;
00679 std::ofstream out_cons("Consensus.dat",std::ios::out);
00680 out_cons << "cons_rt cons_mz cons_int rt_map1 rt_transf_map1 mz_map1 mz_transf_map1 int_map1 rt_map2 rt_transf_map1 mz_map2 mz_transf_map2 int_map2 ... rt_mapn rt_transf_mapn mz_mapn mz_transf_mapn int_mapn\n";
00681 for (UInt i = 0; i < final_consensus_map_.size(); ++i)
00682 {
00683 ConsensusElementType* c = &(final_consensus_map_[i]);
00684 out_cons << c->getRT() << ' '
00685 << c->getMZ() << ' '
00686 << c->getIntensity() << ' ';
00687
00688 for (typename ConsensusElementType::Group::const_iterator it = c->begin(); it != c->end(); ++it)
00689 {
00690 out_cons << it->getElement().getRT() << ' '
00691 << it->getTransformedPosition()[RawDataPoint2D::RT] << ' '
00692 << it->getElement().getMZ() << ' '
00693 << it->getTransformedPosition()[RawDataPoint2D::MZ] << ' '
00694 << it->getElement().getIntensity() << ' ';
00695 }
00696 out_cons << std::endl;
00697 }
00698
00699 std::ofstream out_gp("Consensus.gp",std::ios::out);
00700 UInt first=5;
00701 UInt second=7;
00702 out_gp << "plot \"reference_map.dat\" using 1:2 title \"reference_map\" w points pointtype 20 lt 1\n"
00703 << "replot \"Consensus.dat\" using 1:2 title \"consensus\" w points pointtype 20 lt 2\n"
00704 << "replot \"Consensus.dat\" using " << first << ':' << second << " title \"\" w points pointtype 20 lt 1\n";
00705 n = element_map_vector.size();
00706 for (UInt i=0; i < n; ++i)
00707 {
00708 if (i != reference_map_index_)
00709 {
00710 String map = "map_" + (String)i + ".dat";
00711 out_gp << "replot \"Consensus.dat\" using 1:2:($" << first << "-$1):($" << second << "-$2) w vectors lt 3 nohead title \"pairs\"\n"
00712 << "replot \"" << map << "\" using 1:2 title \"original positions map " << i << "\" pointtype 3 lt " << i+3 << '\n'
00713 << "replot \"" << map << "\" using 3:4 title \"transformed positions map " << i << "\" pointtype 20 lt " << i+3 << '\n'
00714 << "replot \"" << map << "\" using 1:2:($3-$1):($4-$2) w vectors lt 7 nohead title \"transformed\"\n";
00715 first +=5;
00716 second +=5;
00717 }
00718 }
00719 std::cout << "The consensus elements are written to Consensus.dat.\n"
00720 << "You can visualize the result using the gnuplot script \"Consensus.gp\" (Type \"gnuplot Consensus.gp -\")" << std::endl;
00721 #endif
00722
00723 delete pairwise_matcher_;
00724 }
00725 }
00726 ;
00727 }
00728
00729 #endif // OPENMS_ANALYSIS_MAPMATCHING_STARALIGNMENT_H