|
| 1 | +import argparse |
| 2 | +import glob |
| 3 | +import logging |
| 4 | +import re |
| 5 | + |
| 6 | +from . import asn_from_list |
| 7 | + |
| 8 | +# Configure logging |
| 9 | +logger = logging.getLogger(__name__) |
| 10 | +logger.addHandler(logging.NullHandler()) |
| 11 | +logger.setLevel("INFO") |
| 12 | + |
| 13 | +__all__ = ["MultibandAssociation"] |
| 14 | + |
| 15 | + |
| 16 | +class MultibandAssociation: |
| 17 | + """A class to create multiband associations.""" |
| 18 | + |
| 19 | + def __init__(self, files): |
| 20 | + self.files = self._parse_file_list(files) |
| 21 | + self.skycell_groups = self._get_skycell_groups(self.files) |
| 22 | + |
| 23 | + def _parse_file_list(self, files): |
| 24 | + """ |
| 25 | + Parse a file list, expanding wildcards if present. |
| 26 | +
|
| 27 | + If the input list contains a single string with wildcard characters |
| 28 | + ('*' or '?'), expand it to the matching files using glob. Otherwise, |
| 29 | + return the list as is. |
| 30 | +
|
| 31 | + Parameters |
| 32 | + ---------- |
| 33 | + files : list of str |
| 34 | + List of file paths or a single wildcard pattern. |
| 35 | +
|
| 36 | + Returns |
| 37 | + ------- |
| 38 | + list of str |
| 39 | + List of file paths, expanded if a wildcard was provided. |
| 40 | + """ |
| 41 | + if len(files) == 1 and any(char in files[0] for char in ["*", "?"]): |
| 42 | + return glob.glob(files[0]) |
| 43 | + return files |
| 44 | + |
| 45 | + def _get_skycell_groups(self, filelist): |
| 46 | + """ |
| 47 | + Create skycell groups based on the unique skycell identifiers from a list of filenames. |
| 48 | + Parameters |
| 49 | + ---------- |
| 50 | + filelist : list of str |
| 51 | + List of filenames. |
| 52 | + Returns |
| 53 | + ------- |
| 54 | + dict |
| 55 | + Dictionary mapping skycell identifiers to lists of filenames. |
| 56 | + """ |
| 57 | + pattern = re.compile( |
| 58 | + r".*_(?P<skycells>[0-9p]*x[0-9]*y[0-9]*)_f[0-9]*_coadd\.asdf$" |
| 59 | + ) |
| 60 | + groups = {} |
| 61 | + for filename in filelist: |
| 62 | + match = pattern.match(filename) |
| 63 | + if match: |
| 64 | + key = match.group("skycells") |
| 65 | + groups.setdefault(key, []).append(filename) |
| 66 | + return groups |
| 67 | + |
| 68 | + def create_multiband_asn(self): |
| 69 | + """ |
| 70 | + Create a multiband association from a list of files. |
| 71 | +
|
| 72 | + Parameters: |
| 73 | + files (list): List of file paths or pattern to include in the association. |
| 74 | +
|
| 75 | + Returns: |
| 76 | + dict: The created association. |
| 77 | + """ |
| 78 | + for skycell_id, filenames in self.skycell_groups.items(): |
| 79 | + # Get prefixes for all combinations of data_release_id and product_type from filenames |
| 80 | + # (r00001_{data_release_id}_{product_type}_{skycell_id}_asn.json) |
| 81 | + prefixes = {x.split(skycell_id)[0] for x in filenames} |
| 82 | + for prefix in prefixes: |
| 83 | + # Get all files that match this prefix (data_release_id + product_type) and skycell |
| 84 | + files = [x for x in filenames if x.startswith(f"{prefix}{skycell_id}")] |
| 85 | + args = [ |
| 86 | + *files, |
| 87 | + "-o", |
| 88 | + f"{prefix}{skycell_id}_asn.json", |
| 89 | + "--product-name", |
| 90 | + f"{skycell_id}", |
| 91 | + "--data-release-id", |
| 92 | + prefix.split("_")[1], |
| 93 | + ] |
| 94 | + asn_from_list._cli(args) |
| 95 | + |
| 96 | + |
| 97 | +def _cli(): |
| 98 | + parser = argparse.ArgumentParser( |
| 99 | + description="Create a multiband association from a list of files", |
| 100 | + usage="multiband_asn file1.asdf file2.asdf ... fileN.asdf", |
| 101 | + ) |
| 102 | + parser.add_argument( |
| 103 | + "files", |
| 104 | + type=str, |
| 105 | + nargs="+", |
| 106 | + help="List of files to include in the multiband association", |
| 107 | + ) |
| 108 | + |
| 109 | + args = parser.parse_args() |
| 110 | + |
| 111 | + multiband_asn = MultibandAssociation(args.files) |
| 112 | + |
| 113 | + multiband_asn.create_multiband_asn() |
| 114 | + |
| 115 | + logger.info("Multiband association creation complete.") |
0 commit comments