def __init__(self, *args, **kwargs): """ This double-differencer is a cascade of two differencers: |-------------------------------------------| | | | ---------------- ---------------- | --->|---| diffr M1 |---| diffr M1 |-----|----> double difference | ---------------- ---------------- | | | |-------------------------------------------| This cascade halves the bandwidth of either differencer. When used in conjuction with a single differencer, the M1 value here must be 1/2 the M1 value of the single differencer. Specifically: single differencer: M1 = (tau_+ + tau_-) / 2 double differencer: M1 = (tau_+ + tau_-) / 4 With these conditions, the delay of the single- and double-differencer is nearly the same. kwarg keys: name weight arm_ratio order """ # the differencer has a name ScalarFilterBase.__init__(self, *args, **kwargs) # instantiate an underlying poly-ema pair this_order = kwargs.get('order', 1) name_1st_fltr = "%s-1st" % kwargs.get('name', 'f') name_2nd_fltr = "%s-2nd" % kwargs.get('name', 'f') # a note on weights: the filter output is the cascade of these two filters. The total filter # output weight needs to be 1/2 self._1st_fltr = ScalarHomogeneousDifferencer(name=name_1st_fltr, order=this_order, weight=1.0) self._2nd_fltr = ScalarHomogeneousDifferencer(name=name_2nd_fltr, order=this_order, weight=0.5) #-------------------------------------------------------------------- # in this pythonic environ need to have more explicit assurance that the filter is made self._is_made = False
def __init__(self, *args, **kwargs): """ kwarg keys: name weight arm_ratio order """ # this filter bank has a name ScalarFilterBase.__init__(self, *args, **kwargs) """ This filter bank looks like this: |---------------------------------------------| | | | -------------- | | ----------- | diffr M1 |---------------|----> slope | / -------------- | px --->|- | | \ | | \ -------------------- | | \---------| dbl-diffr M1/2 |------------|----> curvature | -------------------- | | | |---------------------------------------------| """ # aux this_order = kwargs.get('order', 1) name_slope_arm = "%s-slope" % kwargs.get('name', 'scf') name_curv_arm = "%s-curv" % kwargs.get('name', 'scf') # the slope filter self._slope_filter = ScalarHomogeneousDifferencer(name=name_slope_arm, order=this_order, weight=1.0) # the curvature filter. This filter is a chain of two half-M1 differencers self._curv_filter = ScalarHomogeneousDoubleDifferencer(name=name_curv_arm, order=this_order, weight=1.0) self._meta_data_queue = deque() #-------------------------------------------------------------------- # in this pythonic environ need to have more explicit assurance that the filter is made self._is_made = False
class SlopeCurvatureFilterBank(ScalarFilterBase): def __init__(self, *args, **kwargs): """ kwarg keys: name weight arm_ratio order """ # this filter bank has a name ScalarFilterBase.__init__(self, *args, **kwargs) """ This filter bank looks like this: |---------------------------------------------| | | | -------------- | | ----------- | diffr M1 |---------------|----> slope | / -------------- | px --->|- | | \ | | \ -------------------- | | \---------| dbl-diffr M1/2 |------------|----> curvature | -------------------- | | | |---------------------------------------------| """ # aux this_order = kwargs.get('order', 1) name_slope_arm = "%s-slope" % kwargs.get('name', 'scf') name_curv_arm = "%s-curv" % kwargs.get('name', 'scf') # the slope filter self._slope_filter = ScalarHomogeneousDifferencer(name=name_slope_arm, order=this_order, weight=1.0) # the curvature filter. This filter is a chain of two half-M1 differencers self._curv_filter = ScalarHomogeneousDoubleDifferencer(name=name_curv_arm, order=this_order, weight=1.0) self._meta_data_queue = deque() #-------------------------------------------------------------------- # in this pythonic environ need to have more explicit assurance that the filter is made self._is_made = False #-------------------------------------------------------------------- # main interface # make the differencer, which makes the two underlying filters def make(self, slope_M1): # simply make the slope and curvature filters, use M1/2 for the curvature filter. self._slope_filter.make(slope_M1) self._curv_filter.make(slope_M1/2.0) self._meta_data_queue = deque(maxlen=slope_M1) # set self._is_made = True def reset(self): self._slope_filter.reset() self._curv_filter.reset() def relevel(self, v): self._slope_filter.relevel(v) self._curv_filter.relevel(v) def update(self, v, meta_data=None): self._slope_filter.update(v) self._curv_filter.update(v) if meta_data: self._meta_data_queue.append(meta_data) def value(self): # return a tuple (slope, curvature) return [self._slope_filter.value(), self._curv_filter.value()] def getMetaDataQueue(self): return self._meta_data_queue def isReady(self): return self._slope_filter.isReady() and self._curv_filter.isReady() def isMade(self): return self._is_made #-------------------------------------------------------------------- # getters def getProperties(self): prop = {} prop['order'] = self._slope_filter.getOrder() prop['name'] = self._name prop['weight'] = self._weight return prop def getArms(self): return {'slope': self._slope_filter, 'curve': self._curv_filter}
class ScalarHomogeneousDoubleDifferencer(ScalarFilterBase): def __init__(self, *args, **kwargs): """ This double-differencer is a cascade of two differencers: |-------------------------------------------| | | | ---------------- ---------------- | --->|---| diffr M1 |---| diffr M1 |-----|----> double difference | ---------------- ---------------- | | | |-------------------------------------------| This cascade halves the bandwidth of either differencer. When used in conjuction with a single differencer, the M1 value here must be 1/2 the M1 value of the single differencer. Specifically: single differencer: M1 = (tau_+ + tau_-) / 2 double differencer: M1 = (tau_+ + tau_-) / 4 With these conditions, the delay of the single- and double-differencer is nearly the same. kwarg keys: name weight arm_ratio order """ # the differencer has a name ScalarFilterBase.__init__(self, *args, **kwargs) # instantiate an underlying poly-ema pair this_order = kwargs.get('order', 1) name_1st_fltr = "%s-1st" % kwargs.get('name', 'f') name_2nd_fltr = "%s-2nd" % kwargs.get('name', 'f') # a note on weights: the filter output is the cascade of these two filters. The total filter # output weight needs to be 1/2 self._1st_fltr = ScalarHomogeneousDifferencer(name=name_1st_fltr, order=this_order, weight=1.0) self._2nd_fltr = ScalarHomogeneousDifferencer(name=name_2nd_fltr, order=this_order, weight=0.5) #-------------------------------------------------------------------- # in this pythonic environ need to have more explicit assurance that the filter is made self._is_made = False #-------------------------------------------------------------------- # main interface # make the differencer, which makes the two underlying filters def make(self, wireframe_M1p_Mpm_avg): self._1st_fltr.make(wireframe_M1p_Mpm_avg) self._2nd_fltr.make(wireframe_M1p_Mpm_avg) self._is_made = True def reset(self): self._1st_fltr.reset() self._2nd_fltr.reset() def relevel(self, v): # the double-differencer is a cascade self._1st_fltr.relevel(v) self._2nd_fltr.relevel( self._1st_fltr.value() ) def update(self, v): # the double-differencer is a cascade self._1st_fltr.update(v) self._2nd_fltr.update( self._1st_fltr.value() ) def value(self): # The double-differencer value is that output of the second diff-r return self._2nd_fltr.value() def isReady(self): return self._is_made and (self._1st_fltr.isReady() and self._2nd_fltr.isReady()) def isMade(self): return self._is_made #-------------------------------------------------------------------- # getters def getProperties(self): prop = {} prop['order'] = self._1st_fltr.getOrder() # Hack prop['arm-ratio'] = self._1st_fltr._arm_ratio # Hack prop['name'] = self._name prop['weight'] = self._weight return prop