@@ -844,17 +844,26 @@ def in_rows(self, rows):
844844 raise KeyError (", " .join (missing_rows ) + " row(s) are" \
845845 + " missing from NavData object." )
846846
847- def find_wildcard_indexes (self , wildcards , max_allow = None ):
847+ def find_wildcard_indexes (self , wildcards , max_allow = None ,
848+ excludes = None ):
848849 """Searches for indexes matching wildcard search input.
849850
850851 For example, a search for ``x_*_m`` would find ``x_rx_m`` or
851852 ``x_sv_m`` or ``x_alpha_beta_gamma_m`` depending on the rows
852853 existing in the NavData instance.
853854
855+ The ``excludes`` variable allows you to exclude indexes when
856+ trying to match a wildcard. For example, if there are rows named
857+ ``pr_raw_m``and ``pr_raw_sigma_m`` then the input
858+ ``wildcards="pr_*_m", excludes=None`` would return
859+ ``{"pr_*_m", ["pr_raw_m","pr_raw_sigma_m"]}`` but with the excludes
860+ parameter set, the input ``wildcards="pr_*_m", excludes="pr_*_sigma_m"``
861+ would only return ``{"pr_*_m", ["pr_raw_m"]}``
862+
854863 Will return an error no index is found matching the wildcard or
855864 if more than ``max_allow`` indexes are found.
856865
857- Currently only allows for a single wildcard per index.
866+ Currently only allows for a single wildcard '*' per index.
858867
859868 Parameters
860869 ----------
@@ -863,6 +872,10 @@ def find_wildcard_indexes(self, wildcards, max_allow = None):
863872 max_allow : int or None
864873 Maximum number of valid indexes to allow before throwing an
865874 error. If None, then no limit is placed.
875+ excludes : array-like or str
876+ List or string to exclude for each wildcard in wildcards.
877+ Must be the same length as wildcards. Allowed to include a
878+ wildcard '*' character but not necessary.
866879
867880 Returns
868881 -------
@@ -879,10 +892,29 @@ def find_wildcard_indexes(self, wildcards, max_allow = None):
879892 if not (isinstance (max_allow ,int ) or max_allow is None ):
880893 raise TypeError ("max_allow input in find_wildcard_indexes" \
881894 + " must be an integer or None." )
895+ # handle exclude types
896+ if isinstance (excludes ,str ):
897+ excludes = [excludes ]
898+ if excludes is None :
899+ excludes = [None ] * len (wildcards )
900+ if not isinstance (excludes , (list ,tuple ,np .ndarray ,set )):
901+ raise TypeError ("excludes input in find_wildcard_indexes" \
902+ + " must be array-like, single string, " \
903+ + "or None for each wildcard" )
904+ if len (excludes ) != len (wildcards ):
905+ raise TypeError ("excludes input must match length of " \
906+ + "wildcard input." )
907+ for ex_idx , exclude in enumerate (excludes ):
908+ if exclude is None or isinstance (exclude ,str ):
909+ excludes [ex_idx ] = [exclude ]
910+ if not isinstance (excludes [ex_idx ], (list ,tuple ,np .ndarray ,set )):
911+ raise TypeError ("excludes input in find_wildcard_indexes" \
912+ + " must be array-like, single string, " \
913+ + "or None for each wildcard" )
882914
883915 wildcard_indexes = {}
884916
885- for wildcard in wildcards :
917+ for wild_idx , wildcard in enumerate ( wildcards ) :
886918 if not isinstance (wildcard ,str ):
887919 raise TypeError ("wildcards must be strings" )
888920 if wildcard .count ("*" ) != 1 :
@@ -891,6 +923,15 @@ def find_wildcard_indexes(self, wildcards, max_allow = None):
891923 indexes = [row for row in self .rows
892924 if row .startswith (wildcard .split ("*" ,maxsplit = 1 )[0 ])
893925 and row .endswith (wildcard .split ("*" ,maxsplit = 1 )[1 ])]
926+ if excludes [wild_idx ] is not None :
927+ for exclude in excludes [wild_idx ]:
928+ if exclude is not None :
929+ if '*' in exclude :
930+ indexes = [row for row in indexes
931+ if not (row .startswith (exclude .split ("*" ,maxsplit = 1 )[0 ])
932+ and row .endswith (exclude .split ("*" ,maxsplit = 1 )[1 ]))]
933+ else :
934+ indexes = [row for row in indexes if exclude != row ]
894935 if max_allow is not None and len (indexes ) > max_allow :
895936 raise KeyError ("More than " + str (max_allow ) \
896937 + " possible row indexes for " + wildcard )
0 commit comments