]> git.donarmstrong.com Git - bamtools.git/blob - src/utils/bamtools_filter_engine.cpp
Added bamtools_filter_engine.*
[bamtools.git] / src / utils / bamtools_filter_engine.cpp
1 // ***************************************************************************
2 // bamtools_filter_engine.cpp (c) 2010 Derek Barnett, Erik Garrison
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 30 August 2010
7 // ---------------------------------------------------------------------------
8 // 
9 // ***************************************************************************
10
11 #include "bamtools_filter_engine.h"
12 #include "BamAux.h"
13 using namespace std;
14 using namespace BamTools;
15
16 // ---------------------------------------------------------
17 // FilterValue implementation
18
19 // checks a string query against filter (value, compare type)
20 bool PropertyFilterValue::check(const string& query) const {
21   
22     // ensure filter value & query are same type
23     if ( !Value.is_type<string>() ) {
24         cerr << "Cannot compare different types!" << endl;
25         return false;
26     }
27   
28     // localize string version of our filter value
29     const string& valueString = Value.get<string>();
30
31     // string matching based on our filter type
32     switch ( Type ) {
33         case ( PropertyFilterValue::CONTAINS)           : return ( query.find(valueString) != string::npos );
34         case ( PropertyFilterValue::ENDS_WITH)          : return ( query.find(valueString) == (query.length() - valueString.length()) ); 
35         case ( PropertyFilterValue::EXACT)              : return ( query == valueString );
36         case ( PropertyFilterValue::GREATER_THAN)       : return ( query >  valueString ); 
37         case ( PropertyFilterValue::GREATER_THAN_EQUAL) : return ( query >= valueString ); 
38         case ( PropertyFilterValue::LESS_THAN)          : return ( query <  valueString );
39         case ( PropertyFilterValue::LESS_THAN_EQUAL)    : return ( query <= valueString );
40         case ( PropertyFilterValue::NOT)                : return ( query != valueString );
41         case ( PropertyFilterValue::STARTS_WITH)        : return ( query.find(valueString) == 0 );
42         default : BAMTOOLS_ASSERT_UNREACHABLE;
43     }
44     return false;
45 }
46
47 // --------------------------------------------------------
48 // PropertyFilter implementation
49 PropertyFilter::PropertyFilter(void)
50     : Type(PropertyFilter::EXACT)
51     , LeftChild(0)
52     , RightChild(0)
53 { }
54
55 PropertyFilter::~PropertyFilter(void) {
56     delete LeftChild;
57     LeftChild = 0;
58   
59     delete RightChild;
60     RightChild = 0;
61 }
62
63 // ---------------------------------------------------------
64 // FilterEngine implementation
65
66 // static FilterEngine data members
67 FilterMap FilterEngine::m_filters;
68 vector<Property> FilterEngine::m_properties;
69
70 // creates a new filter set, returns true if created, false if error or already exists
71 bool FilterEngine::addFilter(const string& filterName) {
72     return (m_filters.insert(make_pair(filterName, PropertyFilter()))).second;
73 }
74
75 // return list of current filter names
76 const vector<string> FilterEngine::filterNames(void) {
77     vector<string> names;
78     names.reserve(m_filters.size());
79     FilterMap::const_iterator mapIter = m_filters.begin();
80     FilterMap::const_iterator mapEnd  = m_filters.end();
81     for ( ; mapIter != mapEnd; ++mapIter )
82         names.push_back( (*mapIter).first ); 
83     return names;
84 }
85
86 // add a new known property (& type) to engine
87 bool FilterEngine::addProperty(const string& propertyName) {
88     const vector<string> propertyNames = allPropertyNames();
89     bool found = binary_search( propertyNames.begin(), propertyNames.end(), propertyName );
90     if ( found ) return false;
91     m_properties.push_back( Property(propertyName) );
92     sort( m_properties.begin(), m_properties.end() );
93     return true;
94 }
95
96
97 // returns list of all properties known by FilterEngine  ( any created using addProperty() )
98 const vector<string> FilterEngine::allPropertyNames(void) {
99     vector<string> names;
100     names.reserve(m_properties.size());
101     vector<Property>::const_iterator propIter = m_properties.begin();
102     vector<Property>::const_iterator propEnd  = m_properties.end();
103     for ( ; propIter != propEnd; ++propIter )
104         names.push_back( (*propIter).Name );    
105     return names;
106 }
107
108 // returns list of property names that are 'enabled' ( only those touched by setProperty() )
109 const vector<string> FilterEngine::enabledPropertyNames(void) {
110     vector<string> names;
111     names.reserve(m_properties.size());
112     vector<Property>::const_iterator propIter = m_properties.begin();
113     vector<Property>::const_iterator propEnd  = m_properties.end();
114     for ( ; propIter != propEnd; ++propIter )
115         if ( (*propIter).IsEnabled ) names.push_back( (*propIter).Name );    
116     return names;
117 }
118
119 // ================================================================
120 // DEBUGGING
121
122 void FilterEngine::print(void) {
123     cout << endl;
124     printAllProperties();
125     printEnabledProperties();
126     printFilters();
127 }
128
129 void FilterEngine::printAllProperties(void) {
130     
131     cout << "=======================================" << endl;
132     cout << "All Properties: " << endl;
133     cout << endl;
134   
135     const vector<string> propertyNames = allPropertyNames();
136     vector<string>::const_iterator nameIter = propertyNames.begin();
137     vector<string>::const_iterator nameEnd  = propertyNames.end();
138     for ( ; nameIter != nameEnd; ++nameIter )
139         cout << (*nameIter) << endl;
140     cout << endl;
141 }
142
143 void FilterEngine::printEnabledProperties(void) {
144     
145     cout << "=======================================" << endl;
146     cout << "Enabled Properties: " << endl;
147     cout << endl;
148   
149     const vector<string> propertyNames = enabledPropertyNames();
150     vector<string>::const_iterator nameIter = propertyNames.begin();
151     vector<string>::const_iterator nameEnd  = propertyNames.end();
152     for ( ; nameIter != nameEnd; ++nameIter )
153         cout << (*nameIter) << endl;
154     cout << endl;
155 }
156
157 void FilterEngine::printFilters(void) {
158   
159     cout << "=======================================" << endl;
160     cout << "Current Filters: " << endl;
161     cout << endl;
162     
163     // iterate over all filters in FilterEngine
164     FilterMap::const_iterator filterIter = m_filters.begin();
165     FilterMap::const_iterator filterEnd  = m_filters.end();
166     for ( ; filterIter != filterEnd; ++filterIter ) {
167         cout << "Filter Name: " << (*filterIter).first << endl;
168       
169         // see if filter set has this property enabled
170         const PropertyFilter& filter = (*filterIter).second;
171         PropertyMap::const_iterator propIter = filter.Properties.begin();
172         PropertyMap::const_iterator propEnd  = filter.Properties.end();
173         for ( ; propIter != propEnd; ++propIter ) {
174           
175             cout << " - " << (*propIter).first << " : ";
176             const PropertyFilterValue& filterValue = (*propIter).second;
177              
178             if ( filterValue.Value.is_type<bool>() )              cout << "\t" << boolalpha << filterValue.Value.get<bool>();
179             else if ( filterValue.Value.is_type<int>() )          cout << "\t" << filterValue.Value.get<int>();
180             else if ( filterValue.Value.is_type<unsigned int>() ) cout << "\t" << filterValue.Value.get<unsigned int>();
181             else if ( filterValue.Value.is_type<unsigned short>() ) cout << "\t" << filterValue.Value.get<unsigned short>();
182             else if ( filterValue.Value.is_type<float>() )        cout << "\t" << filterValue.Value.get<float>();
183             else if ( filterValue.Value.is_type<string>() )  cout << "\t" << filterValue.Value.get<string>();
184             else cout << "** UNKNOWN VALUE TYPE!! **";
185                 
186             switch( filterValue.Type ) {
187                 case (PropertyFilterValue::CONTAINS)           : cout << " (contains)"; break;
188                 case (PropertyFilterValue::ENDS_WITH)          : cout << " (ends_with)"; break;
189                 case (PropertyFilterValue::EXACT)              : cout << " (exact)"; break;
190                 case (PropertyFilterValue::GREATER_THAN)       : cout << " (greater_than)"; break;
191                 case (PropertyFilterValue::GREATER_THAN_EQUAL) : cout << " (greater_than_equal)"; break;
192                 case (PropertyFilterValue::LESS_THAN)          : cout << " (less_than)"; break;
193                 case (PropertyFilterValue::LESS_THAN_EQUAL)    : cout << " (less_than_equal)"; break;
194                 case (PropertyFilterValue::NOT)                : cout << " (not)"; break;
195                 case (PropertyFilterValue::STARTS_WITH)        : cout << " (starts_with)"; break;
196                 default : cout << " : ** UNKNOWN COMPARE TYPE!! **";
197             }
198             cout << endl;
199         }
200     }
201 }