#!/bin/env python # # start_daq.py - starts DAQ with software ROCs # # DL, 07-Mar-2014 # # # # This uses gnome-terminal to open windows and # run the command line parameters. It is used # instead of xterm because there were some issues # with interacting with the xterms via VNC that # made them problematic. # # For this to work right, gnome-terminal should # have profiles defined named the following: # # platform # EB # rcgui # ROC # # Each of these should have the "When command exits:" # menu set to "Hold the terminal open". This is done # via the "Title and Command" tab in the dialog window # used for editing profile preferences. # # The font size (also specified via dialog window) # should be set to: # "Monospace 9" for the platform profile # "Courier 6" for the ROC profile # "Monospace 8" for the EB and rcgui profiles # import sys,os import subprocess import string import time import math import re COOL_HOME = os.getenv("COOL_HOME") EXPID = os.getenv("EXPID") CONFIG = "" if len(sys.argv) > 1 : CONFIG = sys.argv[1] screenwidth = 0 screenheight = 0 rocs = [] # will be filled by GetComponents pebs = [] # will be filled by GetComponents ers = [] # will be filled by GetComponents fcss = [] # will be filled by GetComponents testmode = False # if set to True, then no windows will be opened. Just commands printed. #------------------ # GetScreenSize #------------------ def GetScreenSize(): global screenwidth, screenheight result = subprocess.Popen(["xwininfo", "-root", "-shape"], stdout=subprocess.PIPE).communicate()[0] lines = result.rstrip().split('\n') for s in lines: if type(s) is not str: continue if "Width:" in s: screenwidth = int(string.split(s)[1]) if "Height:" in s: screenheight = int(string.split(s)[1]) #------------------ # GetWindowDimensions #------------------ def GetWindowDimensions(name, wait=False): width = 0 height = 0 if wait : print "Waiting for window %s to open" % name while True: proc = subprocess.Popen(["xwininfo", "-name", name, "-shape"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = proc.communicate()[0] if proc.returncode == 0: lines = result.rstrip().split('\n') for s in lines: if type(s) is not str: continue if "Width:" in s: width = int(string.split(s)[1]) if "Height:" in s: height = int(string.split(s)[1]) return [width, height] if wait==False: return [] time.sleep(1) #------------------ # FindExecutable #------------------ def FindExecutable(exename, args=[]): try: proc = subprocess.Popen(["which", exename], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = proc.communicate()[0].strip() if proc.returncode == 0: for arg in args: result += " " + arg return result except: print sys.exc_info()[0] return "" #------------------ # LaunchROC #------------------ def LaunchROC(roc, xpos, ypos): global coda_roc # By convention, we use the dns name as the roc name in jcedit host = roc roccmd = '%s -i -n %s -t ROC' % (coda_roc, roc) if host!="" : roccmd = 'ssh %s %s' % (host, roccmd) cmd = 'gnome-terminal --geometry 80x10+%d+%d --profile=ROC -t %s -x %s' % (xpos, ypos, roc, roccmd) print cmd if not testmode : subprocess.Popen(string.split(cmd)) return roc #------------------ # LaunchPEB #------------------ def LaunchPEB(peb, xpos, ypos): global coda_eb # By convention, name of the peb in jcedit is just # "peb" with the dns name appended host = peb[3:] pebcmd = '%s %s' % (coda_eb, peb) if host!="" : pebcmd = 'ssh %s %s' % (host, pebcmd) cmd = 'gnome-terminal --geometry 100x10+%d+%d --profile=EB -t %s -x %s' % (xpos, ypos, peb, pebcmd) print cmd if not testmode : subprocess.Popen(string.split(cmd)) return peb #------------------ # LaunchER #------------------ def LaunchER(er, xpos, ypos): global coda_er # By convention, name of the ER in jcedit is just # "ER" with the dns name appended host = er[2:] ercmd = '%s %s' % (coda_er, er) if host!="" : ercmd = 'ssh %s %s' % (host, ercmd) cmd = 'gnome-terminal --geometry 100x10+%d+%d --profile=ER -t %s -x %s' % (xpos, ypos, er, ercmd) print cmd if not testmode : subprocess.Popen(string.split(cmd)) return er #------------------ # LaunchFCS #------------------ def LaunchFCS(fcs, xpos, ypos): global coda_er # By convention, name of the FCS in jcedit is just # "fcs" with the dns name appended host = fcs[3:] fcscmd = '%s %s' % (coda_fcs, fcs) if host!="" : ercmd = 'ssh %s %s' % (host, fcscmd) cmd = 'gnome-terminal --geometry 100x10+%d+%d --profile=FCS -t %s -x %s' % (xpos, ypos, fcs, fcscmd) print cmd if not testmode : subprocess.Popen(string.split(cmd)) return fcs #------------------ # GetConfigurations #------------------ def GetConfigurations(): confdir = "%s/%s/config/Control" % (COOL_HOME, EXPID) if os.path.exists(confdir): return os.listdir(confdir) else: print "Directory doesn't exist: %s" % confdir print "Check your COOL_HOME and EXPID environment variables!" sys.exit(-1) #------------------ # GetComponents #------------------ def GetComponents(): global rocs, pebs, ers fname = "%s/%s/config/Control/%s/%s.rdf" % (COOL_HOME, EXPID, CONFIG, CONFIG) with open(fname) as f: lines = f.readlines() for line in lines: idx_end = string.rfind(line, '.rdf"/>') if idx_end < 2: continue idx_start = string.rfind(line[0:idx_end], '/') if idx_start < 2: continue cname = line[idx_start+1:idx_end] if string.find(cname, "roc") == 0: rocs.append(cname) if string.find(cname, "ts" ) == 0: rocs.append(cname) if string.find(cname, "localhost" ) == 0: rocs.append(cname) # for running sandbox test if string.find(cname, "peb") == 0: pebs.append(cname) if string.find(cname, "fcs") == 0: fcss.append(cname) if string.find(cname, "ER" ) == 0: ers.append(cname) #----------------------------------------- # Check that COOL_HOME and EXPID are set if COOL_HOME == None: print "COOL_HOME environment variable not set!" sys.exit(-1) if EXPID == None: print "EXPID environment variable not set!" sys.exit(-1) # Get configuration list configs = GetConfigurations() if not CONFIG in configs: print "\nYou must specify one of the following configurations:\n" for config in configs: sys.stdout.write("%s " % config) print "\n" sys.exit(0) # Get the list of ROCs, PEBs, and ERs GetComponents() sys.stdout.write("ROCs: ") print rocs sys.stdout.write("PEBs: ") print pebs sys.stdout.write(" ERs: ") print ers print "\n--- Starting all DAQ components ---\n" # Get X-11 screen size GetScreenSize() print "X-windows screen size: %d x %d\n" % (screenwidth,screenheight) # Find executables in current PATH platform = FindExecutable('platform') rcgui = FindExecutable('rcgui') coda_eb = FindExecutable('coda_emu_peb64') coda_er = FindExecutable('coda_emu_er64') coda_fcs = FindExecutable('coda_emu_fcs64') coda_roc = FindExecutable('coda_roc_test') print "CODA executable locations:" print " platform: %s" % platform print " rcgui: %s" % rcgui print " coda_eb: %s" % coda_eb print " coda_er: %s" % coda_er print " coda_fcs: %s" % coda_fcs print " coda_roc: %s" % coda_roc print "" # Print info on ROCs to start print "Number of ROCs: %d" % len(rocs) sys.stdout.write(" ids: ") print rocs #-------------------------------------------------------- # ----- Launch windows ---- ypos = 25 cmd = 'gnome-terminal -t platform --geometry 85x15+1+%d --profile=platform -x %s' % (ypos, platform) print cmd subprocess.Popen(string.split(cmd)) # wait for the platform window to open so we can # find out how wide it is in pixels dim_platform = GetWindowDimensions('platform', True) print "platform: width=%d height=%d" % (dim_platform[0], dim_platform[1]) ypos += dim_platform[1] + 30 # +30 is for frame # Calculate area to use for ROC windows dimROCX = screenwidth - dim_platform[0] dimROCY = screenheight - dim_platform[1] # Launch all PEB windows xpos = +1 for peb in pebs: LaunchPEB(peb, xpos, ypos) dim_peb = GetWindowDimensions(peb, True) ypos += dim_peb[1] + 30 # +30 is for frame # Launch all ER windows for er in ers: LaunchER(er, xpos, ypos) dim_er = GetWindowDimensions(er, True) ypos += dim_er[1] + 30 # +30 is for frame # Launch all FCS windows for fcs in fcss: LaunchFCS(fcs, xpos, ypos) dim_fcs = GetWindowDimensions(fcs, True) ypos += dim_fcs[1] + 30 # +30 is for frame # Launch rcgui window (Run Control) cmd = 'gnome-terminal --geometry 100x8+%d+%d --profile=rcgui -t rcgui -x %s' % (xpos, ypos, rcgui) print cmd subprocess.Popen(string.split(cmd)) dim_rcgui = GetWindowDimensions("rcgui", True) ypos += dim_rcgui[1] + 30 # +30 is for frame # Launch first ROC window so we can get dimensions xpos = dim_platform[0] + 1 ypos = 25 roc = LaunchROC(rocs[0], xpos, ypos) dim_roc = GetWindowDimensions(roc, True) dim_roc[0] += 4 # for frame dim_roc[1] += 30 # for frame print "ROC: width=%d height=%d" % (dim_roc[0], dim_roc[1]) # Calculate x and y offsets to lay roc windows # as neatly as possible. # How many rows and columns can we hold without any overlaps maxRows = int(math.floor(dimROCY/dim_roc[1] + 1.0)) maxCols = int(math.floor(dimROCX/dim_roc[0])) xincr = dim_roc[0] yincr = dim_roc[1] yshift = 0 # check if we need to adjust offsets in order to # fit in the screen area reserved for ROCs if maxRows*maxCols < len(rocs): maxCols = int(math.floor(len(rocs)/maxRows+1)) yshift = 25 xincr = int(math.floor((dimROCX-dim_roc[0])/(maxCols-1) + 1.0)) # Report parameters print "dimROCX = %d" % dimROCX print "dimROCY = %d" % dimROCY print "maxRows = %d" % maxRows print "maxCols = %d" % maxCols print " xincr = %d" % xincr print " yincr = %d" % yincr print " yshift = %d" % yshift # Launch remaining ROC windows icol = 0 irow = 1 for roc in rocs[1:]: if irow >= maxRows: irow = 0 icol += 1 xpos = dim_platform[0] + 1 + xincr*icol ypos = 25 + yincr*irow + yshift*icol roc = LaunchROC(roc, xpos, ypos) print " started %s" % roc irow += 1