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 // ---------------------------------------------------------------------------
9 // ***************************************************************************
11 #include "bamtools_filter_engine.h"
14 using namespace BamTools;
16 // ---------------------------------------------------------
17 // FilterValue implementation
19 // checks a string query against filter (value, compare type)
20 bool PropertyFilterValue::check(const string& query) const {
22 // ensure filter value & query are same type
23 if ( !Value.is_type<string>() ) {
24 cerr << "Cannot compare different types!" << endl;
28 // localize string version of our filter value
29 const string& valueString = Value.get<string>();
31 // string matching based on our filter 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;
47 // --------------------------------------------------------
48 // PropertyFilter implementation
49 PropertyFilter::PropertyFilter(void)
50 : Type(PropertyFilter::EXACT)
55 PropertyFilter::~PropertyFilter(void) {
63 // ---------------------------------------------------------
64 // FilterEngine implementation
66 // static FilterEngine data members
67 FilterMap FilterEngine::m_filters;
68 vector<Property> FilterEngine::m_properties;
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;
75 // return list of current filter names
76 const vector<string> FilterEngine::filterNames(void) {
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 );
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() );
97 // returns list of all properties known by FilterEngine ( any created using addProperty() )
98 const vector<string> FilterEngine::allPropertyNames(void) {
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 );
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 );
119 // ================================================================
122 void FilterEngine::print(void) {
124 printAllProperties();
125 printEnabledProperties();
129 void FilterEngine::printAllProperties(void) {
131 cout << "=======================================" << endl;
132 cout << "All Properties: " << endl;
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;
143 void FilterEngine::printEnabledProperties(void) {
145 cout << "=======================================" << endl;
146 cout << "Enabled Properties: " << endl;
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;
157 void FilterEngine::printFilters(void) {
159 cout << "=======================================" << endl;
160 cout << "Current Filters: " << endl;
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;
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 ) {
175 cout << " - " << (*propIter).first << " : ";
176 const PropertyFilterValue& filterValue = (*propIter).second;
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!! **";
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!! **";