CASA Region
-----------
.. uml::
skinparam style strictuml
hide footbox
title CASA region import/export workflow
actor User
box "Client-side" #EDEDED
participant Frontend
end box
box "Server-side" #lightblue
participant Backend
end box
User -> Frontend: Open image
activate Frontend
Frontend -> Backend : 1. OPEN_FILE
activate Backend
Frontend <-- Backend : 2. OPEN_FILE_ACK
deactivate Backend
User <-- Frontend: Displays image
deactivate Frontend
User -> Frontend: Browse region files
activate Frontend
Frontend -> Backend : 3. REGION_LIST_REQUEST
activate Backend
Frontend <--[#red] Backend : 4. REGION_LIST_RESPONSE [Check 1]
deactivate Backend
User <-- Frontend: Displays region list
deactivate Frontend
User -> Frontend: Get region file info
activate Frontend
Frontend -> Backend : 5. REGION_FILE_INFO_REQUEST
activate Backend
Frontend <--[#red] Backend : 6. REGION_FILE_INFO_RESPONSE [Check 2]
deactivate Backend
User <-- Frontend: Displays region file info
deactivate Frontend
User -> Frontend: Import region file
activate Frontend
Frontend -> Backend : 7. IMPORT_REGION
activate Backend
Frontend <--[#red] Backend : 8. IMPORT_REGION_ACK [Check 3]
deactivate Backend
User <-- Frontend: Displays imported regions
deactivate Frontend
User -> Frontend: Export regions
activate Frontend
Frontend -> Backend : 9. EXPORT_REGION
activate Backend
Frontend <--[#red] Backend : 10. EXPORT_REGION_ACK [Check 4]
deactivate Backend
User <-- Frontend: Region file saved
deactivate Frontend
CASA_REGION_INFO
~~~~~~~~~~~~~~~~
See the `source code `__.
This test verifies that CASA region file listing and file info retrieval work correctly.
1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``)
.. code-block:: protobuf
directory = "set_QA"
file = "M17_SWex.image"
hdu = ""
file_id = 0
render_mode = RASTER
2. Backend returns: **OPEN_FILE_ACK** (``OpenFileAck``) and **REGION_HISTOGRAM_DATA**
:red-text:`Check 1:` the OPEN_FILE_ACK should satisfy:
- OPEN_FILE_ACK.success = True
3. Frontend sends: **REGION_LIST_REQUEST** (``RegionListRequest``)
.. code-block:: protobuf
directory = ""
4. Backend returns: **REGION_LIST_RESPONSE** (``RegionListResponse``)
:red-text:`Check 2:` the REGION_LIST_RESPONSE should satisfy:
- REGION_LIST_RESPONSE.success = True
- REGION_LIST_RESPONSE.directory contains the region subdirectory path
- REGION_LIST_RESPONSE.subdirectories = [] (empty)
- REGION_LIST_RESPONSE.files should contain:
- "M17_SWex_regionSet1_pix.crtf" (type = CRTF)
- "M17_SWex_regionSet1_world.crtf" (type = CRTF)
5. Frontend sends: **REGION_FILE_INFO_REQUEST** (``RegionFileInfoRequest``) for each region file
File 1:
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet1_world.crtf"
File 2:
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet1_pix.crtf"
6. Backend returns: **REGION_FILE_INFO_RESPONSE** (``RegionFileInfoResponse``) for each file
:red-text:`Check 3:` the REGION_FILE_INFO_RESPONSE for the world coordinate file should satisfy:
- Should arrive within 6000 ms
- REGION_FILE_INFO_RESPONSE.success = True
- REGION_FILE_INFO_RESPONSE.file_info.name = "M17_SWex_regionSet1_world.crtf"
- REGION_FILE_INFO_RESPONSE.file_info.type = CRTF
- REGION_FILE_INFO_RESPONSE.contents should contain 17 lines of CRTF region definitions (header + 16 regions)
:red-text:`Check 4:` the REGION_FILE_INFO_RESPONSE for the pixel coordinate file should satisfy:
- REGION_FILE_INFO_RESPONSE.success = True
- REGION_FILE_INFO_RESPONSE.file_info.name = "M17_SWex_regionSet1_pix.crtf"
- REGION_FILE_INFO_RESPONSE.file_info.type = CRTF
- REGION_FILE_INFO_RESPONSE.contents should contain 17 lines of CRTF region definitions (header + 16 regions)
- Contents should match expected CRTF format entries for symbol, centerbox, rotbox, ellipse, and poly region types
CASA_REGION_IMPORT_INTERNAL
~~~~~~~~~~~~~~~~~~~~~~~~~~~
See the `source code `__.
This test verifies that CASA region files (CRTF format) created with CARTA can be imported correctly, comparing both world and pixel coordinate formats.
1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``)
.. code-block:: protobuf
directory = "set_QA"
file = "M17_SWex.image"
hdu = ""
file_id = 0
render_mode = RASTER
2. Backend returns: **OPEN_FILE_ACK** (``OpenFileAck``) and **REGION_HISTOGRAM_DATA**
:red-text:`Check 1:` the OPEN_FILE_ACK should satisfy:
- OPEN_FILE_ACK.success = True
**Import world coordinate region file:**
3. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet1_world.crtf"
type = CRTF
group_id = 0
4. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 2:` the IMPORT_REGION_ACK for the world coordinate file should satisfy:
- Should arrive within 500 ms
- IMPORT_REGION_ACK.success = True
- Length of regions = 16
- Regions should include the following types with correct control points (precision = 1 digit):
- Region 1: POINT at (-103.8, 613.1)
- Region 2: RECTANGLE at (-106.4, 528.9), size (75.1, 75.1), rotation = 0
- Region 3: RECTANGLE at (-118.0, 412.4), size (137.2, 54.4), rotation = 0
- Region 4: RECTANGLE at (-120.6, 251.9), size (173.5, 44.0), rotation = 45
- Region 5: ELLIPSE at (758.3, 635.1), semi-axes (50.5, 50.5), rotation = 0
- Region 6: ELLIPSE at (749.3, 486.2), semi-axes (29.8, 69.9), rotation = 0
- Region 7: ELLIPSE at (745.4, 369.7), semi-axes (18.1, 79.0), rotation = 45
- Region 8: POLYGON with vertices (757.0, 270.1), (715.6, 118.6), (829.5, 191.1)
- Regions 9-16: duplicate set (POINT, RECTANGLE x3, ELLIPSE x3, POLYGON)
**Import pixel coordinate region file:**
5. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet1_pix.crtf"
type = CRTF
group_id = 0
6. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 3:` the IMPORT_REGION_ACK for the pixel coordinate file should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 16
- Region IDs continue from 17 to 32 (appended to existing regions)
- Regions should match the same types and control points as the world coordinate import
CASA_REGION_IMPORT_EXCEPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See the `source code `__.
This test verifies that importing invalid CASA region files produces appropriate error messages.
1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``)
.. code-block:: protobuf
directory = "set_QA"
file = "M17_SWex.image"
hdu = ""
file_id = 0
render_mode = RASTER
2. Backend returns: **OPEN_FILE_ACK** (``OpenFileAck``) and **REGION_HISTOGRAM_DATA**
:red-text:`Check 1:` the OPEN_FILE_ACK should satisfy:
- OPEN_FILE_ACK.success = True
**Case 1: Import region file with mixed coordinates (pixel)**
3. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet2_pix.crtf"
type = CRTF
group_id = 0
:red-text:`Check 2:` the IMPORT_REGION_ACK should satisfy:
- The import should fail with error message: "Mixed world and pixel coordinates not supported"
**Case 2: Import region file with mixed coordinates (world)**
4. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_regionSet2_world.crtf"
type = CRTF
group_id = 0
:red-text:`Check 3:` the IMPORT_REGION_ACK should satisfy:
- The import should fail with error message: "Mixed world and pixel coordinates not supported"
CASA_REGION_IMPORT_EXPORT
~~~~~~~~~~~~~~~~~~~~~~~~~
See the `source code `__.
This test verifies the full round-trip of importing a CASA region file, exporting it to both world and pixel coordinates, and re-importing the exported files. It uses a region file containing 10 region types including rectangles, ellipses, polygons, lines, vectors, text annotations, and points.
1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``)
.. code-block:: protobuf
directory = "set_QA"
file = "M17_SWex.image"
hdu = ""
file_id = 0
render_mode = RASTER
2. Backend returns: **OPEN_FILE_ACK** (``OpenFileAck``) and **REGION_HISTOGRAM_DATA**
:red-text:`Check 1:` the OPEN_FILE_ACK should satisfy:
- OPEN_FILE_ACK.success = True
3. Frontend sends: **ADD_REQUIRED_TILES** and **SET_CURSOR**
.. code-block:: protobuf
file_id = 0
tiles = [0]
point = {x: 1.0, y: 1.0}
**Import initial region file:**
4. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_testRegions_pix.crtf"
type = CRTF
group_id = 0
5. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 2:` the IMPORT_REGION_ACK should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 10
- Regions should include:
- Region 1: RECTANGLE at (320, 400), size (40, 100)
- Region 2: RECTANGLE at (320, 400), size (100, 40)
- Region 3: RECTANGLE at (320, 400), size (200, 40), rotation = 45
- Region 4: POLYGON with vertices (320, 400), (320, 600), (400, 400)
- Region 5: ELLIPSE at (320, 400), semi-axes (200, 200)
- Region 6: ELLIPSE at (320, 400), semi-axes (100, 20), rotation = 45
- Region 7: LINE from (320, 400) to (320, 300)
- Region 8: ANNVECTOR from (320, 400) to (370, 450)
- Region 9: ANNTEXT at (320, 400) with label "CARTA REGION TEST"
- Region 10: POINT at (320, 300)
**Export to world coordinates:**
6. Frontend sends: **EXPORT_REGION** (``ExportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_testRegions_pix_export_to_world.crtf"
type = CRTF
coord_type = WORLD
file_id = 0
7. Backend returns: **EXPORT_REGION_ACK** (``ExportRegionAck``)
:red-text:`Check 3:` the EXPORT_REGION_ACK should satisfy:
- EXPORT_REGION_ACK.success = True
- EXPORT_REGION_ACK.contents = [] (empty, written to file)
**Export to pixel coordinates:**
8. Frontend sends: **EXPORT_REGION** (``ExportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_testRegions_pix_export_to_pix.crtf"
type = CRTF
coord_type = PIXEL
file_id = 0
9. Backend returns: **EXPORT_REGION_ACK** (``ExportRegionAck``)
:red-text:`Check 4:` the EXPORT_REGION_ACK should satisfy:
- EXPORT_REGION_ACK.success = True
- EXPORT_REGION_ACK.contents = [] (empty, written to file)
**Re-import exported world coordinate file:**
10. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_testRegions_pix_export_to_world.crtf"
type = CRTF
group_id = 0
11. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 5:` the re-imported world coordinate IMPORT_REGION_ACK should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 10
- Last region ID = 20
**Re-import exported pixel coordinate file:**
12. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_testRegions_pix_export_to_pix.crtf"
type = CRTF
group_id = 0
13. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 6:` the re-imported pixel coordinate IMPORT_REGION_ACK should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 10
- Last region ID = 30
CASA_REGION_EXPORT
~~~~~~~~~~~~~~~~~~
See the `source code `__.
This test verifies that hand-created regions can be exported to CASA region format (CRTF) and re-imported correctly. It creates 16 regions programmatically (points, rectangles, ellipses, and polygons with various rotations), exports them to both world and pixel coordinate files, and re-imports them.
1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``)
.. code-block:: protobuf
directory = "set_QA"
file = "M17_SWex.image"
hdu = ""
file_id = 0
render_mode = RASTER
2. Backend returns: **OPEN_FILE_ACK** (``OpenFileAck``) and **REGION_HISTOGRAM_DATA**
:red-text:`Check 1:` the OPEN_FILE_ACK should satisfy:
- OPEN_FILE_ACK.success = True
**Create 16 regions programmatically:**
3. Frontend sends: **SET_REGION** (``SetRegion``) 16 times for the following region types:
- Region 1: POINT at (-109.579, 618.563)
- Region 2: RECTANGLE at (-114.748, 508.708), size (90.468, 90.468), rotation = 0
- Region 3: RECTANGLE at (-114.748, 332.941), size (170.597, 64.62), rotation = 0
- Region 4: RECTANGLE at (-126.38, 167.512), size (149.919, 38.772), rotation = 45
- Region 5: ELLIPSE at (758.918, 634.071), semi-axes (62.035, 62.035), rotation = 0
- Region 6: ELLIPSE at (751.163, 444.088), semi-axes (29.725, 93.053), rotation = 0
- Region 7: ELLIPSE at (749.871, 290.291), semi-axes (25.848, 84.006), rotation = 45
- Region 8: POLYGON with vertices (757.626, 184.314), (698.175, 66.7051), (831.293, 106.769)
- Regions 9-16: second set (POINT, RECTANGLE x3, ELLIPSE x3, POLYGON)
:red-text:`Check 2:` all SET_REGION_ACK should satisfy:
- All SET_REGION_ACK.success = True
**Export to world coordinates:**
4. Frontend sends: **EXPORT_REGION** (``ExportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_handMadeRegions_world.crtf"
type = CRTF
coord_type = WORLD
file_id = 0
5. Backend returns: **EXPORT_REGION_ACK** (``ExportRegionAck``)
:red-text:`Check 3:` the EXPORT_REGION_ACK should satisfy:
- EXPORT_REGION_ACK.success = True
- EXPORT_REGION_ACK.contents = []
**Export to pixel coordinates:**
6. Frontend sends: **EXPORT_REGION** (``ExportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_handMadeRegions_pix.crtf"
type = CRTF
coord_type = PIXEL
file_id = 0
7. Backend returns: **EXPORT_REGION_ACK** (``ExportRegionAck``)
:red-text:`Check 4:` the EXPORT_REGION_ACK should satisfy:
- EXPORT_REGION_ACK.success = True
- EXPORT_REGION_ACK.contents = []
**Re-import exported world coordinate file:**
8. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_handMadeRegions_world.crtf"
type = CRTF
group_id = 0
9. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 5:` the IMPORT_REGION_ACK should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 16
- Last region ID = 32
**Re-import exported pixel coordinate file:**
10. Frontend sends: **IMPORT_REGION** (``ImportRegion``)
.. code-block:: protobuf
directory = ""
file = "M17_SWex_handMadeRegions_pix.crtf"
type = CRTF
group_id = 0
11. Backend returns: **IMPORT_REGION_ACK** (``ImportRegionAck``)
:red-text:`Check 6:` the IMPORT_REGION_ACK should satisfy:
- IMPORT_REGION_ACK.success = True
- Length of regions = 16
- Last region ID = 48