-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalize image converter for square pixels #1728
Conversation
pixels - Removes the old astri and chec code as this is now handled in the general case
- Test now compares the original image to the image after tranforming back to 1d - Fixes loop, removes return: Previously most geometries were actually untested, because the pixel shape was compared to a string instead of the enum. This printed a warning about unsupported camera geometries but that was easily missed.
Codecov Report
@@ Coverage Diff @@
## master #1728 +/- ##
==========================================
+ Coverage 91.47% 92.16% +0.69%
==========================================
Files 184 182 -2
Lines 14341 14890 +549
==========================================
+ Hits 13119 13724 +605
+ Misses 1222 1166 -56
Continue to review full report at Codecov.
|
It looks like the tests are not run at all on the CI. |
See #1641 You need to use the |
You can actually parameterize fixtures, so maybe we should add a |
So instead of
this should work better now: from ctapipe.instrument import CameraGeometry
import pytest
@pytest.fixture(params=["LSTCam", "CHEC", "FlashCam", "NectarCam", "MAGICCam", "FACT"])
def camera_geometry(request):
return CameraGeometry.from_name(request.param)
def test_foo(camera_geometry):
print(len(camera_geometry)) Result:
|
Nice! Edit: I skipped it on the other tests because the relevant tests explicitly test |
By the way, if you want to make larger changes to the API, that is also fine - this code was used a lot in the studies on wavelet cleaning for example, but those already no longer work with with the latest ctapipe and are being re-written, so right now there is no real constraint on the API and a nicer one would be welcome |
- hexe -> hex
I would like to, but right now I am not sure what the best way would be. At that point it would probably also be good to have a look into the efforts of the ML group as you mentioned above. Probably not worth to rethink this twice. |
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
We could maybe add convenience functions to geom_2d = geom.to_2d(method='skew')
geom_1d = geom_2d.to_1d() That just calls these functions in the background. In the future we would implement more methods or use the ones by the ML group. The |
The problem I have with cartesian is that it uses opposite axis (y positive up) direction for the y-axis than the usual image convention (y positive down). What do we do here? Does "imshow" look like the same? |
The actual projection (how x/y map to pixels) probably doesn't matter, it should just be documented. Imshow in fact puts Y on the Y axis, but positive down, unlike a normal plot (unless you add an option to flip it), so even using imshow doesn' give what one would expect. In the end machine learning and cleaning algorithms don't really care I guess. |
Currently the axes are set up in a way, that Naming things is hard... Edit: Actually... Is the axis orientation really part of the definition of an euklidian vector space/grid/...? |
By the way, imshow only defaults to y-negative, but you can have it display either way, so it doesn't matter really which way. It may be clearer to have a traditional x-y axis. plt.imshow(image, origin="lower") puts 0,0 at the lower left as usual. It only defaults to the other way because JPG and PNG (and most other graphics formats) use that convention, so that scan lines can be drawn from top-to-botttom. But that does makes it nicer to be able to export the files to PNG, etc. Those are still cartesian images (in that they have an orthonormal basis. The only reason I didn't like "regular" is that the most common English definition is "typical", not "evenly spaced", so for me it was confusing. The real problem is that we have overloaded the word "image"... we could use Cherenkov Image or Camera Image to mean the 1D ones .. |
In fact, at one point I had thought of defining a |
Side Note: We do name the peak times array
|
It sounds excessive to create a new object for each image. If we were to perform all operations on |
Yes this was the main reason I did not do it, along with added complexity when writing the data. |
Co-authored-by: Maximilian Nöthe <[email protected]>
5df56f2
to
4362665
Compare
4362665
to
d499d99
Compare
Sorry @kosack I forgot to remove a now obsolete import in the last commit, which made the tests fail. |
* Implement a general conversion between 1d and 2d images for rectangular pixels - Removes the old astri and chec code as this is now handled in the general case * Fix test, use general converter instead of astri/chec functions - Test now compares the original image to the image after tranforming back to 1d - Fixes loop, removes return: Previously most geometries were actually untested, because the pixel shape was compared to a string instead of the enum. This printed a warning about unsupported camera geometries but that was easily missed. * Add docstrings * Fix flat image dtype * Fix tests - Use parameterized fixture instead of known camera descriptions, because these are not cached at this point and the tests would just skip - Compare to pixel shape enum instead of string * Rename hexagonal geometry converter - hexe -> hex * Fix codacy complaints * Cache row and col for 2d transformation * Remove unused import * Rename row/col properties * Remove import * Move image conversion code to the camera module - Removes some hex-specific code - Why? To attach the conversion code to the camera geometry * Move tests aswell * Add functions to convert images from 1d arrays to 2d and the other way around - define pixel row and column for hexagonal pixels - Use the same, simple 1D<->2D functions for both, square and hexagonal pixels - TODO: This fails for geometries without evenly sized pixels! This probably means the old hex code needs to be added again as workaround for this case as it was working fine that way. * Calculate rows and columns of hexagonal pixels correctly - move row and column properties to one new property to avoid having to perform the same calculation twice - This fixes the case of hexagonal pixels of differing size, that was previously broken (Whipple490 geometry) * Transform multiple images at once - `to_regukar_image` and `regular_image_to_1d` now support the transformation of multiple images at once. For multiple images, the leading dimension has to be one separating the images * Clean up comments and docstrings * Remove empty notebook and unused import * Fix codacy complaints * Fix image orientation - for geometries with hexagonal pixels, the 2d image was flipped. This fixes it in the sense, that it now matches what you expect when comparing with the CameraDisplay * Update docs - Conversion of images to 2d arrays is now done inside of the camera geometry * Remove orphaned reference and add notebook for 2d image vonversion to the index * Add missing import * Rename functions for conversion between 1d and 2d image arrays * Treat circular pixels like hexagonal ones Co-authored-by: Maximilian Nöthe <[email protected]> * Remove unused test code Co-authored-by: Maximilian Nöthe <[email protected]>
This add new converter functions to go from 1d to 2d images and backwards with square pixels (which is the much easier case obviously). It is basically the code from #1139 and added to be able to apply a gaussian filter in #1723 (at least for square pixels).
I see some issues with this structure of converters and I am also not really happy with the API, but for now I wanted to make minimal changes to the code. Maybe this is something that could be attached to the camera geometry in the future?
Also this is pretty trivial to vectorize, but I am not sure about the existing code for hexagonal pixels, so I skipped on that as well (and I intend to use it in an event loop for now).
Bonus:
The existing unit test was not really doing much, because it compared the pixel shape to a string and thus skipped most geometries. Thats fixed as well.