Source code for pyspedas.tplot_tools.wildcard_routines

import fnmatch
import logging

from pyspedas.tplot_tools import data_quants
from pyspedas.tplot_tools import tplot_names

[docs] def wildcard_expand(master_list, patterns, case_sensitive=True, split_whitespace=True, quiet=False): """ Find elements in master list matching one or more wild card patterns Parameters ---------- master_list: str or list of str One or more strings (for example, the set of all tplot variable names) patterns: str or list of str One or more patterns, which may contain wildcard characters, to be matched agains the master list case_sensitive: bool A boolean flag indicating whether case-sensitive matching should be performed. Default: True split_whitespace: bool A boolean flag indicating that master_list or patterns should be treated as space-delimited lists. Set to False if embedded spaces are to be matched. Default: True quiet: bool A boolean flag indicating whether to suppress "match not found" warnings. Default: False Returns ------- list of str A list of elements from master_list that match at least one of the input patterns. Duplicates in the output will be removed. Examples -------- >>> from pyspedas import wildcard_expand >>> master_list = ['mms1_mec_r_sm', 'mms2_mec_r_sm', 'mms3_mec_r_gsm', 'tha_pos_gsm'] >>> wildcard_expand(master_list,'*') ['mms1_mec_r_sm', 'mms2_mec_r_sm', 'mms3_mec_r_gsm', 'tha_pos_gsm'] >>> wildcard_expand(master_list, ['mms?_mec_r_sm']) ['mms1_mec_r_sm', 'mms2_mec_r_sm'] >>>wildcard_expand(master_list, ['*SM'], case_sensitive=False) ['mms1_mec_r_sm', 'mms2_mec_r_sm', 'mms3_mec_r_gsm', 'tha_pos_gsm'] >>> wildcard_expand(master_list,'tha_pos_gsm') ['tha_pos_gsm'] """ if master_list is None: logging.warning("wildcard_expand: master_list must be a non-empty string or list") return [] if patterns is None: # One could argue that it makes sense to return the entire master list here? return [] matched_items=set() ordered_matches=[] # Convert inputs to lists if necessary if isinstance(patterns, str): patterns=[patterns] if isinstance(master_list, str): master_list=[master_list] # Warn if either input is empty if len(master_list) == 0 or master_list is None or master_list==['']: logging.warning("wildcard_expand: empty master list") return [] if len(patterns) == 0 or patterns is None or patterns==['']: logging.warning("wildcard_expand: empty pattern list") return [] # If split_whitespace is true, expand master list and patterns if split_whitespace: expanded_master_list = [] for p in master_list: p_expanded=p.split(' ') expanded_master_list.extend(p_expanded) master_list = expanded_master_list # Do the same for the patterns expanded_patterns=[] for pattern in patterns: split_pattern=pattern.split(' ') expanded_patterns.extend(split_pattern) patterns=expanded_patterns # Prepare temporary lists for matching if case_sensitive: temp_master_list = master_list temp_patterns = patterns else: temp_master_list = [item.lower() for item in master_list] temp_patterns = [pattern.lower() for pattern in patterns] # Check each pattern against each item in the master list using fnmatchcase for pattern in temp_patterns: found = False for temp_item, original_item in zip(temp_master_list, master_list): if fnmatch.fnmatchcase(temp_item, pattern) and original_item not in matched_items: found = True ordered_matches.append(original_item) matched_items.add(original_item) elif fnmatch.fnmatchcase(temp_item, pattern): found = True if not found and not quiet: logging.warning("wildcard_expand: No match found for %s", pattern) return ordered_matches
def tname_byindex(tvar_index): """ Return a tplot variable name given an integer index Parameters ---------- tvar_index: int Index into the list of current tplot variable names Returns ------- str or None Returns the tplot variable name, or None if the index is invalid. """ namelist = list(data_quants.keys()) if tvar_index >= len(namelist) or tvar_index < 0: logging.warning("tname_byindex: index value %d out of bounds", tvar_index) return None else: return namelist[tvar_index] def tindex_byname(tvar_name): """ Return a tplot variable index given a tplot variable name Parameters ---------- tvar_name: str Name of a tplot variable Returns ------- int Index of the variable name, or None if not found """ namelist = list(data_quants.keys()) try: index = namelist.index(tvar_name) return index except ValueError: return None
[docs] def tplot_wildcard_expand(patterns, case_sensitive=True, quiet=False): """ Return tplot variable names matching one or more wildcard patterns Parameters ---------- patterns: str, int, list(str!int) One or more patterns, which may contain wildcard characters, to be matched against the master list Integers are converted to strings using tname_byindex() case_sensitive: bool A boolean flag indicating whether case-sensitive matching should be performed. Default: True quiet: bool A boolean flag indicating "no match found" log messages should be suppressed. Default: False Returns ------- list of str A list of tplot variable names that match at least one of the input patterns. Duplicate values in the output will be removed. """ input_pattern_list = patterns if patterns is None: return [] elif isinstance(patterns,str) or isinstance(patterns,int): input_pattern_list = [patterns] elif isinstance(patterns,list): input_pattern_list = patterns else: logging.warning("tplot_wildcard_expand: patterns must be a string, int or list") return [] string_patterns = [] # Get list of existing tplot names tn = tplot_names(quiet=True) if len(tn) == 0: if not quiet: logging.warning("tplot_wildcard_expand: List of tplot variable names is empty.") return [] # Interpret integers as tplot variable indices for item in input_pattern_list: if isinstance(item, int): name = tname_byindex(item) if name is not None: string_patterns.append(name) else: string_patterns.append(item) elif isinstance(item,str): # tplot names can have embedded spaces, but we also want to allow space-delimited # lists. If a space-delimited list is provided, check to see if the un-split version is # a valid tplot name. If not, try splitting it and look for the subpatterns. # This case used to also be triggered if there were wildcard characters present. But this prevented # using space-delimited patterns with wildcards. if item in tn: string_patterns.append(item) elif ' ' in item: expanded = item.split(' ') string_patterns.extend(expanded) else: # No embedded spaces, and not found in list of names. # But there might be wildcards to expand. string_patterns.append(item) else: logging.warning("tplot_wildcard_expand: bad input: "+str(item) +" Patterns must be a string or int") return wildcard_expand(tn, patterns=string_patterns, case_sensitive=case_sensitive, split_whitespace=False, quiet=quiet)