source: trunk/python/__init__.py @ 1501

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

allow upgrade of ipython rc

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