source: trunk/python/__init__.py@ 1590

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

Introduced print_log_dec(orator)

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