Sort.h

Go to the documentation of this file.
00001 // ***************************************************************************
00002 // Sort.h (c) 2009 Derek Barnett
00003 // Marth Lab, Department of Biology, Boston College
00004 // All rights reserved.
00005 // ---------------------------------------------------------------------------
00006 // Last modified: 4 April 2012 (DB)
00007 // ---------------------------------------------------------------------------
00008 // Provides sorting functionality.
00009 // ***************************************************************************
00010 
00011 #ifndef ALGORITHMS_SORT_H
00012 #define ALGORITHMS_SORT_H
00013 
00014 #include "api/api_global.h"
00015 #include "api/BamAlignment.h"
00016 #include "api/BamReader.h"
00017 #include "api/BamMultiReader.h"
00018 #include <cassert>
00019 #include <algorithm>
00020 #include <functional>
00021 #include <string>
00022 #include <vector>
00023 
00024 namespace BamTools {
00025 namespace Algorithms {
00026 
00030 struct API_EXPORT Sort {
00031 
00033     enum Order { AscendingOrder = 0
00034                , DescendingOrder
00035                };
00036 
00042     template<typename ElemType>
00043     static inline bool sort_helper(const Sort::Order& order, const ElemType& lhs, const ElemType& rhs) {
00044         switch ( order ) {
00045             case ( Sort::AscendingOrder  ) : { std::less<ElemType> comp;    return comp(lhs, rhs); }
00046             case ( Sort::DescendingOrder ) : { std::greater<ElemType> comp; return comp(lhs, rhs); }
00047             default : BT_ASSERT_UNREACHABLE;
00048         }
00049         return false; // <-- unreachable
00050     }
00051 
00053     typedef std::binary_function<BamAlignment, BamAlignment, bool> AlignmentSortBase;
00054 
00071     struct ByName : public AlignmentSortBase {
00072 
00073         // ctor
00074         ByName(const Sort::Order& order = Sort::AscendingOrder)
00075             : m_order(order)
00076         { }
00077 
00078         // comparison function
00079         bool operator()(const BamTools::BamAlignment& lhs, const BamTools::BamAlignment& rhs) {
00080             return sort_helper(m_order, lhs.Name, rhs.Name);
00081         }
00082 
00083         // used by BamMultiReader internals
00084         static inline bool UsesCharData(void) { return true; }
00085 
00086         // data members
00087         private:
00088             const Sort::Order m_order;
00089     };
00090 
00107     struct ByPosition : public AlignmentSortBase {
00108 
00109         // ctor
00110         ByPosition(const Sort::Order& order = Sort::AscendingOrder)
00111             : m_order(order)
00112         { }
00113 
00114         // comparison function
00115         bool operator()(const BamTools::BamAlignment& lhs, const BamTools::BamAlignment& rhs) {
00116 
00117             // force unmapped aligmnents to end
00118             if ( lhs.RefID == -1 ) return false;
00119             if ( rhs.RefID == -1 ) return true;
00120 
00121             // if on same reference, sort on position
00122             if ( lhs.RefID == rhs.RefID )
00123                 return sort_helper(m_order, lhs.Position, rhs.Position);
00124 
00125             // otherwise sort on reference ID
00126             return sort_helper(m_order, lhs.RefID, rhs.RefID);
00127         }
00128 
00129         // used by BamMultiReader internals
00130         static inline bool UsesCharData(void) { return false; }
00131 
00132         // data members
00133         private:
00134             const Sort::Order m_order;
00135     };
00136 
00153     template<typename T>
00154     struct ByTag : public AlignmentSortBase {
00155 
00156         // ctor
00157         ByTag(const std::string& tag,
00158               const Sort::Order& order = Sort::AscendingOrder)
00159             : m_tag(tag)
00160             , m_order(order)
00161         { }
00162 
00163         // comparison function
00164         bool operator()(const BamTools::BamAlignment& lhs, const BamTools::BamAlignment& rhs) {
00165 
00166             // force alignments without tag to end
00167             T lhsTagValue;
00168             T rhsTagValue;
00169             if ( !lhs.GetTag(m_tag, lhsTagValue) ) return false;
00170             if ( !rhs.GetTag(m_tag, rhsTagValue) ) return true;
00171 
00172             // otherwise compare on tag values
00173             return sort_helper(m_order, lhsTagValue, rhsTagValue);
00174         }
00175 
00176         // used by BamMultiReader internals
00177         static inline bool UsesCharData(void) { return true; }
00178 
00179         // data members
00180         private:
00181             const std::string m_tag;
00182             const Sort::Order m_order;
00183     };
00184 
00196     struct Unsorted : public AlignmentSortBase {
00197 
00198         // comparison function
00199         inline bool operator()(const BamTools::BamAlignment&, const BamTools::BamAlignment&) {
00200             return false;   // returning false tends to retain insertion order
00201         }
00202 
00203         // used by BamMultiReader internals
00204         static inline bool UsesCharData(void) { return false; }
00205     };
00206 
00220     template<typename Compare>
00221     static inline void SortAlignments(std::vector<BamAlignment>& data,
00222                                       const Compare& comp = Compare())
00223     {
00224         std::sort(data.begin(), data.end(), comp);
00225     }
00226 
00242     template<typename Compare>
00243     static inline std::vector<BamAlignment> SortAlignments(const std::vector<BamAlignment>& input,
00244                                                            const Compare& comp = Compare())
00245     {
00246         std::vector<BamAlignment> output(input);
00247         SortAlignments(output, comp);
00248         return output;
00249     }
00250 
00271     template<typename Compare>
00272     static std::vector<BamAlignment> GetSortedRegion(BamReader& reader,
00273                                                      const BamRegion& region,
00274                                                      const Compare& comp = Compare())
00275     {
00276         // return empty container if unable to find region
00277         if ( !reader.IsOpen() )          return std::vector<BamAlignment>();
00278         if ( !reader.SetRegion(region) ) return std::vector<BamAlignment>();
00279 
00280         // iterate through region, grabbing alignments
00281         BamAlignment al;
00282         std::vector<BamAlignment> results;
00283         while ( reader.GetNextAlignmentCore(al) )
00284             results.push_back(al);
00285 
00286         // sort & return alignments
00287         SortAlignments(results, comp);
00288         return results;
00289     }
00290 
00311     template<typename Compare>
00312     static std::vector<BamAlignment> GetSortedRegion(BamMultiReader& reader,
00313                                                      const BamRegion& region,
00314                                                      const Compare& comp = Compare())
00315     {
00316         // return empty container if unable to find region
00317         if ( !reader.HasOpenReaders() )  return std::vector<BamAlignment>();
00318         if ( !reader.SetRegion(region) ) return std::vector<BamAlignment>();
00319 
00320         // iterate through region, grabbing alignments
00321         BamAlignment al;
00322         std::vector<BamAlignment> results;
00323         while ( reader.GetNextAlignmentCore(al) )
00324             results.push_back(al);
00325 
00326         // sort & return alignments
00327         SortAlignments(results, comp);
00328         return results;
00329     }
00330 };
00331 
00332 } // namespace Algorithms
00333 } // namespace BamTools
00334 
00335 #endif // ALGORITHMS_SORT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Aug 29 17:43:46 2012 for BamTools by  doxygen 1.6.3