Closed DavidT3 closed 2 months ago
Have identified the ObsIDs for which this is an issue for LoVoCCS:
'height' must be strictly positive 0674560201
'height' must be strictly positive 0843890301
'height' must be strictly positive 0401520801
Right, having just read in one of these region files (0674560201) imagine my surprise when there are no negative width or height values - so something more complicated is going on unfortunately. I will read in the region file into regions line by line to see which one is causing the problem
Hang on nope, I was hasty - there is a region with zero height.
I could add a check for negative or zero valued width/heights in region files - but that would involve more file reading. I think instead I'll add a try-except around the region-read-in so I can at least tell the user which ObsID's region files are causing the problem.
ValueError Traceback (most recent call last) Cell In[6], line 7 4 r500 = Quantity(samp['MCXC_R500'].values, 'Mpc') 5 name = samp['LoVoCCSID'].apply(lambda x: 'LoVoCCS-' + str(x)).values ----> 7 srcs = ClusterSample(ra, dec, z, name, r500=r500, clean_obs=True, clean_obs_reg='r500', clean_obs_threshold=0.9, 8 use_peak=False, load_fits=True)
File /mnt/ufs18/home-218/turne540/code/XGA/xga/samples/extended.py:110, in ClusterSample.init(self, ra, dec, redshift, name, r200, r500, r2500, richness, richness_err, wl_mass, wl_mass_err, custom_region_radius, use_peak, peak_lo_en, peak_hi_en, back_inn_rad_factor, back_out_rad_factor, cosmology, load_fits, clean_obs, clean_obs_reg, clean_obs_threshold, no_prog_bar, psf_corr, peak_find_method) 107 from xga.sas import evselect_image, eexpmap, emosaic 109 # Using the super defines BaseSources and stores them in the self._sources dictionary --> 110 super().init(ra, dec, redshift, name, cosmology, load_products=True, load_fits=False, 111 no_prog_bar=no_prog_bar) 113 # This part is super useful - it is much quicker to use the base sources to generate all 114 # necessary ratemaps, as we can do it in parallel for the entire sample, rather than one at a time as 115 # might be necessary for peak finding in the cluster init. 116 evselect_image(self, peak_lo_en, peak_hi_en)
File /mnt/ufs18/home-218/turne540/code/XGA/xga/samples/base.py:80, in BaseSample.init(self, ra, dec, redshift, name, cosmology, load_products, load_fits, no_prog_bar) 75 z = None 77 try: 78 # We declare the source object, making sure to tell it that its part of a sample 79 # using in_sample=True ---> 80 temp = BaseSource(r, d, z, n, cosmology, load_products, load_fits, True) 81 n = temp.name 82 self._sources[n] = temp
File /mnt/ufs18/home-218/turne540/code/XGA/xga/sources/base.py:238, in BaseSource.init(self, ra, dec, redshift, name, cosmology, load_products, load_fits, in_sample) 236 self._lum_dist = None 237 self._ang_diam_dist = None --> 238 self._initial_regions, self._initial_region_matches = self._load_regions(region_dict) 240 # This is a queue for products to be generated for this source, will be a numpy array in practise. 241 # Items in the same row will all be generated in parallel, whereas items in the same column will 242 # be combined into a command stack and run in order. 243 self.queue = None
File /mnt/ufs18/home-218/turne540/code/XGA/xga/sources/base.py:1316, in BaseSource._load_regions(self, reg_paths) 1314 for obs_id in reg_paths: 1315 if reg_paths[obs_id] is not None: -> 1316 ds9_regs = Regions.read(reg_paths[obs_id], format='ds9').regions 1317 # Grab all images for the ObsID, instruments across an ObsID have the same WCS (other than in cases 1318 # where they were generated with different resolutions). 1319 # TODO see issue #908, figure out how to support different resolutions of image 1320 try:
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/core/regions.py:175, in Regions.read(cls, filename, format, cache, kwargs) 136 @classmethod 137 def read(cls, filename, format=None, cache=False, kwargs): 138 """ 139 Read and parse a region file and return as a Regions object. 140 (...) 173 A
~regions.Regions
object containing the file contents. 174 """ --> 175 return RegionsRegistry.read(filename, cls, format=format, 176 cache=cache, **kwargs)File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/core/registry.py:78, in RegionsRegistry.read(cls, filename, classobj, format, kwargs) 73 msg = (f'No reader defined for format "{format}" and class ' 74 f'"{classobj.name}".\n' 75 f'{cls._get_format_table_str(classobj)}') 76 raise IORegistryError(msg) from None ---> 78 return reader(filename, kwargs)
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/io/ds9/read.py:46, in _read_ds9(filename, cache) 44 with get_readable_fileobj(filename, cache=cache) as fh: 45 region_string = fh.read() ---> 46 return _parse_ds9(region_string)
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/io/ds9/read.py:71, in _parse_ds9(region_str) 69 regions = [] 70 for regiondata in region_data: ---> 71 region = _make_region(regiondata) 72 if region is not None: # skip region if error during parsing 73 regions.extend(region)
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/io/ds9/read.py:667, in _make_region(region_data) 664 shape_params.append(region_data.raw_meta.get('text', '')) 665 meta.pop('text', None) --> 667 region = ds9_shape_to_region[region_type]shape 669 region.meta = RegionMeta(meta) 670 region.visual = RegionVisual(visual)
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/shapes/ellipse.py:368, in EllipseSkyRegion.init(self, center, width, height, angle, meta, visual) 366 self.center = center 367 self.width = width --> 368 self.height = height 369 self.angle = angle 370 self.meta = meta or RegionMeta()
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/core/attributes.py:41, in RegionAttribute.set(self, instance, value) 40 def set(self, instance, value): ---> 41 self._validate(value) 42 instance.dict[self.name] = value
File ~/software/anaconda3/envs/xga_dev/lib/python3.12/site-packages/regions/core/attributes.py:150, in PositiveScalarAngle._validate(self, value) 147 raise ValueError(f'{self.name!r} must have angular units') 149 if not value > 0: --> 150 raise ValueError(f'{self.name!r} must be strictly positive') 151 else: 152 raise ValueError(f'{self.name!r} must be a strictly positive ' 153 'scalar angle')
ValueError: 'height' must be strictly positive
This may be what was happening with all the divide by zero warnings I was getting with some of the LoVoCCS clusters' regions, except no regions is doing an explicit check. I don't expect that this is an XGA or regions problem, rather that there is something funky in one of the XCS region files - though I may add a cleaning step in XGA to avoid this in the future.