def telescope(command, data, group, cdata): """ Adds telescope information to slots. Interactive usage:: telescope slots telescope observatory longitude latitude height Arguments:: slots : string slot, slot range or group which will be processed. telescope : string telescope name. Enter ?? for by-number interactive selection from pre-stored data observatory : string observatory name longitude : float geodetic longitude, degrees. latitude : float geodetic latitude, degrees height : float height above sea level, metres """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('telescope', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('observatory', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('longitude', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('latitude', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('height', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs slots = inpt.get_value('slots', 'slots to mask', '1-1000') slist = interp_slots(slots, True, data, group) telescope = inpt.get_value('telescope', 'name of telescope, ?? for a list', '??') if telescope == '??': try: telescope,observatory,longitude,latitude,height = subs.observatory() except subs.SubsError, err: raise DintError('no observatory data set, ' + str(err)) inpt.set_default('telescope', telescope) inpt.set_default('observatory', observatory) inpt.set_default('longitude', longitude) inpt.set_default('latitude', latitude) inpt.set_default('height', height)
def lponto(command, data, cdata): """ Loads data from a ponto file Interactive usage: lponto pnt slots fslot Arguments: pnt -- name of ponto file slots -- range of slots as in '1-10', or just a single slot '9' to load data into. fslot -- first slot to read in file, starting from 1 """ import trm.subs.cpp as cpp # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('pnt', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('fslot', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs pnt = inpt.get_value('pnt', 'ponto file name', subs.Fname('example', '.pnt')) slots = inpt.get_value('slots', 'slots to load data into', '1-1000') slist = interp_slots(slots, False, data) fslot = inpt.get_value('fslot', 'first slot to read from file', 1, 1, 1000000) # load ponto data try: (fobj,endian) = cpp.open_ponto(str(pnt)) nload = 0 # junk the first fslot-1 for i in range(fslot-1): print('skipped a dset') dnl.rponto(fobj,endian) # save the rest for slot in slist: data[slot] = dnl.rponto(fobj,endian) nload += 1 if not cdata.mute: print('Loaded ponto data into slot',slot) except cpp.CppError, err: fobj.close() raise DintError(str(err))
def load(command, data, cdata): """ Loads dsets. Interactive usage:: load dset slots fslot Arguments:: dset : string name of FITS file containing dsets. '.fits' will be added if not already present slots : string range of slots as in '1-10', or just a single slot '9' to load data into. It is OK to specify more slots than the file contains. Unused slots will be unchanged. fslot : int first slot to read from file, starting from 1 """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('dset', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('fslot', inp.Input.LOCAL, inp.Input.PROMPT) # Get inputs ndset = inpt.get_value('dset', 'file containing one or more dsets', subs.Fname('example', '.fits')) slots = inpt.get_value('slots', 'slots to load dsets into', '1-1000') slist = interp_slots(slots, False, data) fslot = inpt.get_value('fslot', 'first slot to read from file', 1, 1, 1000000) # load dsets nload = 0 for i, dset in enumerate(dnl.io.grfits(ndset, fslot)): data[slist[i]] = dset nload += 1 if not cdata.mute: print('Slot {0:5d}, {1:s}'.format(slist[i],dset.oneLine())) # loading no slots is flagged as an error if nload == 0: raise DintError('load: no slots were loaded')
def add(command, data, group, cdata): """ Add one set of slots to another Interactive usage: add inslot1 inslot1 outslot Arguments:: inslot1 : string range of slots as in '1-10', or just a single slot '9' to plot, or a group name such as 'ippeg'. inslot2 : string range of slots as in '1-10', or just a single slot '9' to plot, or a group name such as 'ippeg', must match number of inslot1 slots outslot : int first slot for output (sequential from there) The headers of the output slots will be taken from the inslot1 slots. """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('inslot1', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('inslot2', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('outslot', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs slots1 = inpt.get_value('inslot1', 'first set of slots', '1') slist1 = interp_slots(slots1, True, data, group) slots2 = inpt.get_value('inslot2', 'slots to add to the first set', '2') slist2 = interp_slots(slots2, True, data, group, nfind=len(slist1)) slots3 = inpt.get_value('outslot', 'first output slot', '3') slist3 = interp_slots(slots3, False, data, group, nfind=len(slist1)) for i in range(len(slist1)): data[slist3[i]] = data[slist1[i]] + data[slist2[i]] if not cdata.mute: print('Slot ' + str(slist3[i]) + ' = slot ' + str(slist1[i]) + ' + slot ' + str(slist2[i])) return True
def write(command, data, group, cdata): """ Writes dsets to disk The data are written using Python's 'cPickle' module to write out in binary. If you need long term storage of your data, be aware that future changes to the Dset class could render these files unreadable. You would be better off writing out in FITS in this case. Interactive usage: write dfile slots append Arguments: dfile -- name of disk file to write to. slots -- range of slots as in '1-10', or just a single slot '9', or the name of a slot group append -- do you want to append the slots to dfile? (careful: this will simply append to *any* file) """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('dfile', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('append', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs dfile = inpt.get_value('dfile', 'file to write the data to', subs.Fname('example', '.dnl', subs.Fname.NEW)) slots = inpt.get_value('slots', 'slots to load dsets into', '1-1000') slist = interp_slots(slots, True, data) append = inpt.get_value('append', 'append to an old file?', False) if append and not dfile.exists(): raise DintError('File = ' + str(dfile) + ' does not exist.') if append: optr = open(dfile,'ab') else: optr = open(dfile,'wb') # write out data for slot in slist: data[slot].write(optr) if not cdata.mute: print('Wrote slot',slot,'into file ' + str(dfile)) optr.close()
def airmass(command, data, group, cdata): """ Converts the X axis of astronomical time series slots to airmass, where airmass is a measure of the amount of air being looked through. The object coordinates must be set with 'coordinates' and the telescope position must be set with 'telescope'. If it encounters an error it will abort the loop rather than try to continue. Interactive usage: airmass slots Arguments: slots -- slot, slot range or group which will be processed. Script usage: command -- contains a string as used interactively data -- a Data containing Dsets. group -- a Group containing slot list groups Returns True/False according to whether it ran OK """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs slots = inpt.get_value('slots', 'slots to mask', '1-1000') slist = interp_slots(slots, True, data, group) for slot in slist: data[slot].amass() if not cdata.mute: print('Converted X-axis of slot ' + str(slot) + ' to airmass.')
def lultracam(command, data, cdata): """ Loads dsets from an Ultracam file This runs on a file created from concatenating ULTRACAM ASCII log files into a single binary file using the script 'cultracam.py'. Such files store all data from all apertures and CCDs. This program will try to load all apertures from all CCDs, depending on how many slots are being loaded. Interactive usage: lultracam ult slots what bmax emax Arguments: ult -- name of a binary file ending '.ult' created by the script lultracam.py from ultracam log files slots -- range of slots as in '1-10', or just a single slot '9' to load data into. what -- 'c' = count rate light curves, 'f' = fwhm seeing in pixels, 'xm' = measured X positions, 'ym' = measured Y positions bmax -- maximum bad pixel in aperture before data are marked as bad emax -- maximum bad pixel in aperture before data are marked as bad """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('ult', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('what', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('bmax', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('emax', inp.Input.LOCAL, inp.Input.HIDE) # get parameters uname = inpt.get_value('ult', 'ultracam binary file', subs.Fname('example', '.ult')) slots = inpt.get_value('slots', 'slots to load dsets into', '1-1000') slist = interp_slots(slots, False, data) what = inpt.get_value('what', 'C(ounts), F(whm), XM(easured), YM(easured)', 'c', lvals=['c','C','f','F', 'xm', 'XM', 'ym', 'YM']) bmax = inpt.get_value('bmax', 'maximum bad pixel in aperture', 50) emax = inpt.get_value('emax', 'maximum error flag', 5) # read the ultracam binary file iptr = open(uname,'rb') ult = pickle.load(iptr) iptr.close() # extract all Dsets, first work out maximum number of apertures for any one CCD # because it is more convenient to extract all CCDs of a given aperture rather than # all apertures of a given CCD maxaps = npy.array([len(ult.x[nccd]) for nccd in ult.x.keys()]).max() nload = 0 for nap in range(maxaps): for nccd in ult.x.keys(): if nap < len(ult.x[nccd]): data[slist[nload]] = ult.tseries(nccd,nap+1,what.lower(),bmax,emax) if not cdata.mute: print('Loaded dset for CCD ' + str(nccd) + ' aperture ' + str(nap+1) + ' into slot',slist[nload]) nload += 1 # loading no slots is flagged as an error if nload == 0: raise DintError('load: no slots were loaded')
def lmolly(command, data, cdata): """ Loads data from a molly file Interactive usage: lmolly mol slots fslot Arguments: mol -- name of molly file slots -- range of slots as in '1-10', or just a single slot '9' to load data into. fslot -- first slot to read in file, starting from 1 """ import trm.dnl.molly as molly # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('mol', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('fslot', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs mol = inpt.get_value('mol', 'molly file name', subs.Fname('example', '.mol')) slots = inpt.get_value('slots', 'slots to load data into', '1-1000') slist = interp_slots(slots, False, data) fslot = inpt.get_value('fslot', 'first slot to read from file', 1, 1, 1000000) # load molly data try: mf = open(mol, 'rb') nload = 0 # junk the first fslot-1 for i in range(fslot-1): print('skipping a molly spectrum') molly.skip_molly(mf) # save the rest for slot in slist: mspec = molly.rmspec(mf) if mspec: data[slot] = mspec nload += 1 if not cdata.mute: print('Loaded ponto data into slot',slot) else: raise EOFError mf.close() except EOFError: print('End-of-file reached.') mf.close() # loading no slots is flagged as an error if nload == 0: raise DintError('load: no slots were loaded') elif not cdata.mute: print(nload,'slots were loaded.')
def help(command, cdata): """ Provides help. Possible ways to call it are: 'help' -- full command list 'help classes' -- list of command classes 'help load' -- help on command 'load' 'help lo.*' -- commands matching regular expression 'lo.*' 'help class IO' -- classes matching regular expression 'lo.*' Note that 'help load' would also list help on 'upload' because of the regular expression matching. """ global COMMANDS, CLASSES try: # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('what', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('class', inp.Input.LOCAL, inp.Input.HIDE) # get inputs inpt.set_default('what', '') what = inpt.get_value('what', 'what do you want help on?', 'classes') if what == 'classes': keys = CLASSES.keys() keys.sort() for key in keys: print('{0:<10s} -- {1:s}'.format(key, CLASSES[key]['about'])) print("\nType 'help class classname' for information" + " on a specific class") elif what == 'class': clss = inpt.get_value('class', 'which class to list (regular expressions supported)', 'IO') m = re.compile('clss') keys = [key for key in CLASSES.keys() if m.search(key)] if len(keys): keys.sort() for key in keys: found = True comms = CLASSES[key]['list'] comms.sort() print('\nCommands of the ' + key + ' class are as follows:\n') for comm in comms: print('{0:<10s} -- {1:s}'.format(key, COMMANDS[key])) else: print('Sorry; no class matching ' + clss + ' was found.') else: if what == '': comms = COMMANDS.keys() else: m = re.compile(what) comms = [comm for comm in COMMANDS.keys() if m.search(comm)] if len(comms): comms.sort() for comm in comms: print('{0:<11s} -- {1:s}'.format(comm, COMMANDS[comm])) else: print('Sorry; no command matching ' + what + ' was found.') return True except inp.InputError, err: print('InputError exception raised: ' + str(err))
def coordinates(command, data, group, cdata): """ Adds astronomical position information to slots. Interactive usage: coordinates slots target position [rapm=0 decpm=0 epoch=2000.0 parallax=0 rv=0] Arguments: slots -- slot, slot range or group which will be processed. target -- target name position -- RA, dec as in '12 34 45.56 -00 12 34.2' or decimal degrees '234.5645 -1.2'. Optionally you can add any of 'ICRS', 'J2000' or 'B1950' at the end, but note that only 'ICRS' (the default) is supported as of Aug 2008. See trm.subs.str2radec for full format info. epoch -- Julian epoch of coordinates (only matters if there is proper motion and RV) pmra -- proper motion in RA (arcsec/year) pmdec -- proper motion in Dec (arcsec/year) parallax -- parallax, (arcsec) rv -- radial velocity, (km/s) Script usage: command -- contains a string as used interactively data -- a Data containing Dsets. group -- a Group containing slot list groups Returns True/False according to whether it ran OK """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('target', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('position', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('epoch', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('pmra', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('pmdec', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('parallax', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('rv', inp.Input.LOCAL, inp.Input.HIDE) # get inputs slots = inpt.get_value('slots', 'slots to mask', '1-1000') slist = interp_slots(slots, True, data, group) target = inpt.get_value('target', 'name of target', 'M31') position = inpt.get_value('position', 'celestial coordinates of target', '12 34 45.67 -00 11 23.4') ra,dec,system = subs.str2radec(position) inpt.set_default('epoch', 2000.0) epoch = inpt.get_value('epoch', 'Julian epoch of coordinates', 2000.0) inpt.set_default('pmra', 0.) pmra = inpt.get_value('pmra', 'proper motion in RA (arcsec/yr)', 0.) inpt.set_default('pmdec', 0.) pmdec = inpt.get_value('pmdec', 'proper motion in Dec (arcsec/yr)', 0.) inpt.set_default('parallax', 0.) parallax = inpt.get_value('parallax', 'parallax (arcsec)', 0.) inpt.set_default('rv', 0.) rv = inpt.get_value('rv', 'radial velocity (km/s)', 0.) for slot in slist: data[slot].setpos(target, ra, dec, system, pmra, pmdec, epoch, parallax, rv) if not cdata.mute: print('Added astronomical target data to slot ' + str(slot))
def appmask(command, data, group, cdata): """ Applies a data mask from a file created e.g. by 'setmask' Interactive usage:: appmask slots mfile [type=temp] Arguments:: slots : string slot, slot range or group which will be masked. mfile : string mask file type : string either the temporary data mask will be set ('temp') or the bad pixel mask ('bad') will be set, excluding the pixels from all plots and processing. See trm.dnl.Dset to understand the difference. Script usage:: command : string contains a string as used interactively data : Data contains Dsets. group : Group contains slot list groups Returns True/False according to whether it ran OK """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('mfile', inp.Input.GLOBAL, inp.Input.PROMPT) inpt.register('type', inp.Input.LOCAL, inp.Input.HIDE) # get inputs slots = inpt.get_value('slots', 'slots to mask', '1-1000') slist = interp_slots(slots, True, data, group) mfile = inpt.get_value('mfile', 'mask file', subs.Fname('mask','.msk')) inpt.set_default('type', 'temp') mtype = inpt.get_value('type', 'temp(oraray) or bad mask?', 'temp', lvals=['temp', 'bad']) # read and apply mask mptr = open(mfile,'r') gmask = pickle.load(mptr) mptr.close() if mtype == 'temp': tmask = True else: tmask = False for i in slist: gmask.app_mask(data[i], tmask) if not cdata.mute: print('Applied mask from ' + str(mfile) + ' to slot ' + str(i))
def setmask(command, data, cdata): """ Sets the mask on a dset and dumps a file containing the mask which can be applied to other dsets using 'appmask'. This is an interactive routine which will request input from the user and is better not used in batch processing. Repeated calls of this routine can be used to build complex masks. The masks are always applied in the original order so that you can mask then partially unmask for example. Note that whatever slot you choose to define the mask will always end up masked; if you don't want this you may want to make a copy. Interactive usage: setmask slot mfile append [device reset x1 x2 y1 y2] mask type Arguments: slot -- an example slot to plot. mfile -- mask file append -- append to an old mask file if possible device -- plot device, e.g. '/xs' reset -- rest plot limits or not x1 -- left X plot limit x2 -- right X plot limit y1 -- bottom Y plot limit y2 -- top Y plot limit mask -- mask 'M', or unmask 'U' or quit 'Q'. type -- type of mask: 'X' masks using ranges in X Mask types: X -- mask a range in X Y -- mask a range in Y I -- mask a range of pixel indices P -- mask in 'phase', i.e. a range that repeats periodically. """ import trm.dnl.mask as mask # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slot', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('mfile', inp.Input.GLOBAL, inp.Input.PROMPT) inpt.register('append', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('device', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('reset', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('x1', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('x2', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('y1', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('y2', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('mask', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('type', inp.Input.LOCAL, inp.Input.PROMPT) # get inputs slots = inpt.get_value('slot', 'slot to plot for mask definition', '1') slist = interp_slots(slots, True, data, nfind=1) dset = data[slist[0]] device = inpt.get_value('device', 'plot device', '/xs') # mask file mfile = inpt.get_value('mfile', 'mask file to save results to', subs.Fname('mask','.msk', subs.Fname.NEW)) append = inpt.get_value('append', 'add to an old mask file if possible', True) if append and mfile.exists(): mptr = open(mfile,'rb') gmask = pickle.load(mptr) gmask.app_mask(dset) mptr.close() else: gmask = mask.Gmask() # other parameters reset = inpt.get_value('reset', 'reset plot limits automatically?', True) # compute default limits (x1,x2,y1,y2) = dset.plimits() if (x2 - x1) < (x1+x2)/2./100.: xoff = x1 x1 = 0. x2 -= xoff else: xoff = 0. yoff = 0. if reset: inpt.set_default('x1', x1) inpt.set_default('x2', x2) inpt.set_default('y1', y1) inpt.set_default('y2', y2) x1 = inpt.get_value('x1', 'left-hand limit of plot', x1) x2 = inpt.get_value('x2', 'right-hand limit of plot', x2) y1 = inpt.get_value('y1', 'bottom limit of plot', y1) y2 = inpt.get_value('y2', 'top limit of plot', y2) m_or_u = inpt.get_value('mask', 'M(ask), U(nmask) or Q(uit)?', 'm', lvals=['m', 'M', 'u', 'U', 'q', 'Q']) if m_or_u.upper() == 'M': mtext = 'mask' else: mtext = 'unmask' mask_type = inpt.get_value('type', 'X, Y, P(hase), I(ndex) or Q(uit)?', 'x', lvals=['x', 'X', 'y', 'Y', 'p', 'P', 'i', 'I', 'q', 'Q']) # initialise plot try: pg.pgopen(device) pg.pgsch(1.5) pg.pgscf(2) pg.pgslw(2) pg.pgsci(4) pg.pgenv(x1,x2,y1,y2,0,0) (xlabel,ylabel) = dset.plabel(xoff,yoff) pg.pgsci(2) pg.pglab(xlabel, ylabel, dset.title) # plot the dset dset.plot(xoff,yoff) x = (x1+x2)/2. y = (y1+y2)/2. # now define masks ch = 'X' while ch.upper() != 'Q': # go through mask options if mask_type.upper() == 'X': print('Set cursor at the one end of the X range, Q to quit') (xm1,y,ch) = pg.pgband(7,0,x,y) if ch.upper() != 'Q': print('Set cursor at the other end of ' + 'the X range, Q to quit') xm2,y,ch = pg.pgband(7,0,xm1,y) if ch.upper() != 'Q': if xm1 > xm2: xm1,xm2 = xm2,xm1 umask = mask.Xmask(xoff+xm1, xoff+xm2, m_or_u.upper() == 'M') elif mask_type.upper() == 'I': print('Place cursor near a point and click to ' + mtext + ' it, Q to quit') x,y,ch = pg.pgband(7,0,x,y) if ch.upper() != 'Q': xmm1,xmm2,ymm1,ymm2 = pg.pgqvp(2) xscale = (xmm2-xmm1)/(x2-x1) yscale = (ymm2-ymm1)/(y2-y1) # only consider good data of opposite 'polarity' to the # change we are making. ok = (dset.good == True) & \ (dset.mask == (m_or_u.upper() == 'M')) if len(dset.x.dat[ok == True]): # compute physical squared distance of cursor from # points sqdist = npy.power( xscale*(dset.x.dat[ok]-(xoff+x)),2) + \ npy.power(yscale*(dset.y.dat[ok]-(yoff+y)),2) # select the index giving the minimum distance indices = npy.arange(len(dset))[ok] index = indices[sqdist.min() == sqdist][0] umask = mask.Imask(index, m_or_u.upper() == 'M') else: print('There seem to be no data to ' + mtext + '; data already ' + mtext + 'ed are ignored.') umask = None if ch.upper() != 'Q' and umask is not None: gmask.append(umask) umask.app_mask(dset) print('overplotting data') # over-plot the dset dset.plot(xoff,yoff) pg.pgclos() except pg.ioerror, err: raise DintError(str(err))
def plot(command, data, group, cdata): """ Plots dsets from a dictionary called data. Interactive usage: plot slots [device x1 x2 y1 y2 xoff ysep=0 pmask] Arguments: slots -- range of slots as in '1-10', or just a single slot '9' to plot, or a group name such as 'ippeg'. device -- plot device (e.g. '/xs', '3/xs', 'hardcopy.ps/cps') x1 -- left-hand plot limit x2 -- right-hand plot limit. Set = x1 for automatic determination y1 -- lower plot limit y2 -- upper plot limit. Set = y1 for automatic determination xoff -- offset to start X axis from, 0 for automatic determination. ysep -- separation in y pmask -- whether to plot masked data """ # generate arguments inpt = inp.Input(DINT_ENV, DINT_DEF, inp.clist(command)) # register parameters inpt.register('slots', inp.Input.LOCAL, inp.Input.PROMPT) inpt.register('device', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('x1', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('x2', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('y1', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('y2', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('xoff', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('ysep', inp.Input.LOCAL, inp.Input.HIDE) inpt.register('pmask', inp.Input.LOCAL, inp.Input.HIDE) # get inputs slots = inpt.get_value('slots', 'slots to plot', '1') slist = interp_slots(slots, True, data, group) device = inpt.get_value('device', 'plot device', '/xs') x1 = inpt.get_value('x1', 'left-hand plot limit', 0.0) x2 = inpt.get_value('x2', 'right-hand plot limit', 0.0) y1 = inpt.get_value('y1', 'lower plot limit', 0.0) y2 = inpt.get_value('y2', 'upper plot limit', 0.0) xoff = inpt.get_value('xoff', 'X offset', 0.0) inpt.set_default('ysep', 0.0) ysep = inpt.get_value('ysep', 'vertical separation between successive dsets', 0.0) pmask = inpt.get_value('pmask', 'do you want to plot the masked data too?', True) # Determine limits automatically if required if xoff !=0. or x1 == x2 or y1 == y2: xa1 = None xa2 = None ya1 = None ya2 = None yadd = 0. for i in slist: (xi1,xi2,yi1,yi2) = data[i].plimits() if xa1 is None: xa1 = xi1 else: xa1 = min(xa1, xi1) if xa2 is None: xa2 = xi2 else: xa2 = max(xa2, xi2) if ya1 is None and yi1 is not None: ya1 = yi1 + yadd elif yi1 is not None: ya1 = min(ya1, yi1 + yadd) if ya2 is None and yi2 is not None: ya2 = yi2 + yadd elif yi2 is not None: ya2 = max(ya2, yi2 + yadd) yadd += ysep if xa1 is None or xa2 is None or ya1 is None or ya2 is None: raise DintError('plot: no automatic limits could be evaluated; possibly no good data to plot?') if xoff == 0.0 and (xa2 - xa1) < (xa1+xa2)/2./100.: xoff = xa1 xa1 -= xoff xa2 -= xoff if x1 == x2: x1 = xa1 x2 = xa2 if y1 == y2: y1 = ya1 y2 = ya2 try: pg.pgopen(device) pg.pgsci(4) pg.pgenv(x1, x2, y1, y2, 0, 0) pg.pgsci(2) first = data[slist[0]] xlabel = first.x.label if xoff == 0 else first.x.label + '-' + str(xoff) xlabel += ' (' + first.x.units + ')' ylabel = first.y.label + ' (' + first.y.units + ')' pg.pglab(xlabel, ylabel, first.title) yadd = 0. for slot in slist: data[slot].plot(xoff,yoff=-yadd,masked=pmask) if not cdata.mute: print('Plotted slot ' + str(slot)) yadd += ysep pg.pgclos() except pg.ioerror, err: raise DintError(str(err))