Skip to content
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

Feature: implement quality assurance #538

Open
wants to merge 17 commits into
base: decentralize
Choose a base branch
from

Conversation

sarkarchandan
Copy link
Contributor

@sarkarchandan sarkarchandan commented Jul 5, 2024

Premise: In this PR we implement quality assurance protocols for online reconstruction. Following is an example session which can be used a preliminary idea to test the implementation. This session uses a file camera and pre-acquired measurements with markers.

import asyncio
import logging
import os
import numpy as np
import zmq
import concert
from concert.experiments.addons import tango as tango_addons
from concert.quantities import q
from concert.devices.motors.dummy import LinearMotor, ContinuousRotationMotor
from concert.devices.shutters.dummy import Shutter
from concert.storage import RemoteDirectoryWalker
from concert.ext.viewers import PyQtGraphViewer
from concert.networking.base import get_tango_device
from concert.experiments.synchrotron import RemoteRadiography
from concert.devices.cameras.dummy import FileCamera
from concert.helpers import CommData
from concert.ext.tangoservers.rae import EstimationAlgorithm

# Run Acquisitions Walker Writer: concert tango walker --loglevel perfdebug --port 7001
# Run RotationAxisEstimator Server 1: concert tango rae --loglevel perfdebug --port 7002
# Run RotationAxisEstimator Server 2: concert tango rae --loglevel perfdebug --port 7003
# Run OnlineReconstruction Server 1: concert tango reco --loglevel perfdebug --port 7004
# Run OnlineReconstruction Server 2: concert tango reco --loglevel perfdebug --port 7005
# Run Walker Server 1 for OnlineReconstruction: concert tango walker --loglevel perfdebug --port 7006
# Run Walker Server 2 for OnlineReconstruction: concert tango walker --loglevel perfdebug --port 7007

# Camera
pattern = "/home/ws/nj4412/workspace/projects/analytical_methods/data/measurements/scan_0007/image_seq"
camera = await FileCamera(pattern=pattern, reset_on_start=False)
if await camera.get_state() == 'recording':
    await camera.stop_recording()

await camera.set_roi_width(1776 * q.px)
await camera.set_roi_height(1272 * q.px)
await camera.set_frame_rate(50 / q.s)

SERVERS = {
        "walker": CommData("localhost", port=8991, socket_type=zmq.PUSH),
        "live": CommData("localhost", port=8992, socket_type=zmq.PUB, sndhwm=1),
        "rae1": CommData("localhost", port=8993, socket_type=zmq.PUSH),
        "rae2": CommData("localhost", port=8994, socket_type=zmq.PUSH),
        "reco1": CommData("localhost", port=8995, socket_type=zmq.PUSH),
        "reco2": CommData("localhost", port=8996, socket_type=zmq.PUSH)
}

for comm in SERVERS.values():
    try:
        await camera.register_endpoint(comm)
    except Exception as e:
        print(f"re-registering `{comm.server_endpoint}'")
        await camera.unregister_endpoint(comm)
        await camera.register_endpoint(comm)

# Experiment and Walker|Writer Configuration
root = "/home/ws/nj4412/workspace/projects/testbed/concert_dev_tests/root"
walker_dev_uri = f"{os.uname()[1]}:7001/concert/tango/walker#dbase=no"
walker_device = get_tango_device(walker_dev_uri, timeout=30 * 60 * q.s)
await walker_device.write_attribute('endpoint', SERVERS["walker"].client_endpoint)
walker = await RemoteDirectoryWalker(device=walker_device, root=root, bytes_per_file=2**40)

shutter = await Shutter()
flat_motor = await LinearMotor()
tomo = await ContinuousRotationMotor()
exp = await RemoteRadiography(walker=walker, camera=camera, shutter=shutter, flat_motor=flat_motor,
                              radio_position=0*q.mm, flat_position=10*q.mm, 
                              num_darks=200, num_flats=200, num_projections=3000)
writer = await tango_addons.ImageWriter(exp, exp.acquisitions)

# Live View Configuration
viewer = await PyQtGraphViewer(show_refresh_rate=True)
viewer.subscribe(SERVERS["live"].client_endpoint)

# RotationAxisEstimator Configuration
# 1.
crop_top = 130
crop_bottom = 230
crop_left = 400
crop_right = 1600
num_markers= 3
marker_diameter_px = 16
wait_window = 75
check_window = 50
estm_offset = 5
err_threshold = 0.01

rae1_dev_uri = f"{os.uname()[1]}:7002/concert/tango/rae#dbase=no"
rae1_device = get_tango_device(uri=rae1_dev_uri, timeout=30 * 60 * q.s)
await rae1_device.write_attribute("endpoint", SERVERS["rae1"].client_endpoint)
rae1 = await tango_addons.RotationAxisEstimator(device=rae1_device, experiment=exp,
                                                acquisitions=exp.acquisitions, num_darks=200,
                                                num_flats=200, num_radios=3000, 
                                                crop_top=crop_top,
                                                crop_bottom=crop_bottom,
                                                crop_left=crop_left,
                                                crop_right=crop_right,
                                                num_markers=num_markers,
                                                marker_diameter_px=marker_diameter_px,
                                                wait_window=wait_window,
                                                check_window=check_window,
                                                estm_offset=estm_offset,
                                                err_threshold=err_threshold,
                                                estimation_algorithm=EstimationAlgorithm.MT_SEGMENTATION)

# 2.
rae2_dev_uri = f"{os.uname()[1]}:7003/concert/tango/rae#dbase=no"
rae2_device = get_tango_device(uri=rae2_dev_uri, timeout=30 * 60 * q.s)
await rae2_device.write_attribute("endpoint", SERVERS["rae2"].client_endpoint)
rae2 = await tango_addons.RotationAxisEstimator(device=rae2_device, experiment=exp,
                                                acquisitions=exp.acquisitions, num_darks=200,
                                                num_flats=200, num_radios=3000,
                                                crop_top=crop_top,
                                                crop_bottom=crop_bottom,
                                                crop_left=crop_left,
                                                crop_right=crop_right,
                                                num_markers=num_markers,
                                                marker_diameter_px=marker_diameter_px,
                                                wait_window=wait_window,
                                                check_window=check_window,
                                                estm_offset=estm_offset,
                                                err_threshold=err_threshold,
                                                estimation_algorithm=EstimationAlgorithm.MT_HOUGH_TRANSFORM)

# Online Reconstruction Configuration
# 1.
remote_reco_walker1_dev_uri = f"{os.uname()[1]}:7006/concert/tango/walker#dbase=no"
remote_reco_walker1_device = get_tango_device(remote_reco_walker1_dev_uri, timeout=30 * 60 * q.s)
remote_reco_walker1 = await RemoteDirectoryWalker(device=remote_reco_walker1_device, root=root,
                                           bytes_per_file=2**40)
reco1_dev_uri = f"{os.uname()[1]}:7004/concert/tango/reco#dbase=no"
reco1_device = get_tango_device(reco1_dev_uri, timeout=30 * 60 * q.s)
await reco1_device.write_attribute('endpoint', SERVERS["reco1"].client_endpoint)
await reco1_device.setup_walker(
    [remote_reco_walker1_dev_uri, root, "tcp", "localhost", "8997"]
)
await reco1_device.register_rotation_axis_feedback(rae1_dev_uri)
reco1 = await tango_addons.OnlineReconstruction(reco1_device, exp, do_normalization=True,
                                               average_normalization=True, slice_directory="online-slices-segmentation")

# We set the center_position_z to the middle pixel in the vertical direction
await reco1_device.write_attribute('center_position_z', [(await camera.get_roi_height()).magnitude / 2 + 0.5])
# We don't need to manually set the z-parameter because it is by default set to z, means region
# gives us the slices to be reconstructed. We reconstruct slices, which is located between an offset of -46 to 46 from the middle.
await reco1.set_region([-46, 46, 1])
await reco1.set_fix_nan_and_inf(True)
await reco1.set_absorptivity(True)
await reco1_device.write_attribute('number', 3000)
await reco1_device.write_attribute('overall_angle', np.pi)

# 2.
remote_reco_walker2_dev_uri = f"{os.uname()[1]}:7007/concert/tango/walker#dbase=no"
remote_reco_walker2_device = get_tango_device(remote_reco_walker2_dev_uri, timeout=30 * 60 * q.s)
remote_reco_walker2 = await RemoteDirectoryWalker(device=remote_reco_walker2_device, root=root,
                                           bytes_per_file=2**40)
reco2_dev_uri = f"{os.uname()[1]}:7005/concert/tango/reco#dbase=no"
reco2_device = get_tango_device(reco2_dev_uri, timeout=30 * 60 * q.s)
await reco2_device.write_attribute('endpoint', SERVERS["reco2"].client_endpoint)
await reco2_device.setup_walker(
    [remote_reco_walker2_dev_uri, root, "tcp", "localhost", "8998"]
)
await reco2_device.register_rotation_axis_feedback(rae2_dev_uri)
reco2 = await tango_addons.OnlineReconstruction(reco2_device, exp, do_normalization=True,
                                               average_normalization=True, slice_directory="online-slices-hough-transform")

# We set the center_position_z to the middle pixel in the vertical direction
await reco2_device.write_attribute('center_position_z', [(await camera.get_roi_height()).magnitude / 2 + 0.5])
# We don't need to manually set the z-parameter because it is by default set to z, means region
# gives us the slices to be reconstructed. We reconstruct slices, which is located between an offset of -46 to 46 from the middle.
await reco2.set_region([-46, 46, 1])
await reco2.set_fix_nan_and_inf(True)
await reco2.set_absorptivity(True)
await reco2_device.write_attribute('number', 3000)
await reco2_device.write_attribute('overall_angle', np.pi)

@sarkarchandan sarkarchandan self-assigned this Jul 5, 2024
Copy link

codecov bot commented Jul 5, 2024

Codecov Report

Attention: Patch coverage is 0.32787% with 304 lines in your changes missing coverage. Please review.

Project coverage is 79.16%. Comparing base (fc0ad7e) to head (d331561).

Files with missing lines Patch % Lines
concert/ext/tangoservers/rae.py 0.00% 208 Missing ⚠️
concert/experiments/addons/tango.py 0.00% 51 Missing ⚠️
concert/ext/tangoservers/reco.py 0.00% 32 Missing ⚠️
concert/experiments/addons/typing.py 0.00% 10 Missing ⚠️
concert/ext/cmd/tango.py 25.00% 3 Missing ⚠️
Additional details and impacted files
@@               Coverage Diff                @@
##           decentralize     #538      +/-   ##
================================================
- Coverage         81.40%   79.16%   -2.24%     
================================================
  Files               134      136       +2     
  Lines             10690    10992     +302     
================================================
  Hits               8702     8702              
- Misses             1988     2290     +302     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sarkarchandan sarkarchandan changed the title feat: Implement quality assurance Feature: implement quality assurance Aug 9, 2024
concert/ext/ufo.py Outdated Show resolved Hide resolved
concert/ext/ufo.py Outdated Show resolved Hide resolved
concert/ext/ufo.py Outdated Show resolved Hide resolved
concert/ext/ufo.py Outdated Show resolved Hide resolved
Copy link
Contributor

@tfarago tfarago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General concept OK, we have to test and test and test some more. When it's robust, then we need to optimize for 1. lowering the number of necessary projections and 2. speed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants