source: trunk/python/__init__.py @ 1504

Last change on this file since 1504 was 1504, checked in by Malte Marquarding, 15 years ago

Fix for ticket #151: added facilities to help with on/off scan identification/setting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.6 KB
Line 
1"""
2This is the ATNF Single Dish Analysis package.
3
4"""
5import os,sys,shutil, platform
6
7# Set up AIPSPATH and first time use of asap i.e. ~/.asap/*
8plf = None
9if sys.platform == "linux2":
10    if platform.architecture()[0] == '64bit':
11        plf = 'linux_64b'
12    else:
13        plf = 'linux_gnu'
14elif sys.platform == 'darwin':
15    plf = 'darwin'
16else:
17    # Shouldn't happen - default to linux
18    plf = 'linux'
19asapdata = __path__[-1]
20# Allow user defined data location
21if os.environ.has_key("ASAPDATA"):
22    if os.path.exists(os.environ["ASAPDATA"]):
23        asapdata = os.environ["ASAPDATA"]
24# use AIPSPATH if defined and "data" dir present
25if not os.environ.has_key("AIPSPATH") or \
26        not os.path.exists(os.environ["AIPSPATH"].split()[0]+"/data"):
27    os.environ["AIPSPATH"] = "%s %s somwhere" % ( asapdata, plf)
28# set up user space
29userdir = os.environ["HOME"]+"/.asap"
30if not os.path.exists(userdir):
31    print 'First time ASAP use. Setting up ~/.asap'
32    os.mkdir(userdir)
33    shutil.copyfile(asapdata+"/data/ipythonrc-asap", userdir+"/ipythonrc-asap")
34    shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
35                    userdir+"/ipy_user_conf.py")
36    f = file(userdir+"/asapuserfuncs.py", "w")
37    f.close()
38    f = file(userdir+"/ipythonrc", "w")
39    f.close()
40else:
41    # upgrade to support later ipython versions
42    if not os.path.exists(userdir+"/ipy_user_conf.py"):
43        shutil.copyfile(asapdata+"/data/ipy_user_conf.py",
44                        userdir+"/ipy_user_conf.py")
45
46# remove from namespace
47del asapdata, userdir, shutil, platform
48
49def _validate_bool(b):
50    'Convert b to a boolean or raise'
51    bl = b.lower()
52    if bl in ('f', 'no', 'false', '0', 0): return False
53    elif bl in ('t', 'yes', 'true', '1', 1): return True
54    else:
55        raise ValueError('Could not convert "%s" to boolean' % b)
56
57def _validate_int(s):
58    'convert s to int or raise'
59    try: return int(s)
60    except ValueError:
61        raise ValueError('Could not convert "%s" to int' % s)
62
63def _asap_fname():
64    """
65    Return the path to the rc file
66
67    Search order:
68
69     * current working dir
70     * environ var ASAPRC
71     * HOME/.asaprc
72
73    """
74
75    fname = os.path.join( os.getcwd(), '.asaprc')
76    if os.path.exists(fname): return fname
77
78    if os.environ.has_key('ASAPRC'):
79        path =  os.environ['ASAPRC']
80        if os.path.exists(path):
81            fname = os.path.join(path, '.asaprc')
82            if os.path.exists(fname):
83                return fname
84
85    if os.environ.has_key('HOME'):
86        home =  os.environ['HOME']
87        fname = os.path.join(home, '.asaprc')
88        if os.path.exists(fname):
89            return fname
90    return None
91
92
93defaultParams = {
94    # general
95    'verbose'             : [True, _validate_bool],
96    'useplotter'          : [True, _validate_bool],
97    'insitu'              : [True, _validate_bool],
98
99    # plotting
100    'plotter.gui'         : [True, _validate_bool],
101    'plotter.stacking'    : ['p', str],
102    'plotter.panelling'   : ['s', str],
103    'plotter.colours'     : ['', str],
104    'plotter.linestyles'  : ['', str],
105    'plotter.decimate'    : [False, _validate_bool],
106    'plotter.ganged'      : [True, _validate_bool],
107    'plotter.histogram'  : [False, _validate_bool],
108    'plotter.papertype'  : ['A4', str],
109
110    # scantable
111    'scantable.save'      : ['ASAP', str],
112    'scantable.autoaverage'      : [True, _validate_bool],
113    'scantable.freqframe' : ['LSRK', str],  #default frequency frame
114    'scantable.verbosesummary'   : [False, _validate_bool],
115    'scantable.storage'   : ['memory', str],
116    'scantable.history'   : [True, _validate_bool],
117    'scantable.reference'      : ['.*(e|w|_R)$', str]
118    # fitter
119    }
120
121def list_rcparameters():
122
123    print """
124# general
125# print verbose output
126verbose                    : True
127
128# preload a default plotter
129useplotter                 : True
130
131# apply operations on the input scantable or return new one
132insitu                     : True
133
134# plotting
135
136# do we want a GUI or plot to a file
137plotter.gui                : True
138
139# default mode for colour stacking
140plotter.stacking           : Pol
141
142# default mode for panelling
143plotter.panelling          : scan
144
145# push panels together, to share axislabels
146plotter.ganged             : True
147
148# decimate the number of points plotted bya afactor of
149# nchan/1024
150plotter.decimate           : False
151
152# default colours/linestyles
153plotter.colours            :
154plotter.linestyles         :
155
156# enable/disable histogram plotting
157plotter.histogram          : False
158
159# ps paper type
160plotter.papertype          : A4
161
162# scantable
163
164# default storage of scantable ('memory'/'disk')
165scantable.storage          : memory
166
167# write history of each call to scantable
168scantable.history          : True
169
170# default ouput format when saving
171scantable.save             : ASAP
172
173# auto averaging on read
174scantable.autoaverage      : True
175
176# default frequency frame to set when function
177# scantable.set_freqframe is called
178scantable.freqframe        : LSRK
179
180# Control the level of information printed by summary
181scantable.verbosesummary   : False
182
183# Control the identification of reference (off) scans
184# This is has to be a regular expression
185scantable.reference         : .*(e|w|_R)$
186# Fitter
187"""
188
189def rc_params():
190    'Return the default params updated from the values in the rc file'
191
192    fname = _asap_fname()
193
194    if fname is None or not os.path.exists(fname):
195        message = 'could not find rc file; returning defaults'
196        ret =  dict([ (key, tup[0]) for key, tup in defaultParams.items()])
197        #print message
198        return ret
199
200    cnt = 0
201    for line in file(fname):
202        cnt +=1
203        line = line.strip()
204        if not len(line): continue
205        if line.startswith('#'): continue
206        tup = line.split(':',1)
207        if len(tup) !=2:
208            print ('Illegal line #%d\n\t%s\n\tin file "%s"' % (cnt, line, fname))
209            continue
210
211        key, val = tup
212        key = key.strip()
213        if not defaultParams.has_key(key):
214            print ('Bad key "%s" on line %d in %s' % (key, cnt, fname))
215            continue
216
217        default, converter =  defaultParams[key]
218
219        ind = val.find('#')
220        if ind>=0: val = val[:ind]   # ignore trailing comments
221        val = val.strip()
222        try: cval = converter(val)   # try to convert to proper type or raise
223        except ValueError, msg:
224            print ('Bad val "%s" on line #%d\n\t"%s"\n\tin file "%s"\n\t%s' % (val, cnt, line, fname, msg))
225            continue
226        else:
227            # Alles Klar, update dict
228            defaultParams[key][0] = cval
229
230    # strip the conveter funcs and return
231    ret =  dict([ (key, tup[0]) for key, tup in defaultParams.items()])
232    print ('loaded rc file %s'%fname)
233
234    return ret
235
236
237# this is the instance used by the asap classes
238rcParams = rc_params()
239
240rcParamsDefault = dict(rcParams.items()) # a copy
241
242def rc(group, **kwargs):
243    """
244    Set the current rc params.  Group is the grouping for the rc, eg
245    for scantable.save the group is 'scantable', for plotter.stacking, the
246    group is 'plotter', and so on.  kwargs is a list of attribute
247    name/value pairs, eg
248
249      rc('scantable', save='SDFITS')
250
251    sets the current rc params and is equivalent to
252
253      rcParams['scantable.save'] = 'SDFITS'
254
255    Use rcdefaults to restore the default rc params after changes.
256    """
257
258    aliases = {}
259
260    for k,v in kwargs.items():
261        name = aliases.get(k) or k
262        if len(group):
263            key = '%s.%s' % (group, name)
264        else:
265            key = name
266        if not rcParams.has_key(key):
267            raise KeyError('Unrecognized key "%s" for group "%s" and name "%s"' % (key, group, name))
268
269        rcParams[key] = v
270
271
272def rcdefaults():
273    """
274    Restore the default rc params - the ones that were created at
275    asap load time
276    """
277    rcParams.update(rcParamsDefault)
278
279def _n_bools(n, val):
280    return [ val for i in xrange(n) ]
281
282def _is_sequence_or_number(param, ptype=int):
283    if isinstance(param,tuple) or isinstance(param,list):
284        if len(param) == 0: return True # empty list
285        out = True
286        for p in param:
287            out &= isinstance(p,ptype)
288        return out
289    elif isinstance(param, ptype):
290        return True
291    return False
292
293def _to_list(param, ptype=int):
294    if isinstance(param, ptype):
295        if ptype is str: return param.split()
296        else: return [param]
297    if _is_sequence_or_number(param, ptype):
298        return param
299    return None
300
301def unique(x):
302    """
303    Return the unique values in a list
304    Parameters:
305        x:      the list to reduce
306    Examples:
307        x = [1,2,3,3,4]
308        print unique(x)
309        [1,2,3,4]
310    """
311    return dict([ (val, 1) for val in x]).keys()
312
313def list_files(path=".",suffix="rpf"):
314    """
315    Return a list files readable by asap, such as rpf, sdfits, mbf, asap
316    Parameters:
317        path:     The directory to list (default '.')
318        suffix:   The file extension (default rpf)
319    Example:
320        files = list_files("data/","sdfits")
321        print files
322        ['data/2001-09-01_0332_P363.sdfits',
323        'data/2003-04-04_131152_t0002.sdfits',
324        'data/Sgr_86p262_best_SPC.sdfits']
325    """
326    if not os.path.isdir(path):
327        return None
328    valid = "rpf rpf.1 rpf.2 sdf sdfits mbf asap".split()
329    if not suffix in valid:
330        return None
331    files = [os.path.expanduser(os.path.expandvars(path+"/"+f)) for f in os.listdir(path)]
332    return filter(lambda x: x.endswith(suffix),files)
333
334# workaround for ipython, which redirects this if banner=0 in ipythonrc
335sys.stdout = sys.__stdout__
336sys.stderr = sys.__stderr__
337
338# Logging
339from asap._asap import Log as _asaplog
340global asaplog
341asaplog=_asaplog()
342if rcParams['verbose']:
343    asaplog.enable()
344else:
345    asaplog.disable()
346
347def print_log():
348    log = asaplog.pop()
349    if len(log) and rcParams['verbose']: print log
350    return
351
352def mask_and(a, b):
353    assert(len(a)==len(b))
354    return [ a[i] & b[i] for i in xrange(len(a)) ]
355
356def mask_or(a, b):
357    assert(len(a)==len(b))
358    return [ a[i] | b[i] for i in xrange(len(a)) ]
359
360def mask_not(a):
361    return [ not i for i in a ]
362
363from asapfitter import fitter
364from asapreader import reader
365from selector import selector
366
367from asapmath import *
368from scantable import scantable
369from asaplinefind import linefinder
370from linecatalog import linecatalog
371
372if rcParams['useplotter']:
373    try:
374        from asapplotter import asapplotter
375        gui = os.environ.has_key('DISPLAY') and rcParams['plotter.gui']
376        if gui:
377            import matplotlib
378            matplotlib.use("TkAgg")
379        import pylab
380        xyplotter = pylab
381        plotter = asapplotter(gui)
382        del gui
383    except ImportError:
384        print "Matplotlib not installed. No plotting available"
385
386__date__ = '$Date: 2009-02-13 00:27:42 +0000 (Fri, 13 Feb 2009) $'.split()[1]
387__version__  = 'trunk'
388
389def is_ipython():
390    return '__IP' in dir(sys.modules["__main__"])
391if is_ipython():
392    def version(): print  "ASAP %s(%s)"% (__version__, __date__)
393   
394    def list_scans(t = scantable):
395        import types
396        globs = sys.modules['__main__'].__dict__.iteritems()
397        print "The user created scantables are:"
398        sts = map(lambda x: x[0], filter(lambda x: isinstance(x[1], t), globs))
399        print filter(lambda x: not x.startswith('_'), sts)
400        return
401
402    def commands():
403        x = """
404    [The scan container]
405        scantable           - a container for integrations/scans
406                              (can open asap/rpfits/sdfits and ms files)
407            copy            - returns a copy of a scan
408            get_scan        - gets a specific scan out of a scantable
409                              (by name or number)
410            drop_scan       - drops a specific scan out of a scantable
411                              (by number)
412            set_selection   - set a new subselection of the data
413            get_selection   - get the current selection object
414            summary         - print info about the scantable contents
415            stats           - get specified statistic of the spectra in
416                              the scantable
417            stddev          - get the standard deviation of the spectra
418                              in the scantable
419            get_tsys        - get the TSys
420            get_time        - get the timestamps of the integrations
421            get_inttime     - get the integration time
422            get_sourcename  - get the source names of the scans
423            get_azimuth     - get the azimuth of the scans
424            get_elevation   - get the elevation of the scans
425            get_parangle    - get the parallactic angle of the scans
426            get_unit        - get the current unit
427            set_unit        - set the abcissa unit to be used from this
428                              point on
429            get_abcissa     - get the abcissa values and name for a given
430                              row (time)
431            get_column_names - get the names of the columns in the scantable
432                               for use with selector.set_query
433            set_freqframe   - set the frame info for the Spectral Axis
434                              (e.g. 'LSRK')
435            set_doppler     - set the doppler to be used from this point on
436            set_dirframe    - set the frame for the direction on the sky
437            set_instrument  - set the instrument name
438            set_feedtype    - set the feed type
439            get_fluxunit    - get the brightness flux unit
440            set_fluxunit    - set the brightness flux unit
441            create_mask     - return an mask in the current unit
442                              for the given region. The specified regions
443                              are NOT masked
444            get_restfreqs   - get the current list of rest frequencies
445            set_restfreqs   - set a list of rest frequencies
446            shift_refpix    - shift the reference pixel of the IFs
447            set_spectrum    - overwrite the spectrum for a given row
448            get_spectrum    - retrieve the spectrum for a given
449            get_mask        - retrieve the mask for a given
450            flag            - flag selected channels in the data
451            lag_flag        - flag specified frequency in the data
452            save            - save the scantable to disk as either 'ASAP',
453                              'SDFITS' or 'ASCII'
454            nbeam,nif,nchan,npol - the number of beams/IFs/Pols/Chans
455            nscan           - the number of scans in the scantable
456            nrow            - the number of spectra in the scantable
457            history         - print the history of the scantable
458            get_fit         - get a fit which has been stored witnh the data
459            average_time    - return the (weighted) time average of a scan
460                              or a list of scans
461            average_pol     - average the polarisations together.
462            average_beam    - average the beams together.
463            convert_pol     - convert to a different polarisation type
464            auto_quotient   - return the on/off quotient with
465                              automatic detection of the on/off scans (closest
466                              in time off is selected)
467            mx_quotient     - Form a quotient using MX data (off beams)
468            scale, *, /     - return a scan scaled by a given factor
469            add, +, -       - return a scan with given value added
470            bin             - return a scan with binned channels
471            resample        - return a scan with resampled channels
472            smooth          - return the spectrally smoothed scan
473            poly_baseline   - fit a polynomial baseline to all Beams/IFs/Pols
474            auto_poly_baseline - automatically fit a polynomial baseline
475            recalc_azel     - recalculate azimuth and elevation based on
476                              the pointing
477            gain_el         - apply gain-elevation correction
478            opacity         - apply opacity correction
479            convert_flux    - convert to and from Jy and Kelvin brightness
480                              units
481            freq_align      - align spectra in frequency frame
482            invert_phase    - Invert the phase of the cross-correlation
483            swap_linears    - Swap XX and YY (or RR LL)
484            rotate_xyphase  - rotate XY phase of cross correlation
485            rotate_linpolphase - rotate the phase of the complex
486                                 polarization O=Q+iU correlation
487            freq_switch     - perform frequency switching on the data
488            stats           - Determine the specified statistic, e.g. 'min'
489                              'max', 'rms' etc.
490            stddev          - Determine the standard deviation of the current
491                              beam/if/pol
492     [Selection]
493         selector              - a selection object to set a subset of a scantable
494            set_scans          - set (a list of) scans by index
495            set_cycles         - set (a list of) cycles by index
496            set_beams          - set (a list of) beamss by index
497            set_ifs            - set (a list of) ifs by index
498            set_polarisations  - set (a list of) polarisations by name
499                                 or by index
500            set_names          - set a selection by name (wildcards allowed)
501            set_tsys           - set a selection by tsys thresholds
502            set_query          - set a selection by SQL-like query, e.g. BEAMNO==1
503            ( also  get_ functions for all these )
504            reset              - unset all selections
505            +                  - merge two selections
506
507     [Math] Mainly functions which operate on more than one scantable
508
509            average_time    - return the (weighted) time average
510                              of a list of scans
511            quotient        - return the on/off quotient
512            simple_math     - simple mathematical operations on two scantables,
513                              'add', 'sub', 'mul', 'div'
514            quotient        - build quotient of the given on and off scans
515                              (matched pairs and 1 off - n on are valid)
516            merge           - merge a list of scantables
517
518     [Line Catalog]
519        linecatalog              - a linecatalog wrapper, taking an ASCII or
520                                   internal format table
521            summary              - print a summary of the current selection
522            set_name             - select a subset by name pattern, e.g. '*OH*'
523            set_strength_limits  - select a subset by line strength limits
524            set_frequency_limits - select a subset by frequency limits
525            reset                - unset all selections
526            save                 - save the current subset to a table (internal
527                                   format)
528            get_row              - get the name and frequency from a specific
529                                   row in the table
530     [Fitting]
531        fitter
532            auto_fit        - return a scan where the function is
533                              applied to all Beams/IFs/Pols.
534            commit          - return a new scan where the fits have been
535                              commited.
536            fit             - execute the actual fitting process
537            store_fit       - store the fit parameters in the data (scantable)
538            get_chi2        - get the Chi^2
539            set_scan        - set the scantable to be fit
540            set_function    - set the fitting function
541            set_parameters  - set the parameters for the function(s), and
542                              set if they should be held fixed during fitting
543            set_gauss_parameters - same as above but specialised for individual
544                                   gaussian components
545            get_parameters  - get the fitted parameters
546            plot            - plot the resulting fit and/or components and
547                              residual
548    [Plotter]
549        asapplotter         - a plotter for asap, default plotter is
550                              called 'plotter'
551            plot            - plot a scantable
552            plot_lines      - plot a linecatalog overlay
553            save            - save the plot to a file ('png' ,'ps' or 'eps')
554            set_mode        - set the state of the plotter, i.e.
555                              what is to be plotted 'colour stacked'
556                              and what 'panelled'
557            set_selection   - only plot a selected part of the data
558            set_range       - set a 'zoom' window [xmin,xmax,ymin,ymax]
559            set_legend      - specify user labels for the legend indeces
560            set_title       - specify user labels for the panel indeces
561            set_abcissa     - specify a user label for the abcissa
562            set_ordinate    - specify a user label for the ordinate
563            set_layout      - specify the multi-panel layout (rows,cols)
564            set_colors      - specify a set of colours to use
565            set_linestyles  - specify a set of linestyles to use if only
566                              using one color
567            set_font        - set general font properties, e.g. 'family'
568            set_histogram   - plot in historam style
569            set_mask        - set a plotting mask for a specific polarization
570            text            - draw text annotations either in data or relative
571                              coordinates
572            arrow           - draw arrow annotations either in data or relative
573                              coordinates
574            axhline,axvline - draw horizontal/vertical lines
575            axhspan,axvspan - draw horizontal/vertical regions
576
577        xyplotter           - matplotlib/pylab plotting functions
578
579    [Reading files]
580        reader              - access rpfits/sdfits files
581            open            - attach reader to a file
582            close           - detach reader from file
583            read            - read in integrations
584            summary         - list info about all integrations
585
586    [General]
587        commands            - this command
588        print               - print details about a variable
589        list_scans          - list all scantables created bt the user
590        list_files          - list all files readable by asap (default rpf)
591        del                 - delete the given variable from memory
592        range               - create a list of values, e.g.
593                              range(3) = [0,1,2], range(2,5) = [2,3,4]
594        help                - print help for one of the listed functions
595        execfile            - execute an asap script, e.g. execfile('myscript')
596        list_rcparameters   - print out a list of possible values to be
597                              put into $HOME/.asaprc
598        rc                  - set rc parameters from within asap
599        mask_and,mask_or,
600        mask_not            - boolean operations on masks created with
601                              scantable.create_mask
602
603    Note:
604        How to use this with help:
605                                         # function 'summary'
606        [xxx] is just a category
607        Every 'sub-level' in this list should be replaces by a '.' Period when
608        using help
609        Example:
610            ASAP> help scantable # to get info on ths scantable
611            ASAP> help scantable.summary # to get help on the scantable's
612            ASAP> help average_time
613
614            """
615        if rcParams['verbose']:
616            try:
617                from IPython.genutils import page as pager
618            except ImportError:
619                from pydoc import pager
620            pager(x)
621        else:
622            print x
623        return
624
625def welcome():
626    return """Welcome to ASAP v%s (%s) - the ATNF Spectral Analysis Package
627
628Please report any bugs via:
629http://svn.atnf.csiro.au/trac/asap/simpleticket
630
631[IMPORTANT: ASAP is 0-based]
632Type commands() to get a list of all available ASAP commands.""" % (__version__, __date__)
Note: See TracBrowser for help on using the repository browser.