towards jungfrau and shapepath...
This commit is contained in:
306
detector.py
Normal file
306
detector.py
Normal file
@@ -0,0 +1,306 @@
|
||||
import logging
|
||||
_log=logging.getLogger(__name__)
|
||||
|
||||
#from datetime import datetime
|
||||
#from glob import glob
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
|
||||
|
||||
#import eventer
|
||||
#import qsingleton
|
||||
#from detector_integration_api import DetectorIntegrationClient
|
||||
#from app_config import settings, appsconf, simulated
|
||||
#config = appsconf['jungfrau']
|
||||
#dia_client = DetectorIntegrationClient(config['uri'])
|
||||
|
||||
class JungfrauWaiter(QObject):
|
||||
finished = pyqtSignal()
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@pyqtSlot()
|
||||
def work(self):
|
||||
pass
|
||||
|
||||
class JungfrauMissingConfiguration(Exception):
|
||||
pass
|
||||
|
||||
class Jungfrau(QObject, metaclass=qsingleton.Singleton):
|
||||
pedestal_selected = pyqtSignal(str)
|
||||
configured = pyqtSignal()
|
||||
armed = pyqtSignal()
|
||||
started = pyqtSignal()
|
||||
triggered = pyqtSignal()
|
||||
aborted = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
super(Jungfrau, self).__init__(parent, **kwargs)
|
||||
self._simulated = kwargs.get("simulate", simulated)
|
||||
self._save_raw = True
|
||||
self._runJungfrau = False
|
||||
self._number_of_frames = 1
|
||||
self._gain_maps = config["gain_maps"]
|
||||
self._uid = None
|
||||
self._serial_number = config['serialnr']
|
||||
self.writer_config = {}
|
||||
self.backend_config = {}
|
||||
self.detector_config = {}
|
||||
self.bsread_config = {}
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def set_run_jungfrau(self, run):
|
||||
"""running or not jungfrau, global simulated flag overrides"""
|
||||
logger.warning(f"{'' if run else 'not '}running jungfrau detector")
|
||||
if not self._simulated:
|
||||
self._runJungfrau = run
|
||||
else:
|
||||
self._runJungfrau = False
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def set_save_raw(self, save_raw):
|
||||
"""enable or not writer_config"""
|
||||
logger.warning(f"{'' if save_raw else 'not '}saving data")
|
||||
self._save_raw = save_raw
|
||||
|
||||
@pyqtSlot(str)
|
||||
def set_detector_serial(self, serial_number):
|
||||
"""set serial number for main detector"""
|
||||
logger.info(f"jungfrau serial number: {serial_number}")
|
||||
self._serial_number = serial_number
|
||||
|
||||
def is_saving_data(self):
|
||||
"""if False writer_config is not issued"""
|
||||
return self._save_raw
|
||||
|
||||
def is_running_detector(self):
|
||||
"""if False nothing is actually called"""
|
||||
return self._runJungfrau
|
||||
|
||||
@pyqtSlot(int)
|
||||
def set_number_of_frames(self, frames):
|
||||
logger.info(f"jungfrau number of frames: {frames}")
|
||||
self._number_of_frames = frames
|
||||
|
||||
@pyqtSlot(int)
|
||||
def set_data_owner_uid(self, uid):
|
||||
logger.info(f"data owner set to UID = {uid}")
|
||||
self._uid = uid
|
||||
|
||||
@pyqtSlot(str)
|
||||
def set_gain_filename(self, gainfile:str):
|
||||
logger.info(f"gain file: {gainfile}")
|
||||
self._gain_maps = gainfile
|
||||
|
||||
def configure(self, outfile=None, outdir=None, **kwargs):
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: configure dismissed")
|
||||
return
|
||||
|
||||
if self._gain_maps is None:
|
||||
raise JungfrauMissingConfiguration("missing gain maps filename")
|
||||
gain_filename = self._gain_maps
|
||||
|
||||
if self._uid is None:
|
||||
raise JungfrauMissingConfiguration("missing data owner p-group UID")
|
||||
uid = self._uid
|
||||
|
||||
n_frames = self._number_of_frames
|
||||
|
||||
pede_pattern = "/sf/bernina/data/p{}/res/JF_pedestals/pedestal_*.JF07T32V01.res.h5".format(
|
||||
uid
|
||||
)
|
||||
try:
|
||||
pf = sorted(glob(pede_pattern))[-1]
|
||||
pf = pf[: pf.index(".JF07T32V01")]
|
||||
except IndexError:
|
||||
pf = None
|
||||
|
||||
pede_filename = pf
|
||||
logger.info(f"Pedestal file {pede_filename}")
|
||||
|
||||
exptime = 0.000005
|
||||
instrument = "Bernina"
|
||||
|
||||
self.writer_config = {
|
||||
"output_file": outdir + "/" + outfile,
|
||||
"user_id": uid,
|
||||
"n_frames": n_frames,
|
||||
"general/user": str(uid),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
"general/instrument": instrument,
|
||||
}
|
||||
|
||||
if not self._save_raw:
|
||||
self.writer_config["output_file"] = "/dev/null"
|
||||
|
||||
self.detector_config = {
|
||||
"exptime": exptime,
|
||||
"frames": 1,
|
||||
"cycles": n_frames,
|
||||
"timing": "trigger",
|
||||
"dr": 16,
|
||||
}
|
||||
|
||||
self.backend_config = {
|
||||
"n_frames": n_frames,
|
||||
"bit_depth": 16,
|
||||
"run_name": outfile,
|
||||
"beam_center_x": 2110.0,
|
||||
"beam_center_y": 2210.0,
|
||||
"beam_energy": 6000.0,
|
||||
"detector_distance": 0.06,
|
||||
"hitfinder_min_snr": 6.0,
|
||||
"hitfinder_min_pix_count": 5,
|
||||
"hitfinder_adc_thresh": 20.0,
|
||||
"swissmx_trajectory_method": "grid",
|
||||
"swissmx_trajectory_details_1": [100],
|
||||
"swissmx_trajectory_details_2": [n_frames // 100 + 1],
|
||||
}
|
||||
|
||||
backend_extras = kwargs.get("backend_extras", None)
|
||||
if backend_extras:
|
||||
self.backend_config.update(backend_extras)
|
||||
|
||||
# """
|
||||
# "swissmx_trajectory_method": "grid",
|
||||
# "swissmx_trajectory_details_1": [100],
|
||||
# "swissmx_trajectory_details_2": [n_frames//100+1],
|
||||
#
|
||||
# "swissmx_trajectory_method": "rotation",
|
||||
# "swissmx_trajectory_details_1": [360],
|
||||
# "swissmx_trajectory_details_2": [0.1],
|
||||
#
|
||||
# "swissmx_trajectory_method": "trajectory",
|
||||
# "swissmx_trajectory_details_1": [random()*100 for i in range(int(n_frames*0.9))],
|
||||
# "swissmx_trajectory_details_2": [random()*100 for i in range(int(n_frames*0.9))],
|
||||
#
|
||||
# """
|
||||
self.bsread_config = {
|
||||
"output_file": outdir + "/" + outfile,
|
||||
"user_id": uid,
|
||||
"general/user": str(uid),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
"general/instrument": instrument,
|
||||
}
|
||||
|
||||
if gain_filename != "" or pede_filename != "":
|
||||
self.backend_config["gain_corrections_filename"] = gain_filename
|
||||
self.backend_config["gain_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_corrections_filename"] = pede_filename
|
||||
self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["activate_corrections_preview"] = True
|
||||
logger.info("Corrections in online viewer activated")
|
||||
|
||||
configuration = {
|
||||
"writer": self.writer_config,
|
||||
"backend": self.backend_config,
|
||||
"detector": self.detector_config,
|
||||
"bsread": self.bsread_config,
|
||||
}
|
||||
|
||||
logger.info("resetting & configuring detector: approx. 6 seconds")
|
||||
dia_client.reset()
|
||||
dia_client.set_config(configuration)
|
||||
logger.info(dia_client.get_config())
|
||||
|
||||
def arm(self) -> int:
|
||||
"""arm detector and return an ID for this series"""
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: arm dismissed")
|
||||
return
|
||||
|
||||
logger.info("arming detector: approx. 2 seconds")
|
||||
dia_client.start(trigger_start=False)
|
||||
|
||||
def wait_finished(self):
|
||||
"""close shutter after this wait is finished regardless of exceptions"""
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: wait_finished dismissed")
|
||||
return
|
||||
|
||||
try:
|
||||
dia_client.wait_for_status(["IntegrationStatus.FINISHED"], polling_interval=0.1)
|
||||
except:
|
||||
logger.info("Got IntegrationStatus ERROR")
|
||||
logger.info(dia_client.get_status())
|
||||
logger.info(dia_client.get_status_details())
|
||||
|
||||
logger.info("Stopping acquisition")
|
||||
dia_client.reset()
|
||||
|
||||
logger.info("Done")
|
||||
|
||||
def disarm(self) -> int:
|
||||
"""arm detector and return an ID for this series"""
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: disarm dismissed")
|
||||
return
|
||||
|
||||
dia_client.reset()
|
||||
|
||||
def trigger(self):
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: trigger dismissed")
|
||||
return
|
||||
logger.info("Trigger in detector is called")
|
||||
eventer.start()
|
||||
|
||||
def abort(self):
|
||||
if not self._runJungfrau:
|
||||
logger.warning("jungfrau not required: abort dismissed")
|
||||
return
|
||||
|
||||
self.disarm()
|
||||
eventer.stop()
|
||||
|
||||
|
||||
jungfrau_detector = Jungfrau()
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
date_string = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
|
||||
parser = argparse.ArgumentParser(description="Create a pedestal file for Jungrau")
|
||||
parser.add_argument("--api", default="http://sf-daq-1:10000", required=True)
|
||||
parser.add_argument(
|
||||
"--filename", default="run_%s.h5" % date_string, help="Output file name"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pede", default="", help="File containing pedestal corrections"
|
||||
)
|
||||
parser.add_argument("--gain", default="", help="File containing gain corrections")
|
||||
parser.add_argument(
|
||||
"--directory", default="/sf/bernina/data/raw/p16582", help="Output directory"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--uid", default=16582, help="User ID which needs to own the file", type=int
|
||||
)
|
||||
parser.add_argument(
|
||||
"--period", default=0.01, help="Period (default is 10Hz - 0.01)", type=float
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exptime",
|
||||
default=0.000010,
|
||||
help="Integration time (default 0.000010 - 10us)",
|
||||
type=float,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--frames", default=10, help="Number of frames to take", type=int
|
||||
)
|
||||
parser.add_argument(
|
||||
"--save", default=False, help="Save data file", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--highgain", default=False, help="Enable High Gain (HG0)", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--instrument", default="", help="Name of the instrument, e.g. Alvra"
|
||||
)
|
||||
# parser.add_argument("--caput", default=False, help="Use the CAPUT trick (experts only!!!)", action="store_true")
|
||||
|
||||
args = parser.parse_args()
|
||||
Reference in New Issue
Block a user