def _parse_args(self, *args, silence_errors=False, **kwargs): """ Parses an args list into data-header pairs. args can contain any mixture of the following entries: * tuples of data,header * data, header not in a tuple * data, wcs object in a tuple * data, wcs object not in a tuple * filename, as a str or pathlib.Path, which will be read * directory, as a str or pathlib.Path, from which all files will be read * glob, from which all files will be read * url, which will be downloaded and read * lists containing any of the above. Examples -------- self._parse_args(data, header, (data, header), ['file1', 'file2', 'file3'], 'file4', 'directory1', '*.fits') """ # Account for nested lists of items args = expand_list(args) # Sanitise the input so that each 'type' of input corresponds to a different # class, so single dispatch can be used later nargs = len(args) i = 0 while i < nargs: arg = args[i] if isinstance(arg, SUPPORTED_ARRAY_TYPES): # The next two items are data and a header data = args.pop(i) header = args.pop(i) args.insert(i, (data, header)) nargs -= 1 elif isinstance(arg, str) and is_url(arg): # Repalce URL string with a Request object to dispatch on later args[i] = Request(arg) elif possibly_a_path(arg): # Repalce path strings with Path objects args[i] = pathlib.Path(arg) i += 1 # Parse the arguments # Note that this list can also contain GenericMaps if they are directly given to the factory data_header_pairs = [] for arg in args: try: data_header_pairs += self._parse_arg(arg, **kwargs) except NoMapsInFileError as e: if not silence_errors: raise warn_user( f"One of the arguments failed to parse with error: {e}") return data_header_pairs
def _sanitise_args(self, args): """ Sanitise a list of args so that a single argument corresponds to either: - (data, header, units) tuple. - path-like `pathlib.Path` (e.g. a filename, directory, glob etc.). - `urllib.request.Request`. - `GenericTimeSeries`. """ # Account for nested lists of items. Simply outputs a single list of # items, nested lists are expanded to element level. args = expand_list(args) # Sanitise the input so that each 'type' of input corresponds to a different # class, so single dispatch can be used later i = 0 while i < len(args): arg = args[i] if isinstance(arg, (np.ndarray, Table, pd.DataFrame)): # Extract data and metadata # The next item is data data = args[i] meta = MetaDict() units = OrderedDict() if isinstance(data, Table): # We have an Astropy Table: data, new_meta, new_units = self._from_table(data) units.update(new_units) meta.update(new_meta) elif isinstance(data, np.ndarray): # We have a numpy ndarray. We assume the first column is a dt index data = pd.DataFrame(data=data[:, 1:], index=Time(data[:, 0])) # The next two could be metadata or units for _ in range(2): j = i + 1 if j < len(args): arg = args[j] if self._is_units(arg): units.update(arg) args.pop(j) elif self._is_metadata(arg): meta.update(self._parse_meta(arg)) args.pop(j) args[i] = (data, meta, units) elif isinstance(arg, str) and is_url(arg): args[i] = Request(arg) elif possibly_a_path(arg): args[i] = pathlib.Path(arg) i += 1 return args