def load_calib_file(self, file): if not self.empty(): logger.printwarn( ('The current session is not empty. Loading a new ' 'boardtype will erase any existing configuration ' 'for the current session')) jsonmap = json.loads(open(file, 'r').read()) for det in jsonmap: if det not in self.det_map: if int(det) >= 0: logger.printwarn( ('Detector recorded in the calibration file but not ' 'defined in the calibration, ignoring')) continue else: self.add_calib_det(det) def format_dict(original_dict): return {float(z): original_dict[z] for z in original_dict} self.det_map[det].lumi_coord = format_dict( jsonmap[det]['Luminosity coordinates']) self.det_map[det].vis_coord = format_dict( jsonmap[det]['Visual coordinates']) self.det_map[det].vis_M = format_dict( jsonmap[det]['FOV transformation'])
def set_camera(self, args): """Setting up the camera system, given /dev/video path""" if (not self.is_dummy_dev(args.camdev, 'Visual System') and args.camdev != self.visual.dev_path): try: self.visual.init_dev(args.camdev) except Exception as err: log.printerr(str(err)) log.printwarn('Initializing webcam has failed, skipping over setting')
def set_boardtype(self, file): if any(self.dets()) or not self.empty(): logger.printwarn( ('The current session is not empty. Loading a new ' 'boardtype will erase any existing configuration ' 'for the current session')) jsonmap = json.loads(open(file, 'r').read()) self.boardtype = jsonmap['board type'] self.boarddescription = jsonmap['board description'] self.boardid = jsonmap['board id'] for detid in jsonmap['detectors']: self.det_map[detid] = Detector(jsonmap['detectors'][detid])
def load_calib_file(self, file): if not self.empty(): logger.printwarn( ('The current session is not empty. Loading a new ' 'boardtype will erase any existing configuration ' 'for the current session')) jsontemp = json.loads(open(file, 'r').read()) def make_fz_dict(ext_dict): return { chipid: {float(z): obj for z, obj in ext_dict[chipid].items()} for chipid in self.chips() } self.lumi_coord = make_fz_dict(jsontemp['Lumi scan calibration']) self.vis_coord = make_fz_dict(jsontemp['FOV scan calibration']) self.visM = make_fz_dict(jsontemp['FOV transformation matrix'])
def set_mode(self, mode): if mode == readout.MODE_PICO and self.pico.device: self.mode = mode elif mode == readout.MODE_ADC: try: self.setup_i2c() print('Setting readout mode to ADC chip') self.mode = mode except Exception as err: log.printerr(str(err)) log.printwarn( ('You are not working in a I2C compatible environment, ' 'Readout values for ADC will use a predefined model ' 'instead')) self.mode = readout.MODE_NONE raise err else: self.mode = readout.MODE_NONE
def __init__(self, jsonmap): self.mode = int(jsonmap['mode']) self.channel = int(jsonmap['channel']) self.orig_coord = jsonmap['default coordinates'] self.vis_coord = {} self.vis_M = {} self.lumi_coord = {} # Additional parsing. if (self.orig_coord[0] > gcoder.GCoder.max_x() or # self.orig_coord[1] > gcoder.GCoder.max_y() or # self.orig_coord[0] < 0 or self.orig_coord[1] < 0): logger.printwarn(f""" The specified detector position (x:{self.orig_coord[0]}, y:{self.orig_coord[1]}) is outside of the gantry boundaries (0-{gcoder.GCoder.max_x()},0-{gcoder.GCoder.max_y()}). The expected detector position will be not adjusted, but gantry motion might not reach it. Which mean any results may be wrong. """)
def set_boardtype(self, file): if any(self.chips()) or not self.empty(): logger.printwarn( ('The current session is not empty. Loading a new ' 'boardtype will erase any existing configuration ' 'for the current session')) jsontemp = json.loads(open(file, 'r').read()) self.boardtype = jsontemp['board type'] self.boardid = jsontemp['board id'] ## Getting the original coordinate list for key in jsontemp['default coordinate']: self.orig_coord[str(key)] = jsontemp['default coordinate'][key] if (self.orig_coord[str(key)][0] > gcoder.GCoder.max_x() or self.orig_coord[str(key)][1] > gcoder.GCoder.max_y() or self.orig_coord[str(key)][0] < 0 or self.orig_coord[str(key)][1] < 0): logger.printwarn( ('The chip position for chip {0} (x:{1},y:{2}) ' 'is outside of the gantry boundaries (0-{3},0-{4}). ' 'For safety of operation, the chip position will be ' 'adjusted. This might lead to unexpected ' 'behavior').format(key, self.orig_coord[str(key)][0], self.orig_coord[str(key)][1], gcoder.GCoder.max_x(), gcoder.GCoder.max_y())) self.orig_coord[str(key)][0] = max([ min([self.orig_coord[str(key)][0], gcoder.GCoder.max_x()]), 0 ]) self.orig_coord[str(key)][1] = max([ min([self.orig_coord[str(key)][1], gcoder.GCoder.max_y()]), 0 ]) self.vis_coord[str(key)] = {} self.visM[str(key)] = {} self.lumi_coord[str(key)] = {}
# requires a fake /dev/ path to be able to trigger the initialization # routine '--drsdevice': "/dev/MYDRS4", '--picodevice': '/dev/MYPICOSCOPE', } for action in prog_parser._actions: for option, default in default_overide.items(): if option in action.option_strings: action.default = default args = prog_parser.parse_args() if args.help: prog_parser.print_help() sys.exit(0) try: print("Running set command") cmd.set.run(args) print("Starting GPIO") cmd.gpio.init() except Exception as err: logger.printerr(str(err)) logger.printwarn( 'There was error in the setup process, program will ' 'continue but will most likely misbehave! Use at your own risk!') cmd.cmdloop() print('Exiting out of loop')
def set_board(self, args): try: self.board.set_boardtype(args.boardtype.name) except Exception as err: log.printerr(str(err)) log.printwarn('Board type setting has failed, skipping over setting')
def create_server_flask(debug=False): """ Generating the server instance, keeping the app instance as a member of the global socketio object so other members can use this. """ socketio.app = Flask(__name__) socketio.app.debug = debug ############################################################################### """ Defining the URLs used for page display. """ ############################################################################### @socketio.app.route('/') def index(): """ This is the main page the is to be rendered to the front user. The corresponding file can be found in the server/static/template/index.html path. """ return render_template('index.html') @socketio.app.route('/debug') def expert(): """ This is the page containing the debugging GUI, mainly used for the fast data turn around and a simple interface for saving single commands and display the output in a simplified data format. This corresponding file is found in the server/static/template/debug.html path. """ return render_template('debug.html') @socketio.app.route('/playground') def playground(): """ This URL is for testing display functions only. """ return render_template('playground.html') ############################################################################### """ URLs used for local file and session data exposure via client side AJAX requests. """ ############################################################################### @socketio.app.route('/geometry/<boardtype>') def geometry(boardtype): """ The geometry json files. These files correspond directly to the json files in the cfg/geometry/ directory if they exists. """ if os.path.exists('cfg/geometry/' + boardtype + '.json'): with open('cfg/geometry/' + boardtype + '.json', 'r') as f: x = json.load(f) return jsonify(x) else: return {}, 404 # Return an empty json file with a error 404 @socketio.app.route('/report/<reporttype>') def status(reporttype): """ Instead of report via a socket command, display updates are performed using the call to a pseudo JSON file that contains the current status of the calibration session. This "file" is generated using a python dictionary. To reduced the required libraries in the various files. The jsonify routine is called here. The various report function should ensure that the return is json compliant. """ return jsonify(session_report(reporttype)) #define in parsing.py @socketio.app.route('/databyfile/<process>/<filename>') def datafile(process, filename): """ Returning the data stored at the requested path, and reduced the data accorrding to the requested process format. """ return jsonify(get_file_data(process, filename)) # Defined in parsing.py @socketio.app.route('/data/<process>/<detid>') def data(process, detid): """ Returning the data of a certain calibration process on a detector elements in json format. This aims to minimized the amount of time the same piece of data needs to be transported over the network. """ return jsonify(get_detid_data(process, detid)) # Defined in parsing.py @socketio.app.route('/visual') def visual(): """ This is a pseudo URL, which responds with the current camera image stored in the session memory, as a byte stream of a JPEG image file. The format of the Response object is found from reference: https://medium.com/datadriveninvestor/ video-streaming-using-flask-and-opencv-c464bf8473d6 """ return Response(current_image_bytes(), mimetype='multipart/x-mixed-replace; boundary=frame') ############################################################################### """ Socket session processing. All processing functions are defined in parsing.py """ ############################################################################### @socketio.on('connect', namespace='/sessionsocket') def establish_connection(): print('Connection established') socket_connect(socketio) @socketio.on('xterminput', namespace='/sessionsocket') def xterm_input(msg): terminal_input(socketio, msg) @socketio.on('resend', namespace='/sessionsocket') def resend(msg): resend_sync(socketio, msg) @socketio.on('run-action-cmd', namespace='/sessionsocket') def run_action_cmd_socket(msg): run_action(socketio, msg) @socketio.on('complete-user-action', namespace='/sessionsocket') def complete_user_action_socket(msg): complete_user_action(socketio) @socketio.on('interrupt', namespace='/sessionsocket') def interrupt(): send_interrupt(socketio) ############################################################################### """ Initialization of the underlying command line instance. """ ############################################################################### ## Resetting the socket application stuff socketio.init_app(socketio.app) # Duplicating the session to allow for default override. prog_parser = copy.deepcopy(session.cmd.set.parser) # Augmenting help messages prog_parser.prog = "gui_control.py" prog_parser.add_argument('-h', '--help', action='store_true', help='print help message and exit') ## Using map to store Default values: default_overide = { '--printerdev': '/dev/ttyUSB0', #'--camdev': '/dev/video0', #'-boardtype': 'cfg/static_calib.json', '--action': 'cfg/useractions.json', '--drsdevice': "MYDRS", # CANNOT actually set '--picodevice': 'MYSERIAL', #Cannot actually set. Just dummy for now #'-remotehost' : ['hepcms.umd.edu', ''] } for action in prog_parser._actions: for option, default in default_overide.items(): if option in action.option_strings: action.default = default args = prog_parser.parse_args() if args.help: prog_parser.print_help() sys.exit(0) try: session.cmd.set.run(args) session.cmd.gpio.init() except Exception as err: logger.printerr(str(err)) logger.printwarn(""" There was error in the setup process, program will continue but will most likely misbehave! Use at your own risk! """) return socketio.app