def values(self, tind, zind=None): """ Args: tind: Value to test for inclusion between time bounds """ span = (None, None) for m in self._members: if m.period is not None: # If a period is defined, extract the attribute from the # pd.Timestamp object before comparison. The min and max # values are in this period unit already. tind_copy = getattr(tind, m.period) else: # If a period isn't defined, make a new Timestamp object # to align with the above name 'tind_copy' tind_copy = tind # If we are between times if tind_copy > m.tspan.minv and tind_copy <= m.tspan.maxv: if not isnan(zind) and not isnan(m.zspan): # If we are between depths if zind > m.zspan.minv and zind <= m.zspan.maxv: span = m.vspan elif isnan(zind) and isnan(m.zspan): span = m.vspan return span
def values(self, tind, zind=None): span = (None, None) for m in self._members: # If we are between times if tind > m.tspan.minv and tind <= m.tspan.maxv: if not isnan(zind) and not isnan(m.zspan): # If we are between depths if zind > m.zspan.minv and zind <= m.zspan.maxv: span = m.vspan elif isnan(zind) and isnan(m.zspan): span = m.vspan return span
def check(self, tinp, inp, zinp): # Start with everything as UNKNOWN (1) flag_arr = np.ma.empty(inp.size, dtype='uint8') flag_arr.fill(QartodFlags.UNKNOWN) # If the value is masked set the flag to MISSING flag_arr[inp.mask] = QartodFlags.MISSING # Iterate over each member and apply its spans on the input data. # Member spans are applied in order and any data points that fall into # more than one member are flagged by each one. for m in self._members: if m.period is not None: # If a period is defined, extract the attribute from the # pd.DatetimeIndex object before comparison. The min and max # values are in this period unit already. tinp_copy = getattr(tinp, m.period).to_series() else: # If a period isn't defined, make a new Timestamp object # to align with the above name 'tinp_copy' tinp_copy = tinp # If a zspan is defined but we don't have z input (zinp), skip this member # Note: `zinp.count()` can return `np.ma.masked` so we also check using isnan if not isnan(m.zspan) and (not zinp.count() or isnan(zinp.any())): continue # Indexes that align with the T t_idx = (tinp_copy >= m.tspan.minv) & (tinp_copy <= m.tspan.maxv) # Indexes that align with the Z if not isnan(m.zspan): # Only test non-masked values between the min and max z_idx = (~zinp.mask) & (zinp >= m.zspan.minv) & (zinp <= m.zspan.maxv) else: # If there is no z data in the config, don't try to filter by depth! # Set z_idx to all True to prevent filtering z_idx = np.ones(inp.size, dtype=bool) # Combine the T and Z indexes values_idx = (t_idx & z_idx) # Failed and suspect data for this value span. Combining fail_idx or # suspect_idx with values_idx represents the subsets of data that should be # fail and suspect respectively. if not isnan(m.fspan): fail_idx = (inp < m.fspan.minv) | (inp > m.fspan.maxv) else: fail_idx = np.zeros(inp.size, dtype=bool) suspect_idx = (inp < m.vspan.minv) | (inp > m.vspan.maxv) with np.errstate(invalid='ignore'): flag_arr[(values_idx & fail_idx)] = QartodFlags.FAIL flag_arr[(values_idx & ~fail_idx & suspect_idx)] = QartodFlags.SUSPECT flag_arr[(values_idx & ~fail_idx & ~suspect_idx)] = QartodFlags.GOOD return flag_arr