Commit b0163734 authored by bliss administrator's avatar bliss administrator
Browse files

Correction of bugs after testing

parent d73d43d4
......@@ -14,6 +14,7 @@ from bliss.common.axis import AxisState
from bliss.common.scans import pointscan, DEFAULT_CHAIN
from bliss.scanning.group import Sequence, Group
from bliss.common.logtools import log_info, log_debug, log_error
from bliss.common import event
from bliss.common.cleanup import (
cleanup,
error_cleanup,
......@@ -25,6 +26,7 @@ from bliss.shell.cli.user_dialog import *
from bliss.shell.cli.pt_widgets import BlissDialog
from bliss.config.static import get_config, ConfigList
from bliss.controllers.machinfo import WaitForRefillPreset
from bliss.scanning.channel import duplicate_channel
import tomo
from tomo.TomoParameters import TomoParameters
......@@ -1088,6 +1090,15 @@ class Tomo(TomoParameters):
setup_globals.machinfo, checktime=dark_scan_time
)
dark_scan.acq_chain.add_preset(refill_preset)
if self.parameters.sinogram_active:
dark_spectrum_acq,= dark_scan.acq_chain.get_node_from_devices(self.tomo_ccd.detector.roi_profiles)
def sequence_channel_emit(event_dict={}, sender=None):
data = event_dict.get("data")
if data is None:
return
scan_sequence.sequence.custom_channels["dark_spectrum"].emit(data)
event.connect(dark_spectrum_acq.channels[0],"new_data",sequence_channel_emit)
# add to scan sequence when requested
if scan_sequence != None:
......@@ -1098,13 +1109,7 @@ class Tomo(TomoParameters):
if run == True:
dark_scan.run()
if self.parameters.sinogram_active:
dark_spectrum_acq = dark_scan.acq_chain.get_node_from_devices(self.tomo_ccd.detector.roi_profiles.counters)
self.tomo_sino.attach_channel_to_sequence(
scan_sequence,
"dark_spectrum",
dark_spectrum_acq.channels[0]
)
# test if an error has occured
if len(capture.failed) > 0:
......@@ -1202,6 +1207,16 @@ class Tomo(TomoParameters):
refill_preset = WaitForRefillPreset(setup_globals.machinfo,checktime=ref_scan_time)
ref_scan.acq_chain.add_preset(refill_preset)
if self.parameters.sinogram_active:
ref_spectrum_acq,= ref_scan.acq_chain.get_node_from_devices(self.tomo_ccd.detector.roi_profiles)
def sequence_channel_emit(event_dict={}, sender=None):
data = event_dict.get("data")
if data is None:
return
scan_sequence.sequence.custom_channels["ref_spectrum"].emit(data)
event.connect(ref_spectrum_acq.channels[0],"new_data",sequence_channel_emit)
# add to scan sequence when requested
if scan_sequence != None:
scan_sequence.add(ref_scan)
......@@ -1211,14 +1226,6 @@ class Tomo(TomoParameters):
if run == True:
ref_scan.run()
if self.parameters.sinogram_active:
ref_spectrum_acq = ref_scan.acq_chain.get_node_from_devices(self.tomo_ccd.detector.roi_profiles.counters)
self.tomo_sino.attach_channel_to_sequence(
scan_sequence,
"ref_spectrum",
ref_spectrum_acq.channels[0]
)
# test if an error has occured
if len(capture.failed) > 0:
log_error(
......
......@@ -17,9 +17,10 @@ from bliss.common.standard import *
from bliss.common.cleanup import cleanup, axis as cleanup_axis
from bliss.shell.standard import umv, umvr
from bliss.scanning.group import Sequence
from bliss.scanning.acquisition.calc import CalcChannelAcquisitionSlave
from bliss.controllers.machinfo import WaitForRefillPreset
from bliss.scanning.channel import duplicate_channel
from bliss.scanning.chain import AcquisitionChannel
from bliss.common import event
from tomo.TomoScan import TomoScan
from tomo.TopoScan import TopoScan
......@@ -351,49 +352,32 @@ class FastTomo:
setup_globals.machinfo, checktime=proj_scan_time
)
proj_scan.acq_chain.add_preset(refill_preset)
if self.tomo.parameters.sinogram_active:
proj_spectrum_acq,= proj_scan.acq_chain.get_node_from_devices(self.tomo.tomo_ccd.detector.roi_profiles)
npixels = self.tomo.tomo_ccd.detector.roi_profiles.get_rois()[0].width
tomo_range = self.tomo.parameters.end_pos-self.tomo.parameters.start_pos
def sequence_channel_emit(event_dict={}, sender=None):
data = event_dict.get("data")
if data is None:
return
if sender == proj_spectrum_acq.channels[0]:
scan_sequence.sequence.custom_channels["proj_spectrum"].emit(data)
data = np.array([np.arange(npixels)] * len(data)).flatten()
scan_sequence.sequence.custom_channels["translation"].emit(data)
elif sender == rotation_acq.channels[0]:
scan_sequence.sequence.custom_channels["rotation"].emit(np.repeat(data%tomo_range, npixels))
event.connect(proj_spectrum_acq.channels[0],"new_data",sequence_channel_emit)
rotation_acq,= proj_scan.acq_chain.get_node_from_devices(self.tomo.rotation_axis)
event.connect(rotation_acq.channels[0],"new_data",sequence_channel_emit)
# add to scan sequence when requested
if scan_sequence != None:
scan_sequence.add(proj_scan)
self.tomo.list_proj_scans.append(proj_scan)
if self.tomo.parameters.sinogram_active:
proj_spectrum_acq = proj_scan.acq_chain.get_node_from_devices(self.tomo_ccd.detector.roi_profiles.counters)
self.tomo_sino.attach_channel_to_sequence(
scan_sequence,
"proj_spectrum",
proj_spectrum_acq.channels[0]
)
tomo_range = self.tomo.parameters.end_pos-self.tomo.parameters.start_pos
npixels = self.tomo.tomo_ccd.detector.roi_profiles.get_rois()[0].width
def replicate(angles):
return np.repeat(angles%tomo_range, npixels)
rotation_acq = proj_scan.acq_chain.get_node_from_devices(self.tomo.rotation_axis)
rotation_channel = [channel for chan in rotation_acq.channels if self.tomo.rotation_axis.name][0]
rotation_replicate_channel, _ , _ = duplicate_channel(rotation_channel,"rotation",replicate,numpy.float)
self.tomo_sino.attach_channel_to_sequence(
scan_sequence,
"rotation",
rotation_replicate_channel)
sino_calc = SinoCalc(scan_sequence.custom_channels["dark_spectrum"],
scan_sequence.custom_channels["ref_spectrum"],
scan_sequence.custom_channels["proj_spectrum"],
scan_sequence.custom_channels["rotation"],
self.tomo.parameters.tomo_n,
scan_sequence)
calc_sino_acq = CalcChannelAcquisitionSlave("calc_sino_acq", [scan_sequence], sino_calc, ["translation"])
chain.add(proj_spectrum_acq,calc_sino_acq)
sino_translation_channel = [channel for chan in calc_sino_acq.channels if "translation"][0]
self.tomo_sino.attach_channel_to_sequence(
scan_sequence,
"translation",
sino_translation_channel)
proj_scan.run()
log_info(self, "projection_scan() leaving")
......@@ -457,7 +441,14 @@ class FastTomo:
)
seq = Sequence(title=self.tomo.sequence, scan_info=scan_info)
if self.tomo.parameters.sinogram_active:
self.tomo.tomo_sino.configure_data_sequence(
seq,
self.tomo.tomo_ccd.detector,
self.tomo.parameters.tomo_n,
)
with seq.sequence_context() as scan_seq:
self.tomo.run_sequence(scan_seq)
......@@ -644,6 +635,13 @@ class HalfTomo(FastTomo, TomoParameters):
)
seq = Sequence(title=self.tomo.sequence, scan_info=scan_info)
if self.tomo.parameters.sinogram_active:
self.tomo.tomo_sino.configure_data_sequence(
seq,
self.tomo.tomo_ccd.detector,
self.tomo.parameters.tomo_n,
)
with seq.sequence_context() as scan_seq:
self.tomo.run_sequence(scan_seq)
......@@ -1848,26 +1846,25 @@ class PcoTomo(FastTomo, TomoParameters):
self.tomo.list_proj_scans.append(proj_scan)
if self.tomo.parameters.sinogram_active:
self.gscan = gevent.spawn(proj_scan.run)
while proj_scan.node is None:
gevent.sleep(0.1)
self.greemit = self.tomo.tomo_sino.create_data_reemitter(
proj_scan.node.db_name, scan_sequence.sequence
)
self.greemit.start()
try:
self.gscan.get()
except:
# stops scan and raises exception
self.gscan.kill()
self.greemit.stop()
raise
finally:
self.greemit.get()
else:
# run the proj scan
proj_scan.run()
proj_spectrum_acq,= proj_scan.acq_chain.get_node_from_devices(self.tomo.tomo_ccd.detector.roi_profiles)
npixels = self.tomo.tomo_ccd.detector.roi_profiles.get_rois()[0].width
tomo_range = self.tomo.parameters.end_pos-self.tomo.parameters.start_pos
def sequence_channel_emit(event_dict={}, sender=None):
data = event_dict.get("data")
if data is None:
return
if sender == proj_spectrum_acq.channels[0]:
scan_sequence.sequence.custom_channels["proj_spectrum"].emit(data)
data = np.array([np.arange(npixels)] * len(data)).flatten()
scan_sequence.sequence.custom_channels["translation"].emit(data)
elif sender == rotation_acq.channels[0]:
scan_sequence.sequence.custom_channels["rotation"].emit(np.repeat(data%tomo_range, npixels))
event.connect(proj_spectrum_acq.channels[0],"new_data",sequence_channel_emit)
rotation_acq,= proj_scan.acq_chain.get_node_from_devices(self.tomo.rotation_axis)
event.connect(rotation_acq.channels[0],"new_data",sequence_channel_emit)
# run the proj scan
proj_scan.run()
log_info(self, "projection_scan() leaving")
......@@ -1929,6 +1926,13 @@ class PcoTomo(FastTomo, TomoParameters):
)
seq = Sequence(title=self.tomo.sequence, scan_info=scan_info)
if self.tomo.parameters.sinogram_active:
self.tomo.tomo_sino.configure_data_sequence(
seq,
self.tomo.tomo_ccd.detector,
self.tomo.parameters.tomo_n,
)
with seq.sequence_context() as scan_seq:
self.tomo.run_sequence(scan_seq)
......
......@@ -69,65 +69,89 @@ class TomoSinogram:
return scan_info
def attach_channel_to_sequence(self,sequence,channel_name,channel_source):
seq_channel= AcquisitionChannel(channel_name}, numpy.float, ())
sequence.add_custom_channel(seq_channel)
attach_channels(seq_channel,channel_source)
def configure_data_sequence(self, sequence, detector, nb_images):
sequence.add_custom_channel(AcquisitionChannel("dark_spectrum", numpy.float, detector.roi_profiles.counters[0].shape))
sequence.add_custom_channel(AcquisitionChannel("ref_spectrum", numpy.float, detector.roi_profiles.counters[0].shape))
sequence.add_custom_channel(AcquisitionChannel("proj_spectrum", numpy.float, detector.roi_profiles.counters[0].shape))
sequence.add_custom_channel(AcquisitionChannel("rotation", numpy.float, (), unit="degree"))
sequence.add_custom_channel(AcquisitionChannel("translation", numpy.float, (), unit="px"))
sinogram_channel= AcquisitionChannel("sinogram", numpy.float, ())
sequence.add_custom_channel(sinogram_channel)
scan=sequence.scan
sino_calc = SinoCalc(sequence.custom_channels["dark_spectrum"],
sequence.custom_channels["ref_spectrum"],
sequence.custom_channels["proj_spectrum"],
sequence.custom_channels["rotation"],
sequence.custom_channels["translation"],
nb_images,
sequence)
calc_sino_acq = CalcChannelAcquisitionSlave("calc_sino_acq",
[sequence.group_custom_slave],
sino_calc,
[sinogram_channel])
scan.acq_chain.add(sequence.group_acq_master,calc_sino_acq)
class SinoCalc(CalcHook):
def __init__(self, dark_channel, ref_channel, proj_channel, rotation_channel, proj_per_turn, sequence, image_to_keep = 0, image_operation = numpy.mean):
def __init__(self, dark_channel, ref_channel, proj_channel, rotation_channel, translation_channel, proj_per_turn, sequence, first_image_index = 0, last_image_index = 1, image_operation = numpy.mean):
self.dark_channel = dark_channel
self.ref_channel = ref_channel
self.proj_channel = proj_channel
self.rotation_channel = rotation_channel
self.translation_channel = translation_channel
self.dark_data = numpy.array([])
self.ref_data = numpy.array([])
self.rotation_data = numpy.array([])
self.image_to_keep = image_to_keep
self.translation_data = numpy.array([])
self.first_image_index = first_image_index
self.last_image_index = last_image_index
self.image_operation = image_operation
self.image_corr = numpy.array([])
self.proj_per_turn = proj_per_turn
self.sequence = sequence
self.saving_tasks = []
def compute(self, sender, data_dict):
dark_data = data_dict.get(self.dark_channel)
dark_data = data_dict.get(self.dark_channel.name)
if dark_data is not None:
numpy.append(self.dark_data,dark_data)
self.dark_data= numpy.append(self.dark_data,dark_data)
ref_data = data_dict.get(self.ref_channel)
ref_data = data_dict.get(self.ref_channel.name)
if ref_data is not None:
numpy.append(self.ref_data,ref_data)
self.ref_data =numpy.append(self.ref_data,ref_data)
rotation_data = data_dict.get(self.rotation_channel)
rotation_data = data_dict.get(self.rotation_channel.name)
if rotation_data is not None:
numpy.append(self.rotation_data,rotation_data)
proj_data = data_dict.get(self.proj_channel)
if proj_data is not None:
self.dark_data = self.image_operation(self.dark_data[self.image_to_keep],axis=0)
self.ref_data = self.image_operation(self.ref_data[self.image_to_keep],axis=0)
self.rotation_data = numpy.append(self.rotation_data,rotation_data)
proj_data = [numpy.arange(len(proj_data[0]))] * len(proj_data)
translation_data = data_dict.get(self.translation_channel.name)
if translation_data is not None:
self.translation_data = numpy.append(self.translation_data,translation_data)
image_corr = (proj_data - self.dark_data).astype(numpy.uint32) / (self.ref_data - self.dark_data).astype(numpy.uint32)
roi_width = int(self.dark_channel.shape[0])
proj_data = data_dict.get(self.proj_channel.name)
if proj_data is not None:
if len(self.dark_data) != roi_width and len(self.ref_data) != roi_width:
nb_dark = int(len(self.dark_data)/roi_width)
self.dark_data = numpy.array(self.image_operation(self.dark_data.reshape(nb_dark,roi_width)[self.first_image_index:self.last_image_index],axis=0))
nb_ref = int(len(self.ref_data)/roi_width)
self.ref_data = numpy.array(self.image_operation(self.ref_data.reshape(nb_ref,roi_width)[self.first_image_index:self.last_image_index],axis=0))
numpy.append(self.image_corr,image_corr)
image_corr = numpy.abs(proj_data-self.dark_data).astype(numpy.uint32)/numpy.abs(self.ref_data-self.dark_data).astype(numpy.uint32)
self.image_corr = numpy.append(self.image_corr,image_corr)
sinogram_data = image_corr.flatten()
if len(self.image_corr) % self.proj_per_turn:
gevent.spawn(self.saving, self.image_corr, self.rotation_data, len(proj_data[0]), numpy.arange(len(proj_data[0])), self.proj_per_turn)
return {"translation":image_corr.flatten()}
return {"sinogram":sinogram_data}
if len(self.image_corr) != 0 and not len(self.image_corr)/roi_width % self.proj_per_turn and len(self.image_corr) == len(self.rotation_data) and len(self.image_corr) == len(self.translation_data):
self.saving_tasks.append(gevent.spawn(self.saving, self.image_corr, self.rotation_data, self.proj_per_turn, self.translation_data, roi_width))
def saving(self, sino_data, y_data, len_y, x_data, len_x):
y_data = numpy.repeat(y_data,len_y)
x_data = numpy.tile(x_data,len_x)
save_NXdata(filename=f"{current_session.scan_saving.get_path()}/sinogram.h5",
signal=sino_data,
signal_name="values",
......@@ -136,3 +160,6 @@ class SinoCalc(CalcHook):
axes_names=["x", "y"],
nxentry_name=f"sinogram_{self.sequence.scan.scan_number}",
nxdata_name=f"data_{self.sequence.scan.scan_number}")
def stop(self):
gevent.joinall(self.saving_tasks)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment