panoptes-data 0.2.3__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: panoptes-data
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: Tools for working with PANOPTES data.
5
5
  Project-URL: Documentation, https://projectpanoptes.org/
6
6
  Project-URL: Source, https://github.com/panoptes/panoptes-data/
@@ -13,6 +13,10 @@ from panoptes.utils.images import fits as fits_utils
13
13
 
14
14
  warnings.filterwarnings('ignore', category=FITSFixedWarning)
15
15
 
16
+ # The metadata columns this class actually needs. Everything else, including
17
+ # every URL column, is optional -- see `ObservationInfo.public_urls`.
18
+ REQUIRED_COLUMNS = ('time', 'uid')
19
+
16
20
 
17
21
  class ObservationInfo:
18
22
  """A container class for information about an Observation."""
@@ -49,7 +53,23 @@ class ObservationInfo:
49
53
  self.meta = dict()
50
54
 
51
55
  self.image_metadata = self.get_metadata(query=image_query)
52
- self.image_list = self.image_metadata.public_url.values
56
+ self.image_list = self.get_image_list()
57
+
58
+ @property
59
+ def public_urls(self):
60
+ """The browsable URLs carried by the metadata, if any.
61
+
62
+ Which ``*_url`` columns exist varies between records: ``public_url``
63
+ and ``raw_url`` on some, ``uploaded_public_url``, ``fits_public_url``
64
+ and ``jpg_public_url`` on others. They are for display and lookup only
65
+ -- the raw frame locations come from `get_image_list` -- so a record
66
+ with no URL column at all still works.
67
+
68
+ Returns:
69
+ A DataFrame of whichever ``*_url`` columns are present, which may
70
+ have no columns.
71
+ """
72
+ return self.image_metadata.filter(regex=r'_url$')
53
73
 
54
74
  def get_image_cutout(self, data=None, coords=None, box_size=None, *args, **kwargs):
55
75
  """Gets a Cutout2D object for the given coords and box_size."""
@@ -72,6 +92,13 @@ class ObservationInfo:
72
92
  metadata_url = f'{self._settings.img_metadata_url.unicode_string()}?sequence_id={self.sequence_id}'
73
93
  images_df = pd.read_csv(metadata_url)
74
94
 
95
+ missing = [col for col in REQUIRED_COLUMNS if col not in images_df.columns]
96
+ if missing:
97
+ raise ValueError(
98
+ f'Metadata for {self.sequence_id} is missing required '
99
+ f'column(s) {missing}; got {sorted(images_df.columns)}'
100
+ )
101
+
75
102
  # Set a time index.
76
103
  images_df.time = pd.to_datetime(images_df.time)
77
104
  images_df = images_df.set_index(['time']).sort_index()
@@ -82,13 +109,18 @@ class ObservationInfo:
82
109
  return images_df
83
110
 
84
111
  def get_image_list(self, bucket: str | None = None, file_ext: str = '.fits.fz'):
85
- """Get the images for the observation.
112
+ """Get the URLs of the raw images for the observation.
113
+
114
+ The URLs are built from each image's ``uid`` rather than read from a URL
115
+ column, which is not dependable (`public_urls`). The ``uid`` is the
116
+ archive path with underscores for separators, so the raw frame's
117
+ location follows from it and the bucket.
86
118
 
87
119
  Args:
88
120
  bucket: The bucket where the images are stored.
89
121
  file_ext: The file extension of the images to retrieve.
90
122
  Returns:
91
- A pandas DataFrame containing the images for the observation.
123
+ A list of URLs, one per image in the metadata.
92
124
  """
93
125
  url_base = self._settings.img_base_url.unicode_string()
94
126
  bucket = bucket or self._settings.img_bucket
@@ -42,6 +42,7 @@ def download(sequence_id: str | None = typer.Argument(..., help='Sequence ID for
42
42
 
43
43
  except Exception as e:
44
44
  print(f'[red]Error downloading images for {sequence_id}: {e}')
45
+ raise typer.Exit(code=1) from e
45
46
 
46
47
  return local_files
47
48
 
@@ -84,6 +85,7 @@ def get_metadata(
84
85
  print(f'[green]Metadata saved to {output_fn}')
85
86
  except Exception as e:
86
87
  print(f'[red]Error downloading metadata for {sequence_id}: {e}')
88
+ raise typer.Exit(code=1) from e
87
89
  else:
88
90
  if unit_id is None:
89
91
  print('[red]Must provide a unit_id if not providing a sequence_id.')
@@ -120,7 +122,8 @@ def get_metadata(
120
122
  pd.concat(dfs).to_csv(output_fn)
121
123
 
122
124
  except ValueError as e:
123
- print(f'Error downloading metadata for {unit_id}: {e}', fg='red')
125
+ print(f'[red]Error downloading metadata for {unit_id}: {e}')
126
+ raise typer.Exit(code=1) from e
124
127
 
125
128
  print(f'Metadata saved to [green]{output_fn}')
126
129
 
File without changes
File without changes
File without changes
File without changes