DavidT3 / XGA

X-ray: Generate and Analyse is a module designed to make the analysis of XMM observations simple and efficient. It provides an interface with SAS for the creation of XMM data products, as well as a way to easily perform fits (scalable for multiple observations) and retrieve information about an object, all within a Python package.
BSD 3-Clause "New" or "Revised" License
29 stars 3 forks source link

ValueError from the regions module with the updated deps #1197

Closed DavidT3 closed 2 months ago

DavidT3 commented 2 months ago

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.

DavidT3 commented 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

DavidT3 commented 2 months ago

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

DavidT3 commented 2 months ago

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.