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

Integrate manual and interactive modification of regions #816

Open DavidT3 opened 2 years ago

DavidT3 commented 2 years ago

This may be a duplicate issue but I can't find the other one (if I ever made it) so I'm doing this one!

I need to include the functionality that I wrote for FatController (ish) where regions can be moved around, new ones added, etc.

But I will need to research and figure out how to do interactive matplotlib in notebooks

DavidT3 commented 2 years ago

The other issue is #80, says much the same thing as this one.

DavidT3 commented 2 years ago

Going to write my general plan here. Work will probably be mostly focused in the Image class:

DavidT3 commented 2 years ago

I think calls to edit regions will have to be done through a source/sample object for proper integration with XGA analyses. All the stuff I'm building into the Image class will remain there, but calling edit regions will return the new regions in various categories.

DavidT3 commented 2 years ago

I did consider making every custom region an ellipse, but actually no I'll make buttons to allow circular or elliptical regions to be added as enabling things like rotation obviously makes no sense for circles, and circles can also have both their axes increased in size by all the buttons.

DavidT3 commented 2 years ago

I'm testing out using a RangeSlider, something that seems to have come into matplotlib in v3.4 (I have 3.4.3 on the dev laptop) - If the rangeslider stays then I need to update the version in requirements.txt

DavidT3 commented 2 years ago

There is the potential for a really big problem here due to the blocking behaviour of matplotlib combined with Jupyter Notebook. The editor is now working really well thankfully, but making it interact properly with XGA is going to be hard. This is because when a editor window is opened, none of the code waits for the user to be done interacting with the plot. So if you were running through 10 cluster's images for instance, you'd get 10 figures popping up, all interactive, and almost impossible to extract regions from.

Its okay if the windows pop out in a new window (as they do when the code is run in a non-Jupyter environment) because then (as long as plt.show(block=True) is added) then the code waits, but adding that line breaks the matplotlib implementation. I'm really not sure what to do about all this

image
DavidT3 commented 2 years ago

So the Jupyter Notebook thing is causing some big issues here in terms of user experience, and I don't (yet) know how to solve them. The fact that the interactive window doesn't block the next steps in the code means that I can't make the code wait for the user to have edited regions.

The trouble is I need it to return an updated region list to a source object (for instance) so that source object can change its masks etc.

The interactive approach DOES work when windows are popped out (for instance when running the region editor from a script in terminal with a QT5Agg backend) but that is not the default behaviour in a notebook.

There are some immediate things I can do to mitigate these problems, though it's mostly putting artificial limits on the user and giving them some guidelines on how to use this in the documentation I'll write:

  1. I can try and make sure that XGA knows when it's being used in a Jupyter Notebook, and give the user warnings about this issue.
  2. I can allow the InteractiveView class to directly save to disk new region files, so that there would be a manual way for people to get their new edited region lists.
  3. I could even not build the integration into XGA yet, so that the new regions aren't automatically included in their source, but have to be put in the XGA region directory manually. This isn't a long term solution but could work for the moment as I do need this for a paper.
  4. The documentation I write will have to be very specific about the way this must be used, and that inline interactive matplotlib in a jupyter notebook will not necessarily be suited for editing regions at the moment.
  5. Obviously can continue to look for ways to make this work for this use case - this may even include adopting a different technology such as a dashboard creator like Panel.
DavidT3 commented 2 years ago

This issue is sort of connected to issue #777, where I want to introduce a method of checking what interloper regions a spectrum was generated with. Obviously if the interloper regions change I want XGA to know and to regenerate spectra etc.

DavidT3 commented 2 years ago

The Image class needs to be altered so that it can have context as to what observation a region comes from. This will probably involve adding the ability to parse a dictionary of ObsID: [regions], as can now be output from a source object using get_interloper_regions().

This in turn will have to be accepted by the _InteractiveView class (which will require some modification), but then it will be able to keep straight which region belongs to which ObsID.

DavidT3 commented 2 years ago

I am deleting the branch in which I performed the _InteractiveView work, as the reality is I'm not going to be coming back to it anytime soon, however this issue will remain open and on-hold.