]> git.donarmstrong.com Git - bamtools.git/blob - src/utils/bamtools_filter_properties.h
9de3e275fe9055d42a6508167c996783fd5ac235
[bamtools.git] / src / utils / bamtools_filter_properties.h
1 // ***************************************************************************
2 // bamtools_filter_properties.h (c) 2010 Derek Barnett, Erik Garrison
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 19 November 2010
7 // ---------------------------------------------------------------------------
8 // Provides support data structures & methods for FilterEngine
9 //
10 // The FilterEngine consists, most importantly, of :
11 //
12 //     a list of possible properties (each tagged whether it has been 'enabled' as a filter)
13 //     a map of filterName => propertySet
14 //     queue for compound rule expression (i.e. "(filter1 AND filter2) OR !filter3" )
15 //     
16 // Each propertySet is a list of properties enabled for this particular filter object
17 //
18 //     Implemented as a map of propertyNames to propertyFilterValue
19 //     ( "property1" => pfv1 
20 //       "property2" => pfv2 
21 //       "property4" => pfv4
22 //       etc. )  
23 //
24 //     Any properties that are 'possible', via FilterEngine::addProperty(), but not enabled 
25 //     via FilterEngine::setProperty() (in our example, say "property3"), evaluate to true 
26 //     for any query.  Meaning that if a property is not set on this filter, we don't care 
27 //     about it here, so it passes though OK.
28 //
29 // A propertyFilterValue contains a value and comparison type
30 //
31 //    ( pfv1: Value = 50,    Type = GREATER_THAN_EQUAL
32 //      pfv2: Value = "foo", Type = STARTS_WITH
33 //      pfv4: Value = "bar", Type = CONTAINS
34 //      etc. )  
35 //
36 //    This allows for more complex queries (than simple isEqual?) against a variety of data types.
37 //
38 // ***************************************************************************
39
40 #ifndef BAMTOOLS_FILTER_PROPERTIES_H
41 #define BAMTOOLS_FILTER_PROPERTIES_H
42
43 #include <utils/bamtools_utilities.h>
44 #include <utils/bamtools_variant.h>
45 #include <utils/utils_global.h>
46 #include <iostream>
47 #include <map>
48 #include <string>
49
50 namespace BamTools {
51
52 // ----------------------------------------------------------
53 // PropertyFilterValue
54   
55 struct UTILS_EXPORT PropertyFilterValue {
56   
57     // define valid ValueCompareTypes
58     enum ValueCompareType { CONTAINS = 0
59                           , ENDS_WITH
60                           , EXACT
61                           , GREATER_THAN
62                           , GREATER_THAN_EQUAL
63                           , LESS_THAN
64                           , LESS_THAN_EQUAL
65                           , NOT
66                           , STARTS_WITH
67                           };
68                    
69     // ctor
70     PropertyFilterValue(const Variant& value = Variant(),
71                         const ValueCompareType& type = PropertyFilterValue::EXACT)
72         : Value(value)
73         , Type(type)
74     { }
75           
76     // filter check methods      
77     template<typename T>
78     bool check(const T& query) const;
79     bool check(const std::string& query) const;
80              
81     // data members
82     Variant Value;
83     ValueCompareType Type;
84 };
85
86 // checks a query against a filter (value, compare type)
87 template<typename T>
88 bool PropertyFilterValue::check(const T& query) const {
89   
90     // ensure filter value & query are same type
91     if ( !Value.is_type<T>() ) { 
92         std::cerr << "Cannot compare different types!" << std::endl;
93         return false;
94     }
95     
96     // string matching
97     if ( Value.is_type<std::string>() ) {
98         std::cerr << "Cannot compare different types - query is a string!" << std::endl;
99         return false;
100     } 
101     
102     // numeric matching based on our filter type
103     switch ( Type ) {
104         case ( PropertyFilterValue::EXACT)              : return ( query == Value.get<T>() );
105         case ( PropertyFilterValue::GREATER_THAN)       : return ( query >  Value.get<T>() ); 
106         case ( PropertyFilterValue::GREATER_THAN_EQUAL) : return ( query >= Value.get<T>() ); 
107         case ( PropertyFilterValue::LESS_THAN)          : return ( query <  Value.get<T>() );
108         case ( PropertyFilterValue::LESS_THAN_EQUAL)    : return ( query <= Value.get<T>() );
109         case ( PropertyFilterValue::NOT)                : return ( query != Value.get<T>() );
110         default : BAMTOOLS_ASSERT_UNREACHABLE;
111     }
112     return false;
113 }
114
115 // checks a string query against filter (value, compare type)
116 inline
117 bool PropertyFilterValue::check(const std::string& query) const {
118   
119     // ensure filter value & query are same type
120     if ( !Value.is_type<std::string>() ) {
121         std::cerr << "Cannot compare different types!" << std::endl;
122         return false;
123     }
124   
125     // localize string version of our filter value
126     const std::string& valueString = Value.get<std::string>();
127     
128     // string matching based on our filter type
129     switch ( Type ) {
130         case ( PropertyFilterValue::CONTAINS)           : return ( query.find(valueString) != std::string::npos );
131         case ( PropertyFilterValue::ENDS_WITH)          : return ( query.find(valueString) == (query.length() - valueString.length()) ); 
132         case ( PropertyFilterValue::EXACT)              : return ( query == valueString );
133         case ( PropertyFilterValue::GREATER_THAN)       : return ( query >  valueString ); 
134         case ( PropertyFilterValue::GREATER_THAN_EQUAL) : return ( query >= valueString ); 
135         case ( PropertyFilterValue::LESS_THAN)          : return ( query <  valueString );
136         case ( PropertyFilterValue::LESS_THAN_EQUAL)    : return ( query <= valueString );
137         case ( PropertyFilterValue::NOT)                : return ( query != valueString );
138         case ( PropertyFilterValue::STARTS_WITH)        : return ( query.find(valueString) == 0 );
139         default : BAMTOOLS_ASSERT_UNREACHABLE;
140     }
141     return false;
142 }
143
144 inline
145 const std::string toString(const PropertyFilterValue::ValueCompareType& type) {
146   
147     switch ( type ) {
148         case ( PropertyFilterValue::CONTAINS )           : return std::string( "CONTAINS");
149         case ( PropertyFilterValue::ENDS_WITH )          : return std::string( "ENDS_WITH");
150         case ( PropertyFilterValue::EXACT )              : return std::string( "EXACT");
151         case ( PropertyFilterValue::GREATER_THAN )       : return std::string( "GREATER_THAN");
152         case ( PropertyFilterValue::GREATER_THAN_EQUAL ) : return std::string( "GREATER_THAN_EQUAL");
153         case ( PropertyFilterValue::LESS_THAN )          : return std::string( "LESS_THAN");
154         case ( PropertyFilterValue::LESS_THAN_EQUAL )    : return std::string( "LESS_THAN_EQUAL");
155         case ( PropertyFilterValue::NOT )                : return std::string( "NOT");
156         case ( PropertyFilterValue::STARTS_WITH )        : return std::string( "STARTS_WITH");
157         default : BAMTOOLS_ASSERT_UNREACHABLE;
158     }
159     return std::string();
160 }
161
162 // property name => property filter value 
163 // ('name' => ('SSR', STARTS_WITH), 'mapQuality' => (50, GREATER_THAN_EQUAL), etc...)
164 typedef std::map<std::string, PropertyFilterValue> PropertyMap;
165
166 // ----------------------------------------------------------
167 // PropertyFilter
168
169 struct UTILS_EXPORT PropertyFilter {
170     // data members
171     PropertyMap Properties;
172 };
173
174 // filter name => properties  
175 // ('filter1' => properties1, 'filter2' => properties2, etc...)
176 typedef std::map<std::string, PropertyFilter> FilterMap;
177   
178 // ----------------------------------------------------------
179 // Property
180   
181 // used to store properties known to engine & keep track of enabled state
182 struct UTILS_EXPORT Property {
183     std::string Name;
184     bool IsEnabled;
185     Property(const std::string& name, bool isEnabled = false) 
186         : Name(name)
187         , IsEnabled(isEnabled) 
188     { }
189 };
190
191 inline bool operator<  (const Property& lhs, const Property& rhs) { return lhs.Name <  rhs.Name; }
192 inline bool operator== (const Property& lhs, const Property& rhs) { return lhs.Name == rhs.Name; }
193
194 } // namespace BamTools
195
196 #endif // BAMTOOLS_FILTER_PROPERTIES_H