def doRead(self, maxage=0): img = self._op.open('http://miracam.mira.frm2/IMAGE.JPG').read() open('/tmp/radmon.jpg', 'wb').write(img) p1 = createSubprocess( '/usr/local/bin/ssocr -d 3 -i 1 -t 50 -l maximum ' 'rotate 1 crop 300 157 57 30 ' 'make_mono invert keep_pixels_filter 5 ' '/tmp/radmon.jpg'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) p2 = createSubprocess( '/usr/local/bin/ssocr -d 1 -i 1 -t 50 -l maximum ' 'rotate 1 crop 391 125 20 30 ' 'make_mono invert keep_pixels_filter 5 ' '/tmp/radmon.jpg'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) out1, err1 = p1.communicate() out2, err2 = p2.communicate() out1 = out1.strip() out2 = out2.strip() self.log.warning('out1=%r, out2=%r', out1, out2) if err1: raise NicosError(self, 'ERROR in mantissa') if err2: raise NicosError(self, 'ERROR in exponent') return 0.01 * float(out1 + b'e-' + out2) * 1e6 # convert to uSv/h
def _spawn_action(self, action): self.log.warning('will execute action %r', action) script = path.join(config.nicos_root, 'bin', 'nicos-script') createSubprocess([ sys.executable, script, '-M', # start in maintenance mode '-S', '60', # abort after 60 seconds '-A', 'watchdog-action', # appname for the logfiles ','.join(self._setups), # setups to load action ]) # code to execute
def startSubprocess(filename, *args, **kwds): adjustPYTHONPATH() name = path.splitext(filename)[0] sys.stderr.write(' [%s start... ' % name) if kwds.get('piped'): popen_kwds = dict(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) else: popen_kwds = dict() proc = createSubprocess( [sys.executable, path.join(module_root, 'test', 'bin', filename)] + list(args), **popen_kwds) proc.nicos_name = name if 'wait_cb' in kwds: try: kwds['wait_cb']() except Exception: caught = sys.exc_info() sys.stderr.write('%s failed]' % proc.pid) try: proc.kill() except Exception: pass proc.wait() reraise(*caught) sys.stderr.write('%s ok]\n' % proc.pid) return proc
def doStart(self, target): if self._subprocess is not None: raise InvalidValueError('Process is still running') fullargs = list(self.args) fullargs.insert(0, self.subprocess) self._subprocess = createSubprocess(fullargs)
def send(self, subject, body, what=None, short=None, important=True): if not important: return receivers = self._getAllRecipients(important) if not receivers: return if not self._checkRateLimit(): return body = self.subject + ': ' + (short or body) body = self._transcode(body)[:160] self.log.debug('sending SMS to %s', ', '.join(receivers)) try: for receiver in receivers: proc = createSubprocess( ['sendsms', '-Q', '-d', receiver, '-m', body, self.server], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out = proc.communicate()[0] if 'message queued' not in out and \ 'message successfully sent' not in out: raise RuntimeError('unexpected output %r' % out.strip()) except Exception: self.log.exception('sendsms failed') return False self.log.info('%sSMS message sent to %s', what and what + ' ' or '', ', '.join(receivers)) return True
def _getCID(self, device): if session.sessiontype == POLLER: while not self.cid: session.delay(0.5) return self.cid self.log.debug('get CARESS device ID: %r', device) answer = createSubprocess( 'cd %s && %s/dump_u1 -n %s' % (self.caresspath, self.toolpath, device), shell=True, stdout=subprocess.PIPE, universal_newlines=True, ).communicate()[0] self._caress_name = device if answer in ('', None): if not CARESSDevice._caress_maps: CARESSDevice._caress_maps[device] = 4096 elif device not in CARESSDevice._caress_maps: CARESSDevice._caress_maps[device] = 1 + \ max(CARESSDevice._caress_maps.values()) res = CARESSDevice._caress_maps[device] else: res = int(answer.split('=')[1]) self.log.debug('get CARESS device ID: %r', res) return res
def _list_devices(server): subp = createSubprocess('/opt/taco/bin/db_devicelist -n %s' % server, shell=True, stdout=subprocess.PIPE) out = subp.communicate()[0] for line in out.splitlines(): if line.startswith('\t'): yield line.strip()
def execute(self, cmd): self.outputBox.setPlainText('[%s] Executing %s...\n' % (time.strftime('%H:%M:%S'), cmd)) proc = createSubprocess(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out = proc.communicate()[0].decode() self.outputBox.appendPlainText(out)
def runTool(window, tconfig): """Run a tool from *tconfig* If it is a tool dialog, use *window* as the parent. """ if isinstance(tconfig, tool): try: toolclass = importString(tconfig.clsname) except ImportError: window.showError('Could not import class %r.' % tconfig.clsname) else: dialog = toolclass(window, window.client, **tconfig.options) dialog.setWindowModality(Qt.NonModal) dialog.setAttribute(Qt.WA_DeleteOnClose, True) dialog.show() elif isinstance(tconfig, cmdtool): try: createSubprocess(tconfig.cmdline) except Exception as err: window.showError('Could not execute command: %s' % err)
def _start_child(self, setup): poller_script = path.join(config.nicos_root, 'bin', 'nicos-poller') additional_args = [] if session._daemon_mode == 'systemd': additional_args.append('-D') process = createSubprocess([sys.executable, poller_script, setup] + additional_args) # we need to keep a reference to the Popen object, since it calls # os.wait() itself in __del__ self._children[setup] = process self._childpids[process.pid] = setup session.log.info('started %s poller, PID %s', setup, process.pid)
def hasGnuplot(): """Check for the presence of gnuplot in the environment. To be used with the `requires` decorator. """ try: gpProcess = createSubprocess(b'gnuplot', shell=True, stdin=subprocess.PIPE, stdout=None) gpProcess.communicate(b'exit') if gpProcess.returncode: return False except (IOError, ValueError): return False return True
def execute(self, cmd): if self.proc and self.proc.poll() is None: self.outputBox.appendPlainText('Tool is already running,' ' not starting a new one.') self.outputBox.setPlainText('[%s] Executing %s...\n' % (time.strftime('%H:%M:%S'), cmd)) datapath = self.client.eval('session.experiment.datapath', '') if not datapath or not path.isdir(datapath): datapath = None self.proc = createSubprocess(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=0, cwd=datapath) self.thread = Thread(target=self._pollOutput) self.thread.start()
def txtplot(x, y, xlab, ylab, xterm_mode=False): """Plot data with gnuplot's dumb ASCII terminal.""" if not x.size: raise ValueError('Empty plot') if len(x) != len(y): raise ValueError('Unequal lengths of X and Y values') try: gnuplot = createSubprocess(['gnuplot', '--persist'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if xterm_mode: cmd = ['set term xterm'] else: cmd = ['set term dumb'] cmd.append('set xlabel "' + xlab + '"') cmd.append('set ylabel "' + ylab + '"') cmd.append('plot "-" with points notitle') for xy in zip(x, y): cmd.append('%s %s' % xy) cmd.append('e\n') cmd = '\n'.join(cmd).encode() out = gnuplot.communicate(cmd)[0] lines = [line for line in out.decode().splitlines() if line] if xterm_mode: lines += [ 'Plotting in xterm Tektronix window.', '\x1b_If you can only see a lot of incomprehensible ' 'text, use xterm instead of your current terminal ' 'emulator.\x1b\\' ] return lines except OSError: raise RuntimeError('Could execute gnuplot for text plot') from None
def _target(self, sandbox, uuid, code, setups, user, emitter, args, quiet): socket = nicos_zmq_ctx.socket(zmq.DEALER) poller = zmq.Poller() poller.register(socket, zmq.POLLIN) if sandbox: # create a new temporary directory for the sandbox helper to # mount the filesystem tempdir = tempfile.mkdtemp() rootdir = path.join(tempdir, 'root') os.mkdir(rootdir) # since the sandbox does not have TCP connection, use a Unix socket sockname = 'ipc://' + path.join(tempdir, 'sock') socket.bind(sockname) prefixargs = [sandbox, rootdir, str(os.getuid()), str(os.getgid())] else: port = socket.bind_to_random_port('tcp://127.0.0.1') sockname = 'tcp://127.0.0.1:%s' % port prefixargs = [] scriptname = path.join(config.nicos_root, 'bin', 'nicos-simulate') userstr = '%s,%d' % (user.name, user.level) if quiet: args.append('--quiet') if config.sandbox_simulation_debug: args.append('--debug') proc = createSubprocess(prefixargs + [ sys.executable, scriptname, sockname, uuid, ','.join(setups), userstr, code ] + args) if sandbox: if not session.current_sysconfig.get('cache'): raise NicosError('no cache is configured') socket.send(pickle.dumps(session.cache.get_values())) else: # let the subprocess connect to the cache socket.send(b'') while True: res = poller.poll(500) if not res: if proc.poll() is not None: if emitter: request = emitter.current_script() if request.reqid == uuid: request.setSimstate('failed') request.emitETA(emitter._controller) if not quiet: session.log.warning('Dry run has terminated ' 'prematurely') return continue msgtype, msg = unserialize(socket.recv()) if msgtype == SIM_MESSAGE: if emitter: emitter.emit_event('simmessage', msg) else: record = logging.LogRecord(msg[0], msg[2], '', 0, msg[3], (), None) record.message = msg[3].rstrip() session.log.handle(record) elif msgtype == SIM_BLOCK_RES: if emitter: block, duration, uuid = msg request = emitter.current_script() if request.reqid == uuid: request.updateRuntime(block, duration) elif msgtype == SIM_END_RES: if emitter: if not quiet: emitter.emit_event('simresult', msg) request = emitter.current_script() if request.reqid == uuid: request.setSimstate('success') request.emitETA(emitter._controller) # In the console session, the summary is printed by the # sim() command. socket.close() break # wait for the process, but only for 5 seconds after the result # has arrived wait_start = time.time() try: # Python 3.x has a timeout argument for poll()... while time.time() < wait_start + 5: if proc.poll() is not None: break else: raise Exception('did not terminate within 5 seconds') except Exception: session.log.exception('Error waiting for dry run process') if sandbox: try: os.rmdir(rootdir) os.rmdir(tempdir) except Exception: pass
def IndexPeaks(max_deviation=0.2, listname='default'): """Index crystal reflections using Indexus. Uses the positions and intensities either the default position list, or the given name. You can also select the maximum deviation of HKL indices from integers using the *max_deviation* parameter (default is 0.2). After indexing is complete, the calculated HKLs and matrix are shown. You can accept the indexing with the `AcceptIndexing()` command. Examples: >>> IndexPeaks() # use default position list >>> IndexPeaks(0.1) # use different maximum deviation >>> IndexPeaks('other') # use other position list This command will generate input files for Indexus (indexus.txt and angles.txt) in the experiment data directory and run Indexus. Then it will read the output files and show the calculated matrix and positions, as well as the gamma/nu offsets. If you want to manually run Indexus, you can use the generated input files as a template. """ if isinstance(max_deviation, str): listname = max_deviation max_deviation = 0.2 sample = session.experiment.sample wavelength = session.getDevice('wavelength').read() lists = dict(sample.poslists) if listname not in lists: session.log.warning('Position list %r does not exist', listname) return posl = lists[listname] if len(posl) < 2: session.log.warning( 'Cannot calculate: need at least two positions in list') return params = ( len(posl), 1.0, 1.0, max_deviation, wavelength, sample.bravais, sample.a, sample.b, sample.c, sample.alpha, sample.beta, sample.gamma, ) # write input file for Indexus root = session.experiment.samplepath with open(path.join(root, 'indexus.txt'), 'w', encoding='utf-8') as fp: fp.write('''\ poli ! instrument n ! extended output %d ! num of spots %f %f ! delta theta, delta angle %f ! max deviation %f ! wavelength %s ! lattice type %.4f %.4f %.4f %.3f %.3f %.3f ! lattice parameters .0 .1 -1.0 1.0 ! offset gamma, step, low and high limits .0 .1 -1.0 1.0 ! offset nu, step, low and high limits ''' % params) R2D = math.degrees with open(path.join(root, 'angles.txt'), 'w', encoding='utf-8') as fp: fp.write(' gamma omega nu I sigI\n') for pos, _hkl, (intensity, sigma) in posl: fp.write('%8.3f %8.3f %8.3f %8.2f %8.2f\n' % (R2D( pos.gamma), R2D(pos.omega), R2D(pos.nu), intensity, sigma)) session.log.info('Running Indexus...') proc = createSubprocess(['indexus'], cwd=root, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output = proc.communicate()[0] if 'unable to find solution' in output: session.log.warning('Indexus could not find a solution.') IndexPeaks._last_result = None return # read output from Indexus p1, p2 = None, None table = [] peaks = [] dgamma = 0. dnu = 0. chi2 = 0. with open(path.join(root, 'indexus.lis'), 'r', encoding='utf-8') as fp: lines = iter(fp) for line in lines: if line.startswith(' best combination:'): parts = line.split() p1, p2 = int(parts[2]) - 1, int(parts[4]) - 1 elif line.startswith(' offset gamma:'): dgamma = float(line.split()[2]) elif line.startswith(' offset nu:'): dnu = float(line.split()[2]) elif line.startswith(' chi2:'): chi2 = float(line.split()[1]) elif line.startswith(' list:'): session.log.info('Indexed reflections:') for i, line in enumerate(lines): if not line.strip(): # empty line after table break cols = line.strip().strip('*').split() if cols[0] == 'H': # header continue peaks.append([float(ix) for ix in cols[:3]]) table.append([str(i)] + cols) break printTable(('pos#', 'h', 'k', 'l', 'γ', 'ω', 'ν', 'I', 'σ(I)'), table, session.log.info, rjust=True) # calculate UB matrix from "best combination" of two peaks or_calc = orient(*sample.cell.cellparams()) pos1 = posl[p1][0] pos2 = posl[p2][0] hkl1 = [int(round(ix)) for ix in peaks[p1]] hkl2 = [int(round(ix)) for ix in peaks[p2]] new_cell = or_calc.Reorient(hkl1, pos1, hkl2, pos2) IndexPeaks._last_result = (new_cell.rmat.T, (dgamma, dnu), listname, peaks) session.log.info( 'Using (%.4g %.4g %.4g) and (%.4g %.4g %.4g) to calculate' ' UB matrix:', *(tuple(hkl1) + tuple(hkl2))) for row in new_cell.rmat.T: # pylint: disable=not-an-iterable session.log.info(' %8.4f %8.4f %8.4f', *row) session.log.info('') session.log.info('Fit quality χ²: %8.4f', chi2) session.log.info('') session.log.info('Offsets:') session.log.info(' delta gamma = %8.4f delta nu = %8.4f', dgamma, dnu) session.log.info('') session.log.info('Use AcceptIndexing() to use this indexing.')
def plotDataset(dataset, fn, fmt): if not dataset.xresults: raise ValueError('no points in dataset') gpProcess = createSubprocess('gnuplot', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) def write(s): gpProcess.stdin.write(s.encode()) write('set terminal %s size 600,400 dashed\n' % fmt) write('set xlabel "%s (%s)"\n' % (dataset.xnames[dataset.xindex], dataset.xunits[dataset.xindex])) write('set title "Scan %s - %s"\n' % (dataset.counter, dataset.scaninfo)) write('set grid lt 3 lc 8\n') write('set style increment user\n') for ls, pt in enumerate([7, 5, 9, 11, 13, 2, 1, 3]): write('set style line %d lt 1 lc %d pt %d\n' % (ls+1, ls+1, pt)) data = [] for xv, yv in zip(dataset.xresults, dataset.yresults): data.append('%s %s' % (xv[dataset.xindex], ' '.join(map(str, yv)))) data = '\n'.join(data) + '\ne\n' plotterms = [] ylabels = [] yunits = set() for i, (name, info) in enumerate(zip(dataset.ynames, dataset.yvalueinfo)): if info.type in ('info', 'error', 'time', 'monitor'): continue term = '"-"' if info.errors == 'sqrt': term += ' using 1:%d:(sqrt($%d))' % (i+2, i+2) elif info.errors == 'next': term += ' using 1:%d:%d' % (i+2, i+3) else: term += ' using 1:%d' % (i+2) term += ' title "%s (%s)"' % (name, info.unit) if info.type == 'other': term += ' axes x1y2' term += ' with errorlines' plotterms.append(term) ylabels.append('%s (%s)' % (name, info.unit)) yunits.add(info.unit) if len(ylabels) == 1: write('set ylabel "%s"\n' % ylabels[0]) write('set key off\n') else: if len(yunits) == 1: write('set ylabel "%s"\n' % yunits.pop()) write('set key outside below\n') write('set output "%s-lin.%s"\n' % (fn, fmt)) write('plot %s\n' % ', '.join(plotterms)) for i in range(len(plotterms)): write(data) write('set output "%s-log.%s"\n' % (fn, fmt)) write('set logscale y\n') write('plot %s\n' % ', '.join(plotterms)) for i in range(len(plotterms)): write(data) write('exit') gpProcess.communicate()