Region Data ----------- .. uml:: skinparam style strictuml hide footbox title Region data 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 Frontend -> Backend : 3. ADD_REQUIRED_TILES Frontend -> Backend : 4. SET_CURSOR Frontend <-- Backend : 5. RASTER_TILE_DATA Frontend <-- Backend : 5. SPATIAL_PROFILE_DATA deactivate Backend User <-- Frontend: Displays image deactivate Frontend User -> Frontend: Draw region activate Frontend Frontend -> Backend : 6. SET_REGION activate Backend Frontend <--[#red] Backend : 7. SET_REGION_ACK [Check 1] deactivate Backend User <-- Frontend: Displays region deactivate Frontend User -> Frontend: Request region data activate Frontend Frontend -> Backend : 8. SET_HISTOGRAM_REQUIREMENTS activate Backend Frontend <--[#red] Backend : 9. REGION_HISTOGRAM_DATA [Check 2] deactivate Backend User <-- Frontend: Displays histogram deactivate Frontend REGION_DATA_STREAM ~~~~~~~~~~~~~~~~~~ See the `source code `__. This test verifies that spectral profile data, histogram data, and statistics data are all streamed correctly after creating a region. 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 - OPEN_FILE_ACK.file_info.name = "M17_SWex.image" 3. Frontend sends: **ADD_REQUIRED_TILES** and **SET_CURSOR** .. code-block:: protobuf file_id = 0 tiles = [0] point = {x: 1.0, y: 1.0} 4. Frontend sends: **SET_REGION** (``SetRegion``) for an ellipse region .. code-block:: protobuf file_id = 0 region_id = 1 region_type = ELLIPSE control_points = [{x: 302, y: 370}, {x: 10, y: 20}] rotation = 30.0 5. Backend returns: **SET_REGION_ACK** (``SetRegionAck``) :red-text:`Check 2:` the SET_REGION_ACK should satisfy: - SET_REGION_ACK.success = True - SET_REGION_ACK.region_id = 1 6. Frontend sends: **SET_SPECTRAL_REQUIREMENTS** (``SetSpectralRequirements``) .. code-block:: protobuf file_id = 0 region_id = 1 spectral_profiles = [{coordinate: "z", stats_types: [Mean]}] 7. Backend returns: **SPECTRAL_PROFILE_DATA** (``SpectralProfileData``) :red-text:`Check 3:` the SPECTRAL_PROFILE_DATA should satisfy: - Should arrive within 5000 ms - SPECTRAL_PROFILE_DATA.region_id = 1 - SPECTRAL_PROFILE_DATA.progress = 1 8. Frontend sends: **SET_HISTOGRAM_REQUIREMENTS** (``SetHistogramRequirements``) .. code-block:: protobuf file_id = 0 region_id = 1 histograms = [{channel: -1, num_bins: -1}] 9. Backend returns: **REGION_HISTOGRAM_DATA** (``RegionHistogramData``) :red-text:`Check 4:` the REGION_HISTOGRAM_DATA should satisfy: - Should arrive within 5000 ms - REGION_HISTOGRAM_DATA.region_id = 1 - REGION_HISTOGRAM_DATA.progress = 1 10. Frontend sends: **SET_STATS_REQUIREMENTS** (``SetStatsRequirements``) .. code-block:: protobuf file_id = 0 region_id = 1 stats_configs = [{coordinate: "z", stats_types: [Count, Sum, FluxDensity, Mean, RMS, Sigma, SumSq, Min, Max, Extrema]}] 11. Backend returns: **REGION_STATS_DATA** (``RegionStatsData``) :red-text:`Check 5:` the REGION_STATS_DATA should satisfy: - Should arrive within 5000 ms - REGION_STATS_DATA.region_id = 1 REGION_HISTOGRAM ~~~~~~~~~~~~~~~~ See the `source code `__. This test verifies that region histograms are computed correctly for rectangle regions with different rotations, comparing results across CASA IMAGE and HDF5 formats. **For each file format (M17_SWex.image and M17_SWex.hdf5):** 1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``) .. code-block:: protobuf directory = "set_QA" file = "M17_SWex.image" / "M17_SWex.hdf5" 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} 4. Frontend sends: **SET_REGION** (``SetRegion``) for 3 rectangle regions Region 1 (no rotation): .. code-block:: protobuf file_id = 0 region_id = -1 region_type = RECTANGLE control_points = [{x: 98, y: 541}, {x: 7, y: 7}] rotation = 0 Region 2 (90 degree rotation): .. code-block:: protobuf file_id = 0 region_id = -1 region_type = RECTANGLE control_points = [{x: 98, y: 541}, {x: 7, y: 7}] rotation = 90 Region 3 (out-of-bounds, 45 degree rotation): .. code-block:: protobuf file_id = 0 region_id = -1 region_type = RECTANGLE control_points = [{x: 0, y: 524}, {x: 7, y: 7}] rotation = 45 5. Backend returns: **SET_REGION_ACK** (``SetRegionAck``) for each region :red-text:`Check 2:` the SET_REGION_ACK should satisfy: - All SET_REGION_ACK.success = True - region_id = 1, 2, 3 respectively 6. Frontend sends: **SET_HISTOGRAM_REQUIREMENTS** (``SetHistogramRequirements``) for each region .. code-block:: protobuf file_id = 0 region_id = <1-3> histograms = [{channel: -1, num_bins: -1}] 7. Backend returns: **REGION_HISTOGRAM_DATA** (``RegionHistogramData``) for each region :red-text:`Check 3:` the REGION_HISTOGRAM_DATA should satisfy: - Should arrive within 5000 ms - Region 1 (no rotation): .. code-block:: protobuf region_id = 1 progress = 1 numBins = 7 binWidth = 0.003347359 firstBinCenter = -0.007536160 bins = [5, 2, 1, 0, 4, 1, 3] - Region 2 (90 degree rotation): same histogram data as Region 1 (symmetric region) .. code-block:: protobuf region_id = 2 progress = 1 numBins = 7 binWidth = 0.003347359 firstBinCenter = -0.007536160 bins = [5, 2, 1, 0, 4, 1, 3] - Region 3 (out-of-bounds): empty histogram .. code-block:: protobuf region_id = 3 progress = 1 numBins = 1 bins = [0] - Results should be consistent between CASA IMAGE and HDF5 formats REGION_HISTOGRAM_ITERATION ~~~~~~~~~~~~~~~~~~~~~~~~~~ See the `source code `__. This test verifies that region histograms change correctly when a region is iteratively rotated. It tests both rectangle and ellipse regions with 5 rotation angles each. 1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``) .. code-block:: protobuf directory = "set_QA" file = "supermosaic.10.fits" 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 - OPEN_FILE_ACK.file_info.name = "supermosaic.10.fits" 3. Frontend sends: **ADD_REQUIRED_TILES** and **SET_CURSOR** .. code-block:: protobuf file_id = 0 tiles = [0] point = {x: 1.0, y: 1.0} **Rectangle region iterations (region #1):** 4. Frontend sends: **SET_REGION** (``SetRegion``) to create a rectangle region, then modifies it with 4 additional rotations Initial creation (rotation = 0): .. code-block:: protobuf file_id = 0 region_id = -1 region_type = RECTANGLE control_points = [{x: 303, y: 607}, {x: 5, y: 10}] rotation = 0 Subsequent modifications (region_id = 1) with rotations: 25, 50, 75, 100 degrees 5. For each rotation, frontend sends: **SET_HISTOGRAM_REQUIREMENTS** (``SetHistogramRequirements``) .. code-block:: protobuf file_id = 0 region_id = 1 histograms = [{channel: -1, num_bins: -1}] 6. Backend returns: **REGION_HISTOGRAM_DATA** (``RegionHistogramData``) for each rotation :red-text:`Check 2:` the REGION_HISTOGRAM_DATA for rectangle should satisfy: - Should arrive within 5000 ms for each rotation - Rotation 0: numBins = 7, bins = [3, 12, 7, 13, 8, 7, 5] - Rotation 25: numBins = 9, bins = [1, 1, 11, 9, 10, 6, 4, 5, 4] - Rotation 50: numBins = 9, bins = [2, 2, 6, 11, 9, 5, 3, 6, 7] - Rotation 75: numBins = 8, bins = [2, 3, 9, 9, 3, 8, 8, 9] - Rotation 100: numBins = 8, bins = [3, 1, 8, 5, 5, 10, 9, 10] **Ellipse region iterations (region #2):** 7. Frontend sends: **SET_REGION** (``SetRegion``) to create an ellipse region, then modifies it with 4 additional rotations Initial creation (rotation = 0): .. code-block:: protobuf file_id = 0 region_id = -1 region_type = ELLIPSE control_points = [{x: 303, y: 607}, {x: 3, y: 7}] rotation = 0 Subsequent modifications (region_id = 2) with rotations: 25, 50, 75, 100 degrees 8. For each rotation, frontend sends: **SET_HISTOGRAM_REQUIREMENTS** (``SetHistogramRequirements``) .. code-block:: protobuf file_id = 0 region_id = 2 histograms = [{channel: -1, num_bins: -1}] 9. Backend returns: **REGION_HISTOGRAM_DATA** (``RegionHistogramData``) for each rotation :red-text:`Check 3:` the REGION_HISTOGRAM_DATA for ellipse should satisfy: - Should arrive within 5000 ms for each rotation - Rotation 0: numBins = 9, bins = [4, 4, 5, 8, 6, 5, 8, 11, 13] - Rotation 25: numBins = 15, bins = [1, 1, 2, 2, 5, 6, 3, 5, 3, 9, 7, 9, 1, 11, 2] - Rotation 50: numBins = 15, bins = [3, 4, 5, 2, 4, 6, 5, 7, 6, 8, 6, 1, 6, 3, 1] - Rotation 75: numBins = 15, bins = [5, 6, 8, 3, 5, 6, 6, 4, 7, 5, 5, 1, 5, 2, 1] - Rotation 100: numBins = 15, bins = [1, 1, 1, 4, 7, 10, 6, 8, 7, 5, 3, 2, 5, 4, 3] REGION_REGISTER ~~~~~~~~~~~~~~~ See the `source code `__. This test verifies region creation, modification, and removal on an image. 1. Frontend sends: **CLOSE_FILE** (``CloseFile``) and **OPEN_FILE** (``OpenFile``) .. code-block:: protobuf directory = "set_QA" file = "M17_SWex.fits" 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 - OPEN_FILE_ACK.file_info.name = "M17_SWex.fits" 3. Frontend sends: **ADD_REQUIRED_TILES** and **SET_CURSOR** .. code-block:: protobuf file_id = 0 tiles = [0] point = {x: 1.0, y: 1.0} **Creating 7 new regions:** 4. Frontend sends: **SET_REGION** (``SetRegion``) for 7 new regions (region_id = -1) Region 1 (rectangle): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 197, y: 489}, {x: 10, y: 10}] rotation = 0.0 Region 2 (rectangle, rotated): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 306, y: 670}, {x: 20, y: 48}] rotation = 27.0 Region 3 (ellipse): .. code-block:: protobuf region_type = ELLIPSE control_points = [{x: 551, y: 330}, {x: 30, y: 15}] rotation = 0.0 Region 4 (rectangle): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 580, y: 240}, {x: 35, y: 35}] rotation = 0.0 Region 5 (rectangle): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 552, y: 184}, {x: 350, y: 18}] rotation = 0.0 Region 6 (rectangle): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 635, y: 128}, {x: 25, y: 48}] rotation = 0.0 Region 7 (rectangle): .. code-block:: protobuf region_type = RECTANGLE control_points = [{x: 694, y: 80}, {x: 25, y: 33}] rotation = 0.0 5. Backend returns: **SET_REGION_ACK** (``SetRegionAck``) for each region :red-text:`Check 2:` the SET_REGION_ACK should satisfy: - All SET_REGION_ACK.success = True - region_id = 1, 2, 3, 4, 5, 6, 7 respectively **Modifying region #1 (moving across the image):** 6. Frontend sends: **SET_REGION** (``SetRegion``) to modify region #1 multiple times Move 1: center at (84, 491) .. code-block:: protobuf region_id = 1 region_type = RECTANGLE control_points = [{x: 84, y: 491}, {x: 10, y: 10}] rotation = 0.0 Move 2: center at (43, 491) .. code-block:: protobuf region_id = 1 control_points = [{x: 43, y: 491}, {x: 10, y: 10}] Move 3: center at (-1, 491) (partially out-of-bounds) .. code-block:: protobuf region_id = 1 control_points = [{x: -1, y: 491}, {x: 10, y: 10}] Move 4: center at (-14, 491) (fully out-of-bounds) .. code-block:: protobuf region_id = 1 control_points = [{x: -14, y: 491}, {x: 10, y: 10}] Move 5: back to original position (197, 489) .. code-block:: protobuf region_id = 1 control_points = [{x: 197, y: 489}, {x: 10, y: 10}] :red-text:`Check 3:` each SET_REGION_ACK should satisfy: - SET_REGION_ACK.success = True - SET_REGION_ACK.region_id = 1 **Removing region #3 and creating a replacement:** 7. Frontend sends: **REMOVE_REGION** to remove region #3 :red-text:`Check 4:` after removing region #3: - No ICD messages should be returned from the backend within 500 ms 8. Frontend sends: **SET_REGION** (``SetRegion``) to create a new ellipse region (region_id = -1) .. code-block:: protobuf region_type = ELLIPSE control_points = [{x: 551, y: 330}, {x: 30, y: 15}] rotation = 30.0 9. Backend returns: **SET_REGION_ACK** (``SetRegionAck``) :red-text:`Check 5:` the SET_REGION_ACK should satisfy: - SET_REGION_ACK.success = True - SET_REGION_ACK.region_id = 8 (next available ID after 7 previously created regions)