Changeset 1757 for branches/alma
- Timestamp:
- 06/09/10 19:03:06 (15 years ago)
- Location:
- branches/alma
- Files:
-
- 35 added
- 4 deleted
- 81 edited
- 29 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/alma
-
Property svn:ignore
set to
.sconf_temp
.sconsign.dblite
-
Property svn:mergeinfo
set to
/branches/asap-3.x merged eligible
-
Property svn:ignore
set to
-
branches/alma/COPYING
r1042 r1757 1 Copyright (C) 2004 ,2005,20062 ATNF 1 Copyright (C) 2004-2009 2 CSIRO 3 3 4 4 This program is free software; you can redistribute it and/or modify it -
branches/alma/INSTALL
r1194 r1757 2 2 ============ 3 3 4 * scons 4 * scons >= 1.1 5 * rpfits >= 2.19 6 * cfitso >= 2 7 * python >= 2.4 8 * boost >= 1.37 9 * casacore >= 1.0 5 10 6 11 Installation … … 8 13 9 14 scons has several targets. It is recommended to execute them sequentially. 10 The normal install procedure is as follows: 11 . <path_to_casa_asap>/aipsinit.sh 15 The normal install procedure is as follows 16 .. code:: 17 12 18 scons 13 # Do this if you haven't got a data directory already19 # Do this if you haven't got a measures data directory already 14 20 export ASAPDATA=. 15 21 ./bin/asap_update_data … … 20 26 Obtaining the data directory 21 27 ============================ 22 The data repository can be obtained seperately after installing ASAP. 23 Before you run asap for the first time simply run 28 29 The data repository can be obtained separately after installing ASAP. 30 Before you run asap for the first time simply run:: 31 24 32 asap_update_data 33 25 34 This will install the data repository into the correct location. 26 35 27 36 There are several ways to do this. 28 a) If you already hae the 'data' directory, copy it to the root directory and run the normal install procedure. 37 a) If you already have the 'data' directory, copy it to the root directory and run the normal install procedure:: 38 29 39 scons 30 40 scons install 31 41 32 42 b) You can obtain the data repository from the ftp site. 33 Simply run 43 Simply run:: 44 34 45 export ASAPDATA=. 35 46 ./bin/asap_update_data 47 36 48 This will retrieve and unpack the data directory. 37 After this run: 49 After this run:: 50 38 51 scons install 39 52 … … 41 54 ============================== 42 55 43 after building using 'scons', you can create a compressed tarball of the binaries. This is done via the target 'makedist='. The argument should be an obvious identifier for the system you want to support, e.g. 'sarge' or 'fc5-x86_64' 56 after building using 'scons', you can create a compressed tarball of the binaries. This is done via the target 'makedist='. The argument should be an obvious identifier for the system you want to support, e.g. 'sarge' or 'fc5-x86_64':: 44 57 45 58 scons makedist=sarge -
branches/alma/SConstruct
r1377 r1757 6 6 7 7 moduledir = distutils.sysconfig.get_python_lib() 8 if platform.architecture()[0] == '64bit': 8 9 if sys.platform.startswith('linux') and platform.architecture()[0] == '64bit': 9 10 # hack to install into /usr/lib64 if scons is in the 32bit /usr/lib/ 10 11 if moduledir.startswith("/usr/lib/"): 11 12 moduledir = moduledir.replace("lib", "lib64") 12 13 13 opts = Options("options.cfg") 14 opts.AddOptions( 14 EnsureSConsVersion(1,1,0) 15 16 opts = Variables("options.cfg") 17 opts.AddVariables( 15 18 ("FORTRAN", "The fortran compiler", None), 16 19 ("f2clib", "The fortran to c library", None), 17 Path Option("prefix",20 PathVariable("prefix", 18 21 "The root installation path", 19 22 distutils.sysconfig.PREFIX), 20 Path Option("moduledir",23 PathVariable("moduledir", 21 24 "The python module path (site-packages))", 22 25 moduledir), 23 Path Option("casacoreroot", "The location of casacore",24 26 PathVariable("casacoreroot", "The location of casacore", 27 "/usr/local"), 25 28 ("boostroot", "The root dir where boost is installed", None), 26 29 ("boostlib", "The name of the boost python library", … … 45 48 ("cfitsiolib", "The cfitsio library name", "cfitsio"), 46 49 ("cfitsioincdir", "The cfitsio include location", None), 50 ("wcslib", "The wcs library name", "wcs"), 47 51 ("wcsroot", 48 52 "The root directory where wcs is installed", None), … … 52 56 "The root directory where rpfits is installed", None), 53 57 ("rpfitslibdir", "The rpfits library location", None), 54 # ("rpfitsincdir", "The rpfits include location", None), 55 EnumOption("mode", "The type of build.", "debug", 58 ("pyraproot", "The root directory where libpyrap is installed", 59 None), 60 ("pyraplib", "The name of the pyrap library", "pyrap"), 61 ("pyraplibdir", "The directory where libpyrap is installed", 62 None), 63 ("pyrapincdir", "The pyrap include location", 64 None), 65 BoolVariable("enable_pyrap", "Use pyrap conversion library", 66 False), 67 68 EnumVariable("mode", "The type of build.", "release", 56 69 ["release","debug"], ignorecase=1), 57 70 ("makedist", 58 71 "Make a binary archive giving a suffix, e.g. sarge or fc5", 59 72 ""), 60 Enum Option("makedoc", "Build the userguide in specified format",73 EnumVariable("makedoc", "Build the userguide in specified format", 61 74 "none", 62 ["none", "pdf", "html"], ignorecase=1) 75 ["none", "pdf", "html"], ignorecase=1), 76 BoolVariable("apps", "Build cpp apps", True), 77 BoolVariable("alma", "Enable alma specific functionality", 78 False), 63 79 ) 64 80 … … 73 89 env.SConsignFile() 74 90 75 if env["PLATFORM"] == "darwin":76 env.EnsureSConsVersion(0,96,95)77 78 91 casacoretooldir = os.path.join(env["casacoreroot"],"share", 79 92 "casacore") … … 83 96 84 97 # load casacore specific build flags 98 env.Tool('casaoptions', [casacoretooldir]) 99 opts.Update(env) 85 100 env.Tool('casa', [casacoretooldir]) 86 101 … … 93 108 "include", "casacore")) 94 109 if not conf.CheckLib("casa_casa", language='c++'): Exit(1) 95 conf.env.PrependUnique(LIBS=["casa_ ms", "casa_components",110 conf.env.PrependUnique(LIBS=["casa_images", "casa_ms", "casa_components", 96 111 "casa_coordinates", "casa_lattices", 97 112 "casa_fits", "casa_measures", "casa_scimath", … … 108 123 109 124 conf.env.AddCustomPackage('boost') 110 if not conf.CheckLibWithHeader( env["boostlib"],125 if not conf.CheckLibWithHeader(conf.env["boostlib"], 111 126 'boost/python.hpp', language='c++'): 112 127 Exit(1) 128 129 conf.env.AddCustomPackage('pyrap') 130 if conf.env.get("enable_pyrap") and conf.CheckLib(conf.env["pyraplib"], 131 language='c++', 132 autoadd=0): 133 conf.env.Append(CPPFLAGS=['-DHAVE_PYRAP']) 134 conf.env.PrependUnique(LIBS=env['pyraplib']) 135 113 136 # test for cfitsio 114 137 if not conf.CheckLib("m"): Exit(1) … … 118 141 Exit(1) 119 142 conf.env.AddCustomPackage('wcs') 120 if not conf.CheckLibWithHeader('wcs', 'wcslib/wcs.h', language='c'): 143 if not conf.CheckLibWithHeader(conf.env["wcslib"], 144 'wcslib/wcs.h', language='c'): 121 145 Exit(1) 122 146 conf.env.AddCustomPackage('rpfits') … … 125 149 126 150 # test for blas/lapack 151 lapackname = conf.env.get("lapacklib", "lapack") 127 152 conf.env.AddCustomPackage("lapack") 128 if not conf.CheckLib( conf.env["lapacklib"]): Exit(1)153 if not conf.CheckLib(lapackname): Exit(1) 129 154 blasname = conf.env.get("blaslib", "blas") 130 155 conf.env.AddCustomPackage("blas") 131 if not conf.CheckLib( conf.env["blaslib"]): Exit(1)156 if not conf.CheckLib(blasname): Exit(1) 132 157 conf.env.CheckFortran(conf) 133 158 if not conf.CheckLib('stdc++', language='c++'): Exit(1) 159 if conf.env["alma"]: 160 conf.env.Append(CPPFLAGS=['-DUSE_ALMA']) 134 161 env = conf.Finish() 135 162 136 env["version"] = " 2.2.x"163 env["version"] = "3.0.0" 137 164 138 165 if env['mode'] == 'release': … … 141 168 env.Append(CCFLAGS=["-O2"]) 142 169 else: 143 env.Append(CCFLAGS=["-g" ])170 env.Append(CCFLAGS=["-g", "-Wall"]) 144 171 145 172 # Export for SConscript files … … 165 192 166 193 # install targets 167 somod = env.Install("$moduledir/asap", so ) 168 pymods = env.Install("$moduledir/asap", env.SGlob("python/*.py")) 169 bins = env.Install("$prefix/bin", ["bin/asap", "bin/asap_update_data"]) 170 shares = env.Install("$moduledir/asap/data", "share/ipythonrc-asap") 171 env.Alias('install', [somod, pymods, bins, shares]) 194 installs = [] 195 installs.append(env.Install("$moduledir/asap", so)) 196 installs.append(env.Install("$moduledir/asap", env.SGlob("python/*.py"))) 197 installs.append(env.Install("$prefix/bin", 198 ["bin/asap", "bin/asap_update_data"])) 199 installs.append(env.Install("$moduledir/asap/data", "share/ipythonrc-asap")) 200 installs.append(env.Install("$moduledir/asap/data", "share/ipy_user_conf.py")) 201 env.Alias('install', installs) 172 202 173 203 # install aips++ data repos 174 rootdir =None204 rootdir = None 175 205 outdir = os.path.join(env["moduledir"],'asap','data') 176 206 sources = ['ephemerides','geodetic'] … … 193 223 env.QInstall("$stagedir", ["bin/install"]) 194 224 env.QInstall("$stagedir/asap/data", "share/ipythonrc-asap") 225 env.QInstall("$stagedir/asap/data", "share/ipy_user_conf.py") 195 226 if rootdir is not None: 196 227 # This creates a directory Using data table... - disabled … … 209 240 env.SConscript("doc/SConscript") 210 241 242 if env["apps"]: 243 env.SConscript("apps/SConscript") 244 211 245 if env.GetOption("clean"): 212 246 Execute(Delete(".sconf_temp")) -
branches/alma/bin/asap
r1210 r1757 51 51 fi 52 52 # now execute ipython using the profile 53 $ip -ipythondir "${HOME}/.asap" -p 'asap'$*53 $ip -ipythondir "${HOME}/.asap" $* 54 54 fi -
branches/alma/bin/install
r1232 r1757 18 18 lddopts = "" 19 19 if (sys.platform == "darwin"): 20 lddcommand = " otool"20 lddcommand = "/usr/bin/otool" 21 21 lddopts = "-L" 22 22 if not os.path.isfile(lddcommand): … … 27 27 resolved = [] 28 28 unresolved = [] 29 for l in p.readlines(): 30 lsp = l.split() 31 # test this to avoid fails on linux_gate, which has no library 32 if len(lsp) >= 3: 33 if lsp[2] == "not": 34 unresolved.append(lsp[0]) 29 if sys.platform == "linux2": 30 for l in p.readlines(): 31 lsp = l.split() 32 # test this to avoid fails on linux_gate, which has no library 33 if len(lsp) >= 3: 34 if lsp[2] == "not": 35 unresolved.append(lsp[0]) 36 else: 37 resolved.append(lsp[2]) 38 elif sys.platform == "darwin": 39 for l in p.readlines(): 40 l = l.strip() 41 if l.endswith(":"): 42 continue 43 l = l.split()[0] 44 if not os.path.exists(l): 45 unresolved.append(l) 35 46 else: 36 resolved.append(l sp[2])47 resolved.append(l) 37 48 return resolved, unresolved 49 38 50 39 51 try: … … 122 134 print "Installing asap scripts in %s" % bindir 123 135 if moduledir != sysmoduledir: 124 import sre136 import re 125 137 print "Changing asap startup script to use custom PYTHONPATH" 126 138 inf = file("bin/asap") … … 137 149 shutil.copy2("bin/asap", bindir) 138 150 shutil.copy2("bin/asap_update_data", bindir) 151 shutil.copy2("bin/asap2to3", bindir) 139 152 if not os.path.exists("asap/data/ephemerides"): 140 153 print "Warning - no data directory present" -
branches/alma/doc/CHANGELOG
r1381 r1757 2 2 ========= 3 3 4 Release 2.2.1 [2007-??-??]4 Release 3.0.0 [2010-05-06] 5 5 6 * source direction for Hobart data - Ticket #109 7 * added running median to scantable.(smooth(kernel='rmedian') 6 * BEWARE: added asap2to3 which converts '.asap' files from version 2 to 7 version 3 8 * Ticket #183 Added scantable.get_weather 9 * Ticket #181 Added work-around for casacore bug in saving tables with 10 selection 11 * Ticket #178 Added opacity_model based on miriad's atmospheric model 12 * Ticket #177 Added function skydip to determine opacities. 13 * Ticket #172 Fixed non-working scantable.resample 14 * Ticket #155 Better output filenames. Ignore non-existsing 15 beams/pols/ifs/scans 16 * Ticket #157 numpy >= 1.1 support 17 * Ticket #158 fixed plotter.set_font 18 * Ticket #160 Aspect ratio of plotter is customisable now 19 * Ticket #163 fixed for scantable.set_sourcetype 20 * Ticket #164 Upgrade note in wiki FAQ 21 * Ticket #165 Handle non-parallactified polarimtery data (if supported in 22 rpfits) 23 * Ticket #167 Added running polynomial filter to scantable.smooth 24 * Ticket #168 Data exported via scantable.save now contains correct frequency 25 or velocity information 26 * Ticket #169 Simplified selection of data 27 * Ticket #46 Interactive lag flagging 28 * Ticket #170 Provided access to frequency coordinate information via 29 scantable.get_coordinate 30 * Added OS X 10.5 Disk image installer 31 * Added support for OS X 10.6 32 * Interactive plotting annotations via optional argument interactive=True 33 * Interactive creation of masks on the plotter - plotter.create_mask 34 * Tidy up date range in asapplotter.plotazel/plotpointings 35 * support for gcc-4.4 36 37 Release 2.3.1 [2009-03-25] 38 39 * Ticket #154 Flagged data wasn't hnoured in fitting 40 * Ticket #153 plotter.plot_lines fixed for matplotlib >= 0.98 41 * Ticket #90 Support integer values for frequencies/errors/intensities 42 43 Release 2.3.0 [2009-03-13] 44 45 * Ticket #150 fix in casacore for frequency frame conversions 46 * Ticket #151 added rc parameter and function set_sourcetype to identify 47 on/off scans 48 * Ticket #78/#112 Resolved the issue with random errors occuring under linux 49 for large 50 data files, which corrupted the identifaction of off scans 51 * Ticket #149 Fixed the bug causing spectral line search to go into an 52 infinite loop in some rare circumstances 53 * Ticket #110 Added export to CLASS readable FITS files 54 scantable.save("myfile.fits", "CLASS") 55 * Ticket #142 Fix of the frequency alignment for long observations 56 * Ticket #133 allow supression of history in the scantable via rc parameters 57 * Ticket #109 source direction for Hobart data 58 * Ticket #115 added running median to scantable.(smooth(kernel='rmedian') 59 * Ticket #148 opacity correction wasn't applied to TSYS 60 * Ticket #135 quotient detection failure for specific source names 61 * Ticket #140 NaN values not handled - added scantable.flag_nans to ensure 62 that the NaN are flagged 63 * added python iterator access to scantable rows 64 * made functions available to directly manipulate spectra 65 scantable.get/set_spectrum 66 * upgrade to support ipython >= 0.8.1 67 * support gcc-4.3 68 * use scons >= 1.1.0 69 * update to latest livedata I/O functions 70 * add WCS info to the exported text files 71 8 72 9 73 Release 2.2.0 [2007-05-02] … … 28 92 * fix for Ticket #88 - numpy masks 29 93 * better TAB completion for ipython (handles quotes, don't list private members) 30 * Fix for Ticket #81 = scanatble.stats output as list 94 * Fix for Ticket #81 = scanatble.stats output as list 31 95 * ticket #64 - speed up of auto_poly_baseline 32 96 * fix for ticket #89 - export of IF sub-selections -
branches/alma/doc/userguide.tex
r1347 r1757 13 13 \setlength{\parskip}{1ex} 14 14 15 \title{ATNF Spectral Analysis Package\\User Guide v2. 1\\DRAFT}15 \title{ATNF Spectral Analysis Package\\User Guide v2.3 } 16 16 \author{Chris Phillips} 17 17 … … 48 48 package. 49 49 50 This userguide has been updated for the ASAP 2. 1. Please report any50 This userguide has been updated for the ASAP 2.3. Please report any 51 51 mistakes you find. 52 52 … … 58 58 \item Epping - use hosts {\tt draco} or {\tt hydra} 59 59 \item Narrabri - use host {\tt kaputar} 60 \item Parkes - use host {\tt bourbon}61 \item Mopra - use host {\tt minos} 60 \item Parkes - use host {\tt ?} 61 \item Mopra - use host {\tt minos} or {\tt kaputar} if at Narrabri 62 62 \end{itemize} 63 63 64 64 Or use your own Linux desktop. 65 65 66 {\em Note. ASAP2. 1only runs on ATNF Linux machines which have been66 {\em Note. ASAP2.2 only runs on ATNF Linux machines which have been 67 67 updated to Debian Sarge and are using the ``DEBIANSarge'' 68 68 /usr/local. If your favourite machine has not been upgraded, send a 69 request to your friendly IT support. At the time of writing asap 2.1 70 does not run on hydra, bourbon or kaputar.} 69 request to your friendly IT support.} 71 70 72 71 \index{Running}To start asap log onto one of these Linux hosts and enter … … 166 165 is un-ambiguous, or a list of possibilities will be 167 166 given. Auto-completion works for the user object names as well as 168 function names . It does not work for filenames, nor for function167 function names and even file names It does not work for for function 169 168 arguments. 170 169 … … 210 209 ASAP>ls 211 210 ASAP>cd /my/data/directory 212 ASAP>! mozilla&211 ASAP>! firefox& 213 212 \end{verbatim} 214 213 … … 352 351 353 352 # Equivalent to brief summary function call 354 ASAP>print scan 353 ASAP>print scans 355 354 \end{verbatim} 356 355 … … 422 421 ASAP>selection.reset() # Turn off selection 423 422 ASAP>scans.set_selection(selection) # Apply the reset selection 423 ASAP>scans.set_selection() # alternative to reset selection 424 424 425 425 \end{verbatim} … … 460 460 \begin{verbatim} 461 461 ASAP>scans = scantable('2004-11-23_1841-P484.rpf') # Read in the data 462 ASAP>scans.set_freqframe('LSRK') # Use the LSR velocity frame462 ASAP>scans.set_freqframe('LSRK') # Use the LSR velocity frame 463 463 ASAP>scans.set_unit('km/s') # Use velocity for plots etc from now on 464 464 ASAP>scans.set_doppler('OPTICAL') # Use the optical velocity convention … … 528 528 529 529 # Select channel range for baselining 530 ASAP>scans.set_unit('channel s')530 ASAP>scans.set_unit('channel') 531 531 ASAP>msk = scans.create_mask([100,400],[600,800]) 532 532 … … 542 542 Example : 543 543 \begin{verbatim} 544 ASAP>scans.set_unit('channel s')544 ASAP>scans.set_unit('channel') 545 545 ASAP>msk = scans.create_mask([0,100],[900-1023], invert=True) 546 546 \end{verbatim} … … 562 562 563 563 \begin{verbatim} 564 ASAP>scans.set_unit('channel s')564 ASAP>scans.set_unit('channel') 565 565 ASAP>msk1 = q.create_mask([0,100],[511,511],[900,1023],invert=True) 566 566 ASAP>scans.set_unit('km/s') … … 614 614 615 615 616 \subsection{Reader object}617 618 \index{Reader object}\index{Scantable!reader object}For more control619 when reading data into ASAP, the reader object should be used. This620 has the option of only reading in a range of integrations, only a621 specified beam or IF and does not perform any scan averaging of the622 data, allowing analysis of the individual integrations. Note that due623 to limitation of the RPFITS library, only one reader object can be624 open at one time reading RPFITS files. To read multiple RPFITS files,625 the old reader must be destroyed before the new file is opened.626 However, multiple readers can be created and attached to SDFITS files.627 628 629 Example usage:630 631 \begin{verbatim}632 ASAP>r = reader('2003-03-16_082048_t0002.rpf')633 ASAP>r.summary()634 ASAP>scan = r.read()635 ASAP>del r636 \end{verbatim}616 %\subsection{Reader object} 617 618 %\index{Reader object}\index{Scantable!reader object}For more control 619 %when reading data into ASAP, the reader object should be used. This 620 %has the option of only reading in a range of integrations, only a 621 %specified beam or IF and does not perform any scan averaging of the 622 %data, allowing analysis of the individual integrations. Note that due 623 %to limitation of the RPFITS library, only one reader object can be 624 %open at one time reading RPFITS files. To read multiple RPFITS files, 625 %the old reader must be destroyed before the new file is opened. 626 %However, multiple readers can be created and attached to SDFITS files. 627 % 628 % 629 %Example usage: 630 % 631 %\begin{verbatim} 632 % ASAP>r = reader('2003-03-16_082048_t0002.rpf') 633 % ASAP>r.summary() 634 % ASAP>scan = r.read() 635 % ASAP>del r 636 %\end{verbatim} 637 637 638 638 \section{Basic Processing} … … 649 649 have a trailing ``\_R'' in the source name for data from Parkes and 650 650 Mopra, and a trailing ``e'' or ``w'' for data from Tidbinbilla. 651 This functions has two \cmd{mode}s. \cmd{paired} (the de afault), which assumes651 This functions has two \cmd{mode}s. \cmd{paired} (the default), which assumes 652 652 matching adjacent pairs of source/reference scans and \cmd{time}, which finds 653 653 the closest reference scan in time. … … 835 835 telescope is wrong due to an incorrect noise diode calibration. This 836 836 can easily be corrected for with the scale function. By default, 837 \cmd{scale} only sca ns the spectra and not the corresponding Tsys.837 \cmd{scale} only scaless the spectra and not the corresponding Tsys. 838 838 839 839 \begin{verbatim} … … 871 871 \begin{verbatim} 872 872 ASAP>scans.recalc_azel() # recalculate az/el 873 873 # based on pointing 874 874 \end{verbatim} 875 875 … … 962 962 \end{verbatim} 963 963 964 One can also apply the inverse of \cmd{get\_scan} \cmd{drop\_scan} 965 964 966 To copy a scantable the following does not work: 965 967 … … 994 996 it. 995 997 996 %\item[FITS] This uses simple ``image'' fits to save the data, each row 997 % being written to a separate fits file. This format is suitable for 998 % importing the data into CLASS. 998 \item[FITS] This uses simple ``image'' fits to save the data, each row 999 being written to a separate fits file. 1000 1001 \item[CLASS] This uses simple ``image'' fits to save the data, each row 1002 being written to a separate fits file. This format has modification so it 1003 is suitable for importing the data into CLASS. 999 1004 1000 1005 \item[ASCII] A simple text based format suitable for the user to … … 1402 1407 \end{verbatim} 1403 1408 1404 For data with many IFs, such as from MOPS, the userit is recommended1405 that the user creates their own line cstalogfor the data and use this1409 For data with many IFs, such as from MOPS, it is recommended 1410 that users creates their own line catalog table for the data and use this 1406 1411 to set the rest frequency for each IF. 1407 1412 … … 1658 1663 size of the dataset which can be loaded. ASAP can use ``disk based'' 1659 1664 scan tables which cache the bulk of the scantable on disk and require 1660 significantly less memory usage. 1665 significantly less memory usage. This should be used for all MOPS data! 1661 1666 1662 1667 To use disk based tables you either need to change the default in your … … 1679 1684 {\bf NOTE: } Currently a bug in ipython means temporary files are not 1680 1685 cleaned up properly when you exit ASAP. If you use disk based scan 1681 tables your directory will be left with 't abXXXXX\_X' directories. These can1686 tables your directory will be left with 'tmpXXXXX\_X' directories. These can 1682 1687 be safely removed if ASAP is not running. 1683 1688 … … 1692 1697 {\em Currently mathematics between two scantables is not available } 1693 1698 1694 % ASAP>sum = scan1+scan21695 1699 \begin{verbatim} 1696 1700 ASAP>scan2 = scan1+2.0 1697 1701 ASAP>scan *= 1.05 1702 ASAP>sum = scan1+scan2 1698 1703 \end{verbatim} 1699 1704 … … 1713 1718 1714 1719 \hspace{1cm} http://www.python.org/doc/Introduction.html 1720 1721 \hspace{1cm} http:/ipython.scipy.org 1715 1722 1716 1723 \subsection{Running scripts} -
branches/alma/external/atnf/PKSIO/FITSreader.cc
r1453 r1757 2 2 //# FITSreader.cc: ATNF single-dish FITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: FITSreader.cc,v 19.4 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The FITSreader class is an abstract base class for the Parkes Multibeam … … 53 55 const int getSpectra, 54 56 const int getXPol, 55 const int getFeedPos) 57 const int getFeedPos, 58 const int getPointing, 59 const int coordSys) 56 60 { 57 61 int maxNChan = 0; … … 84 88 cGetXPol = getXPol && cGetXPol; 85 89 cGetFeedPos = getFeedPos; 90 cCoordSys = coordSys; 91 86 92 87 93 return maxNChan; -
branches/alma/external/atnf/PKSIO/FITSreader.h
r1453 r1757 2 2 //# FITSreader.h: ATNF single-dish FITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: FITSreader.h,v 19.11 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The FITSreader class is an abstract base class for the Parkes Multibeam … … 38 40 #define ATNF_FITSREADER_H 39 41 40 #include <atnf/PKSIO/PKSMBrecord.h> 42 #include <atnf/PKSIO/MBrecord.h> 43 44 using namespace std; 45 41 46 42 47 // <summary> … … 44 49 // </summary> 45 50 51 //class FITSreader 46 52 class FITSreader 47 53 { … … 74 80 double antPos[3], 75 81 char obsType[32], 82 char bunit[32], 76 83 float &equinox, 77 84 char radecsys[32], … … 90 97 // Set data selection criteria. Channel numbering is 1-relative, zero or 91 98 // negative channel numbers are taken to be offsets from the last channel. 99 // Coordinate systems are 100 // 0: equatorial (RA,Dec), 101 // 1: horizontal (Az,El), 102 // 2: feed-plane, 103 // 3: zenithal position angle of feed and elevation, (ZPA,El). 92 104 int select( 93 105 const int startChan[], … … 96 108 const int getSpectra = 1, 97 109 const int getXPol = 0, 98 const int getFeedPos = 0); 110 const int getFeedPos = 0, 111 const int getPointing = 0, 112 const int coordSys = 0); 113 99 114 100 115 // Find the range in time and position of the data selected. … … 108 123 // Read the next data record. 109 124 virtual int read( 110 PKSMBrecord &record) = 0; 125 // PKSMBrecord &record) = 0; 126 MBrecord &record) = 0; 111 127 112 128 // Close the RPFITS file. … … 114 130 115 131 protected: 116 int *cBeams, *cEndChan, cGetFeedPos, cGetSpectra, cGetXPol, cHaveBase, 117 cHaveSpectra, *cHaveXPol, *cIFs, cNBeam, *cNChan, cNIF, *cNPol, 118 *cRefChan, *cStartChan; 132 int *cBeams, *cEndChan, cGetFeedPos, cCoordSys, cGetSpectra, cGetXPol, 133 cHaveBase, cHaveSpectra, *cHaveXPol, *cIFs, cNBeam, *cNChan, cNIF, 134 *cNPol, *cRefChan, *cStartChan; 135 136 // For use in constructing messages. 137 char cMsg[256]; 138 119 139 }; 120 140 -
branches/alma/external/atnf/PKSIO/MBFITSreader.cc
r1453 r1757 2 2 //# MBFITSreader.cc: ATNF single-dish RPFITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: MBFITSreader.cc,v 19.57 2009-10-30 06:34:36 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The MBFITSreader class reads single dish RPFITS files (such as Parkes … … 35 37 //#--------------------------------------------------------------------------- 36 38 39 #include <atnf/pks/pks_maths.h> 37 40 #include <atnf/PKSIO/MBFITSreader.h> 38 #include <atnf/PKSIO/ PKSMBrecord.h>39 40 #include < RPFITS.h>41 #include <atnf/PKSIO/MBrecord.h> 42 43 #include <casa/Logging/LogIO.h> 41 44 42 45 #include <casa/math.h> … … 47 50 #include <unistd.h> 48 51 52 #include <RPFITS.h> 53 49 54 using namespace std; 50 55 … … 52 57 const double PI = 3.141592653589793238462643; 53 58 const double TWOPI = 2.0 * PI; 59 const double HALFPI = PI / 2.0; 60 const double R2D = 180.0 / PI; 61 62 // Class name 63 const string className = "MBFITSreader" ; 54 64 55 65 //------------------------------------------------- MBFITSreader::MBFITSreader … … 81 91 cRefChan = 0x0; 82 92 83 cVis = new float[2*4*8163]; 93 cVis = 0x0; 94 cWgt = 0x0; 84 95 85 96 cBeamSel = 0x0; … … 91 102 92 103 cMBopen = 0; 93 jstat = -3; 104 105 // Tell RPFITSIN not to report errors directly. 106 //iostat_.errlun = -1; 94 107 } 95 108 … … 120 133 int &extraSysCal) 121 134 { 135 const string methodName = "open()" ; 136 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 137 122 138 if (cMBopen) { 123 139 close(); … … 127 143 128 144 // Open the RPFITS file. 129 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 130 &if_no, &sourceno); 131 132 if (jstat) { 133 fprintf(stderr, "Failed to open MBFITS file: %s\n", rpname); 145 int jstat = -3; 146 if (rpfitsin(jstat)) { 147 sprintf(cMsg, "Failed to open MBFITS file\n%s", rpname); 148 os << LogIO::SEVERE << cMsg << LogIO::POST ; 134 149 return 1; 135 150 } … … 147 162 // Read the first header. 148 163 jstat = -1; 149 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 150 &if_no, &sourceno); 151 152 if (jstat) { 153 fprintf(stderr, "Failed to read MBFITS header: %s\n", rpname); 164 if (rpfitsin(jstat)) { 165 sprintf(cMsg, "Failed to read MBFITS header in file\n" 166 "%s", rpname); 167 os << LogIO::SEVERE << cMsg << LogIO::POST ; 154 168 close(); 155 169 return 1; … … 159 173 cMopra = strncmp(names_.instrument, "ATMOPRA", 7) == 0; 160 174 161 // Tidbinbilla data has some more. 162 cTid = strncmp(names_.sta, "tid", 3) == 0; 163 if (cTid) { 164 // Telescope position is stored in the source table. 175 // Non-ATNF data may not store the position in (u,v,w). 176 if (strncmp(names_.sta, "tid", 3) == 0) { 177 sprintf(cMsg, "Found Tidbinbilla data"); 178 cSUpos = 1; 179 } else if (strncmp(names_.sta, "HOB", 3) == 0) { 180 sprintf(cMsg, "Found Hobart data"); 181 cSUpos = 1; 182 } else if (strncmp(names_.sta, "CED", 3) == 0) { 183 sprintf(cMsg, "Found Ceduna data"); 184 cSUpos = 1; 185 } else { 186 cSUpos = 0; 187 } 188 189 if (cSUpos) { 190 strcat(cMsg, ", using telescope position\n from SU table."); 191 os << LogIO::WARN << cMsg << LogIO::POST ; 165 192 cInterp = 0; 166 193 } 194 195 // Mean scan rate (for timestamp repairs). 196 cNRate = 0; 197 cAvRate[0] = 0.0; 198 cAvRate[1] = 0.0; 199 cCode5 = 0; 167 200 168 201 … … 176 209 177 210 if (cNBeam <= 0) { 178 fprintf(stderr, "Couldn't determine number of beams.\n");211 os << LogIO::SEVERE << "Couldn't determine number of beams." << LogIO::POST ; 179 212 close(); 180 213 return 1; … … 189 222 // ...beams present in the data. 190 223 for (int iBeam = 0; iBeam < anten_.nant; iBeam++) { 191 cBeams[anten_.ant_num[iBeam] - 1] = 1; 224 // Guard against dubious beam numbers, e.g. zeroes in 225 // 1999-09-29_1632_024848p14_071b.hpf and the four scans following. 226 // Note that the actual beam number is decoded from the 'baseline' random 227 // parameter for each spectrum and is only used for beam selection. 228 int beamNo = anten_.ant_num[iBeam]; 229 if (beamNo != iBeam+1) { 230 char sta[8]; 231 strncpy(sta, names_.sta+(8*iBeam), 8); 232 char *cp = sta + 7; 233 while (*cp == ' ') *(cp--) = '\0'; 234 235 sprintf(cMsg, 236 "RPFITSIN returned beam number %2d for AN table\n" 237 "entry %2d with name '%.8s'", beamNo, iBeam+1, sta); 238 239 char text[8]; 240 sprintf(text, "MB%2.2d", iBeam+1); 241 cp = cMsg + strlen(cMsg); 242 if (strncmp(sta, text, 8) == 0) { 243 beamNo = iBeam + 1; 244 sprintf(cp, "; using beam number %2d.", beamNo); 245 } else { 246 sprintf(cp, "."); 247 } 248 249 os << LogIO::WARN << cMsg << LogIO::POST ; 250 } 251 252 if (0 < beamNo && beamNo <= cNBeam) { 253 cBeams[beamNo-1] = 1; 254 } 192 255 } 193 256 … … 237 300 } 238 301 239 // Is the vis array declared by RPFITS.h large enough?240 if ( 8*8193 < maxProd) {241 // Need to allocate more memory for RPFITSIN.242 243 }302 // Allocate memory for RPFITSIN subroutine arguments. 303 if (cVis) delete [] cVis; 304 if (cWgt) delete [] cWgt; 305 cVis = new float[2*maxProd]; 306 cWgt = new float[maxProd]; 244 307 245 308 nChan = cNChan; … … 278 341 // Read the first syscal record. 279 342 if (rpget(1, cEOS)) { 280 fprintf(stderr, "Error: Failed to read first syscal record.\n");343 os << LogIO::SEVERE << "Failed to read first syscal record." << LogIO::POST ; 281 344 close(); 282 345 return 1; … … 304 367 double antPos[3], 305 368 char obsType[32], 369 char bunit[32], 306 370 float &equinox, 307 371 char radecsys[32], … … 312 376 double &bandwidth) 313 377 { 378 const string methodName = "getHeader()" ; 379 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 380 314 381 if (!cMBopen) { 315 fprintf(stderr, "An MBFITS file has not been opened.\n");382 os << LogIO::SEVERE << "An MBFITS file has not been opened." << LogIO::POST ; 316 383 return 1; 317 384 } … … 333 400 antPos[1] = 2816759.046; 334 401 antPos[2] = -3454035.950; 402 335 403 } else if (strncmp(names_.sta, "HOH", 3) == 0) { 336 404 // Parkes HOH receiver. … … 339 407 antPos[1] = 2816759.046; 340 408 antPos[2] = -3454035.950; 409 341 410 } else if (strncmp(names_.sta, "CA0", 3) == 0) { 342 411 // An ATCA antenna, use the array centre position. … … 345 414 antPos[1] = 2792906.182; 346 415 antPos[2] = -3200483.747; 416 417 // ATCA-104. Updated position at epoch 2007/06/24 from Chris Phillips. 418 // antPos[0] = -4751640.182; // ± 0.008 419 // antPos[1] = 2791700.322; // ± 0.006 420 // antPos[2] = -3200490.668; // ± 0.007 421 // 347 422 } else if (strncmp(names_.sta, "MOP", 3) == 0) { 348 // Mopra. 423 // Mopra. Updated position at epoch 2007/06/24 from Chris Phillips. 349 424 sprintf(telescope, "%-16.16s", "ATMOPRA"); 350 antPos[0] = -4682768.630; 351 antPos[1] = 2802619.060; 352 antPos[2] = -3291759.900; 425 antPos[0] = -4682769.444; // ± 0.009 426 antPos[1] = 2802618.963; // ± 0.006 427 antPos[2] = -3291758.864; // ± 0.008 428 353 429 } else if (strncmp(names_.sta, "HOB", 3) == 0) { 354 430 // Hobart. … … 357 433 antPos[1] = 2522347.567; 358 434 antPos[2] = -4311562.569; 435 359 436 } else if (strncmp(names_.sta, "CED", 3) == 0) { 360 // Ceduna. 437 // Ceduna. Updated position at epoch 2007/06/24 from Chris Phillips. 361 438 sprintf(telescope, "%-16.16s", "CEDUNA"); 362 antPos[0] = -3749943.657; 363 antPos[1] = 3909017.709; 364 antPos[2] = -3367518.309; 439 antPos[0] = -3753443.168; // ± 0.017 440 antPos[1] = 3912709.794; // ± 0.017 441 antPos[2] = -3348067.060; // ± 0.016 442 365 443 } else if (strncmp(names_.sta, "tid", 3) == 0) { 366 444 // DSS. … … 379 457 obsType[j] = '\0'; 380 458 459 // Brightness unit. 460 sprintf(bunit, "%-16.16s", names_.bunit); 461 if (strcmp(bunit, "JY") == 0) { 462 bunit[1] = 'y'; 463 } else if (strcmp(bunit, "JY/BEAM") == 0) { 464 strcpy(bunit, "Jy/beam"); 465 } 466 381 467 // Coordinate frames. 382 468 equinox = 2000.0f; … … 386 472 // Time at start of observation. 387 473 sprintf(datobs, "%-10.10s", names_.datobs); 388 utc = ut;474 utc = cUTC; 389 475 390 476 // Spectral parameters. … … 425 511 //--------------------------------------------------------- MBFITSreader::read 426 512 427 // Read the next data record .513 // Read the next data record (if you're feeling lucky). 428 514 429 515 int MBFITSreader::read( 430 PKSMBrecord &MBrec)516 MBrecord &MBrec) 431 517 { 518 const string methodName = "read()" ; 519 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 520 432 521 int beamNo = -1; 433 int haveData, status; 434 PKSMBrecord *iMBuff = 0x0; 522 int haveData, pCode = 0, status; 523 double raRate = 0.0, decRate = 0.0, paRate = 0.0; 524 MBrecord *iMBuff = 0x0; 435 525 436 526 if (!cMBopen) { 437 fprintf(stderr, "An MBFITS file has not been opened.\n");527 os << LogIO::SEVERE << "An MBFITS file has not been opened." << LogIO::POST ; 438 528 return 1; 439 529 } 440 530 441 // Positions recorded in the input records do not coincide with the midpoint442 // of the integration and hence the input must be buffered so that true443 // positions may be interpolated.531 // Positions recorded in the input records usually do not coincide with the 532 // midpoint of the integration and hence the input must be buffered so that 533 // true positions may be interpolated. 444 534 // 445 535 // On the first call nBeamSel buffers of length nBin, are allocated and … … 471 561 472 562 // Read the next record. 563 pCode = 0; 473 564 if ((status = rpget(0, cEOS)) == -1) { 474 565 // EOF. … … 479 570 480 571 #ifdef PKSIO_DEBUG 481 printf("End-of-file detected, flushing last scan.\n");572 os << LogIO::DEBUGGING << "\nEnd-of-file detected, flushing last cycle.\n" << LogIO::POST ; 482 573 #endif 483 574 … … 507 598 cXpolOff = new int[cNIF]; 508 599 509 int simulIF = 0;510 600 int maxChan = 0; 511 601 int maxXpol = 0; 512 602 603 cSimulIF = 0; 513 604 for (int iIF = 0; iIF < cNIF; iIF++) { 514 605 if (cIFs[iIF]) { … … 536 627 537 628 // Maximum number of selected IFs in any simultaneous set. 538 simulIF = max(simulIF, cIFSel[iIF]+1);629 cSimulIF = max(cSimulIF, cIFSel[iIF]+1); 539 630 540 631 // Maximum memory required for any simultaneous set. … … 563 654 564 655 if (cNBin > 1 && cNBeamSel > 1) { 565 fprintf(stderr, "Cannot handle binning mode for multiple " 566 "beams.\n"); 656 os << LogIO::SEVERE << "Cannot handle binning mode for multiple beams.\nSelect a single beam for input." << LogIO::POST ; 567 657 close(); 568 658 return 1; 569 659 } 570 660 571 // Allocate buffer data storage. 661 // Allocate buffer data storage; the MBrecord constructor zeroes 662 // class members such as cycleNo that are tested in the first pass 663 // below. 572 664 int nBuff = cNBeamSel * cNBin; 573 cBuffer = new PKSMBrecord[nBuff];665 cBuffer = new MBrecord[nBuff]; 574 666 575 667 // Allocate memory for spectral arrays. 576 668 for (int ibuff = 0; ibuff < nBuff; ibuff++) { 577 cBuffer[ibuff].setNIFs( simulIF);669 cBuffer[ibuff].setNIFs(cSimulIF); 578 670 cBuffer[ibuff].allocate(0, maxChan, maxXpol); 671 672 // Signal that this IF in this buffer has been flushed. 673 for (int iIF = 0; iIF < cSimulIF; iIF++) { 674 cBuffer[ibuff].IFno[iIF] = 0; 675 } 579 676 } 580 677 … … 584 681 cScanNo = 1; 585 682 cCycleNo = 0; 586 cUTC = 0.0; 587 cStaleness = new int[cNBeamSel]; 588 for (int iBeamSel = 0; iBeamSel < cNBeamSel; iBeamSel++) { 589 cStaleness[iBeamSel] = 0; 590 } 683 cPrevUTC = -1.0; 591 684 } 592 685 … … 595 688 cScanNo++; 596 689 cCycleNo = 0; 597 cUTC = 0.0; 598 } 599 600 // Apply beam selection. 601 beamNo = int(baseline / 256.0); 690 cPrevUTC = -1.0; 691 } 692 693 // Apply beam and IF selection before the change-of-day test to allow 694 // a single selected beam and IF to be handled in binning-mode. 695 beamNo = int(cBaseline / 256.0); 696 if (beamNo == 1) { 697 // Store the position of beam 1 for grid convergence corrections. 698 cRA0 = cU; 699 cDec0 = cV; 700 } 602 701 iBeamSel = cBeamSel[beamNo-1]; 603 702 if (iBeamSel < 0) continue; 604 703 605 704 // Sanity check (mainly for MOPS). 606 if (if_no > cNIF) continue; 607 608 // Apply IF selection. 609 iIFSel = cIFSel[if_no - 1]; 705 if (cIFno > cNIF) continue; 706 707 // Apply IF selection; iIFSel == 0 for the first selected IF, == 1 708 // for the second, etc. 709 iIFSel = cIFSel[cIFno - 1]; 610 710 if (iIFSel < 0) continue; 611 711 612 sprintf(cDateObs, "%-10.10s", names_.datobs);613 614 // Change-of-day; note that the ut variable from RPFITS.h is global615 // and will be preserved between calls to this function.616 if (ut < cUTC - 85800.0) {617 ut += 86400.0;618 }619 620 // New integration cycle?621 if (ut > cUTC) {622 cCycleNo++;623 cUTC = ut + 0.0001;624 }625 712 626 713 if (cNBin > 1) { 627 714 // Binning mode: correct the time. 628 ut += param_.intbase * (bin - (cNBin + 1)/2.0); 629 } 715 cUTC += param_.intbase * (cBin - (cNBin + 1)/2.0); 716 } 717 718 // Check for change-of-day. 719 double cod = 0.0; 720 if ((cUTC + 86400.0) < (cPrevUTC + 600.0)) { 721 // cUTC should continue to increase past 86400 during a single scan. 722 // However, if the RPFITS file contains multiple scans that straddle 723 // midnight then cUTC can jump backwards from the end of one scan to 724 // the start of the next. 725 #ifdef PKSIO_DEBUG 726 char buf[256] ; 727 sprintf(buf, "Change-of-day on cUTC: %.1f -> %.1f\n", cPrevUTC, cUTC); 728 os << LogIO::DEBUGGING << buf << LogIO::POST ; 729 #endif 730 // Can't change the recorded value of cUTC directly (without also 731 // changing dateobs) so change-of-day must be recorded separately as 732 // an offset to be applied when comparing integration timestamps. 733 cod = 86400.0; 734 735 } 736 737 if ((cUTC+cod) < cPrevUTC - 1.0) { 738 if (cBin == 1 && iIFSel) { 739 // Multiple-IF, binning-mode data is only partially time ordered. 740 #ifdef PKSIO_DEBUG 741 fprintf(stderr, "New IF in multiple-IF, binning-mode data.\n"); 742 #endif 743 cCycleNo -= cNBin; 744 cPrevUTC = -1.0; 745 746 } else { 747 // All other data should be fully time ordered. 748 sprintf(cMsg, 749 "Cycle %d:%03d-%03d, UTC went backwards from\n" 750 "%.1f to %.1f! Incrementing day number,\n" 751 "positions may be unreliable.", cScanNo, cCycleNo, 752 cCycleNo+1, cPrevUTC, cUTC); 753 //logMsg(cMsg); 754 os << LogIO::WARN << cMsg << LogIO::POST ; 755 cUTC += 86400.0; 756 } 757 } 758 759 // New integration cycle? 760 if ((cUTC+cod) > cPrevUTC) { 761 cCycleNo++; 762 cPrevUTC = cUTC + 0.0001; 763 } 764 765 sprintf(cDateObs, "%-10.10s", names_.datobs); 766 cDateObs[10] = '\0'; 630 767 631 768 // Compute buffer number. 632 769 iMBuff = cBuffer + iBeamSel; 633 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);770 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 634 771 635 772 if (cCycleNo < iMBuff->cycleNo) { … … 640 777 641 778 // Begin flush cycle? 642 if (cEOS || (iMBuff->nIF && ut > iMBuff->utc + 0.0001)) {779 if (cEOS || (iMBuff->nIF && (cUTC+cod) > (iMBuff->utc+0.0001))) { 643 780 cFlushing = 1; 644 781 cFlushBin = 0; … … 647 784 648 785 #ifdef PKSIO_DEBUG 649 printf(" In:%4d%4d%3d%3d\n", cScanNo, cCycleNo, beamNo, if_no); 650 if (cEOS) printf("Start of new scan, flushing previous scan.\n"); 786 char rel = '='; 787 double dt = utcDiff(cUTC, cW); 788 if (dt < 0.0) { 789 rel = '<'; 790 } else if (dt > 0.0) { 791 rel = '>'; 792 } 793 794 sprintf(buf, "\n In:%4d%4d%3d%3d %.3f %c %.3f (%+.3fs) - " 795 "%sflushing\n", cScanNo, cCycleNo, beamNo, cIFno, cUTC, rel, cW, dt, 796 cFlushing ? "" : "not "); 797 os << LogIO::DEBUGGING << buf << LogIO::POST ; 798 if (cEOS) { 799 sprintf(buf, "Start of new scan, flushing previous scan.\n"); 800 os << LogIO::DEBUGGING << buf << LogIO::POST ; 801 } 651 802 #endif 652 803 } … … 663 814 iMBuff = cBuffer + iBeamSel + cNBeamSel*cFlushBin; 664 815 665 // iMBuff->nIF is set to zero (below) to signal that all IFs in666 // an integration have been flushed.816 // iMBuff->nIF is decremented (below) and if zero signals that all 817 // IFs in an integration have been flushed. 667 818 if (iMBuff->nIF) { 668 819 if (cycleNo == 0 || iMBuff->cycleNo < cycleNo) { … … 677 828 break; 678 829 } 830 831 // Start with the first IF in the next bin. 832 cFlushIF = 0; 679 833 } 680 834 … … 684 838 685 839 // Find the IF to flush. 686 for (; cFlushIF < iMBuff->nIF; cFlushIF++) {840 for (; cFlushIF < cSimulIF; cFlushIF++) { 687 841 if (iMBuff->IFno[cFlushIF]) break; 688 842 } … … 696 850 697 851 // The last record read must have been the first of a new cycle. 698 beamNo = int( baseline / 256.0);852 beamNo = int(cBaseline / 256.0); 699 853 iBeamSel = cBeamSel[beamNo-1]; 700 854 701 855 // Compute buffer number. 702 856 iMBuff = cBuffer + iBeamSel; 703 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);857 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 704 858 } 705 859 } 706 860 707 861 708 if (cFlushing && cFlushBin == 0 && cFlushIF == 0 && cInterp) { 709 // Interpolate the beam position at the start of the flush cycle. 862 if (cInterp && cFlushing == 1) { 863 // Start of flush cycle, interpolate the beam position. 864 // 865 // The position is measured by the control system at a time returned by 866 // RPFITSIN as the 'w' visibility coordinate. The ra and dec, returned 867 // as the 'u' and 'v' visibility coordinates, must be interpolated to 868 // the integration time which RPFITSIN returns as 'cUTC', this usually 869 // being a second or two later. The interpolation method used here is 870 // based on the scan rate. 871 // 872 // "This" RA, Dec, and UTC refers to the position currently stored in 873 // the buffer marked for output (iMBuff). This position is interpolated 874 // to the midpoint of that integration using either 875 // a) the rate currently sitting in iMBuff, which was computed from 876 // the previous integration, otherwise 877 // b) from the position recorded in the "next" integration which is 878 // currently sitting in the RPFITS commons, 879 // so that the position timestamps straddle the midpoint of the 880 // integration and is thereby interpolated rather than extrapolated. 881 // 882 // At the end of a scan, or if the next position has not been updated 883 // or its timestamp does not advance sufficiently, the most recent 884 // determination of the scan rate will be used for extrapolation which 885 // is quantified by the "rate age" measured in seconds beyond the 886 // interval defined by the position timestamps. 887 888 // At this point, iMBuff contains cU, cV, cW, parAngle and focusRot 889 // stored from the previous call to rpget() for this beam (i.e. "this"), 890 // and also raRate, decRate and paRate computed from that integration 891 // and the previous one. 892 double thisRA = iMBuff->ra; 893 double thisDec = iMBuff->dec; 894 double thisUTC = cPosUTC[iBeamSel]; 895 double thisPA = iMBuff->parAngle + iMBuff->focusRot; 896 710 897 #ifdef PKSIO_DEBUG 711 printf("Doing position interpolation for beam %d.\n", iMBuff->beamNo); 898 sprintf(buf, "This (%d) ra, dec, UTC: %9.4f %9.4f %10.3f %9.4f\n", 899 iMBuff->cycleNo, thisRA*R2D, thisDec*R2D, thisUTC, thisPA*R2D); 900 os << LogIO::DEBUGGING << buf << LogIO::POST ; 712 901 #endif 713 902 714 double prevRA = iMBuff->ra; 715 double prevDec = iMBuff->dec; 716 double prevUTC = cPosUTC[iBeamSel]; 717 718 if (!cEOF && !cEOS) { 719 // The position is measured by the control system at a time returned 720 // by RPFITSIN as the 'w' visibility coordinate. The ra and dec, 721 // returned as the 'u' and 'v' visibility coordinates, must be 722 // interpolated to the integration time which RPFITSIN returns as 723 // 'ut', this usually being a second or two later. 724 // 725 // Note that the time recorded as the 'w' visibility coordinate 726 // cycles through 86400 back to 0 at midnight, whereas that in 'ut' 727 // continues to increase past 86400. 728 729 double thisRA = u; 730 double thisDec = v; 731 double thisUTC = w; 732 733 if (thisUTC < prevUTC) { 734 // Must have cycled through midnight. 735 thisUTC += 86400.0; 736 } 737 738 // Guard against RA cycling through 24h in either direction. 739 if (fabs(thisRA - prevRA) > PI) { 740 if (thisRA < prevRA) { 741 thisRA += TWOPI; 903 if (cEOF || cEOS) { 904 // Use rates from the last cycle. 905 raRate = iMBuff->raRate; 906 decRate = iMBuff->decRate; 907 paRate = iMBuff->paRate; 908 909 } else { 910 if (cW == thisUTC) { 911 // The control system at Mopra typically does not update the 912 // positions between successive integration cycles at the end of a 913 // scan (nor are they flagged). In this case we use the previously 914 // computed rates, even if from the previous scan since these are 915 // likely to be a better guess than anything else. 916 raRate = iMBuff->raRate; 917 decRate = iMBuff->decRate; 918 paRate = iMBuff->paRate; 919 920 if (cU == thisRA && cV == thisDec) { 921 // Position and timestamp unchanged. 922 pCode = 1; 923 924 } else if (fabs(cU-thisRA) < 0.0001 && fabs(cV-thisDec) < 0.0001) { 925 // Allow small rounding errors (seen infrequently). 926 pCode = 1; 927 742 928 } else { 743 thisRA -= TWOPI; 929 // (cU,cV) are probably rubbish (not yet seen in practice). 930 pCode = 2; 931 cU = thisRA; 932 cV = thisDec; 744 933 } 745 } 746 747 // The control system at Mopra typically does not update the 748 // positions between successive integration cycles at the end of a 749 // scan (nor are they flagged). In this case we use the previously 750 // computed rates, even if from the previous scan since these are 751 // likely to be a better guess than anything else. 752 753 double dUTC = thisUTC - prevUTC; 754 755 // Scan rate for this beam. 756 if (dUTC > 0.0) { 757 iMBuff->raRate = (thisRA - prevRA) / dUTC; 758 iMBuff->decRate = (thisDec - prevDec) / dUTC; 759 760 if (cInterp == 2) { 761 // Use the same interpolation scheme as the original pksmbfits 762 // client. This incorrectly assumed that (thisUTC - prevUTC) is 763 // equal to the integration time and interpolated by computing a 764 // weighted sum of the positions before and after the required 765 // time. 766 767 double utc = iMBuff->utc; 768 if (utc - prevUTC > 100.0) { 769 // Must have cycled through midnight. 770 utc -= 86400.0; 934 935 #ifdef PKSIO_DEBUG 936 sprintf(buf, "Next (%d) ra, dec, UTC: %9.4f %9.4f %10.3f " 937 "(0.000s)\n", cCycleNo, cU*R2D, cV*R2D, cW); 938 os << LogIO::DEBUGGING << buf << LogIO::POST ; 939 #endif 940 941 } else { 942 double nextRA = cU; 943 double nextDec = cV; 944 945 // Check and, if necessary, repair the position timestamp, 946 // remembering that pCode refers to the NEXT cycle. 947 pCode = fixw(cDateObs, cCycleNo, beamNo, cAvRate, thisRA, thisDec, 948 thisUTC, nextRA, nextDec, cW); 949 if (pCode > 0) pCode += 3; 950 double nextUTC = cW; 951 952 #ifdef PKSIO_DEBUG 953 sprintf(buf, "Next (%d) ra, dec, UTC: %9.4f %9.4f %10.3f " 954 "(%+.3fs)\n", cCycleNo, nextRA*R2D, nextDec*R2D, nextUTC, 955 utcDiff(nextUTC, thisUTC)); 956 os << LogIO::DEBUGGING << buf << LogIO::POST ; 957 #endif 958 959 // Compute the scan rate for this beam. 960 double dUTC = utcDiff(nextUTC, thisUTC); 961 if ((0.0 < dUTC) && (dUTC < 600.0)) { 962 scanRate(cRA0, cDec0, thisRA, thisDec, nextRA, nextDec, dUTC, 963 raRate, decRate); 964 965 // Update the mean scan rate. 966 cAvRate[0] = (cAvRate[0]*cNRate + raRate) / (cNRate + 1); 967 cAvRate[1] = (cAvRate[1]*cNRate + decRate) / (cNRate + 1); 968 cNRate++; 969 970 // Rate of change of position angle. 971 if (sc_.sc_ant <= anten_.nant) { 972 paRate = 0.0; 973 } else { 974 int iOff = sc_.sc_q * (sc_.sc_ant - 1) - 1; 975 double nextPA = sc_.sc_cal[iOff + 4] + sc_.sc_cal[iOff + 7]; 976 double paDiff = nextPA - thisPA; 977 if (paDiff > PI) { 978 paDiff -= TWOPI; 979 } else if (paDiff < -PI) { 980 paDiff += TWOPI; 981 } 982 paRate = paDiff / dUTC; 771 983 } 772 984 773 double tw1 = 1.0 - (utc - prevUTC) / iMBuff->exposure; 774 double tw2 = 1.0 - (thisUTC - utc) / iMBuff->exposure; 775 double gamma = (tw2 / (tw1 + tw2)) * dUTC / (utc - prevUTC); 776 777 iMBuff->raRate *= gamma; 778 iMBuff->decRate *= gamma; 779 } 780 781 cStaleness[iBeamSel] = 0; 782 783 } else { 784 // Issue warnings. 785 int nch = 0; 786 fprintf(stderr, "WARNING, scan %d,%n cycle %d: Position ", 787 iMBuff->scanNo, &nch, iMBuff->cycleNo); 788 789 if (dUTC < 0.0) { 790 fprintf(stderr, "timestamp went backwards!\n"); 985 if (cInterp == 2) { 986 // Use the same interpolation scheme as the original pksmbfits 987 // client. This incorrectly assumed that (nextUTC - thisUTC) is 988 // equal to the integration time and interpolated by computing a 989 // weighted sum of the positions before and after the required 990 // time. 991 992 double utc = iMBuff->utc; 993 double tw1 = 1.0 - utcDiff(utc, thisUTC) / iMBuff->exposure; 994 double tw2 = 1.0 - utcDiff(nextUTC, utc) / iMBuff->exposure; 995 double gamma = (tw2 / (tw1 + tw2)) * dUTC / (utc - thisUTC); 996 997 // Guard against RA cycling through 24h in either direction. 998 if (fabs(nextRA - thisRA) > PI) { 999 if (nextRA < thisRA) { 1000 nextRA += TWOPI; 1001 } else { 1002 nextRA -= TWOPI; 1003 } 1004 } 1005 1006 raRate = gamma * (nextRA - thisRA) / dUTC; 1007 decRate = gamma * (nextDec - thisDec) / dUTC; 1008 } 1009 791 1010 } else { 792 if (thisRA != prevRA || thisDec != prevDec) { 793 fprintf(stderr, "changed but timestamp unchanged!\n"); 1011 if (cCycleNo == 2 && fabs(utcDiff(cUTC,cW)) < 600.0) { 1012 // thisUTC (i.e. cW for the first cycle) is rubbish, and 1013 // probably the position as well (extremely rare in practice, 1014 // e.g. 97-12-19_1029_235708-18_586e.hpf which actually has the 1015 // t/1000 scaling bug in the first cycle). 1016 iMBuff->pCode = 3; 1017 thisRA = cU; 1018 thisDec = cV; 1019 thisUTC = cW; 1020 raRate = 0.0; 1021 decRate = 0.0; 1022 paRate = 0.0; 1023 794 1024 } else { 795 fprintf(stderr, "and timestamp unchanged!\n"); 1025 // cW is rubbish and probably (cU,cV), and possibly the 1026 // parallactic angle and everything else as well (rarely seen 1027 // in practice, e.g. 97-12-09_0743_235707-58_327c.hpf and 1028 // 97-09-01_0034_123717-42_242b.hpf, the latter with bad 1029 // parallactic angle). 1030 pCode = 3; 1031 cU = thisRA; 1032 cV = thisDec; 1033 cW = thisUTC; 1034 raRate = iMBuff->raRate; 1035 decRate = iMBuff->decRate; 1036 paRate = iMBuff->paRate; 796 1037 } 797 1038 } 798 799 cStaleness[iBeamSel]++; 800 fprintf(stderr, "%-*s Using stale scan rate, staleness = %d " 801 "cycle%s.\n", nch, "WARNING,", cStaleness[iBeamSel], 802 (cStaleness[iBeamSel] == 1) ? "" : "s"); 803 804 if (thisRA != prevRA || thisDec != prevDec) { 805 if (iMBuff->raRate == 0.0 && iMBuff->decRate == 0.0) { 806 fprintf(stderr, "%-*s But the previous rate was zero! " 807 "Position will be inaccurate.\n", nch, "WARNING,"); 1039 } 1040 } 1041 1042 1043 // Choose the closest rate determination. 1044 if (cCycleNo == 1) { 1045 // Scan containing a single integration. 1046 iMBuff->raRate = 0.0; 1047 iMBuff->decRate = 0.0; 1048 iMBuff->paRate = 0.0; 1049 1050 } else { 1051 double dUTC = iMBuff->utc - cPosUTC[iBeamSel]; 1052 1053 if (dUTC >= 0.0) { 1054 // In HIPASS/ZOA, the position timestamp, which should always occur 1055 // on the whole second, normally precedes an integration midpoint 1056 // falling on the half-second. Consequently, positive ages are 1057 // always half-integral. 1058 dUTC = utcDiff(iMBuff->utc, cW); 1059 if (dUTC > 0.0) { 1060 iMBuff->rateAge = dUTC; 1061 } else { 1062 iMBuff->rateAge = 0.0f; 1063 } 1064 1065 iMBuff->raRate = raRate; 1066 iMBuff->decRate = decRate; 1067 iMBuff->paRate = paRate; 1068 1069 } else { 1070 // In HIPASS/ZOA, negative ages occur when the integration midpoint, 1071 // occurring on the whole second, precedes the position timestamp. 1072 // Thus negative ages are always an integral number of seconds. 1073 // They have only been seen to occur sporadically in the period 1074 // 1999/05/31 to 1999/11/01, e.g. 1999-07-26_1821_005410-74_007c.hpf 1075 // 1076 // In recent (2008/10/07) Mopra data, small negative ages (~10ms, 1077 // occasionally up to ~300ms) seem to be the norm, with both the 1078 // position timestamp and integration midpoint falling close to but 1079 // not on the integral second. 1080 if (cCycleNo == 2) { 1081 // We have to start with something! 1082 iMBuff->rateAge = dUTC; 1083 1084 } else { 1085 // Although we did not record the relevant position timestamp 1086 // explicitly, it can easily be deduced. 1087 double w = iMBuff->utc - utcDiff(cUTC, iMBuff->utc) - 1088 iMBuff->rateAge; 1089 dUTC = utcDiff(iMBuff->utc, w); 1090 1091 if (dUTC > 0.0) { 1092 iMBuff->rateAge = 0.0f; 1093 } else { 1094 iMBuff->rateAge = dUTC; 808 1095 } 809 1096 } 810 } 811 } 1097 1098 iMBuff->raRate = raRate; 1099 iMBuff->decRate = decRate; 1100 iMBuff->paRate = paRate; 1101 } 1102 } 1103 1104 #ifdef PKSIO_DEBUG 1105 double avRate = sqrt(cAvRate[0]*cAvRate[0] + cAvRate[1]*cAvRate[1]); 1106 sprintf(buf, "RA, Dec, Av & PA rates: %8.4f %8.4f %8.4f %8.4f " 1107 "pCode %d\n", raRate*R2D, decRate*R2D, avRate*R2D, paRate*R2D, pCode); 1108 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1109 #endif 1110 812 1111 813 1112 // Compute the position of this beam for all bins. … … 817 1116 cBuffer[jbuff].raRate = iMBuff->raRate; 818 1117 cBuffer[jbuff].decRate = iMBuff->decRate; 819 820 double dutc = cBuffer[jbuff].utc - prevUTC; 821 if (dutc > 100.0) { 1118 cBuffer[jbuff].paRate = iMBuff->paRate; 1119 1120 double dUTC = utcDiff(cBuffer[jbuff].utc, thisUTC); 1121 if (dUTC > 100.0) { 822 1122 // Must have cycled through midnight. 823 dutc -= 86400.0; 824 } 825 826 cBuffer[jbuff].ra = prevRA + cBuffer[jbuff].raRate * dutc; 827 cBuffer[jbuff].dec = prevDec + cBuffer[jbuff].decRate * dutc; 828 if (cBuffer[jbuff].ra < 0.0) { 829 cBuffer[jbuff].ra += TWOPI; 830 } else if (cBuffer[jbuff].ra > TWOPI) { 831 cBuffer[jbuff].ra -= TWOPI; 832 } 833 } 1123 dUTC -= 86400.0; 1124 } 1125 1126 applyRate(cRA0, cDec0, thisRA, thisDec, 1127 cBuffer[jbuff].raRate, cBuffer[jbuff].decRate, dUTC, 1128 cBuffer[jbuff].ra, cBuffer[jbuff].dec); 1129 1130 #ifdef PKSIO_DEBUG 1131 sprintf(buf, "Intp (%d) ra, dec, UTC: %9.4f %9.4f %10.3f (pCode, " 1132 "age: %d %.1fs)\n", iMBuff->cycleNo, cBuffer[jbuff].ra*R2D, 1133 cBuffer[jbuff].dec*R2D, cBuffer[jbuff].utc, iMBuff->pCode, 1134 iMBuff->rateAge); 1135 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1136 #endif 1137 } 1138 1139 cFlushing = 2; 834 1140 } 835 1141 … … 841 1147 842 1148 #ifdef PKSIO_DEBUG 843 printf("Out:%4d%4d%3d%3d\n", MBrec.scanNo, MBrec.cycleNo, MBrec.beamNo, 844 MBrec.IFno[0]); 1149 sprintf(buf, "Out:%4d%4d%3d%3d\n", MBrec.scanNo, MBrec.cycleNo, 1150 MBrec.beamNo, MBrec.IFno[0]); 1151 os << LogIO::DEBUGGING << buf << LogIO::POST ; 845 1152 #endif 846 1153 … … 848 1155 iMBuff->IFno[cFlushIF] = 0; 849 1156 850 if (cFlushIF == iMBuff->nIF - 1) { 851 // Signal that all IFs in this buffer location have been flushed. 852 iMBuff->nIF = 0; 1157 iMBuff->nIF--; 1158 if (iMBuff->nIF == 0) { 1159 // All IFs in this buffer location have been flushed. Stop cEOS 1160 // being set when the next integration is read. 1161 iMBuff->cycleNo = 0; 1162 853 1163 } else { 854 1164 // Carry on flushing the other IFs. … … 859 1169 if (cFlushBin == cNBin - 1) { 860 1170 if (cEOS || cEOF) { 861 // Stop cEOS being set when the next integration is read.862 iMBuff->cycleNo = 0;863 864 1171 // Carry on flushing other buffers. 865 1172 cFlushIF = 0; … … 869 1176 cFlushing = 0; 870 1177 871 beamNo = int( baseline / 256.0);1178 beamNo = int(cBaseline / 256.0); 872 1179 iBeamSel = cBeamSel[beamNo-1]; 873 1180 874 1181 // Compute buffer number. 875 1182 iMBuff = cBuffer + iBeamSel; 876 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);1183 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 877 1184 } 878 1185 } … … 880 1187 if (!cFlushing) { 881 1188 // Buffer this MBrec. 882 if ( cCycleNo == 1&& iMBuff->IFno[0]) {1189 if ((cScanNo > iMBuff->scanNo) && iMBuff->IFno[0]) { 883 1190 // Sanity check on the number of IFs in the new scan. 884 1191 if (if_.n_if != cNIF) { 885 fprintf(stderr, "WARNING, scan %d has %d IFs instead of %d, " 886 "continuing.\n", cScanNo, if_.n_if, cNIF); 887 } 888 } 889 890 iMBuff->scanNo = cScanNo; 891 iMBuff->cycleNo = cCycleNo; 892 893 // Times. 894 strncpy(iMBuff->datobs, cDateObs, 10); 895 iMBuff->utc = ut; 896 iMBuff->exposure = param_.intbase; 897 898 // Source identification. 899 sprintf(iMBuff->srcName, "%-16.16s", 900 names_.su_name + (sourceno-1)*16); 901 iMBuff->srcRA = doubles_.su_ra[sourceno-1]; 902 iMBuff->srcDec = doubles_.su_dec[sourceno-1]; 903 904 // Rest frequency of the line of interest. 905 iMBuff->restFreq = doubles_.rfreq; 906 if (strncmp(names_.instrument, "ATPKSMB", 7) == 0) { 907 // Fix the HI rest frequency recorded for Parkes multibeam data. 908 double reffreq = doubles_.freq; 909 double restfreq = doubles_.rfreq; 910 if ((restfreq == 0.0 || fabs(restfreq - reffreq) == 0.0) && 911 fabs(reffreq - 1420.40575e6) < 100.0) { 912 iMBuff->restFreq = 1420.40575e6; 913 } 914 } 915 916 // Observation type. 917 int j; 918 for (j = 0; j < 15; j++) { 919 iMBuff->obsType[j] = names_.card[11+j]; 920 if (iMBuff->obsType[j] == '\'') break; 921 } 922 iMBuff->obsType[j] = '\0'; 923 924 // Beam-dependent parameters. 925 iMBuff->beamNo = beamNo; 926 927 // Beam position at the specified time. 928 if (cTid) { 929 // Tidbinbilla data. 930 iMBuff->ra = doubles_.su_ra[sourceno-1]; 931 iMBuff->dec = doubles_.su_dec[sourceno-1]; 932 } else { 933 iMBuff->ra = u; 934 iMBuff->dec = v; 935 } 936 cPosUTC[iBeamSel] = w; 1192 sprintf(cMsg, "Scan %d has %d IFs instead of %d, " 1193 "continuing.", cScanNo, if_.n_if, cNIF); 1194 os << LogIO::WARN << cMsg << LogIO::POST ; 1195 } 1196 } 1197 1198 // Sanity check on incomplete integrations within a scan. 1199 if (iMBuff->nIF && (iMBuff->cycleNo != cCycleNo)) { 1200 // Force the incomplete integration to be flushed before proceeding. 1201 cFlushing = 1; 1202 continue; 1203 } 1204 1205 #ifdef PKSIO_DEBUG 1206 sprintf(buf, "Buf:%4d%4d%3d%3d\n", cScanNo, cCycleNo, beamNo, cIFno); 1207 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1208 #endif 1209 1210 // Store IF-independent parameters only for the first IF of a new cycle, 1211 // particularly because this is the only one for which the scan rates 1212 // are computed above. 1213 int firstIF = (iMBuff->nIF == 0); 1214 if (firstIF) { 1215 iMBuff->scanNo = cScanNo; 1216 iMBuff->cycleNo = cCycleNo; 1217 1218 // Times. 1219 strcpy(iMBuff->datobs, cDateObs); 1220 iMBuff->utc = cUTC; 1221 iMBuff->exposure = param_.intbase; 1222 1223 // Source identification. 1224 sprintf(iMBuff->srcName, "%-16.16s", 1225 names_.su_name + (cSrcNo-1)*16); 1226 iMBuff->srcName[16] = '\0'; 1227 iMBuff->srcRA = doubles_.su_ra[cSrcNo-1]; 1228 iMBuff->srcDec = doubles_.su_dec[cSrcNo-1]; 1229 1230 // Rest frequency of the line of interest. 1231 iMBuff->restFreq = doubles_.rfreq; 1232 if (strncmp(names_.instrument, "ATPKSMB", 7) == 0) { 1233 // Fix the HI rest frequency recorded for Parkes multibeam data. 1234 double reffreq = doubles_.freq; 1235 double restfreq = doubles_.rfreq; 1236 if ((restfreq == 0.0 || fabs(restfreq - reffreq) == 0.0) && 1237 fabs(reffreq - 1420.405752e6) < 100.0) { 1238 iMBuff->restFreq = 1420.405752e6; 1239 } 1240 } 1241 1242 // Observation type. 1243 int j; 1244 for (j = 0; j < 15; j++) { 1245 iMBuff->obsType[j] = names_.card[11+j]; 1246 if (iMBuff->obsType[j] == '\'') break; 1247 } 1248 iMBuff->obsType[j] = '\0'; 1249 1250 // Beam-dependent parameters. 1251 iMBuff->beamNo = beamNo; 1252 1253 // Beam position at the specified time. 1254 if (cSUpos) { 1255 // Non-ATNF data that does not store the position in (u,v,w). 1256 iMBuff->ra = doubles_.su_ra[cSrcNo-1]; 1257 iMBuff->dec = doubles_.su_dec[cSrcNo-1]; 1258 } else { 1259 iMBuff->ra = cU; 1260 iMBuff->dec = cV; 1261 } 1262 cPosUTC[iBeamSel] = cW; 1263 iMBuff->pCode = pCode; 1264 1265 // Store rates for next time. 1266 iMBuff->raRate = raRate; 1267 iMBuff->decRate = decRate; 1268 iMBuff->paRate = paRate; 1269 } 937 1270 938 1271 // IF-dependent parameters. 939 int iIF = if_no - 1;1272 int iIF = cIFno - 1; 940 1273 int startChan = cStartChan[iIF]; 941 1274 int endChan = cEndChan[iIF]; … … 945 1278 946 1279 iIFSel = cIFSel[iIF]; 947 iMBuff->nIF++; 948 iMBuff->IFno[iIFSel] = if_no; 1280 if (iMBuff->IFno[iIFSel] == 0) { 1281 iMBuff->nIF++; 1282 iMBuff->IFno[iIFSel] = cIFno; 1283 } else { 1284 // Integration cycle written to the output file twice (the only known 1285 // example is 1999-05-22_1914_000-031805_03v.hpf). 1286 sprintf(cMsg, "Integration cycle %d:%d, beam %2d, \n" 1287 "IF %d was duplicated.", cScanNo, cCycleNo-1, 1288 beamNo, cIFno); 1289 os << LogIO::WARN << cMsg << LogIO::POST ; 1290 } 949 1291 iMBuff->nChan[iIFSel] = nChan; 950 1292 iMBuff->nPol[iIFSel] = cNPol[iIF]; … … 1005 1347 1006 1348 // The baseline flag may be set independently. 1007 if (rpflag == 0) rpflag = flag;1349 if (rpflag == 0) rpflag = cFlag; 1008 1350 1009 1351 // Copy and scale data. … … 1046 1388 1047 1389 1048 // Parallactic angle.1049 iMBuff->parAngle = sc_.sc_cal[scq*iBeam + 11];1050 1051 1390 // Calibration factor applied to the data by the correlator. 1052 1391 if (scq > 14) { … … 1059 1398 } 1060 1399 1061 if (sc_.sc_ant <= anten_.nant) { 1062 // No extra syscal information present. 1063 iMBuff->extraSysCal = 0; 1064 iMBuff->azimuth = 0.0f; 1065 iMBuff->elevation = 0.0f; 1066 iMBuff->parAngle = 0.0f; 1067 iMBuff->focusAxi = 0.0f; 1068 iMBuff->focusTan = 0.0f; 1069 iMBuff->focusRot = 0.0f; 1070 iMBuff->temp = 0.0f; 1071 iMBuff->pressure = 0.0f; 1072 iMBuff->humidity = 0.0f; 1073 iMBuff->windSpeed = 0.0f; 1074 iMBuff->windAz = 0.0f; 1075 strcpy(iMBuff->tcalTime, " "); 1076 iMBuff->refBeam = 0; 1077 1078 } else { 1079 // Additional information for Parkes Multibeam data. 1080 int iOff = scq*(sc_.sc_ant - 1) - 1; 1081 iMBuff->extraSysCal = 1; 1082 iMBuff->azimuth = sc_.sc_cal[iOff + 2]; 1083 iMBuff->elevation = sc_.sc_cal[iOff + 3]; 1084 iMBuff->parAngle = sc_.sc_cal[iOff + 4]; 1085 iMBuff->focusAxi = sc_.sc_cal[iOff + 5] * 1e-3; 1086 iMBuff->focusTan = sc_.sc_cal[iOff + 6] * 1e-3; 1087 iMBuff->focusRot = sc_.sc_cal[iOff + 7]; 1088 iMBuff->temp = sc_.sc_cal[iOff + 8]; 1089 iMBuff->pressure = sc_.sc_cal[iOff + 9]; 1090 iMBuff->humidity = sc_.sc_cal[iOff + 10]; 1091 iMBuff->windSpeed = sc_.sc_cal[iOff + 11]; 1092 iMBuff->windAz = sc_.sc_cal[iOff + 12]; 1093 1094 char *tcalTime = iMBuff->tcalTime; 1095 sprintf(tcalTime, "%-16.16s", (char *)(&sc_.sc_cal[iOff+13])); 1400 if (firstIF) { 1401 if (sc_.sc_ant <= anten_.nant) { 1402 // No extra syscal information present. 1403 iMBuff->extraSysCal = 0; 1404 iMBuff->azimuth = 0.0f; 1405 iMBuff->elevation = 0.0f; 1406 iMBuff->parAngle = 0.0f; 1407 iMBuff->focusAxi = 0.0f; 1408 iMBuff->focusTan = 0.0f; 1409 iMBuff->focusRot = 0.0f; 1410 iMBuff->temp = 0.0f; 1411 iMBuff->pressure = 0.0f; 1412 iMBuff->humidity = 0.0f; 1413 iMBuff->windSpeed = 0.0f; 1414 iMBuff->windAz = 0.0f; 1415 strcpy(iMBuff->tcalTime, " "); 1416 iMBuff->refBeam = 0; 1417 1418 } else { 1419 // Additional information for Parkes Multibeam data. 1420 int iOff = scq*(sc_.sc_ant - 1) - 1; 1421 iMBuff->extraSysCal = 1; 1422 1423 iMBuff->azimuth = sc_.sc_cal[iOff + 2]; 1424 iMBuff->elevation = sc_.sc_cal[iOff + 3]; 1425 iMBuff->parAngle = sc_.sc_cal[iOff + 4]; 1426 1427 iMBuff->focusAxi = sc_.sc_cal[iOff + 5] * 1e-3; 1428 iMBuff->focusTan = sc_.sc_cal[iOff + 6] * 1e-3; 1429 iMBuff->focusRot = sc_.sc_cal[iOff + 7]; 1430 1431 iMBuff->temp = sc_.sc_cal[iOff + 8]; 1432 iMBuff->pressure = sc_.sc_cal[iOff + 9]; 1433 iMBuff->humidity = sc_.sc_cal[iOff + 10]; 1434 iMBuff->windSpeed = sc_.sc_cal[iOff + 11]; 1435 iMBuff->windAz = sc_.sc_cal[iOff + 12]; 1436 1437 char *tcalTime = iMBuff->tcalTime; 1438 sprintf(tcalTime, "%-16.16s", (char *)(&sc_.sc_cal[iOff+13])); 1439 tcalTime[16] = '\0'; 1096 1440 1097 1441 #ifndef AIPS_LITTLE_ENDIAN 1098 // Do byte swapping on the ASCII date string.1099 for (int j = 0; j < 16; j += 4) {1100 char ctmp;1101 ctmp = tcalTime[j];1102 tcalTime[j] = tcalTime[j+3];1103 tcalTime[j+3] = ctmp;1104 ctmp = tcalTime[j+1];1105 tcalTime[j+1] = tcalTime[j+2];1106 tcalTime[j+2] = ctmp;1107 }1442 // Do byte swapping on the ASCII date string. 1443 for (int j = 0; j < 16; j += 4) { 1444 char ctmp; 1445 ctmp = tcalTime[j]; 1446 tcalTime[j] = tcalTime[j+3]; 1447 tcalTime[j+3] = ctmp; 1448 ctmp = tcalTime[j+1]; 1449 tcalTime[j+1] = tcalTime[j+2]; 1450 tcalTime[j+2] = ctmp; 1451 } 1108 1452 #endif 1109 1453 1110 // Reference beam number. 1111 float refbeam = sc_.sc_cal[iOff + 17]; 1112 if (refbeam > 0.0f || refbeam < 100.0f) { 1113 iMBuff->refBeam = int(refbeam); 1114 } else { 1115 iMBuff->refBeam = 0; 1454 // Reference beam number. 1455 float refbeam = sc_.sc_cal[iOff + 17]; 1456 if (refbeam > 0.0f || refbeam < 100.0f) { 1457 iMBuff->refBeam = int(refbeam); 1458 } else { 1459 iMBuff->refBeam = 0; 1460 } 1116 1461 } 1117 1462 } … … 1128 1473 int MBFITSreader::rpget(int syscalonly, int &EOS) 1129 1474 { 1475 const string methodName = "rpget()" ; 1476 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 1477 1130 1478 EOS = 0; 1131 1479 … … 1135 1483 int numErr = 0; 1136 1484 1137 jstat = 0;1485 int jstat = 0; 1138 1486 while (numErr < 10) { 1139 1487 int lastjstat = jstat; 1140 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 1141 &if_no, &sourceno); 1142 1143 switch(jstat) { 1488 1489 switch(rpfitsin(jstat)) { 1144 1490 case -1: 1145 1491 // Read failed; retry. 1146 1492 numErr++; 1147 fprintf(stderr, "RPFITS read failed - retrying.\n");1493 os << LogIO::WARN << "RPFITS read failed - retrying." << LogIO::POST ; 1148 1494 jstat = 0; 1149 1495 break; … … 1152 1498 // Successful read. 1153 1499 if (lastjstat == 0) { 1154 if ( baseline == -1) {1500 if (cBaseline == -1) { 1155 1501 // Syscal data. 1156 1502 if (syscalonly) { … … 1201 1547 default: 1202 1548 // Shouldn't reach here. 1203 fprintf(stderr, "Unrecognized RPFITSIN return code: %d (retrying)\n", 1204 jstat); 1549 sprintf(cMsg, "Unrecognized RPFITSIN return code: %d " 1550 "(retrying).", jstat); 1551 os << LogIO::WARN << cMsg << LogIO::POST ; 1205 1552 jstat = 0; 1206 1553 break; … … 1208 1555 } 1209 1556 1210 fprintf(stderr, "RPFITS read failed too many times.\n");1557 os << LogIO::SEVERE << "RPFITS read failed too many times." << LogIO::POST ; 1211 1558 return 2; 1559 } 1560 1561 //----------------------------------------------------- MBFITSreader::rpfitsin 1562 1563 // Wrapper around RPFITSIN that reports errors. Returned RPFITSIN subroutine 1564 // arguments are captured as MBFITSreader member variables. 1565 1566 int MBFITSreader::rpfitsin(int &jstat) 1567 1568 { 1569 rpfitsin_(&jstat, cVis, cWgt, &cBaseline, &cUTC, &cU, &cV, &cW, &cFlag, 1570 &cBin, &cIFno, &cSrcNo); 1571 1572 // Handle messages from RPFITSIN. 1573 /** 1574 if (names_.errmsg[0] != ' ') { 1575 int i; 1576 for (i = 80; i > 0; i--) { 1577 if (names_.errmsg[i-1] != ' ') break; 1578 } 1579 1580 sprintf(cMsg, "WARNING: Cycle %d:%03d, RPFITSIN reported -\n" 1581 " %.*s", cScanNo, cCycleNo, i, names_.errmsg); 1582 logMsg(cMsg); 1583 } 1584 **/ 1585 return jstat; 1586 } 1587 1588 //------------------------------------------------------- MBFITSreader::fixPos 1589 1590 // Check and, if necessary, repair a position timestamp. 1591 // 1592 // Problems with the position timestamp manifest themselves via the scan rate: 1593 // 1594 // 1) Zero scan rate pairs, 1997/02/28 to 1998/01/07 1595 // 1596 // These occur because the position timestamp for the first integration 1597 // of the pair is erroneous; the value recorded is t/1000, where t is the 1598 // true value. 1599 // Earliest known: 97-02-28_1725_132653-42_258a.hpf 1600 // Latest known: 98-01-02_1923_095644-50_165c.hpf 1601 // (time range chosen to encompass observing runs). 1602 // 1603 // 2) Slow-fast scan rate pairs (0.013 - 0.020 deg/s), 1604 // 1997/03/28 to 1998/01/07. 1605 // 1606 // The UTC position timestamp is 1.0s later than it should be (never 1607 // earlier), almost certainly arising from an error in the telescope 1608 // control system. 1609 // Earliest known: 97-03-28_0150_010420-74_008d.hpf 1610 // Latest known: 98-01-04_1502_065150-02_177c.hpf 1611 // (time range chosen to encompass observing runs). 1612 // 1613 // 3) Slow-fast scan rate pairs (0.015 - 0.018 deg/s), 1614 // 1999/05/20 to 2001/07/12 (HIPASS and ZOA), 1615 // 2001/09/02 to 2001/12/04 (HIPASS and ZOA), 1616 // 2002/03/28 to 2002/05/13 (ZOA only), 1617 // 2003/04/26 to 2003/06/09 (ZOA only). 1618 // Earliest known: 1999-05-20_1818_175720-50_297e.hpf 1619 // Latest known: 2001-12-04_1814_065531p14_173e.hpf (HIPASS) 1620 // 2003-06-09_1924_352-085940_-6c.hpf (ZOA) 1621 // 1622 // Caused by the Linux signalling NaN problem. IEEE "signalling" NaNs 1623 // are silently transformed to "quiet" NaNs during assignment by setting 1624 // bit 22. This affected RPFITS because of its use of VAX-format 1625 // floating-point numbers which, with their permuted bytes, may sometimes 1626 // appear as signalling NaNs. 1627 // 1628 // The problem arose when the linux correlator came online and was 1629 // fixed with a workaround to the RPFITS library (repeated episodes 1630 // are probably due to use of an older version of the library). It 1631 // should not have affected the data significantly because of the 1632 // low relative error, which ranges from 0.0000038 to 0.0000076, but 1633 // it is important for the computation of scan rates which requires 1634 // taking the difference of two large UTC timestamps, one or other 1635 // of which will have 0.5s added to it. 1636 // 1637 // The return value identifies which, if any, of these problems was repaired. 1638 1639 int MBFITSreader::fixw( 1640 const char *datobs, 1641 int cycleNo, 1642 int beamNo, 1643 double avRate[2], 1644 double thisRA, 1645 double thisDec, 1646 double thisUTC, 1647 double nextRA, 1648 double nextDec, 1649 float &nextUTC) 1650 { 1651 if (strcmp(datobs, "2003-06-09") > 0) { 1652 return 0; 1653 1654 } else if (strcmp(datobs, "1998-01-07") <= 0) { 1655 if (nextUTC < thisUTC && (nextUTC + 86400.0) > (thisUTC + 600.0)) { 1656 // Possible scaling problem. 1657 double diff = nextUTC*1000.0 - thisUTC; 1658 if (0.0 < diff && diff < 600.0) { 1659 nextUTC *= 1000.0; 1660 return 1; 1661 } else { 1662 // Irreparable. 1663 return -1; 1664 } 1665 } 1666 1667 if (cycleNo > 2) { 1668 if (beamNo == 1) { 1669 // This test is only reliable for beam 1. 1670 double dUTC = nextUTC - thisUTC; 1671 if (dUTC < 0.0) dUTC += 86400.0; 1672 1673 // Guard against RA cycling through 24h in either direction. 1674 if (fabs(nextRA - thisRA) > PI) { 1675 if (nextRA < thisRA) { 1676 nextRA += TWOPI; 1677 } else { 1678 nextRA -= TWOPI; 1679 } 1680 } 1681 1682 double dRA = (nextRA - thisRA) * cos(nextDec); 1683 double dDec = nextDec - thisDec; 1684 double arc = sqrt(dRA*dRA + dDec*dDec); 1685 1686 double averate = sqrt(avRate[0]*avRate[0] + avRate[1]*avRate[1]); 1687 double diff1 = fabs(averate - arc/(dUTC-1.0)); 1688 double diff2 = fabs(averate - arc/dUTC); 1689 if ((diff1 < diff2) && (diff1 < 0.05*averate)) { 1690 nextUTC -= 1.0; 1691 cCode5 = cycleNo; 1692 return 2; 1693 } else { 1694 cCode5 = 0; 1695 } 1696 1697 } else { 1698 if (cycleNo == cCode5) { 1699 nextUTC -= 1.0; 1700 return 2; 1701 } 1702 } 1703 } 1704 1705 } else if ((strcmp(datobs, "1999-05-20") >= 0 && 1706 strcmp(datobs, "2001-07-12") <= 0) || 1707 (strcmp(datobs, "2001-09-02") >= 0 && 1708 strcmp(datobs, "2001-12-04") <= 0) || 1709 (strcmp(datobs, "2002-03-28") >= 0 && 1710 strcmp(datobs, "2002-05-13") <= 0) || 1711 (strcmp(datobs, "2003-04-26") >= 0 && 1712 strcmp(datobs, "2003-06-09") <= 0)) { 1713 // Signalling NaN problem, e.g. 1999-07-26_1839_011106-74_009c.hpf. 1714 // Position timestamps should always be an integral number of seconds. 1715 double resid = nextUTC - int(nextUTC); 1716 if (resid == 0.5) { 1717 nextUTC -= 0.5; 1718 return 3; 1719 } 1720 } 1721 1722 return 0; 1212 1723 } 1213 1724 … … 1219 1730 { 1220 1731 if (cMBopen) { 1221 jstat = 1;1222 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin,1223 & if_no, &sourceno);1732 int jstat = 1; 1733 rpfitsin_(&jstat, cVis, cWgt, &cBaseline, &cUTC, &cU, &cV, &cW, &cFlag, 1734 &cBin, &cIFno, &cSrcNo); 1224 1735 1225 1736 if (cBeams) delete [] cBeams; … … 1232 1743 if (cRefChan) delete [] cRefChan; 1233 1744 1234 if (cVis) delete [] cVis; 1745 if (cVis) delete [] cVis; 1746 if (cWgt) delete [] cWgt; 1235 1747 1236 1748 if (cBeamSel) delete [] cBeamSel; … … 1244 1756 } 1245 1757 } 1758 1759 //-------------------------------------------------------------------- utcDiff 1760 1761 // Subtract two UTCs (s) allowing for any plausible number of cycles through 1762 // 86400s, returning a result in the range [-43200, +43200]s. 1763 1764 double MBFITSreader::utcDiff(double utc1, double utc2) 1765 { 1766 double diff = utc1 - utc2; 1767 1768 if (diff > 43200.0) { 1769 diff -= 86400.0; 1770 while (diff > 43200.0) diff -= 86400.0; 1771 } else if (diff < -43200.0) { 1772 diff += 86400.0; 1773 while (diff < -43200.0) diff += 86400.0; 1774 } 1775 1776 return diff; 1777 } 1778 1779 //------------------------------------------------------- scanRate & applyRate 1780 1781 // Compute and apply the scan rate corrected for grid convergence. (ra0,dec0) 1782 // are the coordinates of the central beam, assumed to be the tracking centre. 1783 // The rate computed in RA will be a rate of change of angular distance in the 1784 // direction of increasing RA at the position of the central beam. Similarly 1785 // for declination. Angles in radian, time in s. 1786 1787 void MBFITSreader::scanRate( 1788 double ra0, 1789 double dec0, 1790 double ra1, 1791 double dec1, 1792 double ra2, 1793 double dec2, 1794 double dt, 1795 double &raRate, 1796 double &decRate) 1797 { 1798 // Transform to a system where the central beam lies on the equator at 12h. 1799 eulerx(ra1, dec1, ra0+HALFPI, -dec0, -HALFPI, ra1, dec1); 1800 eulerx(ra2, dec2, ra0+HALFPI, -dec0, -HALFPI, ra2, dec2); 1801 1802 raRate = (ra2 - ra1) / dt; 1803 decRate = (dec2 - dec1) / dt; 1804 } 1805 1806 1807 void MBFITSreader::applyRate( 1808 double ra0, 1809 double dec0, 1810 double ra1, 1811 double dec1, 1812 double raRate, 1813 double decRate, 1814 double dt, 1815 double &ra2, 1816 double &dec2) 1817 { 1818 // Transform to a system where the central beam lies on the equator at 12h. 1819 eulerx(ra1, dec1, ra0+HALFPI, -dec0, -HALFPI, ra1, dec1); 1820 1821 ra2 = ra1 + (raRate * dt); 1822 dec2 = dec1 + (decRate * dt); 1823 1824 // Transform back. 1825 eulerx(ra2, dec2, -HALFPI, dec0, ra0+HALFPI, ra2, dec2); 1826 } 1827 1828 //--------------------------------------------------------------------- eulerx 1829 1830 void MBFITSreader::eulerx( 1831 double lng0, 1832 double lat0, 1833 double phi0, 1834 double theta, 1835 double phi, 1836 double &lng1, 1837 double &lat1) 1838 1839 // Applies the Euler angle based transformation of spherical coordinates. 1840 // 1841 // phi0 Longitude of the ascending node in the old system, radians. The 1842 // ascending node is the point of intersection of the equators of 1843 // the two systems such that the equator of the new system crosses 1844 // from south to north as viewed in the old system. 1845 // 1846 // theta Angle between the poles of the two systems, radians. THETA is 1847 // positive for a positive rotation about the ascending node. 1848 // 1849 // phi Longitude of the ascending node in the new system, radians. 1850 1851 { 1852 // Compute intermediaries. 1853 double lng0p = lng0 - phi0; 1854 double slng0p = sin(lng0p); 1855 double clng0p = cos(lng0p); 1856 double slat0 = sin(lat0); 1857 double clat0 = cos(lat0); 1858 double ctheta = cos(theta); 1859 double stheta = sin(theta); 1860 1861 double x = clat0*clng0p; 1862 double y = clat0*slng0p*ctheta + slat0*stheta; 1863 1864 // Longitude in the new system. 1865 if (x != 0.0 || y != 0.0) { 1866 lng1 = phi + atan2(y, x); 1867 } else { 1868 // Longitude at the poles in the new system is consistent with that 1869 // specified in the old system. 1870 lng1 = phi + lng0p; 1871 } 1872 lng1 = fmod(lng1, TWOPI); 1873 if (lng1 < 0.0) lng1 += TWOPI; 1874 1875 lat1 = asin(slat0*ctheta - clat0*stheta*slng0p); 1876 } -
branches/alma/external/atnf/PKSIO/MBFITSreader.h
r1453 r1757 2 2 //# MBFITSreader.h: ATNF single-dish RPFITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: MBFITSreader.h,v 19.23 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The MBFITSreader class reads single dish RPFITS files (such as Parkes … … 39 41 40 42 #include <atnf/PKSIO/FITSreader.h> 41 #include <atnf/PKSIO/PKSMBrecord.h> 43 #include <atnf/PKSIO/MBrecord.h> 44 45 using namespace std; 42 46 43 47 // <summary> … … 78 82 double antPos[3], 79 83 char obsType[32], 84 char bunit[32], 80 85 float &equinox, 81 86 char radecsys[32], … … 101 106 102 107 // Read the next data record. 103 virtual int read( PKSMBrecord &record);108 virtual int read(MBrecord &record); 104 109 105 110 // Close the RPFITS file. … … 107 112 108 113 private: 109 char cDateObs[10]; 114 // RPFITSIN subroutine arguments. 115 int cBaseline, cFlag, cBin, cIFno, cSrcNo; 116 float cUTC, cU, cV, cW, *cVis, *cWgt; 117 118 char cDateObs[12]; 110 119 int *cBeamSel, *cChanOff, cFirst, *cIFSel, cInterp, cIntTime, cMBopen, 111 cMopra, cNBeamSel, cNBin, cRetry, *cStaleness, cTid, *cXpolOff; 112 float *cVis; 120 cMopra, cNBeamSel, cNBin, cRetry, cSimulIF, cSUpos, *cXpolOff; 113 121 114 122 // The data has to be bufferred to allow positions to be interpolated. 115 123 int cEOF, cEOS, cFlushBin, cFlushIF, cFlushing; 116 124 double *cPosUTC; 117 PKSMBrecord *cBuffer;125 MBrecord *cBuffer; 118 126 127 // Scan and cycle number bookkeeping. 119 128 int cCycleNo, cScanNo; 120 double c UTC;129 double cPrevUTC; 121 130 122 131 // Read the next data record from the RPFITS file. 123 132 int rpget(int syscalonly, int &EOS); 124 // These are no longer define in the RPFITS.h file so moved here 125 int jstat; 126 float *weight; 127 int baseline; 128 int flag; 129 int bin; 130 int if_no; 131 int sourceno; 132 float *vis; 133 float u; 134 float v; 135 float w; 136 float ut; 137 133 int rpfitsin(int &jstat); 134 135 // Check and, if necessary, repair a position timestamp. 136 int cCode5, cNRate; 137 double cAvRate[2]; 138 int fixw(const char *datobs, int cycleNo, int beamNo, double avRate[2], 139 double thisRA, double thisDec, double thisUTC, 140 double nextRA, double nextDec, float &nextUTC); 141 142 // Subtract two UTCs (s). 143 double utcDiff(double utc1, double utc2); 144 145 // Compute and apply the scan rate corrected for grid convergence. 146 double cRA0, cDec0; 147 void scanRate(double ra0, double dec0, 148 double ra1, double dec1, 149 double ra2, double dec2, double dt, 150 double &raRate, double &decRate); 151 void applyRate(double ra0, double dec0, 152 double ra1, double dec1, 153 double raRate, double decRate, double dt, 154 double &ra2, double &dec2); 155 void eulerx(double lng0, double lat0, double phi0, double theta, 156 double phi, double &lng1, double &lat1); 138 157 }; 139 158 -
branches/alma/external/atnf/PKSIO/MBrecord.cc
r1752 r1757 322 322 refBeam = other.refBeam; 323 323 324 polNo = other.polNo ; 325 srcVelocity = other.srcVelocity ; 326 324 327 return *this; 325 328 } … … 436 439 refBeam = other.refBeam; 437 440 441 polNo = other.polNo ; 442 srcVelocity = other.srcVelocity ; 443 438 444 return 0; 439 445 } -
branches/alma/external/atnf/PKSIO/MBrecord.h
r1752 r1757 166 166 short refBeam; // Reference beam, in beam-switching (MX) 167 167 // mode (added 1999/03/17). 168 int polNo ; // polarization ID 169 float srcVelocity ; // source velocity w.r.t. reference frame 168 170 169 171 private: -
branches/alma/external/atnf/PKSIO/PKSFITSreader.cc
r1453 r1757 2 2 //# PKSFITSreader.cc: Class to read Parkes multibeam data from a FITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 27 21 //# 28 //# $Id$ 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSFITSreader.cc,v 19.23 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/02, Mark Calabretta, ATNF … … 34 37 #include <atnf/PKSIO/SDFITSreader.h> 35 38 #include <atnf/PKSIO/PKSFITSreader.h> 36 #include <atnf/PKSIO/PKSMBrecord.h> 37 39 #include <atnf/PKSIO/PKSrecord.h> 40 41 #include <casa/stdio.h> 38 42 #include <casa/Arrays/Array.h> 39 43 #include <casa/BasicMath/Math.h> 40 44 #include <casa/Quanta/MVTime.h> 41 42 #include <casa/stdio.h> 45 #include <casa/Logging/LogIO.h> 43 46 44 47 //----------------------------------------------- PKSFITSreader::PKSFITSreader … … 76 79 Int PKSFITSreader::open( 77 80 const String fitsName, 81 const String antenna, 78 82 Vector<Bool> &beams, 79 83 Vector<Bool> &IFs, … … 86 90 int extraSysCal, haveBase_, *haveXPol_, haveSpectra_, nBeam, *nChan_, 87 91 nIF, *nPol_, status; 88 if ((status = cReader->open((char *)fitsName.chars(), nBeam, cBeams, nIF, 89 cIFs, nChan_, nPol_, haveXPol_, haveBase_, 90 haveSpectra_, extraSysCal))) { 92 status = cReader->open((char *)fitsName.chars(), nBeam, cBeams, nIF, cIFs, 93 nChan_, nPol_, haveXPol_, haveBase_, haveSpectra_, 94 extraSysCal); 95 //logMsg(cReader->getMsg()); 96 //cReader->clearMsg(); 97 if (status) { 91 98 return status; 92 99 } … … 138 145 Vector<Double> &antPosition, 139 146 String &obsType, 147 String &bunit, 140 148 Float &equinox, 141 149 String &dopplerFrame, 142 150 Double &mjd, 143 151 Double &refFreq, 144 Double &bandwidth ,145 String &fluxunit) 146 { 147 char datobs[32], dopplerFrame_[32], observer_[32], obsType_[32],148 project_[32], radecsys[32], telescope[32];152 Double &bandwidth) 153 { 154 char bunit_[32], datobs[32], dopplerFrame_[32], observer_[32], 155 obsType_[32], project_[32], radecsys[32], telescope[32]; 156 int status; 149 157 float equinox_; 150 158 double antPos[3], utc; 151 159 152 if (cReader->getHeader(observer_, project_, telescope, antPos, obsType_, 153 equinox_, radecsys, dopplerFrame_, datobs, utc, 154 refFreq, bandwidth)) { 160 status = cReader->getHeader(observer_, project_, telescope, antPos, 161 obsType_, bunit_, equinox_, radecsys, 162 dopplerFrame_, datobs, utc, refFreq, bandwidth); 163 //logMsg(cReader->getMsg()); 164 //cReader->clearMsg(); 165 if (status) { 155 166 return 1; 156 167 } 157 168 158 fluxunit = "";159 169 observer = trim(observer_); 160 170 project = trim(project_); … … 165 175 antPosition(2) = antPos[2]; 166 176 obsType = trim(obsType_); 177 bunit = trim(bunit_); 167 178 equinox = equinox_; 168 179 dopplerFrame = trim(dopplerFrame_); … … 188 199 double *startfreq, *endfreq; 189 200 190 Int status; 191 if (!(status = cReader->getFreqInfo(nIF, startfreq, endfreq))) { 201 Int status = cReader->getFreqInfo(nIF, startfreq, endfreq); 202 203 //logMsg(cReader->getMsg()); 204 //cReader->clearMsg(); 205 if (!status) { 192 206 startFreq.takeStorage(IPosition(1,nIF), startfreq, TAKE_OVER); 193 207 endFreq.takeStorage(IPosition(1,nIF), endfreq, TAKE_OVER); … … 209 223 const Bool getSpectra, 210 224 const Bool getXPol, 211 const Bool getFeedPos) 225 const Bool getFeedPos, 226 const Bool getPointing, 227 const Int coordSys) 212 228 { 213 229 // Apply beam selection. … … 277 293 cGetXPol = getXPol; 278 294 cGetFeedPos = getFeedPos; 295 cGetPointing = getPointing; 296 cCoordSys = coordSys; 279 297 280 298 uInt maxNChan = cReader->select(start, end, ref, cGetSpectra, cGetXPol, 281 cGetFeedPos); 299 cGetFeedPos, cGetPointing, cCoordSys); 300 //logMsg(cReader->getMsg()); 301 //cReader->clearMsg(); 282 302 283 303 delete [] end; … … 302 322 double* posns; 303 323 304 Int status; 305 if (!(status = cReader->findRange(nRow, nSel, dateSpan, utcSpan, posns))) { 324 Int status = cReader->findRange(nRow, nSel, dateSpan, utcSpan, posns); 325 //logMsg(cReader->getMsg()); 326 //cReader->clearMsg(); 327 328 if (!status) { 306 329 timeSpan.resize(2); 307 330 … … 322 345 // Read the next data record. 323 346 324 Int PKSFITSreader::read( 325 Int &scanNo, 326 Int &cycleNo, 327 Double &mjd, 328 Double &interval, 329 String &fieldName, 330 String &srcName, 331 Vector<Double> &srcDir, 332 Vector<Double> &srcPM, 333 Double &srcVel, 334 String &obsType, 335 Int &IFno, 336 Double &refFreq, 337 Double &bandwidth, 338 Double &freqInc, 339 Vector<Double> &restFreq, 340 Vector<Float> &tcal, 341 String &tcalTime, 342 Float &azimuth, 343 Float &elevation, 344 Float &parAngle, 345 Float &focusAxi, 346 Float &focusTan, 347 Float &focusRot, 348 Float &temperature, 349 Float &pressure, 350 Float &humidity, 351 Float &windSpeed, 352 Float &windAz, 353 Int &refBeam, 354 Int &beamNo, 355 Vector<Double> &direction, 356 Vector<Double> &scanRate, 357 Vector<Float> &tsys, 358 Vector<Float> &sigma, 359 Vector<Float> &calFctr, 360 Matrix<Float> &baseLin, 361 Matrix<Float> &baseSub, 362 Matrix<Float> &spectra, 363 Matrix<uChar> &flagged, 364 Complex &xCalFctr, 365 Vector<Complex> &xPol) 366 { 367 Int status; 368 369 if ((status = cReader->read(cMBrec))) { 347 Int PKSFITSreader::read(PKSrecord &pksrec) 348 { 349 Int status = cReader->read(cMBrec); 350 //logMsg(cReader->getMsg()); 351 //cReader->clearMsg(); 352 353 if (status) { 370 354 if (status != -1) { 371 355 status = 1; … … 379 363 uInt nPol = cMBrec.nPol[0]; 380 364 381 scanNo = cMBrec.scanNo; 382 cycleNo = cMBrec.cycleNo; 365 pksrec.scanNo = cMBrec.scanNo; 366 pksrec.cycleNo = cMBrec.cycleNo; 367 pksrec.polNo = cMBrec.polNo ; 383 368 384 369 // Extract MJD. 385 370 Int day, month, year; 386 sscanf(cMBrec.datobs, "%4d-%2d-%2d", &year, &month, &day); 387 mjd = MVTime(year, month, Double(day)).day() + cMBrec.utc/86400.0; 388 389 interval = cMBrec.exposure; 390 391 fieldName = trim(cMBrec.srcName); 392 srcName = fieldName; 393 srcDir(0) = cMBrec.srcRA; 394 srcDir(1) = cMBrec.srcDec; 395 srcPM(0) = 0.0; 396 srcPM(1) = 0.0; 397 srcVel = 0.0; 398 obsType = trim(cMBrec.obsType); 399 400 IFno = cMBrec.IFno[0]; 371 if ( strstr( cMBrec.datobs, "T" ) == NULL ) { 372 sscanf(cMBrec.datobs, "%4d-%2d-%2d", &year, &month, &day); 373 pksrec.mjd = MVTime(year, month, Double(day)).day() + cMBrec.utc/86400.0; 374 } 375 else { 376 Double dd, hour, min, sec ; 377 sscanf( cMBrec.datobs, "%4d-%2d-%2lfT%lf:%lf:%lf", &year, &month, &dd, &hour, &min, &sec ) ; 378 dd = dd + ( hour * 3600.0 + min * 60.0 + sec ) / 86400.0 ; 379 pksrec.mjd = MVTime(year, month, dd).day() ; 380 } 381 382 pksrec.interval = cMBrec.exposure; 383 384 pksrec.fieldName = trim(cMBrec.srcName); 385 pksrec.srcName = pksrec.fieldName; 386 387 int namelen = pksrec.srcName.length() ; 388 if ( namelen > 4 ) { 389 String srcsub = pksrec.srcName.substr( namelen-4, 4 ) ; 390 if ( srcsub.find( "_psc" ) != string::npos ) { 391 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 392 pksrec.srcName = pksrec.fieldName + "_ps_calon" ; 393 } 394 else if ( srcsub.find( "_pso" ) != string::npos ) { 395 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 396 pksrec.srcName = pksrec.fieldName + "_ps" ; 397 } 398 else if ( srcsub.find( "_prc" ) != string::npos ) { 399 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 400 pksrec.srcName = pksrec.fieldName + "_psr_calon" ; 401 } 402 else if ( srcsub.find( "_pro" ) != string::npos ) { 403 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 404 pksrec.srcName = pksrec.fieldName + "_psr" ; 405 } 406 else if ( srcsub.find( "_fsc" ) != string::npos ) { 407 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 408 pksrec.srcName = pksrec.fieldName + "_fs_calon" ; 409 } 410 else if ( srcsub.find( "_fso" ) != string::npos ) { 411 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 412 pksrec.srcName = pksrec.fieldName + "_fs" ; 413 } 414 else if ( srcsub.find( "_frc" ) != string::npos ) { 415 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 416 pksrec.srcName = pksrec.fieldName + "_fsr_calon" ; 417 } 418 else if ( srcsub.find( "_fro" ) != string::npos ) { 419 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 420 pksrec.srcName = pksrec.fieldName + "_fsr" ; 421 } 422 else if ( srcsub.find( "_nsc" ) != string::npos || srcsub.find( "_nrc" ) != string::npos ) { 423 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 424 pksrec.srcName = pksrec.fieldName + "_nod_calon" ; 425 } 426 else if ( srcsub.find( "_nso" ) != string::npos || srcsub.find( "_nro" ) != string::npos ) { 427 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 428 pksrec.srcName = pksrec.fieldName + "_nod" ; 429 } 430 } 431 432 pksrec.srcDir.resize(2); 433 pksrec.srcDir(0) = cMBrec.srcRA; 434 pksrec.srcDir(1) = cMBrec.srcDec; 435 436 pksrec.srcPM.resize(2); 437 pksrec.srcPM(0) = 0.0; 438 pksrec.srcPM(1) = 0.0; 439 pksrec.srcVel = cMBrec.srcVelocity; 440 pksrec.obsType = trim(cMBrec.obsType); 441 442 pksrec.IFno = cMBrec.IFno[0]; 401 443 Double chanWidth = fabs(cMBrec.fqDelt[0]); 402 refFreq = cMBrec.fqRefVal[0]; 403 bandwidth = chanWidth * nChan; 404 freqInc = cMBrec.fqDelt[0]; 405 //restFreq = cMBrec.restFreq; 406 restFreq.resize(1); 407 restFreq(0) = cMBrec.restFreq; 408 409 tcal.resize(nPol); 444 pksrec.refFreq = cMBrec.fqRefVal[0]; 445 pksrec.bandwidth = chanWidth * nChan; 446 pksrec.freqInc = cMBrec.fqDelt[0]; 447 pksrec.restFreq.resize(1) ; 448 pksrec.restFreq(0) = cMBrec.restFreq; 449 450 pksrec.tcal.resize(nPol); 410 451 for (uInt ipol = 0; ipol < nPol; ipol++) { 411 tcal(ipol) = cMBrec.tcal[0][ipol]; 412 } 413 tcalTime = trim(cMBrec.tcalTime); 414 azimuth = cMBrec.azimuth; 415 elevation = cMBrec.elevation; 416 parAngle = cMBrec.parAngle; 417 focusAxi = cMBrec.focusAxi; 418 focusTan = cMBrec.focusTan; 419 focusRot = cMBrec.focusRot; 420 421 temperature = cMBrec.temp; 422 pressure = cMBrec.pressure; 423 humidity = cMBrec.humidity; 424 windSpeed = cMBrec.windSpeed; 425 windAz = cMBrec.windAz; 426 427 refBeam = cMBrec.refBeam; 428 beamNo = cMBrec.beamNo; 429 430 direction(0) = cMBrec.ra; 431 direction(1) = cMBrec.dec; 432 scanRate(0) = cMBrec.raRate; 433 scanRate(1) = cMBrec.decRate; 434 435 tsys.resize(nPol); 436 sigma.resize(nPol); 437 calFctr.resize(nPol); 452 pksrec.tcal(ipol) = cMBrec.tcal[0][ipol]; 453 } 454 pksrec.tcalTime = trim(cMBrec.tcalTime); 455 pksrec.azimuth = cMBrec.azimuth; 456 pksrec.elevation = cMBrec.elevation; 457 pksrec.parAngle = cMBrec.parAngle; 458 459 pksrec.focusAxi = cMBrec.focusAxi; 460 pksrec.focusTan = cMBrec.focusTan; 461 pksrec.focusRot = cMBrec.focusRot; 462 463 pksrec.temperature = cMBrec.temp; 464 pksrec.pressure = cMBrec.pressure; 465 pksrec.humidity = cMBrec.humidity; 466 pksrec.windSpeed = cMBrec.windSpeed; 467 pksrec.windAz = cMBrec.windAz; 468 469 pksrec.refBeam = cMBrec.refBeam; 470 pksrec.beamNo = cMBrec.beamNo; 471 472 pksrec.direction.resize(2); 473 pksrec.direction(0) = cMBrec.ra; 474 pksrec.direction(1) = cMBrec.dec; 475 pksrec.pCode = cMBrec.pCode; 476 pksrec.rateAge = cMBrec.rateAge; 477 pksrec.scanRate.resize(2); 478 pksrec.scanRate(0) = cMBrec.raRate; 479 pksrec.scanRate(1) = cMBrec.decRate; 480 pksrec.paRate = cMBrec.paRate; 481 482 pksrec.tsys.resize(nPol); 483 pksrec.sigma.resize(nPol); 484 pksrec.calFctr.resize(nPol); 438 485 for (uInt ipol = 0; ipol < nPol; ipol++) { 439 tsys(ipol) = cMBrec.tsys[0][ipol]; 440 sigma(ipol) = tsys(ipol) / 0.81 / sqrt(interval * chanWidth); 441 calFctr(ipol) = cMBrec.calfctr[0][ipol]; 486 pksrec.tsys(ipol) = cMBrec.tsys[0][ipol]; 487 pksrec.sigma(ipol) = (pksrec.tsys(ipol) / 0.81) / 488 sqrt(pksrec.interval * chanWidth); 489 pksrec.calFctr(ipol) = cMBrec.calfctr[0][ipol]; 442 490 } 443 491 444 492 if (cMBrec.haveBase) { 445 baseLin.resize(2,nPol);446 baseSub.resize(9,nPol);493 pksrec.baseLin.resize(2,nPol); 494 pksrec.baseSub.resize(24,nPol); 447 495 448 496 for (uInt ipol = 0; ipol < nPol; ipol++) { 449 baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0];450 baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1];451 452 for (uInt j = 0; j < 9; j++) {453 baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j];497 pksrec.baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0]; 498 pksrec.baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1]; 499 500 for (uInt j = 0; j < 24; j++) { 501 pksrec.baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j]; 454 502 } 455 503 } 456 504 457 505 } else { 458 baseLin.resize(0,0);459 baseSub.resize(0,0);506 pksrec.baseLin.resize(0,0); 507 pksrec.baseSub.resize(0,0); 460 508 } 461 509 462 510 if (cGetSpectra && cMBrec.haveSpectra) { 463 spectra.resize(nChan,nPol); 464 spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], SHARE); 465 466 flagged.resize(nChan,nPol); 467 flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], SHARE); 511 pksrec.spectra.resize(nChan,nPol); 512 pksrec.spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], 513 SHARE); 514 515 pksrec.flagged.resize(nChan,nPol); 516 pksrec.flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], 517 SHARE); 468 518 469 519 } else { 470 spectra.resize(0,0);471 flagged.resize(0,0);520 pksrec.spectra.resize(0,0); 521 pksrec.flagged.resize(0,0); 472 522 } 473 523 474 524 if (cGetXPol) { 475 xCalFctr = Complex(cMBrec.xcalfctr[0][0], cMBrec.xcalfctr[0][1]); 476 xPol.resize(nChan); 477 xPol.takeStorage(IPosition(1,nChan), (Complex *)cMBrec.xpol[0], SHARE); 525 pksrec.xCalFctr = Complex(cMBrec.xcalfctr[0][0], 526 cMBrec.xcalfctr[0][1]); 527 pksrec.xPol.resize(nChan); 528 pksrec.xPol.takeStorage(IPosition(1,nChan), (Complex *)cMBrec.xpol[0], 529 SHARE); 478 530 } 479 531 … … 481 533 } 482 534 483 //-------------------------------------------------------- PKSFITSreader::read484 485 // Read the next data record, just the basics.486 487 Int PKSFITSreader::read(488 Int &IFno,489 Vector<Float> &tsys,490 Vector<Float> &calFctr,491 Matrix<Float> &baseLin,492 Matrix<Float> &baseSub,493 Matrix<Float> &spectra,494 Matrix<uChar> &flagged)495 {496 Int status;497 498 if ((status = cReader->read(cMBrec))) {499 if (status != -1) {500 status = 1;501 }502 503 return status;504 }505 506 IFno = cMBrec.IFno[0];507 508 uInt nChan = cMBrec.nChan[0];509 uInt nPol = cMBrec.nPol[0];510 511 tsys.resize(nPol);512 calFctr.resize(nPol);513 for (uInt ipol = 0; ipol < nPol; ipol++) {514 tsys(ipol) = cMBrec.tsys[0][ipol];515 calFctr(ipol) = cMBrec.calfctr[0][ipol];516 }517 518 if (cMBrec.haveBase) {519 baseLin.resize(2,nPol);520 baseSub.resize(9,nPol);521 522 for (uInt ipol = 0; ipol < nPol; ipol++) {523 baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0];524 baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1];525 526 for (uInt j = 0; j < 9; j++) {527 baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j];528 }529 }530 531 } else {532 baseLin.resize(0,0);533 baseSub.resize(0,0);534 }535 536 if (cGetSpectra && cMBrec.haveSpectra) {537 spectra.resize(nChan,nPol);538 spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], SHARE);539 540 flagged.resize(nChan,nPol);541 flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], SHARE);542 543 } else {544 spectra.resize(0,0);545 flagged.resize(0,0);546 }547 548 return 0;549 }550 551 535 //------------------------------------------------------- PKSFITSreader::close 552 536 … … 556 540 { 557 541 cReader->close(); 542 //logMsg(cReader->getMsg()); 543 //cReader->clearMsg(); 558 544 } 559 545 -
branches/alma/external/atnf/PKSIO/PKSFITSreader.h
r1453 r1757 2 2 //# PKSFITSreader.h: Class to read Parkes Multibeam data from a FITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSFITSreader.h,v 19.18 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# This class is basically a wrapper class for reading data from either an … … 39 42 40 43 #include <atnf/PKSIO/FITSreader.h> 44 #include <atnf/PKSIO/PKSrecord.h> 41 45 #include <atnf/PKSIO/PKSreader.h> 42 46 43 47 #include <casa/aips.h> 48 #include <casa/stdio.h> 44 49 #include <casa/Arrays/Vector.h> 45 50 #include <casa/Arrays/Matrix.h> … … 47 52 #include <casa/BasicSL/String.h> 48 53 54 #include <casa/namespace.h> 55 49 56 // <summary> 50 57 // Class to read Parkes Multibeam data from a FITS file. 51 58 // </summary> 52 59 53 #include <casa/namespace.h>54 60 class PKSFITSreader : public PKSreader 55 61 { … … 67 73 virtual Int open( 68 74 const String fitsName, 75 const String antenna, 69 76 Vector<Bool> &beams, 70 77 Vector<Bool> &IFs, … … 82 89 Vector<Double> &antPosition, 83 90 String &obsType, 91 String &bunit, 84 92 Float &equinox, 85 93 String &dopplerFrame, 86 94 Double &mjd, 87 95 Double &refFreq, 88 Double &bandwidth, 89 String &fluxunit); 96 Double &bandwidth); 90 97 91 98 // Get frequency parameters for each IF. … … 104 111 const Bool getSpectra = True, 105 112 const Bool getXPol = False, 106 const Bool getFeedPos = False); 113 const Bool getFeedPos = False, 114 const Bool getPointing = False, 115 const Int coordSys = 0); 107 116 108 117 // Find the range of the data selected in time and position. … … 114 123 115 124 // Read the next data record. 116 virtual Int read( 117 Int &scanNo, 118 Int &cycleNo, 119 Double &mjd, 120 Double &interval, 121 String &fieldName, 122 String &srcName, 123 Vector<Double> &srcDir, 124 Vector<Double> &srcPM, 125 Double &srcVel, 126 String &obsType, 127 Int &IFno, 128 Double &refFreq, 129 Double &bandwidth, 130 Double &freqInc, 131 Vector<Double> &restFreq, 132 Vector<Float> &tcal, 133 String &tcalTime, 134 Float &azimuth, 135 Float &elevation, 136 Float &parAngle, 137 Float &focusAxi, 138 Float &focusTan, 139 Float &focusRot, 140 Float &temperature, 141 Float &pressure, 142 Float &humidity, 143 Float &windSpeed, 144 Float &windAz, 145 Int &refBeam, 146 Int &beamNo, 147 Vector<Double> &direction, 148 Vector<Double> &scanRate, 149 Vector<Float> &tsys, 150 Vector<Float> &sigma, 151 Vector<Float> &calFctr, 152 Matrix<Float> &baseLin, 153 Matrix<Float> &baseSub, 154 Matrix<Float> &spectra, 155 Matrix<uChar> &flagged, 156 Complex &xCalFctr, 157 Vector<Complex> &xPol); 158 159 // Read the next data record, just the basics. 160 virtual Int read( 161 Int &IFno, 162 Vector<Float> &tsys, 163 Vector<Float> &calFctr, 164 Matrix<Float> &baseLin, 165 Matrix<Float> &baseSub, 166 Matrix<Float> &spectra, 167 Matrix<uChar> &flagged); 125 virtual Int read(PKSrecord &pksrec); 168 126 169 127 // Close the FITS file. … … 173 131 Int *cBeams, *cIFs; 174 132 uInt cNBeam, cNIF; 175 PKSMBrecord cMBrec;133 MBrecord cMBrec; 176 134 FITSreader *cReader; 177 135 -
branches/alma/external/atnf/PKSIO/PKSMS2reader.cc
r1453 r1757 2 2 //# PKSMS2reader.cc: Class to read Parkes Multibeam data from a v2 MS. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 27 21 //# 28 //# $Id$ 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSMS2reader.cc,v 19.23 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/03, Mark Calabretta, ATNF 31 34 //#--------------------------------------------------------------------------- 32 33 35 34 36 // AIPS++ includes. … … 41 43 #include <casa/Quanta/MVAngle.h> 42 44 #include <casa/BasicMath/Math.h> 45 #include <casa/Logging/LogIO.h> 46 #include <casa/Utilities/Sort.h> 43 47 #include <measures/Measures/MeasConvert.h> 44 48 #include <measures/Measures/MEpoch.h> … … 48 52 // Parkes includes. 49 53 #include <atnf/pks/pks_maths.h> 54 #include <atnf/PKSIO/PKSrecord.h> 50 55 #include <atnf/PKSIO/PKSMS2reader.h> 51 56 … … 73 78 Int PKSMS2reader::open( 74 79 const String msName, 80 const String antenna, 75 81 Vector<Bool> &beams, 76 82 Vector<Bool> &IFs, … … 91 97 92 98 cPKSMS = MeasurementSet(msName); 99 100 // data selection by antenna 101 if ( antenna.length() == 0 ) { 102 cAntId.resize( 1 ) ; 103 cAntId[0] = 0 ; 104 } 105 else { 106 setupAntennaList( antenna ) ; 107 if ( cAntId.size() > 1 ) { 108 LogIO os( LogOrigin( "PKSMS2reader", "open()", WHERE ) ) ; 109 os << LogIO::WARN << "PKSMS2reader is not ready for multiple antenna selection. Use first antenna id " << cAntId[0] << "."<< LogIO::POST ; 110 Int tmp = cAntId[0] ; 111 cAntId.resize( 1 ) ; 112 cAntId[0] = tmp ; 113 } 114 stringstream ss ; 115 ss << "SELECT FROM $1 WHERE ANTENNA1 == ANTENNA2 && ANTENNA1 IN [" ; 116 for ( uInt i = 0 ; i < cAntId.size() ; i++ ) { 117 ss << cAntId[i] ; 118 if ( i == cAntId.size()-1 ) { 119 ss << "]" ; 120 } 121 else { 122 ss << "," ; 123 } 124 } 125 string taql = ss.str() ; 126 //cerr << "taql = " << taql << endl ; 127 cPKSMS = MeasurementSet( tableCommand( taql, cPKSMS ) ) ; 128 } 129 93 130 // taql access to the syscal table 94 131 cHaveSysCal = False; … … 97 134 } 98 135 136 // Lock the table for read access. 137 cPKSMS.lock(False); 138 99 139 cIdx = 0; 100 140 lastmjd = 0.0; 101 141 cNRow = cPKSMS.nrow(); 102 142 cMSopen = True; 103 104 // Lock the table for read access.105 cPKSMS.lock(False);106 143 107 144 // Main MS table and subtable column access. … … 140 177 cSigStateCol.reference(stateCols.sig()); 141 178 cRefStateCol.reference(stateCols.ref()); 179 142 180 cDataDescIdCol.reference(msCols.dataDescId()); 143 181 cSpWinIdCol.reference(dataDescCols.spectralWindowId()); 144 182 cChanFreqCol.reference(spWinCols.chanFreq()); 183 cTotBWCol.reference(spWinCols.totalBandwidth()); 145 184 146 185 cWeatherTimeCol.reference(weatherCols.time()); … … 151 190 cBeamNoCol.reference(msCols.feed1()); 152 191 cPointingCol.reference(pointingCols.direction()); 192 cPointingTimeCol.reference(pointingCols.time()); 153 193 cSigmaCol.reference(msCols.sigma()); 154 194 cNumReceptorCol.reference(feedCols.numReceptors()); … … 182 222 cHaveDataCol = False; 183 223 cHaveCorrectedDataCol = False; 184 //String telName = antennaCols.name()(0);185 224 ROMSObservationColumns observationCols(cPKSMS.observation()); 186 String telName = observationCols.telescopeName()(0); 187 //cATF = (telName.contains("DA41") || telName.contains("DV01")); 188 cATF = telName.contains("ATF"); 225 //String telName = observationCols.telescopeName()(0); 226 cTelName = observationCols.telescopeName()(0); 227 //cATF = cTelName.contains("ATF"); 228 //cOSF = cTelName.contains("OSF"); 229 //cALMA = cTelName.contains("ALMA"); 230 cALMA = cTelName.contains("ATF")||cTelName.contains("OSF")|| 231 cTelName.contains("ALMA"); 189 232 190 233 if (cHaveDataCol = cPKSMS.isColumn(MSMainEnums::DATA)) { 191 if (cA TF) {234 if (cALMA) { 192 235 //try to read a single baseline interferometeric data 193 236 //and treat it as single dish data … … 204 247 } 205 248 cFlagCol.reference(msCols.flag()); 206 207 208 if (cGetXPol = (cPKSMS.isColumn(MSMainEnums::DATA) && (!cA TF))) {249 cFlagRowCol.reference(msCols.flagRow()); 250 251 if (cGetXPol = (cPKSMS.isColumn(MSMainEnums::DATA) && (!cALMA))) { 209 252 if ((cHaveXCalFctr = cPKSMS.tableDesc().isColumn("XCALFCTR"))) { 210 253 cXCalFctrCol.attach(cPKSMS, "XCALFCTR"); … … 228 271 //uInt nIF = dataDescCols.nrow(); 229 272 uInt nIF =spWinCols.nrow(); 273 Vector<Int> spWinIds = cSpWinIdCol.getColumn() ; 230 274 IFs.resize(nIF); 231 275 IFs = True; 276 for ( Int ispw = 0 ; ispw < nIF ; ispw++ ) { 277 if ( allNE( ispw, spWinIds ) ) { 278 IFs(ispw) = False ; 279 } 280 } 232 281 233 282 // Number of polarizations and channels in each IF. 234 ROScalarColumn<Int> spWinIdCol(dataDescCols.spectralWindowId());235 283 ROScalarColumn<Int> numChanCol(spWinCols.numChan()); 236 284 … … 241 289 nPol.resize(nIF); 242 290 for (uInt iIF = 0; iIF < nIF; iIF++) { 243 nChan(iIF) = numChanCol(spWinIdCol(iIF)); 244 nPol(iIF) = numPolCol(polIdCol(iIF)); 291 if ( IFs(iIF) ) { 292 nChan(iIF) = numChanCol(cSpWinIdCol(iIF)) ; 293 nPol(iIF) = numPolCol(polIdCol(iIF)) ; 294 } 295 else { 296 nChan(iIF) = 0 ; 297 nPol(iIF) = 0 ; 298 } 245 299 } 246 300 … … 249 303 haveXPol = False; 250 304 251 if (cGetXPol && !(cA TF)) {305 if (cGetXPol && !(cALMA)) { 252 306 for (Int irow = 0; irow < cNRow; irow++) { 253 307 if (cDataCol.isDefined(irow)) { … … 298 352 String &antName, 299 353 Vector<Double> &antPosition, 300 String &obsMode, 354 // before merge... 355 //String &obsMode, 356 String &obsType, 357 String &bunit, 301 358 Float &equinox, 302 359 String &dopplerFrame, 303 360 Double &mjd, 304 361 Double &refFreq, 305 Double &bandwidth, 306 String &fluxunit) 362 Double &bandwidth) 307 363 { 308 364 if (!cMSopen) { … … 317 373 // Antenna name and ITRF coordinates. 318 374 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 319 antName = antennaCols.name()(0); 320 antPosition = antennaCols.position()(0); 375 //antName = antennaCols.name()(0); 376 antName = antennaCols.name()(cAntId[0]); 377 if (cALMA) { 378 antName = cTelName + "-" + antName; 379 } 380 //antPosition = antennaCols.position()(0); 381 antPosition = antennaCols.position()(cAntId[0]); 321 382 322 383 // Observation type. 323 384 if (cObsModeCol.nrow()) { 324 obs Mode = cObsModeCol(0);325 if (obs Mode == "\0") obsMode = "RF";385 obsType = cObsModeCol(0); 386 if (obsType == "\0") obsType = "RF"; 326 387 } else { 327 obs Mode = "RF";328 } 329 330 fluxunit = "";388 obsType = "RF"; 389 } 390 391 bunit = ""; 331 392 if (cHaveDataCol) { 332 393 const TableRecord& keywordSet2 333 394 = cDataCol.columnDesc().keywordSet(); 334 395 if(keywordSet2.isDefined("UNIT")) { 335 fluxunit = keywordSet2.asString("UNIT");396 bunit = keywordSet2.asString("UNIT"); 336 397 } 337 398 } else { … … 339 400 = cFloatDataCol.columnDesc().keywordSet(); 340 401 if(keywordSet.isDefined("UNIT")) { 341 fluxunit = keywordSet.asString("UNIT");402 bunit = keywordSet.asString("UNIT"); 342 403 } 343 404 } … … 354 415 String dirref = pointingCols.direction().keywordSet().asRecord("MEASINFO"). 355 416 asString("Ref"); 417 cDirRef = dirref; 418 if (dirref =="AZELGEO" || dirref == "AZEL") { 419 dirref = "J2000"; 420 } 356 421 sscanf(dirref.chars()+1, "%f", &equinox); 357 422 … … 422 487 const Bool getSpectra, 423 488 const Bool getXPol, 424 const Bool getFeedPos) 489 const Bool getFeedPos, 490 const Bool getPointing, 491 const Int coordSys) 425 492 { 426 493 if (!cMSopen) { … … 504 571 cGetFeedPos = False; 505 572 573 // Get Pointing data (for MS) 574 cGetPointing = getPointing; 575 576 // Coordinate system? (Only equatorial available.) 577 cCoordSys = 0; 578 506 579 return maxNChan; 507 580 } … … 555 628 // Read the next data record. 556 629 630 /** 557 631 Int PKSMS2reader::read( 558 632 Int &scanNo, … … 595 669 Matrix<Float> &spectra, 596 670 Matrix<uChar> &flagged, 671 uInt &flagrow, 597 672 Complex &xCalFctr, 598 673 Vector<Complex> &xPol) 674 **/ 675 Int PKSMS2reader::read(PKSrecord &pksrec) 599 676 { 677 LogIO os( LogOrigin( "PKSMS2reader", "read()", WHERE ) ) ; 678 600 679 if (!cMSopen) { 601 680 return 1; … … 627 706 // Renumerate scan no. Here still is 1-based 628 707 //scanNo = cScanNoCol(cIdx) - cScanNoCol(0) + 1; 629 scanNo = cScanNoCol(cIdx); 630 631 if (scanNo != cScanNo) { 708 //scanNo = cScanNoCol(cIdx); 709 pksrec.scanNo = cScanNoCol(cIdx); 710 711 if (pksrec.scanNo != cScanNo) { 632 712 // Start of new scan. 633 cScanNo = scanNo;713 cScanNo = pksrec.scanNo; 634 714 cCycleNo = 1; 635 715 cTime = cTimeCol(cIdx); … … 637 717 638 718 Double time = cTimeCol(cIdx); 639 mjd = time/86400.0;640 interval = cIntervalCol(cIdx);719 pksrec.mjd = time/86400.0; 720 pksrec.interval = cIntervalCol(cIdx); 641 721 642 722 // Reconstruct the integration cycle number; due to small latencies the 643 723 // integration time is usually slightly less than the time between cycles, 644 724 // resetting cTime will prevent the difference from accumulating. 645 cCycleNo += nint((time - cTime)/ interval);646 cycleNo = cCycleNo;647 cTime 725 cCycleNo += nint((time - cTime)/pksrec.interval); 726 pksrec.cycleNo = cCycleNo; 727 cTime = time; 648 728 649 729 Int fieldId = cFieldIdCol(cIdx); 650 fieldName = cFieldNameCol(fieldId);730 pksrec.fieldName = cFieldNameCol(fieldId); 651 731 652 732 Int srcId = cSrcIdCol(fieldId); … … 656 736 for (uInt irow = 0; irow < cSrcId2Col.nrow(); irow++) { 657 737 if (cSrcId2Col(irow) == srcId) { 658 srcName = cSrcNameCol(irow); 659 } 660 } 661 662 srcDir = cSrcDirCol(srcId); 663 srcPM = cSrcPMCol(srcId); 738 //srcName = cSrcNameCol(irow); 739 pksrec.srcName = cSrcNameCol(irow); 740 } 741 } 742 743 pksrec.srcDir = cSrcDirCol(srcId); 744 pksrec.srcPM = cSrcPMCol(srcId); 664 745 665 746 // Systemic velocity. 666 if (!cHaveSrcVel || cA TF) {667 srcVel = 0.0f;747 if (!cHaveSrcVel || cALMA) { 748 pksrec.srcVel = 0.0f; 668 749 } else { 669 srcVel= cSrcVelCol(srcId)(IPosition(1,0));750 pksrec.srcVel = cSrcVelCol(srcId)(IPosition(1,0)); 670 751 } 671 752 672 753 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 673 String telescope = antennaCols.name()(0); 754 //String telescope = antennaCols.name()(0); 755 String telescope = antennaCols.name()(cAntId[0]); 674 756 Bool cGBT = telescope.contains("GBT"); 757 //Bool cPM = telescope.contains("PM"); // ACA TP antenna 758 //Bool cDV = telescope.contains("DV"); // VERTEX 759 //Bool cCM = telescope.contains("CM"); // ACA 7m antenna 760 //Bool cALMA = cPM || cDV || cCM ; 675 761 // Observation type. 676 762 // check if State Table exist … … 680 766 StateNRow=cObsModeCol.nrow(); 681 767 if (Table::isReadable(cPKSMS.stateTableName())) { 682 obsMode = " ";768 pksrec.obsType = " "; 683 769 if (StateNRow > 0) { 684 770 stateId = cStateIdCol(cIdx); 685 771 if (stateId == -1) { 686 // obsMode = " ";772 //pksrec.obsType = " "; 687 773 } else { 688 obsMode = cObsModeCol(stateId);774 pksrec.obsType = cObsModeCol(stateId); 689 775 Bool sigState =cSigStateCol(stateId); 690 776 Bool refState =cRefStateCol(stateId); 691 777 //DEBUG 692 //cerr <<"stateid="<<stateId<<" obsmode="<< obsMode<<endl;778 //cerr <<"stateid="<<stateId<<" obsmode="<<pksrec.obsType<<endl; 693 779 if (cGBT) { 694 // split the obs Mode string and append a proper label780 // split the obsType string and append a proper label 695 781 // (these are GBT specific) 696 int epos = obsMode.find_first_of(':');697 int nextpos = obsMode.find_first_of(':',epos+1);698 string obsMode1 = obsMode.substr(0,epos);699 string obsMode2 = obsMode.substr(epos+1,nextpos-epos-1);782 int epos = pksrec.obsType.find_first_of(':'); 783 int nextpos = pksrec.obsType.find_first_of(':',epos+1); 784 string obsMode1 = pksrec.obsType.substr(0,epos); 785 string obsMode2 = pksrec.obsType.substr(epos+1,nextpos-epos-1); 700 786 701 787 //cerr <<"obsMode2= "<<obsMode2<<endl; 702 if (! srcName.contains("_ps")703 &&! srcName.contains("_psr")704 &&! srcName.contains("_nod")705 &&! srcName.contains("_fs")706 &&! srcName.contains("_fsr")) {788 if (!pksrec.srcName.contains("_ps") 789 &&!pksrec.srcName.contains("_psr") 790 &&!pksrec.srcName.contains("_nod") 791 &&!pksrec.srcName.contains("_fs") 792 &&!pksrec.srcName.contains("_fsr")) { 707 793 // if Nod mode observation , append '_nod' 708 794 if (obsMode1 == "Nod") { 709 srcName.append("_nod"); 795 //pksrec.srcName.append("_nod"); 796 pksrec.srcType = SrcType::NOD ; 710 797 } else if (obsMode1 == "OffOn") { 711 798 // for GBT position switch observations (OffOn or OnOff) 712 if (obsMode2 == "PSWITCHON") srcName.append("_ps"); 713 if (obsMode2 == "PSWITCHOFF") srcName.append("_psr"); 799 //if (obsMode2 == "PSWITCHON") pksrec.srcName.append("_ps"); 800 //if (obsMode2 == "PSWITCHOFF") pksrec.srcName.append("_psr"); 801 if (obsMode2 == "PSWITCHON") pksrec.srcType = SrcType::PSON ; 802 if (obsMode2 == "PSWITCHOFF") pksrec.srcType = SrcType::PSOFF ; 714 803 } else { 715 804 if (obsMode2 == "FSWITCH") { 716 805 // for GBT frequency switch mode 717 if (sigState) srcName.append("_fs"); 718 if (refState) srcName.append("_fsr"); 806 //if (sigState) pksrec.srcName.append("_fs"); 807 //if (refState) pksrec.srcName.append("_fsr"); 808 if (sigState) pksrec.srcType = SrcType::FSON ; 809 if (refState) pksrec.srcType = SrcType::FSOFF ; 719 810 } 720 811 } 721 812 } 722 813 } 814 else if (cALMA) { 815 // ALMA tag 816 // split the obsType string and append a proper label 817 string substr[1] ; 818 int numSubstr = split( pksrec.obsType, substr, 1, "," ); 819 String obsType = String( substr[0] ); 820 int epos = obsType.find_first_of('.'); 821 int nextpos = obsType.find_first_of('.',epos+1); 822 string obsMode1 = obsType.substr(0,epos); 823 string obsMode2 = obsType.substr(epos+1,nextpos-epos-1); 824 825 //cerr <<"obsMode2= "<<obsMode2<<endl; 826 // Current OBS_MODE format: 827 // 828 // ON: OBSERVE_TARGET.ON_SOURCE 829 // OFF: OBSERVE_TARGET.OFF_SOURCE 830 // 831 if (obsMode1 == "OBSERVE_TARGET") { 832 //if (obsMode2 == "ON_SOURCE") pksrec.srcName.append("_pson"); 833 //if (obsMode2 == "OFF_SOURCE") pksrec.srcName.append("_psoff"); 834 if (obsMode2 == "ON_SOURCE") pksrec.srcType = SrcType::PSON ; 835 if (obsMode2 == "OFF_SOURCE") pksrec.srcType = SrcType::PSOFF ; 836 } 837 } 723 838 } 724 839 } … … 733 848 } 734 849 if (cGBT) { 735 if (Cal > 0 && !srcName.contains("_calon")) { 736 srcName.append("_calon"); 737 } 738 } 739 740 IFno = iIF + 1; 850 if (Cal > 0 && !pksrec.srcName.contains("_calon")) { 851 //pksrec.srcName.append("_calon"); 852 if ( pksrec.srcType == SrcType::NOD ) 853 pksrec.srcType = SrcType::NODCAL ; 854 else if ( pksrec.srcType == SrcType::PSON ) 855 pksrec.srcType = SrcType::PONCAL ; 856 else if ( pksrec.srcType == SrcType::PSOFF ) 857 pksrec.srcType = SrcType::POFFCAL ; 858 else if ( pksrec.srcType == SrcType::FSON ) 859 pksrec.srcType = SrcType::FONCAL ; 860 else if ( pksrec.srcType == SrcType::FSOFF ) 861 pksrec.srcType = SrcType::FOFFCAL ; 862 else 863 pksrec.srcName.append("_calon"); 864 } 865 } 866 867 pksrec.IFno = iIF + 1; 741 868 Int nChan = abs(cEndChan(iIF) - cStartChan(iIF)) + 1; 742 869 743 870 // Minimal handling on continuum data. 744 871 Vector<Double> chanFreq = cChanFreqCol(iIF); 872 pksrec.nchan = nChan; 745 873 if (nChan == 1) { 746 freqInc = chanFreq(0); 747 refFreq = chanFreq(0); 748 restFreq = 0.0f; 874 //pksrec.freqInc = chanFreq(0); 875 pksrec.freqInc = cTotBWCol(iIF); 876 pksrec.refFreq = chanFreq(0); 877 pksrec.restFreq.resize(1); 878 pksrec.restFreq[0] = 0.0f; 749 879 } else { 750 880 751 881 if (cStartChan(iIF) <= cEndChan(iIF)) { 752 freqInc = chanFreq(1) - chanFreq(0);882 pksrec.freqInc = chanFreq(1) - chanFreq(0); 753 883 } else { 754 freqInc = chanFreq(0) - chanFreq(1); 755 } 756 refFreq = chanFreq(cRefChan(iIF)-1); 884 pksrec.freqInc = chanFreq(0) - chanFreq(1); 885 } 886 887 pksrec.refFreq = chanFreq(cRefChan(iIF)-1); 888 757 889 Bool HaveSrcRestFreq= cSrcRestFrqCol.isDefined(srcId); 758 890 if (HaveSrcRestFreq) { 759 891 //restFreq = cSrcRestFrqCol(srcId)(IPosition(1,0)); 760 restFreq = cSrcRestFrqCol(srcId); 892 //restFreq = cSrcRestFrqCol(srcId); 893 pksrec.restFreq = cSrcRestFrqCol(srcId); 761 894 } else { 762 restFreq = 0.0f; 763 } 764 } 765 bandwidth = abs(freqInc * nChan); 766 767 tcal.resize(cNPol(iIF)); 768 tcal = 0.0f; 769 tcalTime = ""; 770 //azimuth = 0.0f; 771 //elevation = 0.0f; 772 parAngle = 0.0f; 773 focusAxi = 0.0f; 774 focusTan = 0.0f; 775 focusRot = 0.0f; 895 pksrec.restFreq.resize(1); 896 pksrec.restFreq[0] = 0.0f; 897 } 898 } 899 //pksrec.bandwidth = abs(pksrec.freqInc * nChan); 900 pksrec.bandwidth = abs(cTotBWCol(0)); 901 902 pksrec.tcal.resize(cNPol(iIF)); 903 pksrec.tcal = 0.0f; 904 pksrec.tcalTime = ""; 905 // pksrec.azimuth = 0.0f; 906 // pksrec.elevation = 0.0f; 907 pksrec.parAngle = 0.0f; 908 909 pksrec.focusAxi = 0.0f; 910 pksrec.focusTan = 0.0f; 911 pksrec.focusRot = 0.0f; 776 912 777 913 // Find the appropriate entry in the WEATHER subtable. … … 787 923 } 788 924 } 925 789 926 if (weatherIdx < 0 || !cHaveWeatherTab) { 790 927 // No appropriate WEATHER entry. 791 p ressure= 0.0f;792 humidity= 0.0f;793 temperature= 0.0f;928 pksrec.temperature = 0.0f; 929 pksrec.pressure = 0.0f; 930 pksrec.humidity = 0.0f; 794 931 } else { 795 pressure = cPressureCol(weatherIdx); 796 humidity = cHumidityCol(weatherIdx); 797 temperature = cTemperatureCol(weatherIdx); 798 } 799 800 windSpeed = 0.0f; 801 windAz = 0.0f; 802 803 refBeam = 0; 804 beamNo = ibeam + 1; 805 806 //Matrix<Double> pointingDir = cPointingCol(fieldId); 807 //pointingDir = cPointingCol(fieldId); 808 //direction = pointingDir.column(0); 809 //uInt ncols = pointingDir.ncolumn(); 810 //if (ncols == 1) { 811 // scanRate = 0.0f; 812 //} else { 813 // scanRate = pointingDir.column(1); 814 //} 815 932 pksrec.temperature = cTemperatureCol(weatherIdx); 933 pksrec.pressure = cPressureCol(weatherIdx); 934 pksrec.humidity = cHumidityCol(weatherIdx); 935 } 936 937 pksrec.windSpeed = 0.0f; 938 pksrec.windAz = 0.0f; 939 940 pksrec.refBeam = 0; 941 pksrec.beamNo = ibeam + 1; 942 943 //pointing/azel 944 MVPosition mvpos(antennaCols.position()(cAntId[0])); 945 MPosition mp(mvpos); 946 Quantum<Double> qt(time,"s"); 947 MVEpoch mvt(qt); 948 MEpoch me(mvt); 949 MeasFrame frame(mp, me); 950 MDirection md; 951 pksrec.pCode = 0; 952 pksrec.rateAge = 0.0f; 953 pksrec.paRate = 0.0f; 954 if (cGetPointing) { 955 //cerr << "get pointing data ...." << endl; 956 ROScalarColumn<Int> pAntIdCol ; 957 ROScalarColumn<Double> psTimeCol ; 958 Table ptTable = cPKSMS.pointing() ; 959 MSPointing selPtTab( ptTable( ptTable.col("ANTENNA_ID") == cAntId[0] ) ) ; 960 pAntIdCol.attach( selPtTab, "ANTENNA_ID" ) ; 961 Vector<Int> antIds = pAntIdCol.getColumn() ; 962 psTimeCol.attach( selPtTab, "TIME" ) ; 963 Vector<Double> pTimes = psTimeCol.getColumn(); 964 Bool doInterp = False ; 965 Int PtIdx=-1; 966 for (PtIdx = pTimes.nelements()-1; PtIdx >= 0; PtIdx--) { 967 if ( pTimes[PtIdx] == time ) { 968 break ; 969 } 970 else if ( pTimes[PtIdx] < time ) { 971 if ( PtIdx != pTimes.nelements()-1 ) { 972 doInterp = True ; 973 } 974 break ; 975 } 976 } 977 if ( PtIdx == -1 ) { 978 PtIdx = 0 ; 979 } 980 //cerr << "got index=" << PtIdx << endl; 981 Matrix<Double> pointingDir = cPointingCol(PtIdx); 982 ROMSPointingColumns PtCols( selPtTab ) ; 983 Vector<Double> pointingDirVec ; 984 if ( doInterp ) { 985 Double dt1 = time - pTimes[PtIdx] ; 986 Double dt2 = pTimes[PtIdx+1] - time ; 987 Vector<Double> dirVec1 = pointingDir.column(0) ; 988 Matrix<Double> pointingDir2 = cPointingCol(PtIdx+1) ; 989 Vector<Double> dirVec2 = pointingDir2.column(0) ; 990 pointingDirVec = (dt1*dirVec2+dt2*dirVec1)/(dt1+dt2) ; 991 Vector<MDirection> vmd1(1) ; 992 Vector<MDirection> vmd2(1) ; 993 PtCols.directionMeasCol().get(PtIdx,vmd1) ; 994 Vector<Double> angle1 = vmd1(0).getAngle().getValue("rad") ; 995 PtCols.directionMeasCol().get(PtIdx+1,vmd2) ; 996 Vector<Double> angle2 = vmd2(0).getAngle().getValue("rad") ; 997 Vector<Double> angle = (dt1*angle2+dt2*angle1)/(dt1+dt2) ; 998 Quantum< Vector<Double> > qangle( angle, "rad" ) ; 999 String typeStr = vmd1(0).getRefString() ; 1000 //cerr << "vmd1.getRefString()=" << typeStr << endl ; 1001 MDirection::Types mdType ; 1002 MDirection::getType( mdType, typeStr ) ; 1003 //cerr << "mdType=" << mdType << endl ; 1004 md = MDirection( qangle, mdType ) ; 1005 //cerr << "md=" << md.getAngle().getValue("rad") << endl ; 1006 } 1007 else { 1008 pointingDirVec = pointingDir.column(0) ; 1009 Vector<MDirection> vmd(1); 1010 PtCols.directionMeasCol().get(PtIdx,vmd); 1011 md = vmd[0]; 1012 } 1013 // put J2000 coordinates in "direction" 1014 if (cDirRef =="J2000") { 1015 pksrec.direction = pointingDirVec ; 1016 } 1017 else { 1018 pksrec.direction = 1019 MDirection::Convert(md, MDirection::Ref(MDirection::J2000, 1020 frame) 1021 )().getAngle("rad").getValue(); 1022 1023 } 1024 uInt ncols = pointingDir.ncolumn(); 1025 pksrec.scanRate.resize(2); 1026 if (ncols == 1) { 1027 pksrec.scanRate = 0.0f; 1028 } else { 1029 pksrec.scanRate(0) = pointingDir.column(1)(0); 1030 pksrec.scanRate(1) = pointingDir.column(1)(1); 1031 } 1032 } 1033 else { 816 1034 // Get direction from FIELD table 817 1035 // here, assume direction to be the field direction not pointing 818 Matrix<Double> delayDir = cFieldDelayDirCol(fieldId); 819 direction = delayDir.column(0); 820 uInt ncols = delayDir.ncolumn(); 821 if (ncols == 1) { 822 scanRate = 0.0f; 823 } else { 824 scanRate = delayDir.column(1); 825 } 826 1036 Matrix<Double> delayDir = cFieldDelayDirCol(fieldId); 1037 pksrec.direction = delayDir.column(0); 1038 uInt ncols = delayDir.ncolumn(); 1039 pksrec.scanRate.resize(2); 1040 if (ncols == 1) { 1041 pksrec.scanRate = 0.0f; 1042 } else { 1043 pksrec.scanRate(0) = delayDir.column(1)(0); 1044 pksrec.scanRate(1) = delayDir.column(1)(1); 1045 } 1046 } 827 1047 // caluculate azimuth and elevation 828 1048 // first, get the reference frame 1049 /** 829 1050 MVPosition mvpos(antennaCols.position()(0)); 830 1051 MPosition mp(mvpos); … … 833 1054 MEpoch me(mvt); 834 1055 MeasFrame frame(mp, me); 1056 **/ 835 1057 // 836 1058 ROMSFieldColumns fldCols(cPKSMS.field()); 837 1059 Vector<MDirection> vmd(1); 838 MDirection md;1060 //MDirection md; 839 1061 fldCols.delayDirMeasCol().get(fieldId,vmd); 840 1062 md = vmd[0]; … … 847 1069 )().getAngle("rad").getValue(); 848 1070 //cerr<<"azel="<<azel<<endl; 849 azimuth = azel[0];850 elevation = azel[1];1071 pksrec.azimuth = azel[0]; 1072 pksrec.elevation = azel[1]; 851 1073 852 1074 // Get Tsys assuming that entries in the SYSCAL table match the main table. … … 858 1080 } 859 1081 if (cHaveTsys) { 860 cTsysCol.get(cIdx, tsys, True);1082 cTsysCol.get(cIdx, pksrec.tsys, True); 861 1083 } else { 862 1084 Int numReceptor; 863 1085 cNumReceptorCol.get(0, numReceptor); 864 tsys.resize(numReceptor);865 tsys = 1.0f;866 } 867 cSigmaCol.get(cIdx, sigma, True);1086 pksrec.tsys.resize(numReceptor); 1087 pksrec.tsys = 1.0f; 1088 } 1089 cSigmaCol.get(cIdx, pksrec.sigma, True); 868 1090 869 1091 //get Tcal if available … … 875 1097 if (nTcalColRow > 0) { 876 1098 // find tcal match with the data with the data time stamp 877 Double mjds = mjd*(24*3600);1099 Double mjds = pksrec.mjd*(24*3600); 878 1100 Double dtcalTime; 879 if ( mjd > lastmjd || cIdx==0 ) {1101 if ( pksrec.mjd > lastmjd || cIdx==0 ) { 880 1102 //Table tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds)); 881 1103 tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds), nrws); … … 898 1120 ROScalarColumn<Double> tcalTimeCol(tmptab2, "TIME"); 899 1121 if (syscalrow==0) { 900 cerr<<"Cannot find any matching Tcal at/near the data timestamp." 901 << " Set Tcal=0.0"<<endl; 1122 os << LogIO::NORMAL 1123 <<"Cannot find any matching Tcal at/near the data timestamp." 1124 << " Set Tcal=0.0" << LogIO::POST ; 902 1125 } else { 903 tcalCol.get(0, tcal);1126 tcalCol.get(0, pksrec.tcal); 904 1127 tcalTimeCol.get(0,dtcalTime); 905 tcalTime = MVTime(dtcalTime/(24*3600)).string(MVTime::YMD);1128 pksrec.tcalTime = MVTime(dtcalTime/(24*3600)).string(MVTime::YMD); 906 1129 //DEBUG 907 1130 //cerr<<"cIdx:"<<cIdx<<" tcal="<<tcal<<" tcalTime="<<tcalTime<<endl; … … 910 1133 } 911 1134 } 912 lastmjd = mjd;1135 lastmjd = pksrec.mjd; 913 1136 } 914 1137 915 1138 // Calibration factors (if available). 916 calFctr.resize(cNPol(iIF));1139 pksrec.calFctr.resize(cNPol(iIF)); 917 1140 if (cHaveCalFctr) { 918 cCalFctrCol.get(cIdx, calFctr);1141 cCalFctrCol.get(cIdx, pksrec.calFctr); 919 1142 } else { 920 calFctr = 0.0f;1143 pksrec.calFctr = 0.0f; 921 1144 } 922 1145 923 1146 // Baseline parameters (if available). 924 1147 if (cHaveBaseLin) { 925 baseLin.resize(2,cNPol(iIF));926 cBaseLinCol.get(cIdx, baseLin);927 928 baseSub.resize(9,cNPol(iIF));929 cBaseSubCol.get(cIdx, baseSub);1148 pksrec.baseLin.resize(2,cNPol(iIF)); 1149 cBaseLinCol.get(cIdx, pksrec.baseLin); 1150 1151 pksrec.baseSub.resize(24,cNPol(iIF)); 1152 cBaseSubCol.get(cIdx, pksrec.baseSub); 930 1153 931 1154 } else { 932 baseLin.resize(0,0); 933 baseSub.resize(0,0); 934 } 1155 pksrec.baseLin.resize(0,0); 1156 pksrec.baseSub.resize(0,0); 1157 } 1158 1159 935 1160 // Get spectral data. 936 1161 if (cGetSpectra) { … … 960 1185 // Transpose spectra. 961 1186 Int nPol = tmpData.nrow(); 962 spectra.resize(nChan, nPol);963 flagged.resize(nChan, nPol);1187 pksrec.spectra.resize(nChan, nPol); 1188 pksrec.flagged.resize(nChan, nPol); 964 1189 if (cEndChan(iIF) >= cStartChan(iIF)) { 965 1190 // Simple transposition. 966 1191 for (Int ipol = 0; ipol < nPol; ipol++) { 967 1192 for (Int ichan = 0; ichan < nChan; ichan++) { 968 spectra(ichan,ipol) = tmpData(ipol,ichan);969 flagged(ichan,ipol) = tmpFlag(ipol,ichan);1193 pksrec.spectra(ichan,ipol) = tmpData(ipol,ichan); 1194 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,ichan); 970 1195 } 971 1196 } … … 976 1201 for (Int ipol = 0; ipol < nPol; ipol++) { 977 1202 for (Int ichan = 0; ichan < nChan; ichan++, jchan--) { 978 spectra(ichan,ipol) = tmpData(ipol,jchan);979 flagged(ichan,ipol) = tmpFlag(ipol,jchan);1203 pksrec.spectra(ichan,ipol) = tmpData(ipol,jchan); 1204 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,jchan); 980 1205 } 981 1206 } 982 1207 } 1208 1209 // Row-based flagging info. (True:1, False:0) 1210 pksrec.flagrow = (cFlagRowCol(cIdx) ? 1 : 0); 983 1211 } 984 1212 … … 989 1217 990 1218 if (cHaveXCalFctr) { 991 cXCalFctrCol.get(cIdx, xCalFctr);1219 cXCalFctrCol.get(cIdx, pksrec.xCalFctr); 992 1220 } else { 993 xCalFctr = Complex(0.0f, 0.0f);994 } 995 996 if(!cA TF) {997 cDataCol.get(cIdx, xPol, True);1221 pksrec.xCalFctr = Complex(0.0f, 0.0f); 1222 } 1223 1224 if(!cALMA) { 1225 cDataCol.get(cIdx, pksrec.xPol, True); 998 1226 999 1227 if (cEndChan(iIF) < cStartChan(iIF)) { … … 1001 1229 Int jchan = nChan - 1; 1002 1230 for (Int ichan = 0; ichan < nChan/2; ichan++, jchan--) { 1003 ctmp = xPol(ichan);1004 xPol(ichan) =xPol(jchan);1005 xPol(jchan) = ctmp;1231 ctmp = pksrec.xPol(ichan); 1232 pksrec.xPol(ichan) = pksrec.xPol(jchan); 1233 pksrec.xPol(jchan) = ctmp; 1006 1234 } 1007 1235 } … … 1097 1325 cBaseLinCol.get(cIdx, baseLin); 1098 1326 1099 baseSub.resize( 9,cNPol(iIF));1327 baseSub.resize(24,cNPol(iIF)); 1100 1328 cBaseSubCol.get(cIdx, baseSub); 1101 1329 … … 1158 1386 cMSopen = False; 1159 1387 } 1388 1389 //-------------------------------------------------------- PKSMS2reader::splitAntenanSelectionString 1390 1391 // split antenna selection string 1392 // delimiter is ',' 1393 1394 Vector<String> PKSMS2reader::splitAntennaSelectionString( const String s ) 1395 { 1396 Char delim = ',' ; 1397 Int n = s.freq( delim ) + 1 ; 1398 Vector<String> antlist ; 1399 string sl[n] ; 1400 Int numSubstr = split( s, sl, n, "," ); 1401 antlist.resize( numSubstr ) ; 1402 for ( Int i = 0 ; i < numSubstr ; i++ ) { 1403 antlist[i] = String( sl[i] ) ; 1404 antlist[i].trim() ; 1405 } 1406 //cerr << "antlist = " << antlist << endl ; 1407 return antlist ; 1408 } 1409 1410 //-------------------------------------------------------- PKSMS2reader::setupAntennaList 1411 1412 // Fill cAntenna and cAntId 1413 1414 void PKSMS2reader::setupAntennaList( const String s ) 1415 { 1416 LogIO os( LogOrigin( "PKSMS2reader", "setupAntennaList()", WHERE ) ) ; 1417 //cerr << "antenna specification: " << s << endl ; 1418 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 1419 ROScalarColumn<String> antNames = antennaCols.name(); 1420 Int nrow = antNames.nrow() ; 1421 Vector<String> antlist = splitAntennaSelectionString( s ) ; 1422 Int len = antlist.size() ; 1423 Vector<Int> AntId( len ) ; 1424 Regex re( "[0-9]+" ) ; 1425 for ( Int i = 0 ; i < len ; i++ ) { 1426 if ( antlist[i].matches( re ) ) { 1427 AntId[i] = atoi( antlist[i].c_str() ) ; 1428 if ( AntId[i] >= nrow ) { 1429 os << LogIO::SEVERE << "Antenna index out of range: " << AntId[i] << LogIO::EXCEPTION ; 1430 } 1431 } 1432 else { 1433 AntId[i] = -1 ; 1434 for ( uInt j = 0 ; j < antNames.nrow() ; j++ ) { 1435 if ( antlist[i] == antNames(j) ) { 1436 AntId[i] = j ; 1437 break ; 1438 } 1439 } 1440 if ( AntId[i] == -1 ) { 1441 os << LogIO::SEVERE << "Specified antenna name not found: " << antlist[i] << LogIO::EXCEPTION ; 1442 } 1443 } 1444 } 1445 //cerr << "AntId = " << AntId << endl ; 1446 vector<Int> uniqId ; 1447 uniqId.push_back( AntId(0) ) ; 1448 for ( uInt i = 1 ; i < AntId.size() ; i++ ) { 1449 if ( count(uniqId.begin(),uniqId.end(),AntId[i]) == 0 ) { 1450 uniqId.push_back( AntId[i] ) ; 1451 } 1452 } 1453 Vector<Int> newAntId( uniqId ) ; 1454 cAntId.assign( newAntId ) ; 1455 //cerr << "cAntId = " << cAntId << endl ; 1456 } -
branches/alma/external/atnf/PKSIO/PKSMS2reader.h
r1453 r1757 2 2 //# PKSMS2reader.h: Class to read Parkes Multibeam data from a v2 MS. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSMS2reader.h,v 19.18 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/03, Mark Calabretta, ATNF … … 35 38 36 39 #include <atnf/PKSIO/PKSreader.h> 40 #include <atnf/PKSIO/PKSrecord.h> 37 41 38 42 #include <casa/aips.h> … … 46 50 #include <tables/Tables/ScalarColumn.h> 47 51 52 #include <casa/namespace.h> 53 48 54 // <summary> 49 55 // Class to read Parkes Multibeam data from a v2 MS. 50 56 // </summary> 51 52 #include <casa/namespace.h>53 57 54 58 class PKSMS2reader : public PKSreader … … 64 68 virtual Int open( 65 69 const String msName, 70 const String antenna, 66 71 Vector<Bool> &beams, 67 72 Vector<Bool> &IFs, … … 79 84 Vector<Double> &antPosition, 80 85 String &obsMode, 86 String &bunit, 81 87 Float &equinox, 82 String &freqRef, 88 //String &freqRef, 89 String &dopplerFrame, 83 90 Double &mjd, 84 91 Double &refFreq, 85 Double &bandwidth, 86 String &fluxunit); 92 Double &bandwidth); 87 93 88 94 // Get frequency parameters for each IF. … … 101 107 const Bool getSpectra = True, 102 108 const Bool getXPol = False, 103 const Bool getFeedPos = False); 109 const Bool getFeedPos = False, 110 const Bool getPointing = False, 111 const Int coordSys = 0); 112 104 113 105 114 // Find the range of the data selected in time and position. … … 111 120 112 121 // Read the next data record. 122 /** 113 123 virtual Int read( 114 124 Int &scanNo, … … 153 163 Complex &xCalFctr, 154 164 Vector<Complex> &xPol); 165 **/ 166 virtual Int read(PKSrecord &pksrec); 167 155 168 156 169 // Read the next data record, just the basics. … … 168 181 169 182 private: 183 Vector<String> splitAntennaSelectionString( const String s ); 184 void setupAntennaList( const String s ) ; 185 170 186 Bool cHaveBaseLin, cHaveCalFctr, cHaveSrcVel, cHaveTsys, cHaveXCalFctr, 171 cMSopen, cHaveTcal, cHaveDataCol, cA TF, cHaveSysCal, cHaveCorrectedDataCol;187 cMSopen, cHaveTcal, cHaveDataCol, cALMA, cHaveSysCal, cHaveCorrectedDataCol; 172 188 Int cCycleNo, cIdx, cNRow, cScanNo; 173 189 Double cTime, lastmjd; … … 175 191 Vector<Bool> cBeams, cIFs; 176 192 Vector<Slicer> cDataSel; 193 String cDirRef, cTelName; 177 194 MeasurementSet cPKSMS; 178 195 Table cSysCalTab, tmptab, tmptab2; 196 197 //Vector<String> cAntenna; 198 Vector<Int> cAntId; 179 199 180 200 ROScalarColumn<Int> cScanNoCol; … … 197 217 ROScalarColumn<Int> cSpWinIdCol; 198 218 ROArrayColumn<Double> cChanFreqCol; 219 ROScalarColumn<Double> cTotBWCol; 199 220 ROScalarColumn<Double> cWeatherTimeCol; 200 221 ROScalarColumn<Float> cTemperatureCol; … … 204 225 ROScalarColumn<Int> cBeamNoCol; 205 226 ROArrayColumn<Double> cPointingCol; 227 ROScalarColumn<Double> cPointingTimeCol; 206 228 ROArrayColumn<Float> cTsysCol; 207 229 ROArrayColumn<Float> cSigmaCol; … … 211 233 ROArrayColumn<Float> cFloatDataCol; 212 234 ROArrayColumn<Bool> cFlagCol; 235 ROScalarColumn<Bool> cFlagRowCol; 213 236 ROScalarColumn<Complex> cXCalFctrCol; 214 237 ROArrayColumn<Complex> cDataCol; -
branches/alma/external/atnf/PKSIO/PKSMS2writer.cc
r1453 r1757 2 2 //# PKSMS2writer.cc: Class to write Parkes multibeam data to a measurementset. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 27 21 //# 28 //# $Id: PKSMS2writer.cc,v 19.11 2006/11/06 22:25:22 mmarquar Exp $ 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSMS2writer.cc,v 19.16 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 34 #include <atnf/PKSIO/PKSrecord.h> 31 35 #include <atnf/PKSIO/PKSMS2writer.h> 32 36 … … 49 53 #include <tables/Tables/TiledShapeStMan.h> 50 54 55 // Class name 56 const string className = "PKSMS2writer" ; 57 51 58 //------------------------------------------------- PKSMS2writer::PKSMS2writer 52 59 … … 55 62 PKSMS2writer::PKSMS2writer() 56 63 { 64 cPKSMS = 0x0; 57 65 } 58 66 … … 77 85 const Vector<Double> antPosition, 78 86 const String obsMode, 87 const String bunit, 79 88 const Float equinox, 80 89 const String dopplerFrame, … … 82 91 const Vector<uInt> nPol, 83 92 const Vector<Bool> haveXPol, 84 const Bool haveBase, 85 const String fluxUnit) 86 { 93 const Bool haveBase) 94 { 95 const string methodName = "create()" ; 96 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 97 98 if (cPKSMS) { 99 os << LogIO::SEVERE << "Output MS already open, close it first." << LogIO::POST ; 100 return 1; 101 } 102 87 103 // Open a MS table. 88 104 TableDesc pksDesc = MS::requiredTableDesc(); … … 93 109 94 110 Int maxNPol = max(cNPol); 95 cGBT = cAPEX = cSMT = cALMA = False; 96 111 cGBT = cAPEX = cSMT = cALMA = cATF = False; 112 113 String telName = antName; 97 114 // check if it is GBT data 98 115 if (antName.contains("GBT")) { … … 108 125 cALMA = True; 109 126 } 127 else if (antName.contains("ATF")) { 128 cATF = True; 129 telName="ATF"; 130 } 110 131 111 112 113 //cGBT = antName.contains("GBT");114 //cAPEX = antName.contains("APEX");115 //cSMT = antName.contains("HHT");116 //cALMA = antName.contains("ALMA");117 118 132 // Add the non-standard CALFCTR column. 119 133 pksDesc.addColumn(ArrayColumnDesc<Float>("CALFCTR", "Calibration factors", … … 125 139 // define("UNIT", String("Jy")); 126 140 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). 127 define("UNIT", fluxUnit);141 define("UNIT", bunit); 128 142 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). 129 143 define("MEASURE_TYPE", ""); … … 134 148 IPosition(2,2,maxNPol), ColumnDesc::Direct)); 135 149 pksDesc.addColumn(ArrayColumnDesc<Float>("BASESUB", "Baseline subtracted", 136 IPosition(2, 9,maxNPol), ColumnDesc::Direct));150 IPosition(2,24,maxNPol), ColumnDesc::Direct)); 137 151 } 138 152 … … 147 161 // define("UNIT", "Jy"); 148 162 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). 149 define("UNIT", fluxUnit);163 define("UNIT", bunit); 150 164 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). 151 165 define("MEASURE_TYPE", ""); … … 387 401 addFeedEntry(); 388 402 //addObservationEntry(observer, project); 389 addObservationEntry(observer, project, antName);403 addObservationEntry(observer, project, telName); 390 404 addProcessorEntry(); 391 405 … … 397 411 // Write the next data record. 398 412 413 /** 399 414 Int PKSMS2writer::write( 400 415 const Int scanNo, … … 438 453 const Matrix<Float> &spectra, 439 454 const Matrix<uChar> &flagged, 455 const uInt flagrow, 440 456 const Complex xCalFctr, 441 457 const Vector<Complex> &xPol) 458 **/ 459 Int PKSMS2writer::write( 460 const PKSrecord &pksrec) 442 461 { 443 462 // Extend the time range in the OBSERVATION subtable. 444 463 Vector<Double> timerange(2); 445 464 cObservationCols->timeRange().get(0, timerange); 446 Double time = mjd*86400.0;465 Double time = pksrec.mjd*86400.0; 447 466 if (timerange(0) == 0.0) { 448 467 timerange(0) = time; … … 451 470 cObservationCols->timeRange().put(0, timerange); 452 471 453 Int iIF = IFno - 1;472 Int iIF = pksrec.IFno - 1; 454 473 Int nChan = cNChan(iIF); 455 474 Int nPol = cNPol(iIF); … … 457 476 // IFno is the 1-relative row number in the DATA_DESCRIPTION, 458 477 // SPECTRAL_WINDOW, and POLARIZATION subtables. 459 if (Int(cDataDescription.nrow()) < IFno) {478 if (Int(cDataDescription.nrow()) < pksrec.IFno) { 460 479 // Add a new entry to each subtable. 461 addDataDescriptionEntry(IFno); 462 addSpectralWindowEntry(IFno, nChan, refFreq, bandwidth, freqInc); 463 addPolarizationEntry(IFno, nPol); 480 addDataDescriptionEntry(pksrec.IFno); 481 addSpectralWindowEntry(pksrec.IFno, nChan, pksrec.refFreq, 482 pksrec.bandwidth, pksrec.freqInc); 483 addPolarizationEntry(pksrec.IFno, nPol); 464 484 } 465 485 466 486 // Find or add the source to the SOURCE subtable. 467 Int srcId = addSourceEntry(srcName, srcDir, srcPM, restFreq, srcVel); 487 Int srcId = addSourceEntry(pksrec.srcName, pksrec.srcDir, pksrec.srcPM, 488 pksrec.restFreq, pksrec.srcVel); 468 489 469 490 // Find or add the obsMode to the STATE subtable. 470 Int stateId = addStateEntry( obsMode);491 Int stateId = addStateEntry(pksrec.obsType); 471 492 472 493 // FIELD subtable. 473 Int fieldId = addFieldEntry(fieldName, time, direction, scanRate, srcId); 494 //Vector<Double> scanRate(2); 495 //scanRate(0) = pksrec.scanRate(0); 496 //scanRate(1) = pksrec.scanRate(1); 497 Int fieldId = addFieldEntry(pksrec.fieldName, time, pksrec.direction, 498 pksrec.scanRate, srcId); 474 499 475 500 // POINTING subtable. 476 addPointingEntry(time, interval, fieldName, direction, scanRate); 501 addPointingEntry(time, pksrec.interval, pksrec.fieldName, pksrec.direction, 502 pksrec.scanRate); 477 503 478 504 // SYSCAL subtable. 479 addSysCalEntry( beamNo, iIF, time, interval, tcal, tsys, nPol);480 505 addSysCalEntry(pksrec.beamNo, iIF, time, pksrec.interval, pksrec.tcal, 506 pksrec.tsys, nPol); 481 507 482 508 // Handle weather information. … … 484 510 Int nWeather = wTime.nrow(); 485 511 if (nWeather == 0 || time > wTime(nWeather-1)) { 486 addWeatherEntry(time, interval, pressure, humidity, temperature); 512 addWeatherEntry(time, pksrec.interval, pksrec.pressure, pksrec.humidity, 513 pksrec.temperature); 487 514 } 488 515 … … 496 523 cMSCols->antenna1().put(irow, 0); 497 524 cMSCols->antenna2().put(irow, 0); 498 cMSCols->feed1().put(irow, beamNo-1);499 cMSCols->feed2().put(irow, beamNo-1);525 cMSCols->feed1().put(irow, pksrec.beamNo-1); 526 cMSCols->feed2().put(irow, pksrec.beamNo-1); 500 527 cMSCols->dataDescId().put(irow, iIF); 501 528 cMSCols->processorId().put(irow, 0); … … 503 530 504 531 // Non-key attributes. 505 cMSCols->interval().put(irow, interval);506 cMSCols->exposure().put(irow, interval);532 cMSCols->interval().put(irow, pksrec.interval); 533 cMSCols->exposure().put(irow, pksrec.interval); 507 534 cMSCols->timeCentroid().put(irow, time); 508 cMSCols->scanNumber().put(irow, scanNo);535 cMSCols->scanNumber().put(irow, pksrec.scanNo); 509 536 cMSCols->arrayId().put(irow, 0); 510 537 cMSCols->observationId().put(irow, 0); … … 516 543 // Baseline fit parameters. 517 544 if (cHaveBase) { 518 cBaseLinCol->put(irow, baseLin);519 520 if ( baseSub.nrow() == 9) {521 cBaseSubCol->put(irow, baseSub);545 cBaseLinCol->put(irow, pksrec.baseLin); 546 547 if (pksrec.baseSub.nrow() == 24) { 548 cBaseSubCol->put(irow, pksrec.baseSub); 522 549 523 550 } else { 524 Matrix<Float> tmp( 9, 2, 0.0f);551 Matrix<Float> tmp(24, 2, 0.0f); 525 552 for (Int ipol = 0; ipol < nPol; ipol++) { 526 for (uInt j = 0; j < baseSub.nrow(); j++) {527 tmp(j,ipol) = baseSub(j,ipol);553 for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) { 554 tmp(j,ipol) = pksrec.baseSub(j,ipol); 528 555 } 529 556 } … … 531 558 } 532 559 } 560 533 561 // Transpose spectra. 534 562 Matrix<Float> tmpData(nPol, nChan); … … 536 564 for (Int ipol = 0; ipol < nPol; ipol++) { 537 565 for (Int ichan = 0; ichan < nChan; ichan++) { 538 tmpData(ipol,ichan) = spectra(ichan,ipol);539 tmpFlag(ipol,ichan) = flagged(ichan,ipol);566 tmpData(ipol,ichan) = pksrec.spectra(ichan,ipol); 567 tmpFlag(ipol,ichan) = pksrec.flagged(ichan,ipol); 540 568 } 541 569 } 542 cCalFctrCol->put(irow, calFctr); 570 571 cCalFctrCol->put(irow, pksrec.calFctr); 543 572 cMSCols->floatData().put(irow, tmpData); 544 573 cMSCols->flag().put(irow, tmpFlag); … … 546 575 // Cross-polarization spectra. 547 576 if (cHaveXPol(iIF)) { 548 cXCalFctrCol->put(irow, xCalFctr);549 cMSCols->data().put(irow, xPol);550 } 551 552 cMSCols->sigma().put(irow, sigma);577 cXCalFctrCol->put(irow, pksrec.xCalFctr); 578 cMSCols->data().put(irow, pksrec.xPol); 579 } 580 581 cMSCols->sigma().put(irow, pksrec.sigma); 553 582 554 583 //Vector<Float> weight(1, 1.0f); … … 563 592 //cMSCols->flag().put(irow, flags.xyPlane(0)); 564 593 cMSCols->flagCategory().put(irow, flags); 565 cMSCols->flagRow().put(irow, False); 594 // Row-based flagging info. (True:>0, False:0) 595 cMSCols->flagRow().put(irow, (pksrec.flagrow > 0)); 596 566 597 567 598 return 0; … … 601 632 delete cXCalFctrCol; cXCalFctrCol=0; 602 633 } 603 634 604 635 // Release all subtables. 605 636 cAntenna = MSAntenna(); … … 620 651 cWeather = MSWeather(); 621 652 // Release the main table. 622 delete cPKSMS; cPKSMS=0; 653 delete cPKSMS; 654 cPKSMS=0x0; 623 655 } 624 656 … … 649 681 } 650 682 else if (cALMA) { 683 // this needs to be changed in future... 651 684 cAntennaCols->station().put(n, "CHAJNANTOR"); 685 cAntennaCols->dishDiameter().put(n, 12.0); 686 } 687 else if (cATF) { 688 //pad name for the antenna is static... 689 String stname="unknown"; 690 if (antName.contains("DV")) { 691 stname="PAD001"; 692 } 693 if (antName.contains("DA")) { 694 stname="PAD002"; 695 } 696 cAntennaCols->station().put(n, stname); 652 697 cAntennaCols->dishDiameter().put(n, 12.0); 653 698 } … … 1095 1140 1096 1141 Int PKSMS2writer::addStateEntry( 1097 const String obs Mode)1142 const String obsType) 1098 1143 { 1099 1144 // Look for an entry in the STATE subtable. 1100 1145 for (uInt n = 0; n < cStateCols->nrow(); n++) { 1101 if (cStateCols->obsMode()(n) == obs Mode) {1146 if (cStateCols->obsMode()(n) == obsType) { 1102 1147 return n; 1103 1148 } … … 1109 1154 1110 1155 // Data. 1111 if (obs Mode.contains("RF")) {1156 if (obsType.contains("RF")) { 1112 1157 cStateCols->sig().put(n, False); 1113 1158 cStateCols->ref().put(n, True); 1114 } else if (!obs Mode.contains("PA")) {1159 } else if (!obsType.contains("PA")) { 1115 1160 // Signal and reference are both false for "paddle" data. 1116 1161 cStateCols->sig().put(n, True); … … 1121 1166 cStateCols->cal().put(n, 0.0); 1122 1167 cStateCols->subScan().put(n, 0); 1123 cStateCols->obsMode().put(n, obs Mode);1168 cStateCols->obsMode().put(n, obsType); 1124 1169 1125 1170 // Flags. -
branches/alma/external/atnf/PKSIO/PKSMS2writer.h
r1453 r1757 2 2 //# PKSMS2writer.h: Class to write Parkes Multibeam data to a measurementset. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSMS2writer.h,v 19.14 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 … … 32 35 #define ATNF_PKSMS2WRITER_H 33 36 37 #include <atnf/PKSIO/PKSrecord.h> 34 38 #include <atnf/PKSIO/PKSwriter.h> 35 39 … … 38 42 #include <casa/Arrays/Vector.h> 39 43 #include <casa/BasicSL/Complex.h> 44 #include <casa/BasicSL/String.h> 40 45 #include <ms/MeasurementSets/MeasurementSet.h> 41 46 #include <ms/MeasurementSets/MSColumns.h> 42 #include <casa/BasicSL/String.h> 47 48 #include <casa/namespace.h> 43 49 44 50 // <summary> … … 46 52 // </summary> 47 53 48 #include <casa/namespace.h>49 54 class PKSMS2writer : public PKSwriter 50 55 { … … 64 69 const Vector<Double> antPosition, 65 70 const String obsMode, 71 const String bunit, 66 72 const Float equinox, 67 73 const String dopplerFrame, … … 69 75 const Vector<uInt> nPol, 70 76 const Vector<Bool> haveXPol, 71 const Bool haveBase, 72 const String fluxUnit); 77 const Bool haveBase); 73 78 74 79 // Write the next data record. 80 /** 75 81 virtual Int write( 76 82 const Int scanNo, … … 114 120 const Matrix<Float> &spectra, 115 121 const Matrix<uChar> &flagged, 122 const uInt flagrow, 116 123 const Complex xCalFctr, 117 124 const Vector<Complex> &xPol); 125 **/ 126 virtual Int write( 127 const PKSrecord &pksrec); 118 128 119 129 // Close the MS, flushing all associated Tables. … … 168 178 169 179 // for handling parameters specific to GBT and other telescopes 170 Bool cGBT; 171 Bool cSMT; 172 Bool cAPEX; 173 Bool cALMA; 180 Bool cGBT, cSMT, cAPEX, cALMA, cATF; 174 181 175 182 // Add an entry to the ANTENNA subtable. -
branches/alma/external/atnf/PKSIO/PKSSDwriter.cc
r1453 r1757 2 2 //# PKSSDwriter.cc: Class to write Parkes multibeam data to an SDFITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but 13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSSDwriter.cc,v 19.17 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 31 #include <atnf/PKSIO/ PKSMBrecord.h>34 #include <atnf/PKSIO/MBrecord.h> 32 35 #include <atnf/PKSIO/PKSSDwriter.h> 33 36 37 #include <casa/Logging/LogIO.h> 38 39 #include <casa/stdio.h> 34 40 #include <casa/Quanta/MVTime.h> 35 41 42 #include <string> 43 #include <cstring> 44 45 // Class name 46 const string className = "PKSSDwriter" ; 36 47 37 48 //--------------------------------------------------- PKSSDwriter::PKSSDwriter … … 63 74 const Vector<Double> antPosition, 64 75 const String obsMode, 76 const String bunit, 65 77 const Float equinox, 66 78 const String dopplerFrame, … … 68 80 const Vector<uInt> nPol, 69 81 const Vector<Bool> haveXPol, 70 const Bool haveBase, 71 const String fluxUnit) 72 { 82 const Bool haveBase) 83 { 84 const string methodName = "create()" ; 85 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 86 73 87 double antPos[3]; 74 88 antPos[0] = antPosition(0); … … 78 92 cNIF = nChan.nelements(); 79 93 if (nPol.nelements() != cNIF || haveXPol.nelements() != cNIF) { 80 cerr << "PKSSDwriter::create: " 81 << "Inconsistent number of IFs for nChan, nPol, and/or haveXPol." 82 << endl; 94 os << LogIO::SEVERE << "Inconsistent number of IFs for nChan, nPol, and/or haveXPol." << LogIO::POST ; 83 95 return 1; 84 96 } … … 102 114 Int status = cSDwriter.create((char *)sdName.chars(), 103 115 (char *)observer.chars(), (char *)project.chars(), 104 (char *)antName.chars(), antPos, (char *)obsMode.chars(), equinox,105 (char *) dopplerFrame.chars(), cNIF,116 (char *)antName.chars(), antPos, (char *)obsMode.chars(), 117 (char *)bunit.chars(), equinox, (char *)dopplerFrame.chars(), cNIF, 106 118 (int *)cNChan.getStorage(deleteIt), 107 119 (int *)cNPol.getStorage(deleteIt), 108 120 (int *)cHaveXPol.getStorage(deleteIt), (int)cHaveBase, 1); 121 //logMsg(cSDwriter.getMsg()); 122 //cSDwriter.clearMsg(); 109 123 if (status) { 110 cSDwriter.reportError();111 124 cSDwriter.deleteFile(); 112 125 close(); … … 121 134 122 135 Int PKSSDwriter::write( 123 const Int scanNo, 124 const Int cycleNo, 125 const Double mjd, 126 const Double interval, 127 const String fieldName, 128 const String srcName, 129 const Vector<Double> srcDir, 130 const Vector<Double> srcPM, 131 const Double srcVel, 132 const String obsMode, 133 const Int IFno, 134 const Double refFreq, 135 const Double bandwidth, 136 const Double freqInc, 137 //const Double restFreq, 138 const Vector<Double> restFreq, 139 const Vector<Float> tcal, 140 const String tcalTime, 141 const Float azimuth, 142 const Float elevation, 143 const Float parAngle, 144 const Float focusAxi, 145 const Float focusTan, 146 const Float focusRot, 147 const Float temperature, 148 const Float pressure, 149 const Float humidity, 150 const Float windSpeed, 151 const Float windAz, 152 const Int refBeam, 153 const Int beamNo, 154 const Vector<Double> direction, 155 const Vector<Double> scanRate, 156 const Vector<Float> tsys, 157 const Vector<Float> sigma, 158 const Vector<Float> calFctr, 159 const Matrix<Float> baseLin, 160 const Matrix<Float> baseSub, 161 const Matrix<Float> &spectra, 162 const Matrix<uChar> &flagged, 163 const Complex xCalFctr, 164 const Vector<Complex> &xPol) 165 { 136 const PKSrecord &pksrec) 137 { 138 const string methodName = "write()" ; 139 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 140 166 141 // Do basic checks. 142 Int IFno = pksrec.IFno; 167 143 uInt iIF = IFno - 1; 168 144 if (IFno < 1 || Int(cNIF) < IFno) { 169 cerr << "PKSDwriter::write: "170 171 << " (maximum " << cNIF << ")." << endl;145 os << LogIO::SEVERE 146 << "Invalid IF number " << IFno 147 << " (maximum " << cNIF << ")." << LogIO::POST ; 172 148 return 1; 173 149 } 174 150 175 uInt nChan = spectra.nrow();151 uInt nChan = pksrec.spectra.nrow(); 176 152 if (nChan != cNChan(iIF)) { 177 cerr << "PKSDwriter::write: " 178 << "Wrong number of channels for IF " << IFno << "," << endl 179 << " " 153 os << LogIO::SEVERE << "Wrong number of channels for IF " << IFno << "," << endl 180 154 << "got " << nChan << " should be " << cNChan(iIF) << "." << endl; 155 os << LogIO::POST ; 181 156 return 1; 182 157 } 183 158 184 uInt nPol = spectra.ncolumn();159 uInt nPol = pksrec.spectra.ncolumn(); 185 160 if (nPol != cNPol(iIF)) { 186 cerr << "PKSDwriter::write: " 187 << "Wrong number of polarizations for IF " << IFno << "," << endl 188 << " " 189 << "got " << nPol << " should be " << cNPol(iIF) << "." << endl; 161 os << LogIO::SEVERE << "Wrong number of polarizations for IF " << IFno << "," << endl 162 << "got " << nPol << " should be " << cNPol(iIF) << "." << endl; 163 os << LogIO::POST ; 190 164 return 1; 191 165 } 192 166 193 // Extract calendar information fr om mjd.194 MVTime time( mjd);167 // Extract calendar information frrom mjd. 168 MVTime time(pksrec.mjd); 195 169 Int year = time.year(); 196 170 Int month = time.month(); 197 171 Int day = time.monthday(); 198 172 199 // Transfer data to a single-IF PKSMBrecord.200 PKSMBrecord mbrec(1);173 // Transfer data to a single-IF MBrecord. 174 MBrecord mbrec(1); 201 175 202 176 // Start with basic beam- and IF-independent bookkeeping information. 203 mbrec.scanNo = scanNo;204 mbrec.cycleNo = cycleNo;177 mbrec.scanNo = pksrec.scanNo; 178 mbrec.cycleNo = pksrec.cycleNo; 205 179 206 180 sprintf(mbrec.datobs, "%4.4d-%2.2d-%2.2d", year, month, day); 207 mbrec.utc = fmod(mjd, 1.0) * 86400.0; 208 mbrec.exposure = float(interval); 209 210 strncpy(mbrec.srcName, (char *)srcName.chars(), 17); 211 mbrec.srcRA = srcDir(0); 212 mbrec.srcDec = srcDir(1); 213 214 //mbrec.restFreq = restFreq; 215 mbrec.restFreq = restFreq(0); 216 217 strncpy(mbrec.obsType, (char *)obsMode.chars(), 16); 181 mbrec.utc = fmod(pksrec.mjd, 1.0) * 86400.0; 182 mbrec.exposure = float(pksrec.interval); 183 184 strncpy(mbrec.srcName, (char *)pksrec.srcName.chars(), 17); 185 mbrec.srcRA = pksrec.srcDir(0); 186 mbrec.srcDec = pksrec.srcDir(1); 187 if (pksrec.restFreq.shape()==0) { 188 mbrec.restFreq = 0; 189 } 190 else { 191 mbrec.restFreq = pksrec.restFreq(0); 192 } 193 strncpy(mbrec.obsType, (char *)pksrec.obsType.chars(), 16); 218 194 219 195 // Now beam-dependent parameters. 220 mbrec.beamNo = beamNo;221 mbrec.ra = direction(0);222 mbrec.dec = direction(1);223 mbrec.raRate = scanRate(0);224 mbrec.decRate = scanRate(1);196 mbrec.beamNo = pksrec.beamNo; 197 mbrec.ra = pksrec.direction(0); 198 mbrec.dec = pksrec.direction(1); 199 mbrec.raRate = pksrec.scanRate(0); 200 mbrec.decRate = pksrec.scanRate(1); 225 201 226 202 // Now IF-dependent parameters. … … 231 207 232 208 mbrec.fqRefPix[0] = (nChan/2) + 1; 233 mbrec.fqRefVal[0] = refFreq;234 mbrec.fqDelt[0] = freqInc;209 mbrec.fqRefVal[0] = pksrec.refFreq; 210 mbrec.fqDelt[0] = pksrec.freqInc; 235 211 236 212 // Now the data itself. 237 for (uInt i = 0; i < tsys.nelements(); i++) {238 mbrec.tsys[0][i] = tsys(i);213 for (uInt i = 0; i < pksrec.tsys.nelements(); i++) { 214 mbrec.tsys[0][i] = pksrec.tsys(i); 239 215 } 240 216 241 217 for (uInt ipol = 0; ipol < nPol; ipol++) { 242 mbrec.calfctr[0][ipol] = calFctr(ipol);218 mbrec.calfctr[0][ipol] = pksrec.calFctr(ipol); 243 219 } 244 220 245 221 if (cHaveXPol(iIF)) { 246 mbrec.xcalfctr[0][0] = xCalFctr.real();247 mbrec.xcalfctr[0][1] = xCalFctr.imag();222 mbrec.xcalfctr[0][0] = pksrec.xCalFctr.real(); 223 mbrec.xcalfctr[0][1] = pksrec.xCalFctr.imag(); 248 224 } else { 249 225 mbrec.xcalfctr[0][0] = 0.0f; … … 255 231 256 232 for (uInt ipol = 0; ipol < nPol; ipol++) { 257 mbrec.baseLin[0][ipol][0] = baseLin(0,ipol);258 mbrec.baseLin[0][ipol][1] = baseLin(1,ipol);259 260 for (uInt j = 0; j < baseSub.nrow(); j++) {261 mbrec.baseSub[0][ipol][j] = baseSub(j,ipol);233 mbrec.baseLin[0][ipol][0] = pksrec.baseLin(0,ipol); 234 mbrec.baseLin[0][ipol][1] = pksrec.baseLin(1,ipol); 235 236 for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) { 237 mbrec.baseSub[0][ipol][j] = pksrec.baseSub(j,ipol); 262 238 } 263 for (uInt j = baseSub.nrow(); j < 9; j++) {239 for (uInt j = pksrec.baseSub.nrow(); j < 24; j++) { 264 240 mbrec.baseSub[0][ipol][j] = 0.0f; 265 241 } … … 271 247 272 248 Bool delSpectra = False; 273 const Float *specstor = spectra.getStorage(delSpectra);249 const Float *specstor = pksrec.spectra.getStorage(delSpectra); 274 250 mbrec.spectra[0] = (float *)specstor; 275 251 276 252 Bool delFlagged = False; 277 const uChar *flagstor = flagged.getStorage(delFlagged);253 const uChar *flagstor = pksrec.flagged.getStorage(delFlagged); 278 254 mbrec.flagged[0] = (unsigned char *)flagstor; 279 255 … … 281 257 const Complex *xpolstor; 282 258 if (cHaveXPol(iIF)) { 283 xpolstor = xPol.getStorage(delXPol);259 xpolstor = pksrec.xPol.getStorage(delXPol); 284 260 } else { 285 261 xpolstor = 0; … … 289 265 // Finish off with system calibration parameters. 290 266 mbrec.extraSysCal = 1; 291 mbrec.refBeam = refBeam;292 for (uInt i = 0; i < tcal.nelements(); i++) {293 mbrec.tcal[0][i] = tcal(i);294 } 295 strncpy(mbrec.tcalTime, (char *) tcalTime.chars(), 16);296 mbrec.azimuth = azimuth;297 mbrec.elevation = elevation;298 mbrec.parAngle = p arAngle;299 mbrec.focusAxi = focusAxi;300 mbrec.focusTan = focusTan;301 mbrec.focusRot = focusRot;302 mbrec.temp = temperature;303 mbrec.pressure = p ressure;304 mbrec.humidity = humidity;305 mbrec.windSpeed = windSpeed;306 mbrec.windAz = windAz;267 mbrec.refBeam = pksrec.refBeam; 268 for (uInt i = 0; i < pksrec.tcal.nelements(); i++) { 269 mbrec.tcal[0][i] = pksrec.tcal(i); 270 } 271 strncpy(mbrec.tcalTime, (char *)pksrec.tcalTime.chars(), 16); 272 mbrec.azimuth = pksrec.azimuth; 273 mbrec.elevation = pksrec.elevation; 274 mbrec.parAngle = pksrec.parAngle; 275 mbrec.focusAxi = pksrec.focusAxi; 276 mbrec.focusTan = pksrec.focusTan; 277 mbrec.focusRot = pksrec.focusRot; 278 mbrec.temp = pksrec.temperature; 279 mbrec.pressure = pksrec.pressure; 280 mbrec.humidity = pksrec.humidity; 281 mbrec.windSpeed = pksrec.windSpeed; 282 mbrec.windAz = pksrec.windAz; 307 283 308 284 Int status = cSDwriter.write(mbrec); 285 //logMsg(cSDwriter.getMsg()); 286 //cSDwriter.clearMsg(); 309 287 if (status) { 310 cSDwriter.reportError();311 288 status = 1; 312 289 } 313 290 314 spectra.freeStorage(specstor, delSpectra);315 flagged.freeStorage(flagstor, delFlagged);316 xPol.freeStorage(xpolstor, delXPol);291 pksrec.spectra.freeStorage(specstor, delSpectra); 292 pksrec.flagged.freeStorage(flagstor, delFlagged); 293 pksrec.xPol.freeStorage(xpolstor, delXPol); 317 294 318 295 return status; 319 296 } 320 297 298 //------------------------------------------------------- PKSSDwriter::history 299 300 // Write a history record. 301 302 Int PKSSDwriter::history(const String text) 303 { 304 return cSDwriter.history((char *)text.chars()); 305 } 306 307 Int PKSSDwriter::history(const char *text) 308 { 309 return cSDwriter.history((char *)text); 310 } 311 321 312 //--------------------------------------------------------- PKSSDwriter::close 322 313 … … 326 317 { 327 318 cSDwriter.close(); 328 } 319 //logMsg(cSDwriter.getMsg()); 320 //cSDwriter.clearMsg(); 321 } -
branches/alma/external/atnf/PKSIO/PKSSDwriter.h
r1453 r1757 1 1 //#--------------------------------------------------------------------------- 2 //# PKSSD Writer.h: Class to write Parkes multibeam data to an SDFITS file.2 //# PKSSDwriter.h: Class to write Parkes multibeam data to an SDFITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSSDwriter.h,v 19.17 2009-09-29 07:33:38 cal103 Exp $ 29 32 //# Original: 2000/07/21, Mark Calabretta, ATNF 30 33 //#--------------------------------------------------------------------------- … … 34 37 35 38 #include <atnf/PKSIO/PKSwriter.h> 39 #include <atnf/PKSIO/PKSrecord.h> 36 40 #include <atnf/PKSIO/SDFITSwriter.h> 37 41 38 42 #include <casa/aips.h> 43 #include <casa/stdio.h> 39 44 #include <casa/Arrays/Vector.h> 40 45 #include <casa/Arrays/Matrix.h> … … 42 47 #include <casa/BasicSL/String.h> 43 48 49 #include <casa/namespace.h> 50 44 51 // <summary> 45 52 // Class to write Parkes multibeam data to an SDFITS file. 46 53 // </summary> 47 54 48 #include <casa/namespace.h>49 55 class PKSSDwriter : public PKSwriter 50 56 { … … 64 70 const Vector<Double> antPosition, 65 71 const String obsMode, 72 const String bunit, 66 73 const Float equinox, 67 74 const String dopplerFrame, … … 69 76 const Vector<uInt> nPol, 70 77 const Vector<Bool> haveXPol, 71 const Bool haveBase, 72 const String fluxUnit); 78 const Bool haveBase); 73 79 74 80 // Write the next data record. 75 81 virtual Int write( 76 const Int scanNo, 77 const Int cycleNo, 78 const Double mjd, 79 const Double interval, 80 const String fieldName, 81 const String srcName, 82 const Vector<Double> srcDir, 83 const Vector<Double> srcPM, 84 const Double srcVel, 85 const String obsMode, 86 const Int IFno, 87 const Double refFreq, 88 const Double bandwidth, 89 const Double freqInc, 90 //const Double restFreq, 91 const Vector<Double> restFreq, 92 const Vector<Float> tcal, 93 const String tcalTime, 94 const Float azimuth, 95 const Float elevation, 96 const Float parAngle, 97 const Float focusAxi, 98 const Float focusTan, 99 const Float focusRot, 100 const Float temperature, 101 const Float pressure, 102 const Float humidity, 103 const Float windSpeed, 104 const Float windAz, 105 const Int refBeam, 106 const Int beamNo, 107 const Vector<Double> direction, 108 const Vector<Double> scanRate, 109 const Vector<Float> tsys, 110 const Vector<Float> sigma, 111 const Vector<Float> calFctr, 112 const Matrix<Float> baselin, 113 const Matrix<Float> basesub, 114 const Matrix<Float> &spectra, 115 const Matrix<uChar> &flagged, 116 const Complex xCalFctr, 117 const Vector<Complex> &xPol); 82 const PKSrecord &pksrec); 83 84 // Write a history record. 85 virtual Int history(const String text); 86 virtual Int history(const char *text); 118 87 119 88 // Close the SDFITS file. -
branches/alma/external/atnf/PKSIO/PKSreader.cc
r1453 r1757 2 2 //# PKSreader.cc: Class to read Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSreader.cc,v 19.13 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/23, Mark Calabretta, ATNF … … 41 44 #include <casa/OS/File.h> 42 45 43 44 46 //--------------------------------------------------------------- getPKSreader 45 47 … … 50 52 const Int retry, 51 53 const Int interpolate, 52 String &format, 53 Vector<Bool> &beams, 54 Vector<Bool> &IFs, 55 Vector<uInt> &nChan, 56 Vector<uInt> &nPol, 57 Vector<Bool> &haveXPol, 58 Bool &haveBase, 59 Bool &haveSpectra) 54 String &format) 60 55 { 61 56 // Check accessibility of the input. … … 63 58 if (!inFile.exists()) { 64 59 format = "DATASET NOT FOUND"; 65 return 0 ;60 return 0x0; 66 61 } 67 62 68 63 if (!inFile.isReadable()) { 69 64 format = "DATASET UNREADABLE"; 70 return 0 ;65 return 0x0; 71 66 } 72 67 73 68 // Determine the type of input. 74 PKSreader *reader = 0 ;69 PKSreader *reader = 0x0; 75 70 if (inFile.isRegular()) { 76 71 // Is it MBFITS or SDFITS? 77 RegularFileIO file(name); 78 char buf[32]; 79 file.read(30, buf, False); 80 buf[30] = '\0'; 81 if (String(buf) == "SIMPLE = T") { 82 // Looks like SDFITS. 72 if (strstr(name.chars(), ".sdfits")) { 73 // Looks like SDFITS, possibly gzip'd. 83 74 format = "SDFITS"; 84 75 reader = new PKSFITSreader("SDFITS"); 85 76 86 77 } else { 87 // Assume it's MBFITS. 88 format = "MBFITS"; 89 reader = new PKSFITSreader("MBFITS", retry, interpolate); 78 RegularFileIO file(name); 79 char buf[32]; 80 file.read(30, buf, False); 81 buf[30] = '\0'; 82 if (String(buf) == "SIMPLE = T") { 83 // Looks like SDFITS. 84 format = "SDFITS"; 85 reader = new PKSFITSreader("SDFITS"); 86 87 } else { 88 // Assume it's MBFITS. 89 format = "MBFITS"; 90 reader = new PKSFITSreader("MBFITS", retry, interpolate); 91 } 90 92 } 91 93 … … 104 106 format = "UNRECOGNIZED INPUT FORMAT"; 105 107 } 106 108 return reader; 109 } 110 111 //--------------------------------------------------------------- getPKSreader 112 113 // Search a list of directories for a Parkes Multibeam dataset and return an 114 115 PKSreader* getPKSreader( 116 const String name, 117 const Vector<String> directories, 118 const Int retry, 119 const Int interpolate, 120 Int &iDir, 121 String &format) 122 { 123 PKSreader *reader = 0x0; 124 125 iDir = -1; 126 Int nDir = directories.nelements(); 127 for (Int i = 0; i < nDir; i++) { 128 String inName = directories(i) + "/" + name; 129 reader = getPKSreader(inName, retry, interpolate, format); 130 if (reader) { 131 iDir = i; 132 break; 133 } 134 } 135 136 return reader; 137 } 138 139 //--------------------------------------------------------------- getPKSreader 140 141 // Open an appropriate PKSreader for a Parkes Multibeam dataset. 142 143 PKSreader* getPKSreader( 144 const String name, 145 const String antenna, 146 const Int retry, 147 const Int interpolate, 148 String &format, 149 Vector<Bool> &beams, 150 Vector<Bool> &IFs, 151 Vector<uInt> &nChan, 152 Vector<uInt> &nPol, 153 Vector<Bool> &haveXPol, 154 Bool &haveBase, 155 Bool &haveSpectra) 156 { 157 PKSreader *reader = getPKSreader(name, retry, interpolate, format); 107 158 108 159 // Try to open it. 109 160 if (reader) { 110 if (reader->open(name, beams, IFs, nChan, nPol, haveXPol, haveBase,111 have Spectra)) {161 if (reader->open(name, antenna, beams, IFs, nChan, nPol, haveXPol, 162 haveBase, haveSpectra)) { 112 163 format += " OPEN ERROR"; 113 164 delete reader; 114 } else { 115 return reader; 116 } 117 } 118 119 return 0; 120 } 121 165 reader = 0x0; 166 } 167 } 168 169 return reader; 170 } 122 171 123 172 //--------------------------------------------------------------- getPKSreader … … 125 174 // Search a list of directories for a Parkes Multibeam dataset and return an 126 175 // appropriate PKSreader for it. 127 128 PKSreader* getPKSreader( 129 const String name,176 PKSreader* getPKSreader( 177 const String name, 178 const String antenna, 130 179 const Vector<String> directories, 131 180 const Int retry, … … 141 190 Bool &haveSpectra) 142 191 { 143 Int nDir = directories.nelements(); 144 for (iDir = 0; iDir < nDir; iDir++) { 145 String inName = directories(iDir) + "/" + name; 146 PKSreader *reader = getPKSreader(inName, retry, interpolate, format, 147 beams, IFs, nChan, nPol, haveXPol, 148 haveBase, haveSpectra); 149 if (reader != 0) { 150 return reader; 151 } 152 } 153 154 iDir = -1; 155 return 0; 156 } 192 PKSreader *reader = getPKSreader(name, directories, retry, interpolate, 193 iDir, format); 194 195 // Try to open it. 196 if (reader) { 197 if (reader->open(name, antenna, beams, IFs, nChan, nPol, haveXPol, 198 haveBase, haveSpectra)) { 199 format += " OPEN ERROR"; 200 delete reader; 201 reader = 0x0; 202 } 203 } 204 205 return reader; 206 } -
branches/alma/external/atnf/PKSIO/PKSreader.h
r1453 r1757 2 2 //# PKSreader.h: Class to read Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSreader.h,v 19.24 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/02, Mark Calabretta, ATNF … … 33 36 #ifndef ATNF_PKSREADER_H 34 37 #define ATNF_PKSREADER_H 38 39 #include <atnf/PKSIO/PKSrecord.h> 40 #include <atnf/PKSIO/SrcType.h> 35 41 36 42 #include <casa/aips.h> … … 40 46 #include <casa/BasicSL/String.h> 41 47 48 #include <casa/namespace.h> 49 42 50 // <summary> 43 51 // Class to read Parkes multibeam data. 44 52 // </summary> 45 53 46 #include <casa/namespace.h> 54 // Return an appropriate PKSreader for a Parkes Multibeam dataset. 55 class PKSreader* getPKSreader( 56 const String name, 57 const Int retry, 58 const Int interpolate, 59 String &format); 60 61 // As above, but search a list of directories for it. 62 class PKSreader* getPKSreader( 63 const String name, 64 const Vector<String> directories, 65 const Int retry, 66 const Int interpolate, 67 Int &iDir, 68 String &format); 47 69 48 70 // Open an appropriate PKSreader for a Parkes Multibeam dataset. 49 71 class PKSreader* getPKSreader( 50 72 const String name, 73 const String antenna, 51 74 const Int retry, 52 75 const Int interpolate, … … 63 86 class PKSreader* getPKSreader( 64 87 const String name, 88 const String antenna, 65 89 const Vector<String> directories, 66 90 const Int retry, … … 86 110 virtual Int open( 87 111 const String inName, 112 const String antenna, 88 113 Vector<Bool> &beams, 89 114 Vector<Bool> &IFs, … … 101 126 Vector<Double> &antPosition, 102 127 String &obsType, 128 String &bunit, 103 129 Float &equinox, 104 130 String &dopplerFrame, 105 131 Double &mjd, 106 132 Double &refFreq, 107 Double &bandwidth, 108 String &fluxunit) = 0; 133 Double &bandwidth) = 0; 109 134 110 135 // Get frequency parameters for each IF. … … 115 140 // Set data selection criteria. Channel numbering is 1-relative, zero or 116 141 // negative channel numbers are taken to be offsets from the last channel. 142 // Coordinate system selection (only supported for SDFITS input): 143 // 0: equatorial (RA,Dec), 144 // 1: horizontal (Az,El), 145 // 2: feed-plane, 146 // 3: zenithal position angle of feed and elevation, (ZPA,El). 117 147 virtual uInt select( 118 148 const Vector<Bool> beamSel, … … 123 153 const Bool getSpectra = True, 124 154 const Bool getXPol = False, 125 const Bool getFeedPos = False) = 0; 155 const Bool getFeedPos = False, 156 const Bool getPointing = False, 157 const Int coordSys = 0) = 0; 158 126 159 127 160 // Find the range of the data selected in time and position. … … 132 165 Matrix<Double> &positions) = 0; 133 166 134 // Read the next data record. 167 // Read the next data record. 168 /** 135 169 virtual Int read( 136 170 Int &scanNo, … … 175 209 Complex &xCalFctr, 176 210 Vector<Complex> &xPol) = 0; 177 211 **/ 212 /** 178 213 // Read the next data record, just the basics. 179 214 virtual Int read( … … 185 220 Matrix<Float> &spectra, 186 221 Matrix<uChar> &flagged) = 0; 222 **/ 223 virtual Int read(PKSrecord &pksrec) = 0; 187 224 188 225 // Close the input file. … … 190 227 191 228 protected: 192 Bool cGetFeedPos, cGetSpectra, cGetXPol; 229 Bool cGetFeedPos, cGetSpectra, cGetXPol, cGetPointing; 230 Int cCoordSys; 193 231 194 232 Vector<uInt> cNChan, cNPol; -
branches/alma/external/atnf/PKSIO/PKSrecord.h
r1752 r1757 67 67 Double bandwidth; 68 68 Double freqInc; 69 Double restFreq; 69 Int nchan; 70 Vector<Double> restFreq; 70 71 Vector<Float> tcal; 71 72 String tcalTime; … … 86 87 Int pCode; 87 88 Float rateAge; 88 Vector< Float>scanRate;89 Vector<Double> scanRate; 89 90 Float paRate; 90 91 Vector<Float> tsys; … … 95 96 Matrix<Float> spectra; 96 97 Matrix<uChar> flagged; 98 uInt flagrow; 97 99 Complex xCalFctr; 98 100 Vector<Complex> xPol; 101 Int polNo ; 102 Int srcType ; 99 103 }; 100 104 -
branches/alma/external/atnf/PKSIO/PKSwriter.h
r1453 r1757 2 2 //# PKSwriter.h: Class to write out Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSwriter.h,v 19.17 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 31 34 #ifndef ATNF_PKSWRITER_H 32 35 #define ATNF_PKSWRITER_H 36 37 #include <atnf/PKSIO/PKSrecord.h> 33 38 34 39 #include <casa/aips.h> … … 38 43 #include <casa/BasicSL/String.h> 39 44 45 #include <casa/namespace.h> 46 40 47 // <summary> 41 48 // Class to write out Parkes multibeam data. 42 49 // </summary> 43 50 44 #include <casa/namespace.h>45 51 class PKSwriter 46 52 { … … 57 63 const Vector<Double> antPosition, 58 64 const String obsMode, 65 const String bunit, 59 66 const Float equinox, 60 67 const String dopplerFrame, … … 62 69 const Vector<uInt> nPol, 63 70 const Vector<Bool> haveXPol, 64 const Bool havebase, 65 const String fluxUnit) = 0; 71 const Bool havebase) = 0; 66 72 67 73 // Write the next data record. 68 74 virtual Int write ( 69 const Int scanNo, 70 const Int cycleNo, 71 const Double mjd, 72 const Double interval, 73 const String fieldName, 74 const String srcName, 75 const Vector<Double> srcDir, 76 const Vector<Double> srcPM, 77 const Double srcVel, 78 const String obsMode, 79 const Int IFno, 80 const Double refFreq, 81 const Double bandwidth, 82 const Double freqInc, 83 //const Double restFreq, 84 const Vector<Double> restFreq, 85 const Vector<Float> tcal, 86 const String tcalTime, 87 const Float azimuth, 88 const Float elevation, 89 const Float parAngle, 90 const Float focusAxi, 91 const Float focusTan, 92 const Float focusRot, 93 const Float temperature, 94 const Float pressure, 95 const Float humidity, 96 const Float windSpeed, 97 const Float windAz, 98 const Int refBeam, 99 const Int beamNo, 100 const Vector<Double> direction, 101 const Vector<Double> scanRate, 102 const Vector<Float> tsys, 103 const Vector<Float> sigma, 104 const Vector<Float> calFctr, 105 const Matrix<Float> baseLin, 106 const Matrix<Float> baseSub, 107 const Matrix<Float> &spectra, 108 const Matrix<uChar> &flagged, 109 const Complex xCalFctr, 110 const Vector<Complex> &xPol) = 0; 75 const PKSrecord &pksrec) = 0; 76 77 // Write a history record. 78 virtual Int history(const String text) {return 0;}; 79 virtual Int history(const char *text) {return 0;}; 111 80 112 81 // Close the output file. -
branches/alma/external/atnf/PKSIO/SDFITSreader.cc
r1453 r1757 1 1 //#--------------------------------------------------------------------------- 2 //# SDFITSreader.cc: ATNF CFITSIO interface class for SDFITS input.2 //# SDFITSreader.cc: ATNF interface class for SDFITS input using CFITSIO. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSreader.cc,v 19.45 2009-09-30 07:23:48 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# The SDFITSreader class reads single dish FITS files such as those written … … 34 37 //#--------------------------------------------------------------------------- 35 38 39 #include <atnf/pks/pks_maths.h> 40 #include <atnf/PKSIO/MBrecord.h> 41 #include <atnf/PKSIO/SDFITSreader.h> 42 43 #include <casa/Logging/LogIO.h> 44 #include <casa/Quanta/MVTime.h> 45 #include <casa/math.h> 46 #include <casa/stdio.h> 47 36 48 #include <algorithm> 37 49 #include <strings.h> 38 39 // AIPS++ includes. 40 #include <casa/iostream.h> 41 #include <casa/math.h> 42 #include <casa/stdio.h> 43 44 // ATNF includes. 45 #include <atnf/pks/pks_maths.h> 46 #include <atnf/PKSIO/PKSMBrecord.h> 47 #include <atnf/PKSIO/SDFITSreader.h> 48 50 #include <cstring> 49 51 50 52 class FITSparm … … 57 59 long nelem; // Column data repeat count; < 0 for vardim. 58 60 int tdimcol; // TDIM column number; 0 for keyword; -1 absent. 61 char units[32]; // Units from TUNITn keyword. 59 62 }; 60 63 … … 64 67 // Factor to convert radians to degrees. 65 68 const double D2R = PI / 180.0; 69 70 // Class name 71 const string className = "SDFITSreader" ; 72 73 //---------------------------------------------------- SDFITSreader::(statics) 74 75 int SDFITSreader::sInit = 1; 76 int SDFITSreader::sReset = 0; 77 int (*SDFITSreader::sALFAcalNon)[2] = (int (*)[2])(new float[16]); 78 int (*SDFITSreader::sALFAcalNoff)[2] = (int (*)[2])(new float[16]); 79 float (*SDFITSreader::sALFAcalOn)[2] = (float (*)[2])(new float[16]); 80 float (*SDFITSreader::sALFAcalOff)[2] = (float (*)[2])(new float[16]); 81 float (*SDFITSreader::sALFAcal)[2] = (float (*)[2])(new float[16]); 66 82 67 83 //------------------------------------------------- SDFITSreader::SDFITSreader … … 70 86 { 71 87 // Default constructor. 72 cSDptr = 0 ;88 cSDptr = 0x0; 73 89 74 90 // Allocate space for data descriptors. … … 85 101 cEndChan = 0x0; 86 102 cRefChan = 0x0; 103 cPols = 0x0; 87 104 } 88 105 … … 113 130 int &extraSysCal) 114 131 { 132 const string methodName = "open()" ; 133 115 134 if (cSDptr) { 116 135 close(); … … 120 139 cStatus = 0; 121 140 if (fits_open_file(&cSDptr, sdName, READONLY, &cStatus)) { 122 cerr << "Failed to open SDFITS file: " << sdName << endl;123 reportError();141 sprintf(cMsg, "ERROR: Failed to open SDFITS file\n %s", sdName); 142 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, cMsg); 124 143 return 1; 125 144 } … … 138 157 cALFA_CIMA = 1; 139 158 159 // Check for later versions of CIMAFITS. 160 float version; 161 readParm("VERSION", TFLOAT, &version); 162 if (version >= 2.0f) cALFA_CIMA = int(version); 163 140 164 } else { 141 cerr << "Failed to locate SDFITS binary table." << endl; 142 reportError(); 165 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to locate SDFITS binary table."); 143 166 close(); 144 167 return 1; … … 148 171 // Arecibo ALFA data of some kind. 149 172 cALFA = 1; 150 for (int iBeam = 0; iBeam < 8; iBeam++) { 151 for (int iPol = 0; iPol < 2; iPol++) { 152 cALFAcalOn[iBeam][iPol] = 0.0f; 153 cALFAcalOff[iBeam][iPol] = 0.0f; 154 155 // Nominal factor to calibrate spectra in Jy. 156 cALFAcal[iBeam][iPol] = 3.0f; 157 } 173 if (sInit) { 174 for (int iBeam = 0; iBeam < 8; iBeam++) { 175 for (int iPol = 0; iPol < 2; iPol++) { 176 sALFAcalOn[iBeam][iPol] = 0.0f; 177 sALFAcalOff[iBeam][iPol] = 0.0f; 178 179 // Nominal factor to calibrate spectra in Jy. 180 sALFAcal[iBeam][iPol] = 3.0f; 181 } 182 } 183 184 sInit = 0; 158 185 } 159 186 } … … 165 192 strncmp(telescope, "NRAO_GBT", 8) == 0; 166 193 167 cRow = 0;168 169 194 170 195 // Check that the DATA array column is present. … … 172 197 haveSpectra = cHaveSpectra = cData[DATA].colnum > 0; 173 198 199 cNAxisTime = 0; 174 200 if (cHaveSpectra) { 175 201 // Find the number of data axes (must be the same for each IF). 176 cNAx is = 5;177 if (readDim(DATA, 1, &cNAx is, cNAxes)) {178 reportError();202 cNAxes = 5; 203 if (readDim(DATA, 1, &cNAxes, cNAxis)) { 204 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 179 205 close(); 180 206 return 1; … … 182 208 183 209 if (cALFA_BD) { 184 // ALFA BDFITS: variable length arrays don't actually vary and there is 210 // ALFA BDFITS: variable length arrays don't actually vary and there is 185 211 // no TDIM (or MAXISn) card; use the LAGS_IN value. 186 cNAx is = 5;187 readParm("LAGS_IN", TLONG, cNAx es);188 cNAx es[1] = 1;189 cNAx es[2] = 1;190 cNAx es[3] = 1;191 cNAx es[4] = 1;192 cData[DATA].nelem = cNAx es[0];193 } 194 195 if (cNAx is < 4) {212 cNAxes = 5; 213 readParm("LAGS_IN", TLONG, cNAxis); 214 cNAxis[1] = 1; 215 cNAxis[2] = 1; 216 cNAxis[3] = 1; 217 cNAxis[4] = 1; 218 cData[DATA].nelem = cNAxis[0]; 219 } 220 221 if (cNAxes < 4) { 196 222 // Need at least four axes (for now). 197 cerr << "DATA array contains fewer than four axes." << endl;223 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array contains fewer than four axes."); 198 224 close(); 199 225 return 1; 200 } else if (cNAx is > 5) {226 } else if (cNAxes > 5) { 201 227 // We support up to five axes. 202 cerr << "DATA array contains more than five axes." << endl;228 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array contains more than five axes."); 203 229 close(); 204 230 return 1; … … 211 237 findData(DATAXED, "DATAXED", TSTRING); 212 238 if (cData[DATAXED].colnum < 0) { 213 cerr << "DATA array column absent from binary table." << endl;239 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array column absent from binary table."); 214 240 close(); 215 241 return 1; … … 220 246 readParm("DATAXED", TSTRING, dataxed); 221 247 222 for (int iaxis = 0; iaxis < 5; iaxis++) cNAx es[iaxis] = 0;223 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAx es, cNAxes+1, cNAxes+2,224 cNAx es+3, cNAxes+4);248 for (int iaxis = 0; iaxis < 5; iaxis++) cNAxis[iaxis] = 0; 249 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAxis, cNAxis+1, cNAxis+2, 250 cNAxis+3, cNAxis+4); 225 251 for (int iaxis = 4; iaxis > -1; iaxis--) { 226 if (cNAx es[iaxis] == 0) cNAxis = iaxis;252 if (cNAxis[iaxis] == 0) cNAxes = iaxis; 227 253 } 228 254 } … … 235 261 // Find required DATA array axes. 236 262 char ctype[5][72]; 237 for (int iaxis = 0; iaxis < cNAx is; iaxis++) {263 for (int iaxis = 0; iaxis < cNAxes; iaxis++) { 238 264 strcpy(ctype[iaxis], ""); 239 265 readParm(CTYPE[iaxis], TSTRING, ctype[iaxis]); // Core. … … 241 267 242 268 if (cStatus) { 243 reportError();269 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 244 270 close(); 245 271 return 1; 246 272 } 247 273 248 char *fqCRPIX = 0;249 274 char *fqCRVAL = 0; 250 275 char *fqCDELT = 0; 276 char *fqCRPIX = 0; 251 277 char *raCRVAL = 0; 252 278 char *decCRVAL = 0; 253 279 char *timeCRVAL = 0; 280 char *timeCDELT = 0; 281 char *timeCRPIX = 0; 254 282 char *beamCRVAL = 0; 255 256 for (int iaxis = 0; iaxis < cNAxis; iaxis++) { 283 char *polCRVAL = 0; 284 285 cFreqAxis = -1; 286 cStokesAxis = -1; 287 cRaAxis = -1; 288 cDecAxis = -1; 289 cTimeAxis = -1; 290 cBeamAxis = -1; 291 292 for (int iaxis = 0; iaxis < cNAxes; iaxis++) { 257 293 if (strncmp(ctype[iaxis], "FREQ", 4) == 0) { 258 c Reqax[0]= iaxis;259 fqCR PIX = CRPIX[iaxis];260 fqC RVAL = CRVAL[iaxis];261 fqC DELT = CDELT[iaxis];294 cFreqAxis = iaxis; 295 fqCRVAL = CRVAL[iaxis]; 296 fqCDELT = CDELT[iaxis]; 297 fqCRPIX = CRPIX[iaxis]; 262 298 263 299 } else if (strncmp(ctype[iaxis], "STOKES", 6) == 0) { 264 cReqax[1] = iaxis; 300 cStokesAxis = iaxis; 301 polCRVAL = CRVAL[iaxis]; 265 302 266 303 } else if (strncmp(ctype[iaxis], "RA", 2) == 0) { 267 cR eqax[2]= iaxis;268 raCRVAL = CRVAL[iaxis];304 cRaAxis = iaxis; 305 raCRVAL = CRVAL[iaxis]; 269 306 270 307 } else if (strncmp(ctype[iaxis], "DEC", 3) == 0) { 271 c Reqax[3]= iaxis;272 decCRVAL = CRVAL[iaxis];308 cDecAxis = iaxis; 309 decCRVAL = CRVAL[iaxis]; 273 310 274 311 } else if (strcmp(ctype[iaxis], "TIME") == 0) { 275 // TIME (UTC seconds since midnight) can be a keyword or axis type. 312 // TIME (UTC seconds since midnight); axis type, if present, takes 313 // precedence over keyword. 314 cTimeAxis = iaxis; 276 315 timeCRVAL = CRVAL[iaxis]; 316 317 // Check for non-degeneracy. 318 if ((cNAxisTime = cNAxis[iaxis]) > 1) { 319 timeCDELT = CDELT[iaxis]; 320 timeCRPIX = CRPIX[iaxis]; 321 sprintf(cMsg, "DATA array contains a TIME axis of length %ld.", 322 cNAxisTime); 323 //logMsg(cMsg); 324 log(LogOrigin( className, methodName, WHERE ), LogIO::NORMAL, cMsg); 325 } 277 326 278 327 } else if (strcmp(ctype[iaxis], "BEAM") == 0) { 279 328 // BEAM can be a keyword or axis type. 329 cBeamAxis = iaxis; 280 330 beamCRVAL = CRVAL[iaxis]; 281 331 } … … 284 334 if (cALFA_BD) { 285 335 // Fixed in ALFA CIMAFITS. 286 cR eqax[2]= 2;336 cRaAxis = 2; 287 337 raCRVAL = "CRVAL2A"; 288 338 289 c Reqax[3]= 3;339 cDecAxis = 3; 290 340 decCRVAL = "CRVAL3A"; 291 341 } 292 342 293 // Check that all are present. 294 for (int iaxis = 0; iaxis < 4; iaxis++) { 295 if (cReqax[iaxis] < 0) { 296 cerr << "Could not find required DATA array axes." << endl; 297 close(); 298 return 1; 299 } 343 344 // Check that required axes are present. 345 if (cFreqAxis < 0 || cStokesAxis < 0 || cRaAxis < 0 || cDecAxis < 0) { 346 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Could not find required DATA array axes."); 347 close(); 348 return 1; 300 349 } 301 350 … … 304 353 findData(CYCLE, "CYCLE", TINT); // Additional. 305 354 findData(DATE_OBS, "DATE-OBS", TSTRING); // Core. 306 findData(TIME, "TIME", TDOUBLE); // Core. 355 356 if (cTimeAxis >= 0) { 357 // The DATA array has a TIME axis. 358 if (cNAxisTime > 1) { 359 // Non-degenerate. 360 findData(TimeRefVal, timeCRVAL, TDOUBLE); // Time reference value. 361 findData(TimeDelt, timeCDELT, TDOUBLE); // Time increment. 362 findData(TimeRefPix, timeCRPIX, TFLOAT); // Time reference pixel. 363 } else { 364 // Degenerate, treat its like a simple TIME keyword. 365 findData(TIME, timeCRVAL, TDOUBLE); 366 } 367 368 } else { 369 findData(TIME, "TIME", TDOUBLE); // Core. 370 } 371 307 372 findData(EXPOSURE, "EXPOSURE", TFLOAT); // Core. 308 373 findData(OBJECT, "OBJECT", TSTRING); // Core. … … 314 379 findData(BEAM, "BEAM", TSHORT); // Additional. 315 380 findData(IF, "IF", TSHORT); // Additional. 316 findData(FqRefPix, fqCRPIX, TFLOAT); // Frequency reference pixel.317 381 findData(FqRefVal, fqCRVAL, TDOUBLE); // Frequency reference value. 318 382 findData(FqDelt, fqCDELT, TDOUBLE); // Frequency increment. 383 findData(FqRefPix, fqCRPIX, TFLOAT); // Frequency reference pixel. 319 384 findData(RA, raCRVAL, TDOUBLE); // Right ascension. 320 385 findData(DEC, decCRVAL, TDOUBLE); // Declination. … … 343 408 findData(WINDDIRE, "WINDDIRE", TFLOAT); // Shared. 344 409 410 findData(STOKES, polCRVAL, TINT); 411 findData(SIG, "SIG", TSTRING); 412 findData(CAL, "CAL", TSTRING); 413 414 findData(RVSYS, "RVSYS", TDOUBLE); 415 findData(VFRAME, "VFRAME", TDOUBLE); 416 findData(VELDEF, "VELDEF", TSTRING); 417 345 418 if (cStatus) { 346 reportError();419 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 347 420 close(); 348 421 return 1; … … 355 428 cALFAscan = 0; 356 429 cScanNo = 0; 357 if (cALFA_BD) { 430 if (cALFA_CIMA) { 431 findData(SCAN, "SCAN_ID", TINT); 432 if (cALFA_CIMA > 1) { 433 // Note that RECNUM increases by cNAxisTime per row. 434 findData(CYCLE, "RECNUM", TINT); 435 } else { 436 findData(CYCLE, "SUBSCAN", TINT); 437 } 438 } else if (cALFA_BD) { 358 439 findData(SCAN, "SCAN_NUMBER", TINT); 359 440 findData(CYCLE, "PATTERN_NUMBER", TINT); 360 } else if (cALFA_CIMA) {361 findData(SCAN, "SCAN_ID", TINT);362 findData(CYCLE, "SUBSCAN", TINT);363 441 } 364 442 } else { … … 368 446 cCycleNo = 0; 369 447 cLastUTC = 0.0; 448 for ( int i = 0 ; i < 4 ; i++ ) { 449 cGLastUTC[i] = 0.0 ; 450 cGLastScan[i] = -1 ; 451 cGCycleNo[i] = 0 ; 452 } 370 453 371 454 // Beam number, 1-relative by default. 372 455 cBeam_1rel = 1; 373 if (cData[BEAM].colnum < 0) { 456 if (cALFA) { 457 // ALFA INPUT_ID, 0-relative (overrides BEAM column if present). 458 findData(BEAM, "INPUT_ID", TSHORT); 459 cBeam_1rel = 0; 460 461 } else if (cData[BEAM].colnum < 0) { 374 462 if (beamCRVAL) { 375 463 // There is a BEAM axis. 376 464 findData(BEAM, beamCRVAL, TDOUBLE); 377 378 465 } else { 379 if (cALFA) { 380 // ALFA data, 0-relative. 381 findData(BEAM, "INPUT_ID", TSHORT); 382 } else { 383 // ms2sdfits output, 0-relative "feed" number. 384 findData(BEAM, "MAIN_FEED1", TSHORT); 385 } 386 466 // ms2sdfits output, 0-relative "feed" number. 467 findData(BEAM, "MAIN_FEED1", TSHORT); 387 468 cBeam_1rel = 0; 388 469 } … … 393 474 if (cALFA && cData[IF].colnum < 0) { 394 475 // ALFA data, 0-relative. 395 findData(IF, "IFVAL", TSHORT); 476 if (cALFA_CIMA > 1) { 477 findData(IF, "IFN", TSHORT); 478 } else { 479 findData(IF, "IFVAL", TSHORT); 480 } 396 481 cIF_1rel = 0; 397 }398 399 if (cData[TIME].colnum < 0) {400 if (timeCRVAL) {401 // There is a TIME axis.402 findData(TIME, timeCRVAL, TDOUBLE);403 }404 482 } 405 483 … … 476 554 fits_get_num_rows(cSDptr, &cNRow, &cStatus); 477 555 if (!cNRow) { 478 cerr << "Table contains no entries." << endl;556 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Table contains no entries."); 479 557 close(); 480 558 return 1; … … 489 567 if (fits_read_col(cSDptr, TSHORT, cData[BEAM].colnum, 1, 1, cNRow, 490 568 &beamNul, beamCol, &anynul, &cStatus)) { 491 reportError();492 569 delete [] beamCol; 570 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 493 571 close(); 494 572 return 1; … … 504 582 // Check validity. 505 583 if (beamCol[irow] < cBeam_1rel) { 506 cerr << "SDFITS file contains invalid beam number." << endl;507 584 delete [] beamCol; 585 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "SDFITS file contains invalid beam number."); 508 586 close(); 509 587 return 1; … … 545 623 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 546 624 &IFNul, IFCol, &anynul, &cStatus)) { 547 reportError();548 625 delete [] IFCol; 626 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 549 627 close(); 550 628 return 1; … … 560 638 // Check validity. 561 639 if (IFCol[irow] < cIF_1rel) { 562 cerr << "SDFITS file contains invalid IF number." << endl;563 640 delete [] IFCol; 641 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "SDFITS file contains invalid IF number."); 564 642 close(); 565 643 return 1; … … 592 670 if (cData[DATA].nelem < 0) { 593 671 // Variable dimension array. 594 if (readDim(DATA, irow+1, &cNAx is, cNAxes)) {595 reportError();672 if (readDim(DATA, irow+1, &cNAxes, cNAxis)) { 673 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 596 674 close(); 597 675 return 1; … … 604 682 readParm("DATAXED", TSTRING, dataxed); 605 683 606 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAx es, cNAxes+1,607 cNAx es+2, cNAxes+3, cNAxes+4);684 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAxis, cNAxis+1, 685 cNAxis+2, cNAxis+3, cNAxis+4); 608 686 } 609 687 } 610 688 611 689 // Number of channels and polarizations. 612 cNChan[iIF] = cNAx es[cReqax[0]];613 cNPol[iIF] = cNAx es[cReqax[1]];690 cNChan[iIF] = cNAxis[cFreqAxis]; 691 cNPol[iIF] = cNAxis[cStokesAxis]; 614 692 cHaveXPol[iIF] = 0; 615 693 … … 621 699 622 700 if (readDim(XPOLDATA, irow+1, &nAxis, nAxes)) { 623 reportError();701 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE ); 624 702 close(); 625 703 return 1; … … 650 728 651 729 // Number of channels and polarizations. 652 cNChan[0] = cNAx es[cReqax[0]];653 cNPol[0] = cNAx es[cReqax[1]];730 cNChan[0] = cNAxis[cFreqAxis]; 731 cNPol[0] = cNAxis[cStokesAxis]; 654 732 cHaveXPol[0] = 0; 655 733 } 656 734 657 if (cALFA ) {658 // ALFAlabels each polarization as a separate IF.735 if (cALFA && cALFA_CIMA < 2) { 736 // Older ALFA data labels each polarization as a separate IF. 659 737 cNPol[0] = cNIF; 660 738 cNIF = 1; 739 } 740 741 // For GBT data that stores spectra for each polarization in separate rows 742 if ( cData[STOKES].colnum > 0 ) { 743 int *stokesCol = new int[cNRow]; 744 int stokesNul = 1; 745 int anynul; 746 if (fits_read_col(cSDptr, TINT, cData[STOKES].colnum, 1, 1, cNRow, 747 &stokesNul, stokesCol, &anynul, &cStatus)) { 748 delete [] stokesCol; 749 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 750 close(); 751 return 1; 752 } 753 754 vector<int> pols ; 755 pols.push_back( stokesCol[0] ) ; 756 for ( int i = 0 ; i < cNRow ; i++ ) { 757 bool pmatch = false ; 758 for ( uint j = 0 ; j < pols.size() ; j++ ) { 759 if ( stokesCol[i] == pols[j] ) { 760 pmatch = true ; 761 break ; 762 } 763 } 764 if ( !pmatch ) { 765 pols.push_back( stokesCol[i] ) ; 766 } 767 } 768 769 cPols = new int[pols.size()] ; 770 for ( uint i = 0 ; i < pols.size() ; i++ ) { 771 cPols[i] = pols[i] ; 772 } 773 774 for ( int i = 0 ; i < cNIF ; i++ ) { 775 cNPol[i] = pols.size() ; 776 } 777 778 delete [] stokesCol ; 661 779 } 662 780 … … 712 830 extraSysCal = cExtraSysCal; 713 831 832 833 // Extras for ALFA data. 834 cALFAacc = 0.0f; 835 if (cALFA_CIMA > 1) { 836 // FFTs per second when the Mock correlator operates in RFI blanking mode. 837 readData("PHFFTACC", TFLOAT, 0, &cALFAacc); 838 } 839 840 841 cRow = 0; 842 cTimeIdx = cNAxisTime; 843 714 844 return 0; 715 845 } … … 725 855 double antPos[3], 726 856 char obsMode[32], 857 char bunit[32], 727 858 float &equinox, 728 859 char radecsys[32], … … 733 864 double &bandwidth) 734 865 { 866 const string methodName = "getHeader()" ; 867 735 868 // Has the file been opened? 736 869 if (!cSDptr) { … … 773 906 readData(OBSMODE, 1, obsMode); // Shared. 774 907 908 // Brightness unit. 909 if (cData[DATAXED].colnum >= 0) { 910 strcpy(bunit, "Jy"); 911 } else { 912 strcpy(bunit, cData[DATA].units); 913 } 914 915 if (strcmp(bunit, "JY") == 0) { 916 bunit[1] = 'y'; 917 } else if (strcmp(bunit, "JY/BEAM") == 0) { 918 strcpy(bunit, "Jy/beam"); 919 } 920 775 921 readParm("EQUINOX", TFLOAT, &equinox); // Shared. 776 922 if (cStatus == 405) { … … 793 939 794 940 // Look for VELFRAME, written by earlier versions of Livedata. 941 // 942 // Added few more codes currently (as of 2009 Oct) used in the GBT 943 // SDFITS (based io_sdfits_define.pro of GBTIDL). - TT 795 944 if (readParm("VELFRAME", TSTRING, dopplerFrame)) { // Additional. 796 945 // No, try digging it out of the CTYPE card (AIPS convention). 797 946 char keyw[9], ctype[9]; 798 sprintf(keyw, "CTYPE%ld", c Reqax[0]+1);947 sprintf(keyw, "CTYPE%ld", cFreqAxis+1); 799 948 readParm(keyw, TSTRING, ctype); 800 949 … … 804 953 // LSR unqualified usually means LSR (kinematic). 805 954 strcpy(dopplerFrame, "LSRK"); 955 } else if (strcmp(dopplerFrame, "LSD") == 0) { 956 // LSR as a dynamical defintion 957 strcpy(dopplerFrame, "LSRD"); 806 958 } else if (strcmp(dopplerFrame, "HEL") == 0) { 807 959 // Almost certainly barycentric. 808 960 strcpy(dopplerFrame, "BARYCENT"); 961 } else if (strcmp(dopplerFrame, "BAR") == 0) { 962 // barycentric. 963 strcpy(dopplerFrame, "BARYCENT"); 964 } else if (strcmp(dopplerFrame, "OBS") == 0) { 965 // observed or topocentric. 966 strcpy(dopplerFrame, "TOPO"); 967 } else if (strcmp(dopplerFrame, "GEO") == 0) { 968 // geocentric 969 strcpy(dopplerFrame, "GEO"); 970 } else if (strcmp(dopplerFrame, "GAL") == 0) { 971 // galactic 972 strcpy(dopplerFrame, "GAL"); 973 } else if (strcmp(dopplerFrame, "LGR") == 0) { 974 // Local group 975 strcpy(dopplerFrame, "LGROUP"); 976 } else if (strcmp(dopplerFrame, "CMB") == 0) { 977 // Cosimic Microwave Backgroup 978 strcpy(dopplerFrame, "CMB"); 809 979 } 810 980 } else { … … 812 982 } 813 983 } 814 815 984 // Translate to FITS standard names. 816 985 if (strncmp(dopplerFrame, "TOP", 3) == 0) { … … 822 991 } else if (strncmp(dopplerFrame, "BARY", 4) == 0) { 823 992 strcpy(dopplerFrame, "BARYCENT"); 824 } 825 } 826 993 } else if (strncmp(dopplerFrame, "GAL", 3) == 0) { 994 strcpy(dopplerFrame, "GALACTOC"); 995 } else if (strncmp(dopplerFrame, "LGROUP", 6) == 0) { 996 strcpy(dopplerFrame, "LOCALGRP"); 997 } else if (strncmp(dopplerFrame, "CMB", 3) == 0) { 998 strcpy(dopplerFrame, "CMBDIPOL"); 999 } 1000 } 1001 827 1002 if (cStatus) { 828 reportError();1003 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 829 1004 return 1; 830 1005 } 831 1006 832 1007 // Get parameters from first row of table. 833 readData(DATE_OBS, 1, datobs); 834 readData(TIME, 1, &utc); 1008 readTime(1, 1, datobs, utc); 835 1009 readData(FqRefVal, 1, &refFreq); 836 1010 readParm("BANDWID", TDOUBLE, &bandwidth); // Core. 837 1011 838 if (cALFA_BD) utc *= 3600.0;839 840 1012 if (cStatus) { 841 reportError();1013 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 842 1014 return 1; 843 }844 845 // Check DATE-OBS format.846 if (datobs[2] == '/') {847 // Translate an old-format DATE-OBS.848 datobs[9] = datobs[1];849 datobs[8] = datobs[0];850 datobs[2] = datobs[6];851 datobs[5] = datobs[3];852 datobs[3] = datobs[7];853 datobs[6] = datobs[4];854 datobs[7] = '-';855 datobs[4] = '-';856 datobs[1] = '9';857 datobs[0] = '1';858 datobs[10] = '\0';859 860 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) {861 // Dig UTC out of a new-format DATE-OBS.862 int hh, mm;863 float ss;864 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss);865 utc = (hh*60 + mm)*60 + ss;866 datobs[10] = '\0';867 1015 } 868 1016 … … 879 1027 double* &endFreq) 880 1028 { 1029 const string methodName = "getFreqInfo()" ; 1030 881 1031 float fqRefPix; 882 1032 double fqDelt, fqRefVal; … … 892 1042 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 893 1043 &IFNul, IFCol, &anynul, &cStatus)) { 894 reportError();895 1044 delete [] IFCol; 1045 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 896 1046 close(); 897 1047 return 1; … … 956 1106 double* &positions) 957 1107 { 958 int anynul;1108 const string methodName = "findRange()" ; 959 1109 960 1110 // Has the file been opened? … … 966 1116 967 1117 // Find the number of rows selected. 968 short *sel = new short[ nRow];969 for (int irow = 0; irow < nRow; irow++) {1118 short *sel = new short[cNRow]; 1119 for (int irow = 0; irow < cNRow; irow++) { 970 1120 sel[irow] = 1; 971 1121 } 972 1122 1123 int anynul; 973 1124 if (cData[BEAM].colnum > 0) { 974 1125 short *beamCol = new short[cNRow]; … … 976 1127 if (fits_read_col(cSDptr, TSHORT, cData[BEAM].colnum, 1, 1, cNRow, 977 1128 &beamNul, beamCol, &anynul, &cStatus)) { 978 reportError();979 1129 delete [] beamCol; 980 1130 delete [] sel; 1131 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 981 1132 return 1; 982 1133 } 983 1134 984 for (int irow = 0; irow < nRow; irow++) {1135 for (int irow = 0; irow < cNRow; irow++) { 985 1136 if (!cBeams[beamCol[irow]-cBeam_1rel]) { 986 1137 sel[irow] = 0; … … 996 1147 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 997 1148 &IFNul, IFCol, &anynul, &cStatus)) { 998 reportError();999 1149 delete [] IFCol; 1000 1150 delete [] sel; 1151 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1001 1152 return 1; 1002 1153 } 1003 1154 1004 for (int irow = 0; irow < nRow; irow++) {1155 for (int irow = 0; irow < cNRow; irow++) { 1005 1156 if (!cIFs[IFCol[irow]-cIF_1rel]) { 1006 1157 sel[irow] = 0; … … 1012 1163 1013 1164 nSel = 0; 1014 for (int irow = 0; irow < nRow; irow++) {1165 for (int irow = 0; irow < cNRow; irow++) { 1015 1166 nSel += sel[irow]; 1016 1167 } … … 1018 1169 1019 1170 // Find the time range assuming the data is in chronological order. 1020 readData(DATE_OBS, 1, dateSpan[0]); 1021 readData(DATE_OBS, nRow, dateSpan[1]); 1022 readData(TIME, 1, utcSpan); 1023 readData(TIME, nRow, utcSpan+1); 1024 1025 if (cALFA_BD) { 1026 utcSpan[0] *= 3600.0; 1027 utcSpan[1] *= 3600.0; 1028 } 1029 1030 // Check DATE-OBS format. 1031 for (int i = 0; i < 2; i++) { 1032 if (dateSpan[0][2] == '/') { 1033 // Translate an old-format DATE-OBS. 1034 dateSpan[i][9] = dateSpan[i][1]; 1035 dateSpan[i][8] = dateSpan[i][0]; 1036 dateSpan[i][2] = dateSpan[i][6]; 1037 dateSpan[i][5] = dateSpan[i][3]; 1038 dateSpan[i][3] = dateSpan[i][7]; 1039 dateSpan[i][6] = dateSpan[i][4]; 1040 dateSpan[i][7] = '-'; 1041 dateSpan[i][4] = '-'; 1042 dateSpan[i][1] = '9'; 1043 dateSpan[i][0] = '1'; 1044 dateSpan[i][10] = '\0'; 1045 } 1046 1047 if (dateSpan[i][10] == 'T' && cData[TIME].colnum < 0) { 1048 // Dig UTC out of a new-format DATE-OBS. 1049 int hh, mm; 1050 float ss; 1051 sscanf(dateSpan[i]+11, "%d:%d:%f", &hh, &mm, &ss); 1052 utcSpan[i] = (hh*60 + mm)*60 + ss; 1053 } 1054 } 1171 readTime(1, 1, dateSpan[0], utcSpan[0]); 1172 readTime(cNRow, cNAxisTime, dateSpan[1], utcSpan[1]); 1055 1173 1056 1174 1057 1175 // Retrieve positions for selected data. 1058 double *ra = new double[cNRow];1059 double *dec = new double[cNRow];1060 fits_read_col(cSDptr, TDOUBLE, cData[RA].colnum, 1, 1, nRow, 0, ra,1061 &anynul, &cStatus);1062 fits_read_col(cSDptr, TDOUBLE, cData[DEC].colnum, 1, 1, nRow, 0, dec,1063 &anynul, &cStatus);1064 1065 if (cALFA_BD) {1066 for (int irow = 0; irow < nRow; irow++) {1067 // Convert hours to degrees.1068 ra[irow] *= 15.0;1069 }1070 }1071 1072 1176 int isel = 0; 1073 1177 positions = new double[2*nSel]; 1074 1178 1075 // Parameters needed to compute feed-plane coordinates. 1076 double *srcRA, *srcDec; 1077 float *par, *rot; 1078 if (cGetFeedPos) { 1079 srcRA = new double[cNRow]; 1080 srcDec = new double[cNRow]; 1081 par = new float[cNRow]; 1082 rot = new float[cNRow]; 1083 fits_read_col(cSDptr, TDOUBLE, cData[OBJ_RA].colnum, 1, 1, nRow, 0, 1084 srcRA, &anynul, &cStatus); 1085 fits_read_col(cSDptr, TDOUBLE, cData[OBJ_DEC].colnum, 1, 1, nRow, 0, 1086 srcDec, &anynul, &cStatus); 1087 fits_read_col(cSDptr, TFLOAT, cData[PARANGLE].colnum, 1, 1, nRow, 0, 1088 par, &anynul, &cStatus); 1089 fits_read_col(cSDptr, TFLOAT, cData[FOCUSROT].colnum, 1, 1, nRow, 0, 1090 rot, &anynul, &cStatus); 1091 1092 for (int irow = 0; irow < nRow; irow++) { 1093 if (sel[irow]) { 1094 // Convert to feed-plane coordinates. 1095 Double dist, pa; 1096 distPA(ra[irow]*D2R, dec[irow]*D2R, srcRA[irow]*D2R, srcDec[irow]*D2R, 1097 dist, pa); 1098 1099 Double spin = (par[irow] + rot[irow])*D2R - pa + PI; 1100 if (spin > 2.0*PI) spin -= 2.0*PI; 1101 Double squint = PI/2.0 - dist; 1102 1103 positions[isel++] = spin; 1104 positions[isel++] = squint; 1105 } 1106 } 1107 1108 delete [] srcRA; 1109 delete [] srcDec; 1110 delete [] par; 1111 delete [] rot; 1179 if (cCoordSys == 1) { 1180 // Horizontal (Az,El). 1181 if (cData[AZIMUTH].colnum < 0 || 1182 cData[ELEVATIO].colnum < 0) { 1183 log(LogOrigin( className, methodName, WHERE ), LogIO::WARN, "Azimuth/elevation information absent."); 1184 cStatus = -1; 1185 1186 } else { 1187 float *az = new float[cNRow]; 1188 float *el = new float[cNRow]; 1189 readCol(AZIMUTH, az); 1190 readCol(ELEVATIO, el); 1191 1192 if (!cStatus) { 1193 for (int irow = 0; irow < cNRow; irow++) { 1194 if (sel[irow]) { 1195 positions[isel++] = az[irow] * D2R; 1196 positions[isel++] = el[irow] * D2R; 1197 } 1198 } 1199 } 1200 1201 delete [] az; 1202 delete [] el; 1203 } 1204 1205 } else if (cCoordSys == 3) { 1206 // ZPA-EL. 1207 if (cData[BEAM].colnum < 0 || 1208 cData[FOCUSROT].colnum < 0 || 1209 cData[ELEVATIO].colnum < 0) { 1210 log(LogOrigin( className, methodName, WHERE ), LogIO::WARN, "ZPA/elevation information absent."); 1211 cStatus = -1; 1212 1213 } else { 1214 short *beam = new short[cNRow]; 1215 float *rot = new float[cNRow]; 1216 float *el = new float[cNRow]; 1217 readCol(BEAM, beam); 1218 readCol(FOCUSROT, rot); 1219 readCol(ELEVATIO, el); 1220 1221 if (!cStatus) { 1222 for (int irow = 0; irow < cNRow; irow++) { 1223 if (sel[irow]) { 1224 Int beamNo = beam[irow]; 1225 Double zpa = rot[irow]; 1226 if (beamNo > 1) { 1227 // Beam geometry for the Parkes multibeam. 1228 if (beamNo < 8) { 1229 zpa += -60.0 + 60.0*(beamNo-2); 1230 } else { 1231 zpa += -90.0 + 60.0*(beamNo-8); 1232 } 1233 1234 if (zpa < -180.0) { 1235 zpa += 360.0; 1236 } else if (zpa > 180.0) { 1237 zpa -= 360.0; 1238 } 1239 } 1240 1241 positions[isel++] = zpa * D2R; 1242 positions[isel++] = el[irow] * D2R; 1243 } 1244 } 1245 } 1246 1247 delete [] beam; 1248 delete [] rot; 1249 delete [] el; 1250 } 1112 1251 1113 1252 } else { 1114 for (int irow = 0; irow < nRow; irow++) { 1115 if (sel[irow]) { 1116 positions[isel++] = ra[irow] * D2R; 1117 positions[isel++] = dec[irow] * D2R; 1118 } 1119 } 1120 } 1121 1253 double *ra = new double[cNRow]; 1254 double *dec = new double[cNRow]; 1255 readCol(RA, ra); 1256 readCol(DEC, dec); 1257 1258 if (cStatus) { 1259 delete [] ra; 1260 delete [] dec; 1261 goto cleanup; 1262 } 1263 1264 if (cALFA_BD) { 1265 for (int irow = 0; irow < cNRow; irow++) { 1266 // Convert hours to degrees. 1267 ra[irow] *= 15.0; 1268 } 1269 } 1270 1271 if (cCoordSys == 0) { 1272 // Equatorial (RA,Dec). 1273 for (int irow = 0; irow < cNRow; irow++) { 1274 if (sel[irow]) { 1275 positions[isel++] = ra[irow] * D2R; 1276 positions[isel++] = dec[irow] * D2R; 1277 } 1278 } 1279 1280 } else if (cCoordSys == 2) { 1281 // Feed-plane. 1282 if (cData[OBJ_RA].colnum < 0 || 1283 cData[OBJ_DEC].colnum < 0 || 1284 cData[PARANGLE].colnum < 0 || 1285 cData[FOCUSROT].colnum < 0) { 1286 log( LogOrigin( className, methodName, WHERE ), LogIO::WARN, 1287 "Insufficient information to compute feed-plane\n" 1288 " coordinates."); 1289 cStatus = -1; 1290 1291 } else { 1292 double *srcRA = new double[cNRow]; 1293 double *srcDec = new double[cNRow]; 1294 float *par = new float[cNRow]; 1295 float *rot = new float[cNRow]; 1296 1297 readCol(OBJ_RA, srcRA); 1298 readCol(OBJ_DEC, srcDec); 1299 readCol(PARANGLE, par); 1300 readCol(FOCUSROT, rot); 1301 1302 if (!cStatus) { 1303 for (int irow = 0; irow < cNRow; irow++) { 1304 if (sel[irow]) { 1305 // Convert to feed-plane coordinates. 1306 Double dist, pa; 1307 distPA(ra[irow]*D2R, dec[irow]*D2R, srcRA[irow]*D2R, 1308 srcDec[irow]*D2R, dist, pa); 1309 1310 Double spin = (par[irow] + rot[irow])*D2R - pa; 1311 if (spin > 2.0*PI) spin -= 2.0*PI; 1312 Double squint = PI/2.0 - dist; 1313 1314 positions[isel++] = spin; 1315 positions[isel++] = squint; 1316 } 1317 } 1318 } 1319 1320 delete [] srcRA; 1321 delete [] srcDec; 1322 delete [] par; 1323 delete [] rot; 1324 } 1325 } 1326 1327 delete [] ra; 1328 delete [] dec; 1329 } 1330 1331 cleanup: 1122 1332 delete [] sel; 1123 delete [] ra; 1124 delete [] dec; 1125 1126 return cStatus; 1333 1334 if (cStatus) { 1335 nSel = 0; 1336 delete [] positions; 1337 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1338 cStatus = 0; 1339 return 1; 1340 } 1341 1342 return 0; 1127 1343 } 1128 1344 … … 1133 1349 1134 1350 int SDFITSreader::read( 1135 PKSMBrecord &mbrec)1351 MBrecord &mbrec) 1136 1352 { 1353 const string methodName = "read()" ; 1354 1137 1355 // Has the file been opened? 1138 1356 if (!cSDptr) { 1139 1357 return 1; 1140 1358 } 1141 1142 1359 // Find the next selected beam and IF. 1143 1360 short iBeam = 0, iIF = 0; 1144 while (++cRow <= cNRow) { 1361 int iPol = -1 ; 1362 while (1) { 1363 if (++cTimeIdx > cNAxisTime) { 1364 if (++cRow > cNRow) break; 1365 cTimeIdx = 1; 1366 } 1367 1145 1368 if (cData[BEAM].colnum > 0) { 1146 1369 readData(BEAM, cRow, &iBeam); … … 1164 1387 char chars[32]; 1165 1388 readData(OBSMODE, cRow, chars); 1166 if (strcmp(chars, "CAL") == 0) { 1167 // iIF is really the polarization in ALFA data. 1168 alfaCal(iBeam, iIF); 1389 if (strcmp(chars, "DROP") == 0) { 1390 // Completely flagged integration. 1169 1391 continue; 1392 1393 } else if (strcmp(chars, "CAL") == 0) { 1394 sReset = 1; 1395 if (cALFA_CIMA > 1) { 1396 for (short iPol = 0; iPol < cNPol[iIF]; iPol++) { 1397 alfaCal(iBeam, iIF, iPol); 1398 } 1399 continue; 1400 } else { 1401 // iIF is really the polarization in older ALFA data. 1402 alfaCal(iBeam, 0, iIF); 1403 continue; 1404 } 1405 1406 } else { 1407 // Reset for the next CAL record. 1408 if (sReset) { 1409 for (short iPol = 0; iPol < cNPol[iIF]; iPol++) { 1410 sALFAcalNon[iBeam][iPol] = 0; 1411 sALFAcalNoff[iBeam][iPol] = 0; 1412 sALFAcalOn[iBeam][iPol] = 0.0f; 1413 sALFAcalOff[iBeam][iPol] = 0.0f; 1414 } 1415 sReset = 0; 1416 1417 sprintf(cMsg, "ALFA cal factors for beam %d: %.3e, %.3e", 1418 iBeam+1, sALFAcal[iBeam][0], sALFAcal[iBeam][1]); 1419 log(LogOrigin( className, methodName, WHERE ), LogIO::NORMAL, cMsg); 1420 //logMsg(cMsg); 1421 } 1170 1422 } 1171 1423 } 1172 1424 1425 // for GBT SDFITS 1426 if (cData[STOKES].colnum > 0 ) { 1427 readData(STOKES, cRow, &iPol ) ; 1428 for ( int i = 0 ; i < cNPol[iIF] ; i++ ) { 1429 if ( cPols[i] == iPol ) { 1430 iPol = i ; 1431 break ; 1432 } 1433 } 1434 } 1173 1435 break; 1174 1436 } … … 1200 1462 // Times. 1201 1463 char datobs[32]; 1202 readData(DATE_OBS, cRow, datobs); 1203 readData(TIME, cRow, &mbrec.utc); 1204 if (cALFA_BD) mbrec.utc *= 3600.0; 1205 1206 if (datobs[2] == '/') { 1207 // Translate an old-format DATE-OBS. 1208 datobs[9] = datobs[1]; 1209 datobs[8] = datobs[0]; 1210 datobs[2] = datobs[6]; 1211 datobs[5] = datobs[3]; 1212 datobs[3] = datobs[7]; 1213 datobs[6] = datobs[4]; 1214 datobs[7] = '-'; 1215 datobs[4] = '-'; 1216 datobs[1] = '9'; 1217 datobs[0] = '1'; 1218 1219 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) { 1220 // Dig UTC out of a new-format DATE-OBS. 1221 int hh, mm; 1222 float ss; 1223 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss); 1224 mbrec.utc = (hh*60 + mm)*60 + ss; 1225 } 1226 1227 datobs[10] = '\0'; 1464 readTime(cRow, cTimeIdx, datobs, mbrec.utc); 1228 1465 strcpy(mbrec.datobs, datobs); 1229 1466 1230 1467 if (cData[CYCLE].colnum > 0) { 1231 1468 readData(CYCLE, cRow, &mbrec.cycleNo); 1469 mbrec.cycleNo += cTimeIdx - 1; 1232 1470 if (cALFA_BD) mbrec.cycleNo++; 1233 1471 } else { … … 1239 1477 } 1240 1478 1479 if ( iPol != -1 ) { 1480 if ( mbrec.scanNo != cGLastScan[iPol] ) { 1481 cGLastScan[iPol] = mbrec.scanNo ; 1482 cGCycleNo[iPol] = 0 ; 1483 mbrec.cycleNo = ++cGCycleNo[iPol] ; 1484 } 1485 else { 1486 mbrec.cycleNo = ++cGCycleNo[iPol] ; 1487 } 1488 } 1489 1241 1490 readData(EXPOSURE, cRow, &mbrec.exposure); 1242 1491 1243 1492 // Source identification. 1244 readData(OBJECT, cRow, mbrec.srcName); 1493 readData(OBJECT, cRow, mbrec.srcName); 1494 1495 if ( iPol != -1 ) { 1496 char obsmode[32] ; 1497 readData( OBSMODE, cRow, obsmode ) ; 1498 char sig[1] ; 1499 char cal[1] ; 1500 readData( SIG, cRow, sig ) ; 1501 readData( CAL, cRow, cal ) ; 1502 if ( strstr( obsmode, "PSWITCH" ) != NULL ) { 1503 // position switch 1504 strcat( mbrec.srcName, "_p" ) ; 1505 if ( strstr( obsmode, "PSWITCHON" ) != NULL ) { 1506 strcat( mbrec.srcName, "s" ) ; 1507 } 1508 else if ( strstr( obsmode, "PSWITCHOFF" ) != NULL ) { 1509 strcat( mbrec.srcName, "r" ) ; 1510 } 1511 } 1512 else if ( strstr( obsmode, "Nod" ) != NULL ) { 1513 // nod 1514 strcat( mbrec.srcName, "_n" ) ; 1515 if ( sig[0] == 'T' ) { 1516 strcat( mbrec.srcName, "s" ) ; 1517 } 1518 else { 1519 strcat( mbrec.srcName, "r" ) ; 1520 } 1521 } 1522 else if ( strstr( obsmode, "FSWITCH" ) != NULL ) { 1523 // frequency switch 1524 strcat( mbrec.srcName, "_f" ) ; 1525 if ( sig[0] == 'T' ) { 1526 strcat( mbrec.srcName, "s" ) ; 1527 } 1528 else { 1529 strcat( mbrec.srcName, "r" ) ; 1530 } 1531 } 1532 if ( cal[0] == 'T' ) { 1533 strcat( mbrec.srcName, "c" ) ; 1534 } 1535 else { 1536 strcat( mbrec.srcName, "o" ) ; 1537 } 1538 } 1245 1539 1246 1540 readData(OBJ_RA, cRow, &mbrec.srcRA); … … 1279 1573 mbrec.decRate = scanrate[1] * D2R; 1280 1574 } 1575 mbrec.paRate = 0.0f; 1281 1576 1282 1577 // IF-dependent parameters. … … 1289 1584 int nPol = cNPol[iIF]; 1290 1585 1586 if ( cData[STOKES].colnum > 0 ) 1587 nPol = 1 ; 1588 1291 1589 if (cGetSpectra || cGetXPol) { 1292 1590 int nxpol = cGetXPol ? 2*nChan : 0; … … 1298 1596 mbrec.nChan[0] = nChan; 1299 1597 mbrec.nPol[0] = nPol; 1598 mbrec.polNo = iPol ; 1300 1599 1301 1600 readData(FqRefPix, cRow, mbrec.fqRefPix); … … 1316 1615 1317 1616 if (cStatus) { 1318 reportError();1617 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1319 1618 return 1; 1320 1619 } … … 1353 1652 1354 1653 if (cStatus) { 1355 reportError();1654 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1356 1655 return 1; 1357 1656 } 1358 1657 1359 1658 // Read data, sectioning and transposing it in the process. 1360 long *blc = new long[cNAx is+1];1361 long *trc = new long[cNAx is+1];1362 long *inc = new long[cNAx is+1];1363 for (int iaxis = 0; iaxis <= cNAx is; iaxis++) {1659 long *blc = new long[cNAxes+1]; 1660 long *trc = new long[cNAxes+1]; 1661 long *inc = new long[cNAxes+1]; 1662 for (int iaxis = 0; iaxis <= cNAxes; iaxis++) { 1364 1663 blc[iaxis] = 1; 1365 1664 trc[iaxis] = 1; … … 1367 1666 } 1368 1667 1369 blc[cReqax[0]] = std::min(startChan, endChan); 1370 trc[cReqax[0]] = std::max(startChan, endChan); 1371 blc[cNAxis] = cRow; 1372 trc[cNAxis] = cRow; 1668 blc[cFreqAxis] = std::min(startChan, endChan); 1669 trc[cFreqAxis] = std::max(startChan, endChan); 1670 if (cTimeAxis >= 0) { 1671 blc[cTimeAxis] = cTimeIdx; 1672 trc[cTimeAxis] = cTimeIdx; 1673 } 1674 blc[cNAxes] = cRow; 1675 trc[cNAxes] = cRow; 1373 1676 1374 1677 mbrec.haveSpectra = cGetSpectra; … … 1376 1679 int anynul; 1377 1680 1378 for (int i pol = 0; ipol < nPol; ipol++) {1379 blc[c Reqax[1]] = ipol+1;1380 trc[c Reqax[1]] = ipol+1;1381 1382 if (cALFA ) {1681 for (int iPol = 0; iPol < nPol; iPol++) { 1682 blc[cStokesAxis] = iPol+1; 1683 trc[cStokesAxis] = iPol+1; 1684 1685 if (cALFA && cALFA_CIMA < 2) { 1383 1686 // ALFA data: polarizations are stored in successive rows. 1384 blc[c Reqax[1]] = 1;1385 trc[c Reqax[1]] = 1;1386 1387 if (i pol) {1687 blc[cStokesAxis] = 1; 1688 trc[cStokesAxis] = 1; 1689 1690 if (iPol) { 1388 1691 if (++cRow > cNRow) { 1389 1692 return -1; 1390 1693 } 1391 1694 1392 blc[cNAx is] = cRow;1393 trc[cNAx is] = cRow;1695 blc[cNAxes] = cRow; 1696 trc[cNAxes] = cRow; 1394 1697 } 1395 1698 1396 1699 } else if (cData[DATA].nelem < 0) { 1397 1700 // Variable dimension array; get axis lengths. 1398 int naxis = 5, status;1399 1400 if ((status = readDim(DATA, cRow, &nax is, cNAxes))) {1401 reportError();1402 1403 } else if ((status = (nax is != cNAxis))) {1404 cerr << "DATA array dimensions changed." << endl;1701 int naxes = 5, status; 1702 1703 if ((status = readDim(DATA, cRow, &naxes, cNAxis))) { 1704 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1705 1706 } else if ((status = (naxes != cNAxes))) { 1707 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array dimensions changed."); 1405 1708 } 1406 1709 … … 1413 1716 } 1414 1717 1415 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAx is, cNAxes,1416 blc, trc, inc, 0, mbrec.spectra[0] + i pol*nChan, &anynul,1718 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxes, cNAxis, 1719 blc, trc, inc, 0, mbrec.spectra[0] + iPol*nChan, &anynul, 1417 1720 &cStatus)) { 1418 reportError();1721 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1419 1722 delete [] blc; 1420 1723 delete [] trc; … … 1425 1728 if (endChan < startChan) { 1426 1729 // Reverse the spectrum. 1427 float *iptr = mbrec.spectra[0] + i pol*nChan;1730 float *iptr = mbrec.spectra[0] + iPol*nChan; 1428 1731 float *jptr = iptr + nChan - 1; 1429 1732 float *mid = iptr + nChan/2; … … 1437 1740 if (cALFA) { 1438 1741 // ALFA data, rescale the spectrum. 1439 float *chan = mbrec.spectra[0] + ipol*nChan; 1742 float el, zd; 1743 readData(ELEVATIO, cRow, &el); 1744 zd = 90.0f - el; 1745 1746 float factor = sALFAcal[iBeam][iPol] / alfaGain(zd); 1747 1748 if (cALFA_CIMA > 1) { 1749 // Rescale according to the number of unblanked accumulations. 1750 int colnum, naccum; 1751 findCol("STAT", &colnum); 1752 fits_read_col(cSDptr, TINT, colnum, cRow, 10*(cTimeIdx-1)+2, 1, 0, 1753 &naccum, &anynul, &cStatus); 1754 factor *= cALFAacc / naccum; 1755 } 1756 1757 float *chan = mbrec.spectra[0] + iPol*nChan; 1440 1758 float *chanN = chan + nChan; 1441 1759 while (chan < chanN) { 1442 1760 // Approximate conversion to Jy. 1443 *(chan++) *= cALFAcal[iBeam][iIF];1761 *(chan++) *= factor; 1444 1762 } 1445 1763 } 1446 1764 1447 if (mbrec.tsys[0][i pol] == 0.0) {1765 if (mbrec.tsys[0][iPol] == 0.0) { 1448 1766 // Compute Tsys as the average across the spectrum. 1449 float *chan = mbrec.spectra[0] + i pol*nChan;1767 float *chan = mbrec.spectra[0] + iPol*nChan; 1450 1768 float *chanN = chan + nChan; 1451 float *tsys = mbrec.tsys[0] + i pol;1769 float *tsys = mbrec.tsys[0] + iPol; 1452 1770 while (chan < chanN) { 1453 1771 *tsys += *(chan++); … … 1459 1777 // Read data flags. 1460 1778 if (cData[FLAGGED].colnum > 0) { 1461 if (fits_read_subset_byt(cSDptr, cData[FLAGGED].colnum, cNAx is,1462 cNAx es, blc, trc, inc, 0, mbrec.flagged[0] + ipol*nChan, &anynul,1779 if (fits_read_subset_byt(cSDptr, cData[FLAGGED].colnum, cNAxes, 1780 cNAxis, blc, trc, inc, 0, mbrec.flagged[0] + iPol*nChan, &anynul, 1463 1781 &cStatus)) { 1464 reportError();1782 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1465 1783 delete [] blc; 1466 1784 delete [] trc; … … 1471 1789 if (endChan < startChan) { 1472 1790 // Reverse the flag vector. 1473 unsigned char *iptr = mbrec.flagged[0] + i pol*nChan;1791 unsigned char *iptr = mbrec.flagged[0] + iPol*nChan; 1474 1792 unsigned char *jptr = iptr + nChan - 1; 1475 1793 for (int ichan = 0; ichan < nChan/2; ichan++) { … … 1482 1800 } else { 1483 1801 // All channels are unflagged by default. 1484 unsigned char *iptr = mbrec.flagged[0] + i pol*nChan;1802 unsigned char *iptr = mbrec.flagged[0] + iPol*nChan; 1485 1803 for (int ichan = 0; ichan < nChan; ichan++) { 1486 1804 *(iptr++) = 0; … … 1513 1831 if (fits_read_subset_flt(cSDptr, cData[XPOLDATA].colnum, nAxis, nAxes, 1514 1832 blc, trc, inc, 0, mbrec.xpol[0], &anynul, &cStatus)) { 1515 reportError();1833 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1516 1834 delete [] blc; 1517 1835 delete [] trc; … … 1544 1862 1545 1863 if (cStatus) { 1546 reportError();1864 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1547 1865 return 1; 1548 1866 } … … 1552 1870 readData(TCAL, cRow, &mbrec.tcal[0]); 1553 1871 readData(TCALTIME, cRow, mbrec.tcalTime); 1872 1554 1873 readData(AZIMUTH, cRow, &mbrec.azimuth); 1555 1874 readData(ELEVATIO, cRow, &mbrec.elevation); 1556 1875 readData(PARANGLE, cRow, &mbrec.parAngle); 1876 1557 1877 readData(FOCUSAXI, cRow, &mbrec.focusAxi); 1558 1878 readData(FOCUSTAN, cRow, &mbrec.focusTan); 1559 1879 readData(FOCUSROT, cRow, &mbrec.focusRot); 1880 1560 1881 readData(TAMBIENT, cRow, &mbrec.temp); 1561 1882 readData(PRESSURE, cRow, &mbrec.pressure); … … 1575 1896 mbrec.windAz *= D2R; 1576 1897 1898 // For GBT data, source velocity can be evaluated 1899 if ( cData[RVSYS].colnum > 0 && cData[VFRAME].colnum > 0 ) { 1900 float vframe; 1901 readData(VFRAME, cRow, &vframe); 1902 float rvsys; 1903 readData(RVSYS, cRow, &rvsys); 1904 //mbrec.srcVelocity = rvsys - vframe ; 1905 mbrec.srcVelocity = rvsys ; 1906 } 1907 1577 1908 if (cStatus) { 1578 reportError();1909 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1579 1910 return 1; 1580 1911 } 1581 1912 1582 1913 return 0; 1583 }1584 1585 1586 //------------------------------------------------------ SDFITSreader::alfaCal1587 1588 // Process ALFA calibration data.1589 1590 int SDFITSreader::alfaCal(1591 short iBeam,1592 short iPol)1593 {1594 int calOn;1595 char chars[32];1596 if (cALFA_BD) {1597 readData("OBS_NAME", TSTRING, cRow, chars);1598 } else {1599 readData("SCANTYPE", TSTRING, cRow, chars);1600 }1601 1602 if (strcmp(chars, "ON") == 0) {1603 calOn = 1;1604 } else if (strcmp(chars, "OFF") == 0) {1605 calOn = 0;1606 } else {1607 return 1;1608 }1609 1610 // Read cal data.1611 long *blc = new long[cNAxis+1];1612 long *trc = new long[cNAxis+1];1613 long *inc = new long[cNAxis+1];1614 for (int iaxis = 0; iaxis <= cNAxis; iaxis++) {1615 blc[iaxis] = 1;1616 trc[iaxis] = 1;1617 inc[iaxis] = 1;1618 }1619 1620 // User channel selection.1621 int startChan = cStartChan[0];1622 int endChan = cEndChan[0];1623 1624 blc[cNAxis] = cRow;1625 trc[cNAxis] = cRow;1626 blc[cReqax[0]] = std::min(startChan, endChan);1627 trc[cReqax[0]] = std::max(startChan, endChan);1628 blc[cReqax[1]] = 1;1629 trc[cReqax[1]] = 1;1630 1631 float spectrum[endChan];1632 int anynul;1633 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxis, cNAxes,1634 blc, trc, inc, 0, spectrum, &anynul, &cStatus)) {1635 reportError();1636 delete [] blc;1637 delete [] trc;1638 delete [] inc;1639 return 1;1640 }1641 1642 // Average the spectrum.1643 float mean = 1e9f;1644 for (int k = 0; k < 2; k++) {1645 float discrim = 2.0f * mean;1646 1647 int nChan = 0;1648 float sum = 0.0f;1649 1650 float *chanN = spectrum + abs(endChan - startChan) + 1;1651 for (float *chan = spectrum; chan < chanN; chan++) {1652 // Simple discriminant that eliminates strong radar interference.1653 if (*chan < discrim) {1654 nChan++;1655 sum += *chan;1656 }1657 }1658 1659 mean = sum / nChan;1660 }1661 1662 if (calOn) {1663 cALFAcalOn[iBeam][iPol] += mean;1664 } else {1665 cALFAcalOff[iBeam][iPol] += mean;1666 }1667 1668 if (cALFAcalOn[iBeam][iPol] != 0.0f &&1669 cALFAcalOff[iBeam][iPol] != 0.0f) {1670 // Tcal should come from the TCAL table, it varies weakly with beam,1671 // polarization, and frequency. However, TCAL is not written properly.1672 float Tcal = 12.0f;1673 cALFAcal[iBeam][iPol] = Tcal / (cALFAcalOn[iBeam][iPol] -1674 cALFAcalOff[iBeam][iPol]);1675 1676 // Scale from K to Jy; the gain also varies weakly with beam,1677 // polarization, frequency, and zenith angle.1678 float fluxCal = 10.0f;1679 cALFAcal[iBeam][iPol] /= fluxCal;1680 1681 cALFAcalOn[iBeam][iPol] = 0.0f;1682 cALFAcalOff[iBeam][iPol] = 0.0f;1683 }1684 1685 return 0;1686 }1687 1688 1689 //-------------------------------------------------- SDFITSreader::reportError1690 1691 // Print the error message corresponding to the input status value and all the1692 // messages on the CFITSIO error stack to stderr.1693 1694 void SDFITSreader::reportError()1695 {1696 fits_report_error(stderr, cStatus);1697 1914 } 1698 1915 … … 1706 1923 int status = 0; 1707 1924 fits_close_file(cSDptr, &status); 1708 cSDptr = 0 ;1925 cSDptr = 0x0; 1709 1926 1710 1927 if (cBeams) delete [] cBeams; … … 1714 1931 if (cRefChan) delete [] cRefChan; 1715 1932 } 1933 } 1934 1935 //------------------------------------------------------- SDFITSreader::log 1936 1937 // Log a message. If the current CFITSIO status value is non-zero, also log 1938 // the corresponding error message and the CFITSIO message stack. 1939 1940 void SDFITSreader::log(LogOrigin origin, LogIO::Command cmd, const char *msg) 1941 { 1942 LogIO os( origin ) ; 1943 1944 os << msg << endl ; 1945 1946 if (cStatus > 0) { 1947 fits_get_errstatus(cStatus, cMsg); 1948 os << cMsg << endl ; 1949 1950 while (fits_read_errmsg(cMsg)) { 1951 os << cMsg << endl ; 1952 } 1953 } 1954 os << LogIO::POST ; 1716 1955 } 1717 1956 … … 1737 1976 long nelem, width; 1738 1977 fits_get_coltype(cSDptr, colnum, &coltype, &nelem, &width, &cStatus); 1978 fits_get_bcolparms(cSDptr, colnum, 0x0, cData[iData].units, 0x0, 0x0, 0x0, 1979 0x0, 0x0, 0x0, &cStatus); 1739 1980 1740 1981 // Look for a TDIMnnn keyword or column. … … 1768 2009 } 1769 2010 2011 //------------------------------------------------------ SDFITSreader::findCol 2012 2013 // Locate a parameter in the SDFITS file. 2014 2015 void SDFITSreader::findCol( 2016 char *name, 2017 int *colnum) 2018 { 2019 *colnum = 0; 2020 int status = 0; 2021 fits_get_colnum(cSDptr, CASESEN, name, colnum, &status); 2022 2023 if (status) { 2024 // Not a real column - maybe it's virtual. 2025 char card[81]; 2026 2027 status = 0; 2028 fits_read_card(cSDptr, name, card, &status); 2029 if (status) { 2030 // Not virtual either. 2031 *colnum = -1; 2032 } 2033 2034 // Clear error messages. 2035 fits_clear_errmsg(); 2036 } 2037 } 2038 1770 2039 //------------------------------------------------------ SDFITSreader::readDim 1771 2040 … … 1775 2044 int iData, 1776 2045 long iRow, 1777 int *nax is,1778 long nax es[])2046 int *naxes, 2047 long naxis[]) 1779 2048 { 1780 2049 int colnum = cData[iData].colnum; … … 1783 2052 } 1784 2053 1785 int maxdim = *nax is;2054 int maxdim = *naxes; 1786 2055 if (cData[iData].tdimcol < 0) { 1787 2056 // No TDIMnnn column for this array. 1788 2057 if (cData[iData].nelem < 0) { 1789 2058 // Variable length array; read the array descriptor. 1790 *nax is = 1;2059 *naxes = 1; 1791 2060 long dummy; 1792 if (fits_read_descript(cSDptr, colnum, iRow, nax es, &dummy, &cStatus)) {2061 if (fits_read_descript(cSDptr, colnum, iRow, naxis, &dummy, &cStatus)) { 1793 2062 return 1; 1794 2063 } … … 1796 2065 } else { 1797 2066 // Read the repeat count from TFORMnnn. 1798 if (fits_read_tdim(cSDptr, colnum, maxdim, nax is, naxes, &cStatus)) {2067 if (fits_read_tdim(cSDptr, colnum, maxdim, naxes, naxis, &cStatus)) { 1799 2068 return 1; 1800 2069 } … … 1814 2083 1815 2084 tp++; 1816 *nax is = 0;2085 *naxes = 0; 1817 2086 for (size_t j = 1; j < strlen(tdimval); j++) { 1818 2087 if (tdimval[j] == ',' || tdimval[j] == ')') { 1819 sscanf(tp, "%ld", nax es + (*naxis)++);2088 sscanf(tp, "%ld", naxis + (*naxes)++); 1820 2089 if (tdimval[j] == ')') break; 1821 2090 tp = tdimval + j + 1; … … 1852 2121 findCol(name, &colnum); 1853 2122 1854 if (colnum > 0 ) {2123 if (colnum > 0 && iRow > 0) { 1855 2124 // Read the first value from the specified row of the table. 1856 2125 int coltype; … … 1915 2184 void *value) 1916 2185 { 1917 char *name = cData[iData].name;1918 2186 int type = cData[iData].type; 1919 2187 int colnum = cData[iData].colnum; 1920 long nelem = cData[iData].nelem; 1921 1922 if (colnum > 0) { 2188 2189 if (colnum > 0 && iRow > 0) { 1923 2190 // Read the required number of values from the specified row of the table. 2191 long nelem = cData[iData].nelem; 1924 2192 int anynul; 1925 2193 if (type == TSTRING) { … … 1950 2218 } else if (colnum == 0) { 1951 2219 // Read keyword value. 2220 char *name = cData[iData].name; 1952 2221 fits_read_key(cSDptr, type, name, value, 0, &cStatus); 1953 2222 … … 1970 2239 } 1971 2240 1972 //------------------------------------------------------ SDFITSreader:: findCol1973 1974 // Locate a parameter inthe SDFITS file.1975 1976 void SDFITSreader::findCol(1977 char *name,1978 int *colnum)2241 //------------------------------------------------------ SDFITSreader::readCol 2242 2243 // Read a scalar column from the SDFITS file. 2244 2245 int SDFITSreader::readCol( 2246 int iData, 2247 void *value) 1979 2248 { 1980 *colnum = 0; 1981 int status = 0; 1982 fits_get_colnum(cSDptr, CASESEN, name, colnum, &status); 1983 1984 if (status) { 1985 // Not a real column - maybe it's virtual. 1986 char card[81]; 1987 1988 status = 0; 1989 fits_read_card(cSDptr, name, card, &status); 1990 if (status) { 1991 // Not virtual either. 1992 *colnum = -1; 1993 } 1994 1995 // Clear error messages. 1996 fits_clear_errmsg(); 1997 } 2249 int type = cData[iData].type; 2250 2251 if (cData[iData].colnum > 0) { 2252 // Table column. 2253 int anynul; 2254 fits_read_col(cSDptr, type, cData[iData].colnum, 1, 1, cNRow, 0, 2255 value, &anynul, &cStatus); 2256 2257 } else { 2258 // Header keyword. 2259 readData(iData, 0, value); 2260 for (int irow = 1; irow < cNRow; irow++) { 2261 if (type == TSHORT) { 2262 ((short *)value)[irow] = *((short *)value); 2263 } else if (type == TINT) { 2264 ((int *)value)[irow] = *((int *)value); 2265 } else if (type == TFLOAT) { 2266 ((float *)value)[irow] = *((float *)value); 2267 } else if (type == TDOUBLE) { 2268 ((double *)value)[irow] = *((double *)value); 2269 } 2270 } 2271 } 2272 2273 return cData[iData].colnum < 0; 1998 2274 } 2275 2276 //----------------------------------------------------- SDFITSreader::readTime 2277 2278 // Read the time from the SDFITS file. 2279 2280 int SDFITSreader::readTime( 2281 long iRow, 2282 int iPix, 2283 char *datobs, 2284 double &utc) 2285 { 2286 readData(DATE_OBS, iRow, datobs); 2287 if (cData[TIME].colnum >= 0) { 2288 readData(TIME, iRow, &utc); 2289 } else if (cGBT) { 2290 Int yy, mm ; 2291 Double dd, hour, min, sec ; 2292 sscanf( datobs, "%d-%d-%lfT%lf:%lf:%lf", &yy, &mm, &dd, &hour, &min, &sec ) ; 2293 dd = dd + ( hour * 3600.0 + min * 60.0 + sec ) / 86400.0 ; 2294 MVTime mvt( yy, mm, dd ) ; 2295 dd = mvt.day() ; 2296 utc = fmod( dd, 1.0 ) * 86400.0 ; 2297 } else if (cNAxisTime > 1) { 2298 double timeDelt, timeRefPix, timeRefVal; 2299 readData(TimeRefVal, iRow, &timeRefVal); 2300 readData(TimeDelt, iRow, &timeDelt); 2301 readData(TimeRefPix, iRow, &timeRefPix); 2302 utc = timeRefVal + (iPix - timeRefPix) * timeDelt; 2303 } 2304 2305 if (cALFA_BD) utc *= 3600.0; 2306 2307 // Check DATE-OBS format. 2308 if (datobs[2] == '/') { 2309 // Translate an old-format DATE-OBS. 2310 datobs[9] = datobs[1]; 2311 datobs[8] = datobs[0]; 2312 datobs[2] = datobs[6]; 2313 datobs[5] = datobs[3]; 2314 datobs[3] = datobs[7]; 2315 datobs[6] = datobs[4]; 2316 datobs[7] = '-'; 2317 datobs[4] = '-'; 2318 datobs[1] = '9'; 2319 datobs[0] = '1'; 2320 2321 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) { 2322 // Dig UTC out of a new-format DATE-OBS. 2323 int hh, mm; 2324 float ss; 2325 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss); 2326 utc = (hh*60 + mm)*60 + ss; 2327 } 2328 2329 datobs[10] = '\0'; 2330 2331 return 0; 2332 } 2333 2334 //------------------------------------------------------ SDFITSreader::alfaCal 2335 2336 // Process ALFA calibration data. 2337 2338 int SDFITSreader::alfaCal( 2339 short iBeam, 2340 short iIF, 2341 short iPol) 2342 { 2343 const string methodName = "alfaCal()" ; 2344 2345 int calOn; 2346 char chars[32]; 2347 if (cALFA_BD) { 2348 readData("OBS_NAME", TSTRING, cRow, chars); 2349 } else { 2350 readData("SCANTYPE", TSTRING, cRow, chars); 2351 } 2352 2353 if (strcmp(chars, "ON") == 0) { 2354 calOn = 1; 2355 } else if (strcmp(chars, "OFF") == 0) { 2356 calOn = 0; 2357 } else { 2358 return 1; 2359 } 2360 2361 // Read cal data. 2362 long *blc = new long[cNAxes+1]; 2363 long *trc = new long[cNAxes+1]; 2364 long *inc = new long[cNAxes+1]; 2365 for (int iaxis = 0; iaxis <= cNAxes; iaxis++) { 2366 blc[iaxis] = 1; 2367 trc[iaxis] = 1; 2368 inc[iaxis] = 1; 2369 } 2370 2371 // User channel selection. 2372 int startChan = cStartChan[iIF]; 2373 int endChan = cEndChan[iIF]; 2374 2375 blc[cFreqAxis] = std::min(startChan, endChan); 2376 trc[cFreqAxis] = std::max(startChan, endChan); 2377 if (cALFA_CIMA > 1) { 2378 // CIMAFITS 2.x has a legitimate STOKES axis... 2379 blc[cStokesAxis] = iPol+1; 2380 trc[cStokesAxis] = iPol+1; 2381 } else { 2382 // ...older ALFA data does not. 2383 blc[cStokesAxis] = 1; 2384 trc[cStokesAxis] = 1; 2385 } 2386 if (cTimeAxis >= 0) { 2387 blc[cTimeAxis] = cTimeIdx; 2388 trc[cTimeAxis] = cTimeIdx; 2389 } 2390 blc[cNAxes] = cRow; 2391 trc[cNAxes] = cRow; 2392 2393 float spectrum[endChan]; 2394 int anynul; 2395 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxes, cNAxis, 2396 blc, trc, inc, 0, spectrum, &anynul, &cStatus)) { 2397 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 2398 delete [] blc; 2399 delete [] trc; 2400 delete [] inc; 2401 return 1; 2402 } 2403 2404 // Factor to rescale according to the number of unblanked accumulations. 2405 float factor = 1.0f; 2406 if (cALFA_CIMA > 1) { 2407 int colnum, naccum; 2408 findCol("STAT", &colnum); 2409 fits_read_col(cSDptr, TINT, colnum, cRow, 2, 1, 0, &naccum, &anynul, 2410 &cStatus); 2411 factor = cALFAacc / naccum; 2412 } 2413 2414 // Average the spectrum. 2415 float mean = 1e9f; 2416 for (int k = 0; k < 2; k++) { 2417 float discrim = 2.0f * mean; 2418 2419 int nChan = 0; 2420 float sum = 0.0f; 2421 2422 float *chanN = spectrum + abs(endChan - startChan) + 1; 2423 for (float *chan = spectrum; chan < chanN; chan++) { 2424 // Simple discriminant that eliminates strong radar interference. 2425 if (*chan < discrim) { 2426 nChan++; 2427 sum += *chan * factor; 2428 } 2429 } 2430 2431 mean = sum / nChan; 2432 } 2433 2434 if (calOn) { 2435 sALFAcalOn[iBeam][iPol] *= sALFAcalNon[iBeam][iPol]; 2436 sALFAcalOn[iBeam][iPol] += mean; 2437 sALFAcalOn[iBeam][iPol] /= ++sALFAcalNon[iBeam][iPol]; 2438 } else { 2439 sALFAcalOff[iBeam][iPol] *= sALFAcalNoff[iBeam][iPol]; 2440 sALFAcalOff[iBeam][iPol] += mean; 2441 sALFAcalOff[iBeam][iPol] /= ++sALFAcalNoff[iBeam][iPol]; 2442 } 2443 2444 if (sALFAcalNon[iBeam][iPol] && sALFAcalNoff[iBeam][iPol]) { 2445 // Tcal should come from the TCAL table, it varies weakly with beam, 2446 // polarization, and frequency. However, TCAL is not written properly. 2447 float Tcal = 12.0f; 2448 sALFAcal[iBeam][iPol] = Tcal / (sALFAcalOn[iBeam][iPol] - 2449 sALFAcalOff[iBeam][iPol]); 2450 2451 // Scale from K to Jy; the gain also varies weakly with beam, 2452 // polarization, frequency, and zenith angle. 2453 float fluxCal = 10.0f; 2454 sALFAcal[iBeam][iPol] /= fluxCal; 2455 } 2456 2457 return 0; 2458 } 2459 2460 //----------------------------------------------------- SDFITSreader::alfaGain 2461 2462 // ALFA gain factor. 2463 2464 float SDFITSreader::alfaGain( 2465 float zd) 2466 { 2467 // Gain vs zenith distance table from Robert Minchin, 2008/12/08. 2468 const int nZD = 37; 2469 const float zdLim[] = {1.5f, 19.5f}; 2470 const float zdInc = (nZD - 1) / (zdLim[1] - zdLim[0]); 2471 float zdGain[] = { 1.00723708, 2472 1.16644573, 1.15003645, 1.07117307, 1.02532673, 2473 1.01788402, 1.01369524, 1.00000000, 0.989855111, 2474 0.990888834, 0.993996620, 0.989964068, 0.982213855, 2475 0.978662670, 0.979349494, 0.978478372, 0.974631131, 2476 0.972126007, 0.972835243, 0.972742677, 0.968671739, 2477 0.963891327, 0.963452935, 0.966831207, 0.969585896, 2478 0.970700860, 0.972644389, 0.973754644, 0.967344403, 2479 0.952168941, 0.937160134, 0.927843094, 0.914048433, 2480 0.886700928, 0.864701211, 0.869126320, 0.854309499}; 2481 2482 float gain; 2483 // Do table lookup by linear interpolation. 2484 float lambda = zdInc * (zd - zdLim[0]); 2485 int j = int(lambda); 2486 if (j < 0) { 2487 gain = zdGain[0]; 2488 } else if (j >= nZD-1) { 2489 gain = zdGain[nZD-1]; 2490 } else { 2491 gain = zdGain[j] + (lambda - j) * (zdGain[j+1] - zdGain[j]); 2492 } 2493 2494 return gain; 2495 } 2496 -
branches/alma/external/atnf/PKSIO/SDFITSreader.h
r1453 r1757 2 2 //# SDFITSreader.h: ATNF CFITSIO interface class for SDFITS input. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSreader.h,v 19.22 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# The SDFITSreader class reads single dish FITS files such as those written … … 38 41 39 42 #include <atnf/PKSIO/FITSreader.h> 40 #include <atnf/PKSIO/PKSMBrecord.h> 43 #include <atnf/PKSIO/MBrecord.h> 44 45 #include <casa/Logging/LogIO.h> 41 46 42 47 #include <fitsio.h> 48 49 using namespace std; 50 using namespace casa; 43 51 44 52 // <summary> … … 76 84 double antPos[3], 77 85 char obsMode[32], 86 char bunit[32], 78 87 float &equinox, 79 88 char radecsys[32], … … 99 108 100 109 // Read the next data record. 101 virtual int read(PKSMBrecord &record); 102 103 // Print out CFITSIO error messages. 104 void reportError(void); 110 virtual int read(MBrecord &record); 105 111 106 112 // Close the SDFITS file. … … 108 114 109 115 private: 110 int cCycleNo, cExtraSysCal, cNAxis, cStatus; 111 long cNAxes[5], cNRow, cReqax[4], cRow; 116 int cCycleNo, cExtraSysCal, cNAxes, cStatus; 117 long cBeamAxis, cDecAxis, cFreqAxis, cNAxis[5], cNAxisTime, cNRow, 118 cRaAxis, cRow, cStokesAxis, cTimeAxis, cTimeIdx; 112 119 double cLastUTC; 113 120 fitsfile *cSDptr; … … 117 124 int cBeam_1rel, cIF_1rel; 118 125 126 // for GBT 127 int *cPols ; 128 119 129 enum {SCAN, CYCLE, DATE_OBS, TIME, EXPOSURE, OBJECT, OBJ_RA, OBJ_DEC, 120 RESTFRQ, OBSMODE, BEAM, IF, FqRefPix, FqRefVal, FqDelt, RA, DEC, 121 SCANRATE, TSYS, CALFCTR, XCALFCTR, BASELIN, BASESUB, DATA, FLAGGED, 122 DATAXED, XPOLDATA, REFBEAM, TCAL, TCALTIME, AZIMUTH, ELEVATIO, 123 PARANGLE, FOCUSAXI, FOCUSTAN, FOCUSROT, TAMBIENT, PRESSURE, 124 HUMIDITY, WINDSPEE, WINDDIRE, NDATA}; 130 RESTFRQ, OBSMODE, BEAM, IF, FqRefVal, FqDelt, FqRefPix, RA, DEC, 131 TimeRefVal, TimeDelt, TimeRefPix, SCANRATE, TSYS, CALFCTR, XCALFCTR, 132 BASELIN, BASESUB, DATA, FLAGGED, DATAXED, XPOLDATA, REFBEAM, TCAL, 133 TCALTIME, AZIMUTH, ELEVATIO, PARANGLE, FOCUSAXI, FOCUSTAN, FOCUSROT, 134 TAMBIENT, PRESSURE, HUMIDITY, WINDSPEE, WINDDIRE, STOKES, SIG, CAL, 135 VFRAME, RVSYS, VELDEF, NDATA}; 136 137 // Message handling. 138 void log(LogOrigin origin, LogIO::Command cmd, const char *msg = 0x0); 125 139 126 140 void findData(int iData, char *name, int type); 141 void findCol(char *name, int *colnum); 127 142 int readDim(int iData, long iRow, int *naxis, long naxes[]); 128 143 int readParm(char *name, int type, void *value); 129 144 int readData(char *name, int type, long iRow, void *value); 130 145 int readData(int iData, long iRow, void *value); 131 void findCol(char *name, int *colnum); 146 int readCol(int iData, void *value); 147 int readTime(long iRow, int iPix, char *datobs, double &utc); 132 148 133 // These are for ALFA data, "BDFITS" or "CIMAFITS". 149 // These are for ALFA data: "BDFITS" or "CIMAFITS". Statics are required 150 // for CIMAFITS v2.0 because CAL ON/OFF data is split into separate files. 151 static int sInit, sReset; 152 static int (*sALFAcalNon)[2], (*sALFAcalNoff)[2]; 153 static float (*sALFAcal)[2], (*sALFAcalOn)[2], (*sALFAcalOff)[2]; 154 134 155 int cALFA, cALFA_BD, cALFA_CIMA, cALFAscan, cScanNo; 135 float cALFAcal[8][2], cALFAcalOn[8][2], cALFAcalOff[8][2]; 136 int alfaCal(short iBeam, short iIF); 156 float cALFAacc; 157 int alfaCal(short iBeam, short iIF, short iPol); 158 float alfaGain(float zd); 137 159 138 160 // These are for GBT data. 139 161 int cGBT, cFirstScanNo; 162 double cGLastUTC[4] ; 163 int cGLastScan[4] ; 164 int cGCycleNo[4] ; 140 165 }; 141 166 -
branches/alma/external/atnf/PKSIO/SDFITSwriter.cc
r1453 r1757 2 2 //# SDFITSwriter.cc: ATNF CFITSIO interface class for SDFITS output. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSwriter.cc,v 19.18 2009-09-29 07:33:39 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# Original: 2000/07/24, Mark Calabretta, ATNF 32 34 //#--------------------------------------------------------------------------- 33 35 36 #include <atnf/PKSIO/MBrecord.h> 37 #include <atnf/PKSIO/SDFITSwriter.h> 38 39 #include <casa/Logging/LogIO.h> 40 41 #include <casa/iostream.h> 42 34 43 #include <algorithm> 35 44 #include <math.h> 36 37 // AIPS++ includes. 38 #include <casa/iostream.h> 39 40 // ATNF includes. 41 #include <atnf/PKSIO/PKSMBrecord.h> 42 #include <atnf/PKSIO/SDFITSwriter.h> 45 #include <cstring> 43 46 44 47 using namespace std; … … 49 52 // Factor to convert radians to degrees. 50 53 const double R2D = 180.0 / PI; 54 55 // Class name 56 const string className = "SDFITSwriter" ; 51 57 52 58 //------------------------------------------------- SDFITSwriter::SDFITSwriter … … 55 61 { 56 62 // Default constructor. 57 cSDptr = 0 ;63 cSDptr = 0x0; 58 64 } 59 65 … … 76 82 double antPos[3], 77 83 char* obsMode, 84 char* bunit, 78 85 float equinox, 79 86 char* dopplerFrame, … … 85 92 int extraSysCal) 86 93 { 94 const string methodName = "create()" ; 95 96 if (cSDptr) { 97 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Output file already open, close it first."); 98 return 1; 99 } 100 87 101 // Prepend an '!' to the output name to force it to be overwritten. 88 102 char sdname[80]; … … 93 107 cStatus = 0; 94 108 if (fits_create_file(&cSDptr, sdname, &cStatus)) { 109 sprintf(cMsg, "Failed to create SDFITS file\n %s", sdName); 110 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, cMsg); 95 111 return cStatus; 96 112 } … … 113 129 break; 114 130 } 115 131 116 132 if (cNChan[iIF] != cNChan[0] || cNPol[iIF] != cNPol[0]) { 117 133 // Varying channels and/or polarizations, need a TDIM column at least. … … 140 156 // Write required primary header keywords. 141 157 if (fits_write_imghdr(cSDptr, 8, 0, 0, &cStatus)) { 158 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to write required primary header keywords."); 142 159 return cStatus; 143 160 } … … 159 176 char version[7]; 160 177 char date[11]; 161 sscanf("$Revision: 19.1 0$", "%*s%s", version);162 sscanf("$Date: 200 6/07/05 05:44:52$", "%*s%s", date);178 sscanf("$Revision: 19.18 $", "%*s%s", version); 179 sscanf("$Date: 2009-09-29 07:33:39 $", "%*s%s", date); 163 180 sprintf(text, "SDFITSwriter (v%s, %s)", version, date); 164 181 fits_write_key_str(cSDptr, "ORIGIN", text, "output class", &cStatus); … … 170 187 fits_write_comment(cSDptr, text, &cStatus); 171 188 189 if (cStatus) { 190 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing primary header."); 191 return cStatus; 192 } 193 194 172 195 // Create an SDFITS extension. 173 196 long nrow = 0; … … 175 198 if (fits_create_tbl(cSDptr, BINARY_TBL, nrow, ncol, NULL, NULL, NULL, 176 199 "SINGLE DISH", &cStatus)) { 200 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to create a binary table extension."); 177 201 return 1; 178 202 } … … 209 233 210 234 // CYCLE (additional, real). 211 fits_insert_col(cSDptr, ++ncol, "CYCLE", "1 I", &cStatus);235 fits_insert_col(cSDptr, ++ncol, "CYCLE", "1J", &cStatus); 212 236 213 237 // DATE-OBS (core, real). … … 355 379 fits_insert_col(cSDptr, ++ncol, "TSYS", tform, &cStatus); 356 380 sprintf(tunit, "TUNIT%d", ncol); 357 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);381 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 358 382 359 383 // CALFCTR (additional, real). … … 369 393 370 394 // BASESUB (additional, real). 371 sprintf(tform, "%dE", 9*maxNPol);395 sprintf(tform, "%dE", 24*maxNPol); 372 396 fits_insert_col(cSDptr, ++ncol, "BASESUB", tform, &cStatus); 373 tdim[0] = 9;397 tdim[0] = 24; 374 398 fits_write_tdim(cSDptr, ncol, 2, tdim, &cStatus); 375 399 } … … 396 420 397 421 sprintf(tunit, "TUNIT%d", ncol); 398 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);422 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 399 423 400 424 // FLAGGED (additional, logical). … … 444 468 445 469 sprintf(tunit, "TUNIT%d", ncol); 446 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);470 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 447 471 } 448 472 … … 523 547 } 524 548 549 if (cStatus) { 550 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing binary table header."); 551 } 552 525 553 return cStatus; 526 554 } … … 530 558 // Write a record to the SDFITS file. 531 559 532 int SDFITSwriter::write( PKSMBrecord &mbrec)560 int SDFITSwriter::write(MBrecord &mbrec) 533 561 { 562 const string methodName = "write()" ; 563 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 564 534 565 char *cptr; 535 566 … … 537 568 int IFno = mbrec.IFno[0]; 538 569 if (IFno < 1 || cNIF < IFno) { 539 cerr << "SDFITSwriter::write: " 540 << "Invalid IF number " << IFno 541 << " (maximum " << cNIF << ")." << endl; 570 os << LogIO::WARN 571 << "SDFITSwriter::write: " 572 << "Invalid IF number " << IFno 573 << " (maximum " << cNIF << ")." << LogIO::POST ; 542 574 return 1; 543 575 } … … 546 578 int nChan = cNChan[iIF]; 547 579 if (mbrec.nChan[0] != nChan) { 548 cerr << "SDFITSriter::write: " 549 << "Wrong number of channels for IF " << IFno << "," << endl 550 << " " 551 << "got " << nChan << " should be " << mbrec.nChan[0] << "." << endl; 580 os << LogIO::WARN 581 << "SDFITSriter::write: " 582 << "Wrong number of channels for IF " << IFno << "," << endl 583 << " " 584 << "got " << nChan << " should be " << mbrec.nChan[0] << "." << endl; 585 os << LogIO::POST ; 552 586 return 1; 553 587 } … … 555 589 int nPol = cNPol[iIF]; 556 590 if (mbrec.nPol[0] != nPol) { 557 cerr << "SDFITSriter::write: " 558 << "Wrong number of polarizations for IF " << IFno << "," << endl 559 << " " 560 << "got " << nPol << " should be " << mbrec.nPol[0] << "." << endl; 591 os << LogIO::WARN 592 << "SDFITSriter::write: " 593 << "Wrong number of polarizations for IF " << IFno << "," << endl 594 << " " 595 << "got " << nPol << " should be " << mbrec.nPol[0] << "." << endl; 596 os << LogIO::POST ; 561 597 return 1; 562 598 } … … 655 691 656 692 // BASESUB. 657 fits_write_col_flt(cSDptr, ++icol, cRow, 1, 9*nPol, mbrec.baseSub[0][0],693 fits_write_col_flt(cSDptr, ++icol, cRow, 1, 24*nPol, mbrec.baseSub[0][0], 658 694 &cStatus); 659 695 } … … 739 775 } 740 776 777 if (cStatus) { 778 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing binary table entry."); 779 } 780 741 781 return cStatus; 742 782 } 743 783 744 784 745 //-------------------------------------------------- SDFITSwriter::reportError746 747 // Print the error message corresponding to the input status value and all the748 // messages on the CFITSIO error stack to stderr. 749 750 void SDFITSwriter::reportError() 785 //------------------------------------------------------ SDFITSwriter::history 786 787 // Write a history record. 788 789 int SDFITSwriter::history(char *text) 790 751 791 { 752 fits_report_error(stderr, cStatus); 792 const string methodName = "history()" ; 793 794 if (!cSDptr) { 795 return 1; 796 } 797 798 if (fits_write_history(cSDptr, text, &cStatus)) { 799 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing HISTORY records."); 800 } 801 802 return cStatus; 753 803 } 754 804 … … 759 809 void SDFITSwriter::close() 760 810 { 811 const string methodName = "close()" ; 812 761 813 if (cSDptr) { 762 814 cStatus = 0; 763 fits_close_file(cSDptr, &cStatus); 815 if (fits_close_file(cSDptr, &cStatus)) { 816 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to close file."); 817 } 818 764 819 cSDptr = 0; 765 820 } … … 772 827 void SDFITSwriter::deleteFile() 773 828 { 829 const string methodName = "deleteFile()" ; 830 774 831 if (cSDptr) { 775 832 cStatus = 0; 776 fits_delete_file(cSDptr, &cStatus); 833 if (fits_delete_file(cSDptr, &cStatus)) { 834 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to close and delete file."); 835 } 836 777 837 cSDptr = 0; 778 838 } 779 839 } 840 841 //------------------------------------------------------- SDFITSwriter::log 842 843 // Log a message. If the current CFITSIO status value is non-zero, also log 844 // the corresponding error message and dump the CFITSIO message stack. 845 846 void SDFITSwriter::log(LogOrigin origin, LogIO::Command cmd, const char *msg) 847 { 848 LogIO os( origin ) ; 849 850 os << cmd << msg << endl ; 851 852 if (cStatus) { 853 fits_get_errstatus(cStatus, cMsg); 854 os << cMsg << endl ; 855 856 while (fits_read_errmsg(cMsg)) { 857 os << cMsg << endl ; 858 } 859 } 860 861 os << LogIO::POST ; 862 } -
branches/alma/external/atnf/PKSIO/SDFITSwriter.h
r1453 r1757 2 2 //# SDFITSwriter.h: ATNF CFITSIO interface class for SDFITS output. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSwriter.h,v 19.10 2009-09-29 07:33:39 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# Original: 2000/07/24, Mark Calabretta, ATNF … … 35 37 #define ATNF_SDFITSWRITER_H 36 38 37 #include <atnf/PKSIO/PKSMBrecord.h> 39 #include <atnf/PKSIO/MBrecord.h> 40 #include <casa/Logging/LogIO.h> 38 41 39 42 #include <fitsio.h> 43 44 using namespace std; 45 using namespace casa; 40 46 41 47 // <summary> … … 50 56 51 57 // Destructor. 52 ~SDFITSwriter();58 virtual ~SDFITSwriter(); 53 59 54 60 // Create a new SDFITSwriter and store static data. … … 60 66 double antPos[3], 61 67 char* obsMode, 68 char* bunit, 62 69 float equinox, 63 70 char* dopplerFrame, … … 70 77 71 78 // Store time-variable data. 72 int write( PKSMBrecord &record);79 int write(MBrecord &record); 73 80 74 // Print out CFITSIO error messages.75 void reportError();81 // Write a history record. 82 int history(char* text); 76 83 77 84 // Close the SDFITS file. … … 86 93 *cNChan, cNIF, *cNPol, cStatus; 87 94 long cRow; 95 96 // Message handling. 97 char cMsg[256]; 98 void log(LogOrigin origin, LogIO::Command cmd, const char *msg = 0x0); 88 99 }; 89 100 -
branches/alma/external/atnf/PKSIO/makefile
r1325 r1757 1 # $Id : makefile,v 19.0 2003/07/16 03:34:05 aips2adm Exp$1 # $Id$ 2 2 3 3 XLIBLIST := CFITSIO RPFITS … … 5 5 # Use the generic AIPS++ class implementation makefile. 6 6 #------------------------------------------------------ 7 include $(word 1, $( AIPSPATH))/code/install/makefile.imp7 include $(word 1, $(CASAPATH))/code/install/makefile.imp -
branches/alma/external/atnf/pks/makefile
r1325 r1757 1 # $Id : makefile,v 19.0 2003/07/16 03:33:47 aips2adm Exp$1 # $Id$ 2 2 3 3 # Use the generic AIPS++ class implementation makefile. 4 4 #------------------------------------------------------ 5 include $(word 1, $( AIPSPATH))/code/install/makefile.imp5 include $(word 1, $(CASAPATH))/code/install/makefile.imp -
branches/alma/external/atnf/pks/pks_maths.cc
r1325 r1757 2 2 //# pks_maths.cc: Mathematical functions for Parkes single-dish data reduction 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 1994-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2004-2009, Australia Telescope National Facility, CSIRO 6 //# 7 //# This file is part of livedata. 8 //# 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# Original: Mark Calabretta 29 //# $Id: pks_maths.cc,v 1.5 2006/05/19 00:12:35 mcalabre Exp $ 30 //---------------------------------------------------------------------------- 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: pks_maths.cc,v 1.7 2009-09-29 07:45:02 cal103 Exp $ 32 //#--------------------------------------------------------------------------- 33 //# Original: 2004/07/16 Mark Calabretta 34 //#--------------------------------------------------------------------------- 31 35 32 36 // AIPS++ includes. … … 295 299 //----------------------------------------------------------------------- azel 296 300 297 // Convert (ra,dec) to (az,el), from 298 // http://aa.usno.navy.mil/faq/docs/Alt_Az.html. Position as a Cartesian 299 // triplet in m, UT1 in MJD form, and all angles in radian. 301 // Convert (ra,dec) to (az,el). Position as a Cartesian triplet in m, UT1 in 302 // MJD form, and all angles in radian. 300 303 301 304 void azel(const Vector<Double> position, Double ut1, Double ra, Double dec, 302 305 Double &az, Double &el) 303 306 { 304 // Get g ocentric longitude and latitude (rad).307 // Get geocentric longitude and latitude (rad). 305 308 Double x = position(0); 306 309 Double y = position(1); … … 318 321 319 322 // Azimuth and elevation (rad). 320 az = atan2(cos(dec)*sin(ha), cos(dec)*sin(lat)*cos(ha) - sin(dec)*cos(lat)); 323 az = atan2(cos(dec)*sin(ha), 324 cos(dec)*sin(lat)*cos(ha) - sin(dec)*cos(lat)); 321 325 if (az < 0.0) az += C::_2pi; 322 el = asin(cos(dec)*cos(lat)*cos(ha) + sin(dec)*sin(lat)); 326 el = asin(sin(dec)*sin(lat) + cos(dec)*cos(lat)*cos(ha)); 327 323 328 } 324 329 -
branches/alma/external/atnf/pks/pks_maths.h
r1325 r1757 1 // ----------------------------------------------------------------------------1 //#--------------------------------------------------------------------------- 2 2 //# pks_maths.h: Mathematical functions for Parkes single dish data reduction 3 // ----------------------------------------------------------------------------4 //# Copyright (C) 1994-20065 //# Associated Universities, Inc. Washington DC, USA.3 //#--------------------------------------------------------------------------- 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 9 //# livedata is free software: you can redistribute it and/or modify it under 10 //# the terms of the GNU General Public License as published by the Free 11 //# Software Foundation, either version 3 of the License, or (at your option) 12 //# any later version. 13 //# 14 //# livedata is distributed in the hope that it will be useful, but WITHOUT 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 27 29 //# 28 //# Original: Mark Calabretta 29 //# $Id: pks_maths.h,v 1.6 2006/05/19 00:12:06 mcalabre Exp $ 30 //---------------------------------------------------------------------------- 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: pks_maths.h,v 1.7 2009-09-29 07:45:02 cal103 Exp $ 32 //#--------------------------------------------------------------------------- 33 //# Original: 2004/07/16 Mark Calabretta 34 //#--------------------------------------------------------------------------- 31 35 #ifndef ATNF_PKS_MATHS_H 32 36 #define ATNF_PKS_MATHS_H -
branches/alma/monitor/cgi-bin/asapconfig.py
r712 r1757 5 5 'lines' : {} } 6 6 7 asapmonhome = "/var/www/htdocs" 8 asapmonrel = "/asapmon/" 7 9 import os,sys 8 # This is where asap lives9 sys.path.insert(2,'/opt/lib/python2.3/site-packages')10 os.environ["AIPSPATH"]="/opt/share/asap linux_gnu somewhere localhost"11 12 #overwrite /usr/local/... as default13 sys.path.insert(2,'/usr/lib/python2.3/site-packages')14 15 # This is needed for plotting with matplotlib16 # where matplotlib data is located17 os.environ["MATPLOTLIBDATA"]="/opt/share/matplotlib"18 10 # where matplotlib puts it temporary font files 19 11 # this location can also have a custom .matplotlibrc 20 os.environ["HOME"]="/var/www/ asapmon/tmp"12 os.environ["HOME"]="/var/www/htdocs/asapmon/tmp" -
branches/alma/monitor/cgi-bin/asapmon.py
r1295 r1757 7 7 from simpletal import simpleTAL, simpleTALES 8 8 9 #absolute home10 abspath= "/var/www/asapmon/"11 cgiloc = "/cgi-bin/asapmon/"12 tmppath = os.path.join(abspath,"tmp/")13 htmlloc = "/asapmon/"14 tmploc = "/asapmon/tmp/"15 16 9 from obsconfig import * 10 11 tmppath = os.path.join(asapmonhome,"tmp/") 12 tmppath = os.path.join(asapmonrel,"tmp/") 17 13 18 14 # a redirection object for stdout/stderr … … 28 24 sys.stderr = logsink2 29 25 import asap 26 asap.rc('scantable', storage="memory") 30 27 sys.stdout = sys.__stdout__ 31 28 sys.stderr = sys.__stderr__ … … 58 55 def decodeWindow(self,window): 59 56 if not len(window.strip()): return None,None 60 x = window.split(", 57 x = window.split(",") 61 58 return [float(x[0].strip()), float(x[1].strip())] 62 59 … … 167 164 else: 168 165 # get only the last source in the table if not averaging 169 s = s.get_scan(self.fields['sourcenames'][-1]) 170 #self.fields['debug'] = "DEBUG" 166 # This doesn't work anymore, but works on the command-line?? 167 # Use explict selection 168 #s = s.get_scan(str(self.fields['sourcenames'][-1])) 169 sel = asap.selector() 170 sel.set_name(str(self.fields['sourcenames'][-1])) 171 s.set_selection(sel) 172 s = s.copy() 171 173 self.fields['csource'] = s.get_sourcename()[-1] 172 174 if self.fields['cunit'] == 1: 173 srest = s._getrestfreqs() 174 if isinstance(srest, tuple) and len(srest) != s.nif(): 175 s.set_restfreqs(restfs, unit="GHz") 175 s.set_restfreqs(restfs, unit="GHz") 176 176 s.set_unit(self.fields['units'][self.fields['cunit']]) 177 177 s.set_freqframe(self.form.getfirst("frame", "LSRK")) … … 213 213 rcp['figure.subplot.wspace'] = 0.3 214 214 rcp['figure.subplot.hspace'] = 0.3 215 del asap.plotter215 #del asap.plotter 216 216 # plotter without GUI 217 217 asap.plotter = asap.asapplotter(False) … … 259 259 self.setDefaultFields() 260 260 title = "ASAP %s Online Monitor" % (observatory['name']) 261 tmplname = a bspath+"asapmon.html.template"261 tmplname = asapmonhome+"asapmon.html.template" 262 262 if ( self.form.has_key("plot")): 263 263 self.plotForm() -
branches/alma/monitor/cgi-bin/obsconfig.py
r712 r1757 5 5 6 6 # Append observing directories 7 observatory['rpfpath'].append("/u/mar637/brage/singledish/data") 8 observatory['rpfpath'].append("/u/mar637/brage/singledish/data/mopra200505") 9 observatory['rpfpath'].append("/u/mar637/brage/singledish/data/mopra/phoenix") 7 observatory['rpfpath'].append("/DATA/MPCCC1_1/corr/dat/") 10 8 11 9 # Restfrequencies in GHz -
branches/alma/monitor/htdocs/asapmon.html.template
r711 r1757 4 4 <head> 5 5 <title tal:content="title">ASAP Online Monitor</title> 6 <link rel="stylesheet" href="/asap test/fields.css" type="text/css">6 <link rel="stylesheet" href="/asapmon/asapmon.css" type="text/css"> 7 7 <script type="text/javascript" src="/asapmon/prototype.js"></script> 8 8 <script type="text/javascript" src="/asapmon/asapmon.js"></script> -
branches/alma/python/__init__.py
r1729 r1757 4 4 """ 5 5 import os,sys,shutil, platform 6 try: 7 from functools import wraps as wraps_dec 8 except ImportError: 9 from asap.compatibility import wraps as wraps_dec 6 10 7 11 # Set up CASAPATH and first time use of asap i.e. ~/.asap/* … … 33 37 #shutil.copyfile(asapdata+"/data/ipythonrc-asap", userdir+"/ipythonrc-asap") 34 38 # commented out by TT on 2009.06.23 for casapy use 35 ##shutil.copyfile(asapdata+"/data/ipy_user_conf.py", 39 ##shutil.copyfile(asapdata+"/data/ipy_user_conf.py", 36 40 ## userdir+"/ipy_user_conf.py") 37 41 f = file(userdir+"/asapuserfuncs.py", "w") … … 43 47 # upgrade to support later ipython versions 44 48 ##if not os.path.exists(userdir+"/ipy_user_conf.py"): 45 ## shutil.copyfile(asapdata+"/data/ipy_user_conf.py", 49 ## shutil.copyfile(asapdata+"/data/ipy_user_conf.py", 46 50 ## userdir+"/ipy_user_conf.py") 47 51 … … 74 78 75 79 """ 76 77 80 fname = os.path.join( os.getcwd(), '.asaprc') 78 81 if os.path.exists(fname): return fname … … 109 112 'plotter.histogram' : [False, _validate_bool], 110 113 'plotter.papertype' : ['A4', str], 111 'plotter.xaxisformatting' : ['asap', str], 114 ## for older Matplotlib version 115 #'plotter.axesformatting' : ['mpl', str], 116 'plotter.axesformatting' : ['asap', str], 112 117 113 118 # scantable … … 118 123 'scantable.storage' : ['memory', str], 119 124 'scantable.history' : [True, _validate_bool], 120 'scantable.reference' : ['.*(e|w|_R)$', str] 125 'scantable.reference' : ['.*(e|w|_R)$', str], 126 'scantable.parallactify' : [False, _validate_bool] 121 127 # fitter 122 128 } … … 146 152 plotter.panelling : scan 147 153 148 # push panels together, to share axis labels154 # push panels together, to share axis labels 149 155 plotter.ganged : True 150 156 … … 164 170 165 171 # The formatting style of the xaxis 166 plotter. xaxisformatting : 'asap' or 'mpl'172 plotter.axesformatting : 'mpl' (default) or 'asap' (for old versions of matplotlib) 167 173 168 174 # scantable … … 189 195 # Control the identification of reference (off) scans 190 196 # This is has to be a regular expression 191 scantable.reference : .*(e|w|_R)$ 197 scantable.reference : .*(e|w|_R)$ 198 199 # Indicate whether the data was parallactified (total phase offest == 0.0) 200 scantable.parallactify : False 201 192 202 # Fitter 193 203 """ … … 290 300 291 301 def _n_bools(n, val): 292 return [ val for i in xrange(n) ] 302 return [ val for i in xrange(n) ] 293 303 294 304 def _is_sequence_or_number(param, ptype=int): … … 357 367 asaplog.disable() 358 368 369 370 def print_log_dec(f): 371 @wraps_dec(f) 372 def wrap_it(*args, **kw): 373 val = f(*args, **kw) 374 print_log() 375 return val 376 return wrap_it 377 359 378 def print_log(level='INFO'): 360 379 from taskinit import casalog … … 382 401 from scantable import scantable 383 402 from asaplinefind import linefinder 403 from simplelinefinder import simplelinefinder 384 404 from linecatalog import linecatalog 385 405 from interactivemask import interactivemask 406 from opacity import skydip 407 from opacity import model as opacity_model 386 408 387 409 if rcParams['useplotter']: … … 392 414 import matplotlib 393 415 if not matplotlib.sys.modules['matplotlib.backends']: matplotlib.use("TkAgg") 394 import pylab416 from matplotlib import pylab 395 417 xyplotter = pylab 396 418 plotter = asapplotter(gui) … … 402 424 403 425 __date__ = '$Date$'.split()[1] 404 __version__ = ' 2.3.1alma'426 __version__ = '3.0.0 alma' 405 427 # nrao casapy specific, get revision number 406 428 #__revision__ = ' unknown ' … … 427 449 428 450 def is_ipython(): 429 return ' __IP' in dir(sys.modules["__main__"])451 return 'IPython' in sys.modules.keys() 430 452 if is_ipython(): 431 453 def version(): print "ASAP %s(%s)"% (__version__, __date__) 454 432 455 def list_scans(t = scantable): 433 import types 434 globs = sys.modules['__main__'].__dict__.iteritems() 435 print "The user created scantables are:" 436 sts = map(lambda x: x[0], filter(lambda x: isinstance(x[1], t), globs)) 437 print filter(lambda x: not x.startswith('_'), sts) 438 return 456 import inspect 457 print "The user created scantables are: ", 458 globs=inspect.currentframe().f_back.f_locals.copy() 459 out = [ k for k,v in globs.iteritems() \ 460 if isinstance(v, scantable) and not k.startswith("_") ] 461 print out 462 return out 439 463 440 464 def commands(): … … 462 486 get_elevation - get the elevation of the scans 463 487 get_parangle - get the parallactic angle of the scans 488 get_coordinate - get the spectral coordinate for the given row, 489 which can be used for coordinate conversions 490 get_weather - get the weather condition parameters 464 491 get_unit - get the current unit 465 492 set_unit - set the abcissa unit to be used from this … … 506 533 mx_quotient - Form a quotient using MX data (off beams) 507 534 scale, *, / - return a scan scaled by a given factor 508 add, +, - - return a scan with given value added 535 add, + - return a scan with given value added 536 sub, - - return a scan with given value subtracted 509 537 bin - return a scan with binned channels 510 538 resample - return a scan with resampled channels … … 529 557 stddev - Determine the standard deviation of the current 530 558 beam/if/pol 559 get_row_selector - get the selection object for a specified row 560 number 531 561 [Selection] 532 562 selector - a selection object to set a subset of a scantable … … 590 620 plot - plot a scantable 591 621 plot_lines - plot a linecatalog overlay 622 plotazel - plot azimuth and elevation versus time 623 plotpointing - plot telescope pointings 592 624 save - save the plot to a file ('png' ,'ps' or 'eps') 593 625 set_mode - set the state of the plotter, i.e. … … 613 645 axhline,axvline - draw horizontal/vertical lines 614 646 axhspan,axvspan - draw horizontal/vertical regions 647 annotate - draw an arrow with label 648 create_mask - create a scnatble mask interactively 615 649 616 650 xyplotter - matplotlib/pylab plotting functions 617 618 [Reading files]619 reader - access rpfits/sdfits files620 open - attach reader to a file621 close - detach reader from file622 read - read in integrations623 summary - list info about all integrations624 651 625 652 [General] 626 653 commands - this command 627 654 print - print details about a variable 628 list_scans - list all scantables created b tthe user655 list_scans - list all scantables created by the user 629 656 list_files - list all files readable by asap (default rpf) 630 657 del - delete the given variable from memory … … 639 666 mask_not - boolean operations on masks created with 640 667 scantable.create_mask 668 skydip - gain opacity values from a sky dip observation 669 opacity_model - compute opacities fro given frequencies based on 670 atmospheric model 641 671 642 672 Note: -
branches/alma/python/asapfitter.py
r1701 r1757 1 1 import _asap 2 2 from asap import rcParams 3 from asap import print_log 3 from asap import print_log, print_log_dec 4 4 from asap import _n_bools 5 5 from asap import mask_and … … 79 79 Set the function to be fit. 80 80 Parameters: 81 poly: use a polynomial of the order given with nonlinear least squares fit 81 poly: use a polynomial of the order given with nonlinear least squares fit 82 82 lpoly: use polynomial of the order given with linear least squares fit 83 83 gauss: fit the number of gaussian specified … … 95 95 n = kwargs.get('poly') 96 96 self.components = [n] 97 self.uselinear = False 97 self.uselinear = False 98 98 elif kwargs.has_key('lpoly'): 99 99 self.fitfunc = 'poly' … … 106 106 self.fitfuncs = [ 'gauss' for i in range(n) ] 107 107 self.components = [ 3 for i in range(n) ] 108 self.uselinear = False 108 self.uselinear = False 109 109 elif kwargs.has_key('lorentz'): 110 110 n = kwargs.get('lorentz') … … 112 112 self.fitfuncs = [ 'lorentz' for i in range(n) ] 113 113 self.components = [ 3 for i in range(n) ] 114 self.uselinear = False 114 self.uselinear = False 115 115 else: 116 116 msg = "Invalid function type." … … 127 127 return 128 128 129 #@print_log_dec 129 130 def fit(self, row=0, estimate=False): 130 131 """ … … 164 165 self.data.getbeam(i), 165 166 self.data.getif(i), 166 self.data.getpol(i), 167 self.data.getpol(i), 167 168 self.data.getcycle(i)) 168 169 asaplog.push(out,False) … … 221 222 self.data._addfit(fit,self._fittedrow) 222 223 223 # def set_parameters(self, params, fixed=None, component=None):224 #@print_log_dec 224 225 def set_parameters(self,*args,**kwargs): 225 226 """ … … 543 544 return self.fitter.getfit() 544 545 546 #@print_log_dec 545 547 def commit(self): 546 548 """ … … 571 573 return scan 572 574 573 def plot(self, residual=False, components=None, plotparms=False, filename=None): 575 #@print_log_dec 576 def plot(self, residual=False, components=None, plotparms=False, 577 filename=None): 574 578 """ 575 579 Plot the last fit. … … 598 602 xlab = 'Abcissa' 599 603 ylab = 'Ordinate' 600 from matplotlib.numeriximport ma,logical_not,logical_and,array604 from numpy import ma,logical_not,logical_and,array 601 605 m = self.mask 602 606 if self.data: … … 606 610 array(self.data._getmask(self._fittedrow), 607 611 copy=False)) 608 612 609 613 ylab = self.data._get_ordinate_label() 610 614 … … 670 674 print_log() 671 675 676 #@print_log_dec 672 677 def auto_fit(self, insitu=None, plot=False): 673 678 """ … … 700 705 scan.getbeam(r), 701 706 scan.getif(r), 702 scan.getpol(r), 707 scan.getpol(r), 703 708 scan.getcycle(r)) 704 709 asaplog.push(out, False) … … 723 728 print_log() 724 729 return scan 725 -
branches/alma/python/asaplinefind.py
r929 r1757 41 41 42 42 def set_options(self,threshold=1.7320508075688772,min_nchan=3, 43 avg_limit=8,box_size=0.2 ):43 avg_limit=8,box_size=0.2,noise_box='all',noise_stat='mean80'): 44 44 """ 45 45 Set the parameters of the algorithm … … 55 55 this parameter can be averaged to search for 56 56 broad lines. Default is 8. 57 box_size A running mean box size specified as a fraction57 box_size A running mean/median box size specified as a fraction 58 58 of the total spectrum length. Default is 1/5 59 noise_box Area of the spectrum used to estimate noise stats 60 Both string values and numbers are allowed 61 Allowed string values: 62 'all' use all the spectrum (default) 63 'box' noise box is the same as running mean/median 64 box 65 Numeric values are defined as a fraction from the 66 spectrum size. Values should be positive. 67 (noise_box == box_size has the same effect as 68 noise_box = 'box') 69 noise_stat Statistics used to estimate noise, allowed values: 70 'mean80' use the 80% of the lowest deviations 71 in the noise box (default) 72 'median' median of deviations in the noise box 73 59 74 Note: For bad baselines threshold should be increased, 60 75 and avg_limit decreased (or even switched off completely by … … 62 77 undulations instead of real lines. 63 78 """ 64 self.finder.setoptions(threshold,min_nchan,avg_limit,box_size) 79 if noise_stat.lower() not in ["mean80",'median']: 80 raise RuntimeError, "noise_stat argument in linefinder.set_options can only be mean80 or median" 81 nStat = (noise_stat.lower() == "median") 82 nBox = -1. 83 if isinstance(noise_box,str): 84 if noise_box.lower() not in ['all','box']: 85 raise RuntimeError, "string-valued noise_box in linefinder.set_options can only be all or box" 86 if noise_box.lower() == 'box': 87 nBox = box_size 88 else: 89 nBox = float(noise_box) 90 self.finder.setoptions(threshold,min_nchan,avg_limit,box_size,nBox,nStat) 65 91 return 66 92 -
branches/alma/python/asaplot.py
r708 r1757 11 11 ASAP plotting class based on matplotlib. 12 12 """ 13 def __init__(self, rows=1, cols=0, title='', size= (8,4), buffering=False):13 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False): 14 14 """ 15 15 Create a new instance of the ASAPlot plotting class. -
branches/alma/python/asaplotbase.py
r1723 r1757 10 10 from matplotlib.figure import Figure, Text 11 11 from matplotlib.font_manager import FontProperties as FP 12 from matplotlib.numeriximport sqrt12 from numpy import sqrt 13 13 from matplotlib import rc, rcParams 14 14 from asap import rcParams as asaprcParams 15 15 from matplotlib.ticker import OldScalarFormatter 16 from matplotlib.ticker import NullLocator17 16 18 17 # API change in mpl >= 0.98 … … 20 19 from matplotlib.transforms import blended_transform_factory 21 20 except ImportError: 22 from matplotlib.transforms import blend_xy_sep_transform 21 from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory 23 22 24 23 from asap import asaplog … … 29 28 print_log( 'WARN' ) 30 29 31 #class MyFormatter(OldScalarFormatter):32 # def __call__(self, x, pos=None):33 # last = len(self.locs)-234 # if pos==0:35 # return ''36 # else: return OldScalarFormatter.__call__(self, x, pos)37 38 30 class asaplotbase: 39 31 """ … … 41 33 """ 42 34 43 def __init__(self, rows=1, cols=0, title='', size= (8,6), buffering=False):35 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False): 44 36 """ 45 37 Create a new instance of the ASAPlot plotting class. … … 157 149 fmt is the line style as in plot(). 158 150 """ 159 from matplotlib.numeriximport array160 from matplotlib.numerix.ma import MaskedArray151 from numpy import array 152 from numpy.ma import MaskedArray 161 153 if x is None: 162 154 if y is None: return … … 289 281 self.register('button_press', position_disable) 290 282 283 284 # def get_region(self): 285 # pos = [] 286 # print "Please select the bottom/left point" 287 # pos.append(self.figure.ginput(n=1, show_clicks=False)[0]) 288 # print "Please select the top/right point" 289 # pos.append(self.figure.ginput(n=1, show_clicks=False)[0]) 290 # return pos 291 292 # def get_point(self): 293 # print "Please select the point" 294 # pt = self.figure.ginput(n=1, show_clicks=False) 295 # if pt: 296 # return pt[0] 297 # else: 298 # return None 291 299 292 300 def region(self): … … 640 648 self.subplots[i]['axes'] = self.figure.add_subplot(rows, 641 649 cols, i+1) 642 if asaprcParams['plotter. xaxisformatting'] == 'mpl':650 if asaprcParams['plotter.axesformatting'] != 'mpl': 643 651 self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter()) 644 652 else: … … 646 654 self.subplots[i]['axes'] = self.figure.add_subplot(rows, 647 655 cols, i+1) 648 if asaprcParams['plotter. xaxisformatting'] != 'mpl':656 if asaprcParams['plotter.axesformatting'] != 'mpl': 649 657 650 658 self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter()) … … 730 738 731 739 from matplotlib.artist import setp 732 fp = FP(size=rcParams['xtick.labelsize']) 733 xts = fp.get_size_in_points()- (self.cols)/2 734 fp = FP(size=rcParams['ytick.labelsize']) 735 yts = fp.get_size_in_points() - (self.rows)/2 740 fpx = FP(size=rcParams['xtick.labelsize']) 741 xts = fpx.get_size_in_points()- (self.cols)/2 742 fpy = FP(size=rcParams['ytick.labelsize']) 743 yts = fpy.get_size_in_points() - (self.rows)/2 744 fpa = FP(size=rcParams['axes.labelsize']) 745 fpat = FP(size=rcParams['axes.titlesize']) 746 axsize = fpa.get_size_in_points() 747 tsize = fpat.get_size_in_points()-(self.cols)/2 736 748 for sp in self.subplots: 737 749 ax = sp['axes'] 738 #s = ax.title.get_size()739 #tsize = s-(self.cols+self.rows)740 s=FP(size=rcParams['axes.titlesize'])741 tsize = s.get_size_in_points()-(self.cols)/2742 750 ax.title.set_size(tsize) 743 fp = FP(size=rcParams['axes.labelsize'])744 751 setp(ax.get_xticklabels(), fontsize=xts) 745 752 setp(ax.get_yticklabels(), fontsize=yts) 746 origx = fp.get_size_in_points()747 origy = origx748 753 off = 0 749 754 if self.cols > 1: off = self.cols 750 xfsize = origx-off 751 ax.xaxis.label.set_size(xfsize) 755 ax.xaxis.label.set_size(axsize-off) 752 756 off = 0 753 757 if self.rows > 1: off = self.rows 754 yfsize = origy-off 755 ax.yaxis.label.set_size(yfsize) 758 ax.yaxis.label.set_size(axsize-off) 756 759 757 760 def subplot(self, i=None, inc=None): -
branches/alma/python/asaplotgui.py
r1699 r1757 16 16 """ 17 17 18 def __init__(self, rows=1, cols=0, title='', size= (8,6), buffering=False):18 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False): 19 19 """ 20 20 Create a new instance of the ASAPlot plotting class. -
branches/alma/python/asaplotgui_gtk.py
r1619 r1757 18 18 """ 19 19 20 def __init__(self, rows=1, cols=0, title='', size= (8,6), buffering=False):20 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False): 21 21 """ 22 22 Create a new instance of the ASAPlot plotting class. -
branches/alma/python/asaplotgui_qt4.py
r1640 r1757 18 18 """ 19 19 20 def __init__(self, rows=1, cols=0, title='', size= (8,6), buffering=False):20 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False): 21 21 """ 22 22 Create a new instance of the ASAPlot plotting class. -
branches/alma/python/asapmath.py
r1693 r1757 1 1 from asap.scantable import scantable 2 2 from asap import rcParams 3 from asap import print_log 3 from asap import print_log, print_log_dec 4 4 from asap import selector 5 5 from asap import asaplog 6 6 from asap import asaplotgui 7 7 8 #@print_log_dec 8 9 def average_time(*args, **kwargs): 9 10 """ … … 29 30 # without using a mask 30 31 scanav = average_time(scana,scanb) 31 32 32 # or equivalent 33 # scanav = average_time([scana, scanb]) 33 34 # return the (time) averaged scan, i.e. the average of 34 35 # all correlator cycles … … 122 123 return s 123 124 125 #@print_log_dec 124 126 def dototalpower(calon, caloff, tcalval=0.0): 125 127 """ … … 140 142 return s 141 143 144 #@print_log_dec 142 145 def dosigref(sig, ref, smooth, tsysval=0.0, tauval=0.0): 143 146 """ … … 160 163 return s 161 164 165 #@print_log_dec 162 166 def calps(scantab, scannos, smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False): 163 167 """ … … 442 446 return ress 443 447 448 #@print_log_dec 444 449 def calnod(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False): 445 450 """ … … 682 687 return resspec 683 688 689 #@print_log_dec 684 690 def calfs(scantab, scannos=[], smooth=1, tsysval=0.0, tauval=0.0, tcalval=0.0, verify=False): 685 691 """ … … 889 895 return resspec 890 896 891 def simple_math(left, right, op='add', tsys=True): 892 """ 893 Apply simple mathematical binary operations to two 894 scan tables, returning the result in a new scan table. 895 The operation is applied to both the correlations and the TSys data 896 The cursor of the output scan is set to 0 897 Parameters: 898 left: the 'left' scan 899 right: the 'right' scan 900 op: the operation: 'add' (default), 'sub', 'mul', 'div' 901 tsys: if True (default) then apply the operation to Tsys 902 as well as the data 903 """ 904 #print "simple_math is deprecated use +=/* instead." 905 asaplog.push( "simple_math is deprecated use +=/* instead." ) 906 print_log('WARN') 907 897 #@print_log_dec 908 898 def merge(*args): 909 899 """ … … 914 904 Example: 915 905 myscans = [scan1, scan2] 916 917 918 906 allscans = merge(myscans) 907 # or equivalent 908 sameallscans = merge(scan1, scan2) 919 909 """ 920 910 varlist = vars() -
branches/alma/python/asapplotter.py
r1732 r1757 1 from asap import rcParams, print_log, selector 1 from asap import rcParams, print_log, print_log_dec 2 from asap import selector, scantable 2 3 from asap import asaplog 3 4 import matplotlib.axes 5 from matplotlib.font_manager import FontProperties 6 from matplotlib.text import Text 7 4 8 import re 5 9 … … 13 17 other variables. 14 18 """ 15 def __init__(self, visible=None ):19 def __init__(self, visible=None , **kwargs): 16 20 self._visible = rcParams['plotter.gui'] 17 21 if visible is not None: 18 22 self._visible = visible 19 self._plotter = self._newplotter( )23 self._plotter = self._newplotter(**kwargs) 20 24 if self._visible and matplotlib.get_backend() == "TkAgg": 21 25 from asap.casatoolbar import CustomToolbarTkAgg … … 42 46 self._selection = selector() 43 47 self._hist = rcParams['plotter.histogram'] 48 self._fp = FontProperties() 44 49 self._panellayout = self.set_panellayout(refresh=False) 45 50 … … 52 57 return None 53 58 54 def _newplotter(self ):59 def _newplotter(self, **kwargs): 55 60 backend=matplotlib.get_backend() 56 61 if not self._visible: … … 64 69 else: 65 70 from asap.asaplot import asaplot 66 return asaplot( )67 68 71 return asaplot(**kwargs) 72 73 #@print_log_dec 69 74 def plot(self, scan=None): 70 75 """ … … 101 106 return 102 107 108 def gca(self): 109 return self._plotter.figure.gca() 110 111 def refresh(self): 112 """Do a soft refresh""" 113 self._plotter.figure.show() 114 115 def create_mask(self, nwin=1, panel=0, color=None): 116 """ 117 Interactively define a mask.It retruns a mask that is equivalent to 118 the one created manually with scantable.create_mask. 119 Parameters: 120 nwin: The number of mask windows to create interactively 121 default is 1. 122 panel: Which panel to use for mask selection. This is useful 123 if different IFs are spread over panels (default 0) 124 """ 125 if self._data is None: 126 return [] 127 outmask = [] 128 self._plotter.subplot(panel) 129 xmin, xmax = self._plotter.axes.get_xlim() 130 marg = 0.05*(xmax-xmin) 131 self._plotter.axes.set_xlim(xmin-marg, xmax+marg) 132 self.refresh() 133 134 def cleanup(lines=False, texts=False, refresh=False): 135 if lines: 136 del self._plotter.axes.lines[-1] 137 if texts: 138 del self._plotter.axes.texts[-1] 139 if refresh: 140 self.refresh() 141 142 for w in xrange(nwin): 143 wpos = [] 144 self.text(0.05,1.0, "Add start boundary", 145 coords="relative", fontsize=10) 146 point = self._plotter.get_point() 147 cleanup(texts=True) 148 if point is None: 149 continue 150 wpos.append(point[0]) 151 self.axvline(wpos[0], color=color) 152 self.text(0.05,1.0, "Add end boundary", coords="relative", fontsize=10) 153 point = self._plotter.get_point() 154 cleanup(texts=True, lines=True) 155 if point is None: 156 self.refresh() 157 continue 158 wpos.append(point[0]) 159 self.axvspan(wpos[0], wpos[1], alpha=0.1, 160 edgecolor=color, facecolor=color) 161 ymin, ymax = self._plotter.axes.get_ylim() 162 outmask.append(wpos) 163 164 self._plotter.axes.set_xlim(xmin, xmax) 165 self.refresh() 166 if len(outmask) > 0: 167 return self._data.create_mask(*outmask) 168 return [] 103 169 104 170 # forwards to matplotlib axes 105 171 def text(self, *args, **kwargs): 172 if kwargs.has_key("interactive"): 173 #if kwargs.pop("interactive"): 174 # pos = self._plotter.get_point() 175 # args = tuple(pos)+args 176 kwargs.pop("interactive") 106 177 self._axes_callback("text", *args, **kwargs) 178 107 179 text.__doc__ = matplotlib.axes.Axes.text.__doc__ 180 108 181 def arrow(self, *args, **kwargs): 182 if kwargs.has_key("interactive"): 183 #if kwargs.pop("interactive"): 184 # pos = self._plotter.get_region() 185 # dpos = (pos[0][0], pos[0][1], 186 # pos[1][0]-pos[0][0], 187 # pos[1][1] - pos[0][1]) 188 # args = dpos + args 189 kwargs.pop("interactive") 109 190 self._axes_callback("arrow", *args, **kwargs) 191 110 192 arrow.__doc__ = matplotlib.axes.Axes.arrow.__doc__ 193 194 def annotate(self, text, xy=None, xytext=None, **kwargs): 195 if kwargs.has_key("interactive"): 196 #if kwargs.pop("interactive"): 197 # xy = self._plotter.get_point() 198 # xytext = self._plotter.get_point() 199 kwargs.pop("interactive") 200 if not kwargs.has_key("arrowprops"): 201 kwargs["arrowprops"] = dict(arrowstyle="->") 202 self._axes_callback("annotate", text, xy, xytext, **kwargs) 203 204 annotate.__doc__ = matplotlib.axes.Axes.annotate.__doc__ 205 111 206 def axvline(self, *args, **kwargs): 207 if kwargs.has_key("interactive"): 208 #if kwargs.pop("interactive"): 209 # pos = self._plotter.get_point() 210 # args = (pos[0],)+args 211 kwargs.pop("interactive") 112 212 self._axes_callback("axvline", *args, **kwargs) 213 113 214 axvline.__doc__ = matplotlib.axes.Axes.axvline.__doc__ 215 114 216 def axhline(self, *args, **kwargs): 217 if kwargs.has_key("interactive"): 218 #if kwargs.pop("interactive"): 219 # pos = self._plotter.get_point() 220 # args = (pos[1],)+args 221 kwargs.pop("interactive") 115 222 self._axes_callback("axhline", *args, **kwargs) 223 116 224 axhline.__doc__ = matplotlib.axes.Axes.axhline.__doc__ 225 117 226 def axvspan(self, *args, **kwargs): 227 if kwargs.has_key("interactive"): 228 #if kwargs.pop("interactive"): 229 # pos = self._plotter.get_region() 230 # dpos = (pos[0][0], pos[1][0]) 231 # args = dpos + args 232 kwargs.pop("interactive") 118 233 self._axes_callback("axvspan", *args, **kwargs) 119 234 # hack to preventy mpl from redrawing the patch 120 235 # it seem to convert the patch into lines on every draw. 121 236 # This doesn't happen in a test script??? 122 del self._plotter.axes.patches[-1] 237 #del self._plotter.axes.patches[-1] 238 123 239 axvspan.__doc__ = matplotlib.axes.Axes.axvspan.__doc__ 124 240 125 241 def axhspan(self, *args, **kwargs): 242 if kwargs.has_key("interactive"): 243 #if kwargs.pop("interactive"): 244 # pos = self._plotter.get_region() 245 # dpos = (pos[0][1], pos[1][1]) 246 # args = dpos + args 247 kwargs.pop("interactive") 126 248 self._axes_callback("axhspan", *args, **kwargs) 127 249 # hack to preventy mpl from redrawing the patch 128 250 # it seem to convert the patch into lines on every draw. 129 251 # This doesn't happen in a test script??? 130 del self._plotter.axes.patches[-1] 252 #del self._plotter.axes.patches[-1] 253 131 254 axhspan.__doc__ = matplotlib.axes.Axes.axhspan.__doc__ 132 255 … … 465 588 if refresh and self._data: self.plot(self._data) 466 589 467 def set_font(self, family=None, style=None, weight=None, size=None, refresh=True):590 def set_font(self, refresh=True,**kwargs): 468 591 """ 469 592 Set font properties. … … 479 602 """ 480 603 from matplotlib import rc as rcp 481 if isinstance(family, str): 482 rcp('font', family=family) 483 if isinstance(style, str): 484 rcp('font', style=style) 485 if isinstance(weight, str): 486 rcp('font', weight=weight) 487 if isinstance(size, float) or isinstance(size, int): 488 rcp('font', size=size) 604 fdict = {} 605 for k,v in kwargs.iteritems(): 606 if v: 607 fdict[k] = v 608 self._fp = FontProperties(**fdict) 489 609 if refresh and self._data: self.plot(self._data) 490 610 … … 540 660 if not self._data.get_unit().endswith("Hz"): 541 661 raise RuntimeError("Can only overlay linecatalogs when data is in frequency.") 542 from matplotlib.numeriximport ma662 from numpy import ma 543 663 for j in range(len(self._plotter.subplots)): 544 664 self._plotter.subplot(j) … … 716 836 if isinstance(nstack0, int): nstack = nstack0 717 837 else: nstack = len(nstack0) 718 maxpanel, maxstack = 16, 8838 maxpanel, maxstack = 16,16 719 839 if n > maxpanel or nstack > maxstack: 720 840 maxn = 0 … … 761 881 ylab = self._ordinate and self._ordinate[panelcount] \ 762 882 or scan._get_ordinate_label() 763 self._plotter.set_axes('xlabel', xlab)764 self._plotter.set_axes('ylabel', ylab)883 self._plotter.set_axes('xlabel', xlab) 884 self._plotter.set_axes('ylabel', ylab) 765 885 lbl = self._get_label(scan, r, self._panelling, self._title) 766 886 if isinstance(lbl, list) or isinstance(lbl, tuple): … … 781 901 y = scan._getspectrum(r) 782 902 m = scan._getmask(r) 783 from matplotlib.numeriximport logical_not, logical_and903 from numpy import logical_not, logical_and 784 904 if self._maskselection and len(self._usermask) == len(m): 785 905 if d[self._stacking](r) in self._maskselection[self._stacking]: 786 906 m = logical_and(m, self._usermask) 787 907 x = scan._getabcissa(r) 788 from matplotlib.numeriximport ma, array908 from numpy import ma, array 789 909 y = ma.masked_array(y,mask=logical_not(array(m,copy=False))) 790 910 if self._minmaxx is not None: … … 839 959 #reset the selector to the scantable's original 840 960 scan.set_selection(savesel) 841 842 def set_selection(self, selection=None, refresh=True): 961 962 #temporary switch-off for older matplotlib 963 #if self._fp is not None: 964 if self._fp is not None and getattr(self._plotter.figure,'findobj',False): 965 for o in self._plotter.figure.findobj(Text): 966 o.set_fontproperties(self._fp) 967 968 def set_selection(self, selection=None, refresh=True, **kw): 843 969 """ 844 970 Parameters: … … 848 974 Otherwise,the parameter(s) are set without replotting. 849 975 """ 850 self._selection = isinstance(selection,selector) and selection or selector() 976 if selection is None: 977 # reset 978 if len(kw) == 0: 979 self._selection = selector() 980 else: 981 # try keywords 982 for k in kw: 983 if k not in selector.fields: 984 raise KeyError("Invalid selection key '%s', valid keys are %s" % (k, selector.fields)) 985 self._selection = selector(**kw) 986 elif isinstance(selection, selector): 987 self._selection = selection 988 else: 989 raise TypeError("'selection' is not of type selector") 990 851 991 d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO', 852 992 'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' } … … 885 1025 886 1026 def plotazel(self, scan=None, outfile=None): 887 """ 888 plot azimuth and elevation versus time of a scantable 889 """ 890 import pylab as PL 891 from matplotlib.dates import DateFormatter, timezone, HourLocator, MinuteLocator, DayLocator 1027 #def plotazel(self): 1028 """ 1029 plot azimuth and elevation versus time of a scantable 1030 """ 1031 from matplotlib import pylab as PL 1032 from matplotlib.dates import DateFormatter, timezone 1033 from matplotlib.dates import HourLocator, MinuteLocator,SecondLocator, DayLocator 892 1034 from matplotlib.ticker import MultipleLocator 893 from matplotlib.numeriximport array, pi1035 from numpy import array, pi 894 1036 self._data = scan 895 1037 self._outfile = outfile … … 898 1040 tz = timezone('UTC') 899 1041 PL.cla() 900 #PL.ioff()1042 PL.ioff() 901 1043 PL.clf() 902 1044 # Adjust subplot layouts … … 917 1059 minloc = HourLocator(range(0,23,12)) 918 1060 timefmt = DateFormatter("%b%d") 1061 elif tdel > 24./60.: 1062 timefmt = DateFormatter('%H:%M') 1063 majloc = HourLocator() 1064 minloc = MinuteLocator(30) 919 1065 else: 920 timefmt = DateFormatter('%H') 921 majloc = HourLocator() 922 minloc = MinuteLocator(20) 1066 timefmt = DateFormatter('%H:%M') 1067 majloc = MinuteLocator(interval=5) 1068 minloc = SecondLocator(30) 1069 923 1070 PL.title(dstr) 924 925 1071 if tdel == 0.0: 926 1072 th = (t - PL.floor(t))*24.0 … … 947 1093 if az[irow] < 0: az[irow] += 360.0 948 1094 949 ax = PL.subplot(2,1,2)1095 ax2 = PL.subplot(2,1,2) 950 1096 #PL.xlabel('Time (UT [hour])') 951 1097 PL.ylabel('Az [deg.]') … … 954 1100 else: 955 1101 PL.plot_date(t,az,'o', markersize=2,markeredgecolor='b',markerfacecolor='b',tz=tz) 956 ax .xaxis.set_major_formatter(timefmt)957 ax .xaxis.set_major_locator(majloc)958 ax .xaxis.set_minor_locator(minloc)959 #ax .grid(True)960 ax .set_ylim(0,360)961 ax .yaxis.grid(True)1102 ax2.xaxis.set_major_formatter(timefmt) 1103 ax2.xaxis.set_major_locator(majloc) 1104 ax2.xaxis.set_minor_locator(minloc) 1105 #ax2.grid(True) 1106 ax2.set_ylim(0,360) 1107 ax2.yaxis.grid(True) 962 1108 #hfmt = DateFormatter('%H') 963 1109 #hloc = HourLocator() 964 1110 yloc = MultipleLocator(60) 965 ax .yaxis.set_major_locator(yloc)1111 ax2.yaxis.set_major_locator(yloc) 966 1112 if tdel > 1.0: 967 labels = ax .get_xticklabels()1113 labels = ax2.get_xticklabels() 968 1114 PL.setp(labels, fontsize=10) 969 1115 PL.xlabel('Time (UT [day])') … … 971 1117 PL.xlabel('Time (UT [hour])') 972 1118 973 #PL.ion()1119 PL.ion() 974 1120 PL.draw() 975 1121 if (self._outfile is not None): … … 977 1123 978 1124 def plotpointing(self, scan=None, outfile=None): 1125 #def plotpointing(self): 979 1126 """ 980 1127 plot telescope pointings 981 1128 """ 982 import pylab as PL 983 from matplotlib.dates import DateFormatter, timezone 984 from matplotlib.ticker import MultipleLocator 985 from matplotlib.numerix import array, pi, zeros 1129 from matplotlib import pylab as PL 1130 from numpy import array, pi 986 1131 self._data = scan 987 1132 self._outfile = outfile … … 1001 1146 #ax = PL.axes([0.1,0.1,0.8,0.8]) 1002 1147 ax.set_aspect('equal') 1003 PL.plot(ra, dec, 'b,')1148 PL.plot(ra, dec, 'b,') 1004 1149 PL.xlabel('RA [deg.]') 1005 1150 PL.ylabel('Declination [deg.]') … … 1135 1280 # Print Observation header to the upper-left corner of plot 1136 1281 if plot: 1137 srest=ssum[ssum.find('Rest Freqs:'):ssum.find('Abcissa:')]1138 shead=ssum[ssum.find('Beams:'):ssum.find('Flux Unit:')]1139 headstr=shead.split('\n\n')1140 if extrastr != '': headstr[ 1]=extrastr+'\n'+headstr[1]1282 headstr=[ssum[ssum.find('Observer:'):ssum.find('Flux Unit:')]] 1283 headstr.append(ssum[ssum.find('Beams:'):ssum.find('Observer:')] 1284 +ssum[ssum.find('Rest Freqs:'):ssum.find('Abcissa:')]) 1285 if extrastr != '': headstr[0]=extrastr+'\n'+headstr[0] 1141 1286 #headstr[1]='Data File: '+(filestr or 'unknown')+'\n'+headstr[1] 1142 headstr[0]=headstr[0]+'\n'+srest1143 headstr.reverse()1144 1287 ssel='***Selections***\n'+(selstr+self._data.get_selection().__str__() or 'none') 1145 1288 headstr.append(ssel) … … 1159 1302 verticalalignment='bottom',fontsize=8) 1160 1303 self._plotter.release() 1161 del srest, shead,headstr, ssel1304 del headstr, ssel 1162 1305 if logger: 1163 1306 asaplog.push("----------------\n Plot Summary\n----------------") -
branches/alma/python/asapreader.py
r1059 r1757 1 1 from asap._asap import stfiller 2 from asap import print_log 2 from asap import print_log, print_log_dec 3 3 4 4 class reader(stfiller): … … 25 25 rpfits ONLY. 26 26 """ 27 27 #@print_log_dec 28 28 def __init__(self, filename, unit=None, theif=None, thebeam=None): 29 29 self.unit = unit … … 48 48 print_log() 49 49 50 #@print_log_dec 50 51 def read(self): 51 52 """ -
branches/alma/python/scantable.py
r1701 r1757 1 import os 2 try: 3 from functools import wraps as wraps_dec 4 except ImportError: 5 from asap.compatibility import wraps as wraps_dec 6 1 7 from asap._asap import Scantable 2 8 from asap import rcParams 3 from asap import print_log 9 from asap import print_log, print_log_dec 4 10 from asap import asaplog 5 11 from asap import selector 6 12 from asap import linecatalog 13 from asap.coordinate import coordinate 7 14 from asap import _n_bools, mask_not, mask_and, mask_or 15 16 17 def preserve_selection(func): 18 @wraps_dec(func) 19 def wrap(obj, *args, **kw): 20 basesel = obj.get_selection() 21 val = func(obj, *args, **kw) 22 obj.set_selection(basesel) 23 return val 24 return wrap 25 26 27 def is_scantable(filename): 28 return (os.path.isdir(filename) 29 and not os.path.exists(filename+'/table.f1') 30 and os.path.exists(filename+'/table.info')) 31 8 32 9 33 class scantable(Scantable): … … 12 36 """ 13 37 14 def __init__(self, filename, average=None, unit=None, getpt=None, antenna=None): 38 #@print_log_dec 39 def __init__(self, filename, average=None, unit=None, getpt=None, antenna=None, parallactify=None): 15 40 """ 16 41 Create a scantable from a saved one or make a reference … … 36 61 antenna: Antenna selection. integer (id) or string (name 37 62 or id). 63 parallactify: Indcicate that the data had been parallatified. 64 Default is taken form rc file. 38 65 """ 39 66 if average is None: … … 57 84 return 58 85 antenna = tmpstr.rstrip(',') 86 parallactify = parallactify or rcParams['scantable.parallactify'] 59 87 varlist = vars() 60 88 from asap._asap import stmath … … 63 91 Scantable.__init__(self, filename) 64 92 else: 65 if isinstance(filename, str):# or \ 66 # (isinstance(filename, list) or isinstance(filename, tuple)) \ 67 # and isinstance(filename[-1], str): 68 import os.path 93 if isinstance(filename, str): 69 94 filename = os.path.expandvars(filename) 70 95 filename = os.path.expanduser(filename) … … 73 98 if rcParams['verbose']: 74 99 asaplog.push(s) 75 #print asaplog.pop().strip()76 100 print_log('ERROR') 77 101 return 78 102 raise IOError(s) 79 if os.path.isdir(filename) \ 80 and not os.path.exists(filename+'/table.f1'): 81 # crude check if asap table 82 if os.path.exists(filename+'/table.info'): 83 ondisk = rcParams['scantable.storage'] == 'disk' 84 Scantable.__init__(self, filename, ondisk) 85 if unit is not None: 86 self.set_fluxunit(unit) 87 # do not reset to the default freqframe 88 #self.set_freqframe(rcParams['scantable.freqframe']) 103 if is_scantable(filename): 104 ondisk = rcParams['scantable.storage'] == 'disk' 105 Scantable.__init__(self, filename, ondisk) 106 if unit is not None: 107 self.set_fluxunit(unit) 108 # do not reset to the default freqframe 109 #self.set_freqframe(rcParams['scantable.freqframe']) 110 elif os.path.isdir(filename) \ 111 and not os.path.exists(filename+'/table.f1'): 112 msg = "The given file '%s'is not a valid " \ 113 "asap table." % (filename) 114 if rcParams['verbose']: 115 #print msg 116 asaplog.push( msg ) 117 print_log( 'ERROR' ) 118 return 89 119 else: 90 msg = "The given file '%s'is not a valid " \ 91 "asap table." % (filename) 92 if rcParams['verbose']: 93 #print msg 94 asaplog.push( msg ) 95 print_log( 'ERROR' ) 96 return 97 else: 98 raise IOError(msg) 120 raise IOError(msg) 99 121 else: 100 122 self._fill([filename], unit, average, getpt, antenna) … … 102 124 and isinstance(filename[-1], str): 103 125 self._fill(filename, unit, average, getpt, antenna) 126 self.parallactify(parallactify) 104 127 self._add_history("scantable", varlist) 105 128 print_log() 106 129 130 #@print_log_dec 107 131 def save(self, name=None, format=None, overwrite=False): 108 132 """ … … 119 143 'MS2' (saves as an aips++ 120 144 MeasurementSet V2) 121 'FITS' (save as image FITS - not 145 'FITS' (save as image FITS - not 122 146 readable by class) 123 147 'CLASS' (save as FITS readable by CLASS) … … 130 154 """ 131 155 from os import path 132 if format is None: format =rcParams['scantable.save']156 format = format or rcParams['scantable.save'] 133 157 suffix = '.'+format.lower() 134 158 if name is None or name == "": … … 203 227 else: raise 204 228 try: 205 bsel = self.get_selection() 206 sel = selector() 207 sel.set_scans(allscans) 208 self.set_selection(bsel+sel) 209 scopy = self._copy() 210 self.set_selection(bsel) 211 return scantable(scopy) 229 sel = selector(scans=allscans) 230 return self._select_copy(sel) 212 231 except RuntimeError: 213 232 if rcParams['verbose']: … … 219 238 raise 220 239 240 def _select_copy(self, selection): 241 orig = self.get_selection() 242 self.set_selection(orig+selection) 243 cp = self.copy() 244 self.set_selection(orig) 245 return cp 221 246 222 247 def get_scan(self, scanid=None): … … 253 278 if type(scanid) is str: 254 279 sel.set_name(scanid) 255 self.set_selection(bsel+sel) 256 scopy = self._copy() 257 self.set_selection(bsel) 258 return scantable(scopy) 280 return self._select_copy(sel) 259 281 elif type(scanid) is int: 260 282 sel.set_scans([scanid]) 261 self.set_selection(bsel+sel) 262 scopy = self._copy() 263 self.set_selection(bsel) 264 return scantable(scopy) 283 return self._select_copy(sel) 265 284 elif type(scanid) is list: 266 285 sel.set_scans(scanid) 267 self.set_selection(sel) 268 scopy = self._copy() 269 self.set_selection(bsel) 270 return scantable(scopy) 286 return self._select_copy(sel) 271 287 else: 272 288 msg = "Illegal scanid type, use 'int' or 'list' if ints." … … 294 310 filename: the name of a file to write the putput to 295 311 Default - no file output 296 verbose: print extra info such as the frequency table297 The default (False) is taken from .asaprc298 312 """ 299 313 info = Scantable._summary(self, True) 300 #if verbose is None: verbose = rcParams['scantable.verbosesummary']301 314 if filename is not None: 302 315 if filename is "": … … 328 341 """Return the spectrum for the current row in the scantable as a list. 329 342 Parameters: 330 rowno: the row number to retrieve the spectrum from 343 rowno: the row number to retrieve the spectrum from 331 344 """ 332 345 return self._getspectrum(rowno) … … 335 348 """Return the mask for the current row in the scantable as a list. 336 349 Parameters: 337 rowno: the row number to retrieve the mask from 350 rowno: the row number to retrieve the mask from 338 351 """ 339 352 return self._getmask(rowno) … … 343 356 Parameters: 344 357 spec: the spectrum 345 rowno: the row number to set the spectrum for 358 rowno: the row number to set the spectrum for 346 359 """ 347 360 assert(len(spec) == self.nchan()) 348 361 return self._setspectrum(spec, rowno) 362 363 def get_coordinate(self, rowno): 364 """Return the (spectral) coordinate for a a given 'rowno'. 365 NOTE: 366 * This coordinate is only valid until a scantable method modifies 367 the frequency axis. 368 * This coordinate does contain the original frequency set-up 369 NOT the new frame. The conversions however are done using the user 370 specified frame (e.g. LSRK/TOPO). To get the 'real' coordinate, 371 use scantable.freq_align first. Without it there is no closure, 372 i.e. 373 c = myscan.get_coordinate(0) 374 c.to_frequency(c.get_reference_pixel()) != c.get_reference_value() 375 376 Parameters: 377 rowno: the row number for the spectral coordinate 378 379 """ 380 return coordinate(Scantable.get_coordinate(self, rowno)) 349 381 350 382 def get_selection(self): … … 360 392 return selector(self._getselection()) 361 393 362 def set_selection(self, selection= selector()):394 def set_selection(self, selection=None, **kw): 363 395 """ 364 396 Select a subset of the data. All following operations on this scantable 365 397 are only applied to thi selection. 366 398 Parameters: 367 selection: a selector object (default unset the selection) 399 selection: a selector object (default unset the selection), 400 401 or 402 403 any combination of 404 "pols", "ifs", "beams", "scans", "cycles", "name", "query" 405 368 406 Examples: 369 407 sel = selector() # create a selection object … … 372 410 scan.summary() # will only print summary of scanno 0 an 3 373 411 scan.set_selection() # unset the selection 374 """ 412 # or the equivalent 413 scan.set_selection(scans=[0,3]) 414 scan.summary() # will only print summary of scanno 0 an 3 415 scan.set_selection() # unset the selection 416 """ 417 if selection is None: 418 # reset 419 if len(kw) == 0: 420 selection = selector() 421 else: 422 # try keywords 423 for k in kw: 424 if k not in selector.fields: 425 raise KeyError("Invalid selection key '%s', valid keys are %s" % (k, selector.fields)) 426 selection = selector(**kw) 375 427 self._setselection(selection) 376 428 … … 425 477 scan.stats(stat='mean', mask=m) 426 478 """ 427 if mask == None: 428 mask = [] 429 axes = ['Beam', 'IF', 'Pol', 'Time'] 479 mask = mask or [] 430 480 if not self._check_ifs(): 431 481 raise ValueError("Cannot apply mask as the IFs have different " … … 441 491 if not rtnabc: statvals = self._math._stats(self, mask, stat) 442 492 443 out = '' 444 axes = [] 493 #def cb(i): 494 # return statvals[i] 495 496 #return self._row_callback(cb, stat) 497 498 label=stat 499 #callback=cb 500 out = "" 501 #outvec = [] 502 sep = '-'*50 445 503 for i in range(self.nrow()): 446 axis = []447 axis.append(self.getscan(i))448 axis.append(self.getbeam(i))449 axis.append(self.getif(i))450 axis.append(self.getpol(i))451 axis.append(self.getcycle(i))452 axes.append(axis)453 tm = self._gettime(i)454 src = self._getsourcename(i)455 504 refstr = '' 456 505 statunit= '' … … 459 508 if rtnabc: 460 509 statvals.append(qx['value']) 461 #refstr = '(value: %3.3f' % (qy['value'])+' ['+qy['unit']+'])'462 510 refstr = ('(value: %'+form) % (qy['value'])+' ['+qy['unit']+'])' 463 511 statunit= '['+qx['unit']+']' 464 512 else: 465 #refstr = '(@ %3.3f' % (qx['value'])+' ['+qx['unit']+'])'466 513 refstr = ('(@ %'+form) % (qx['value'])+' ['+qx['unit']+'])' 467 #statunit= ' ['+qy['unit']+']' 468 out += 'Scan[%d] (%s) ' % (axis[0], src) 514 515 tm = self._gettime(i) 516 src = self._getsourcename(i) 517 out += 'Scan[%d] (%s) ' % (self.getscan(i), src) 469 518 out += 'Time[%s]:\n' % (tm) 470 if self.nbeam(-1) > 1: out += ' Beam[%d] ' % (axis[1]) 471 if self.nif(-1) > 1: out += ' IF[%d] ' % (axis[2]) 472 if self.npol(-1) > 1: out += ' Pol[%d] ' % (axis[3]) 473 #out += '= %3.3f ' % (statvals[i]) +refstr+'\n' 519 if self.nbeam(-1) > 1: 520 out += ' Beam[%d] ' % (self.getbeam(i)) 521 if self.nif(-1) > 1: out += ' IF[%d] ' % (self.getif(i)) 522 if self.npol(-1) > 1: out += ' Pol[%d] ' % (self.getpol(i)) 523 #outvec.append(callback(i)) 524 #out += ('= %'+form) % (outvec[i]) +' '+refstr+'\n' 474 525 out += ('= %'+form) % (statvals[i]) +' '+refstr+'\n' 475 out += "--------------------------------------------------\n"526 out += sep+"\n" 476 527 477 528 if rcParams['verbose']: … … 484 535 tmpfile='/tmp/tmp_'+usr+'_casapy_asap_scantable_stats' 485 536 f=open(tmpfile,'w') 486 print >> f, "--------------------------------------------------"487 print >> f, " ", stat, statunit488 print >> f, "--------------------------------------------------"537 print >> f, sep 538 print >> f, ' %s %s' % (label, statunit) 539 print >> f, sep 489 540 print >> f, out 490 541 f.close() … … 492 543 x=f.readlines() 493 544 f.close() 494 for xx in x: 495 asaplog.push( xx, False ) 545 blanc='' 546 asaplog.push(blanc.join(x), False) 547 #for xx in x: 548 # asaplog.push( xx, False ) 496 549 print_log() 497 #else:498 #retval = { 'axesnames': ['scanno', 'beamno', 'ifno', 'polno', 'cycleno'],499 # 'axes' : axes,500 # 'data': statvals}501 550 return statvals 502 551 … … 541 590 return list(Scantable.get_column_names(self)) 542 591 543 def get_tsys(self ):592 def get_tsys(self, row=-1): 544 593 """ 545 594 Return the System temperatures. … … 547 596 a list of Tsys values for the current selection 548 597 """ 549 598 if row > -1: 599 return self._get_column(self._gettsys, row) 550 600 return self._row_callback(self._gettsys, "Tsys") 551 601 602 603 def get_weather(self, row=-1): 604 values = self._get_column(self._get_weather, row) 605 if row > -1: 606 return {'temperature': values[0], 607 'pressure': values[1], 'humidity' : values[2], 608 'windspeed' : values[3], 'windaz' : values[4] 609 } 610 else: 611 out = [] 612 for r in values: 613 614 out.append({'temperature': r[0], 615 'pressure': r[1], 'humidity' : r[2], 616 'windspeed' : r[3], 'windaz' : r[4] 617 }) 618 return out 619 552 620 def _row_callback(self, callback, label): 553 axes = []554 axesnames = ['scanno', 'beamno', 'ifno', 'polno', 'cycleno']555 621 out = "" 556 622 outvec = [] 623 sep = '-'*50 557 624 for i in range(self.nrow()): 558 axis = []559 axis.append(self.getscan(i))560 axis.append(self.getbeam(i))561 axis.append(self.getif(i))562 axis.append(self.getpol(i))563 axis.append(self.getcycle(i))564 axes.append(axis)565 625 tm = self._gettime(i) 566 626 src = self._getsourcename(i) 567 out += 'Scan[%d] (%s) ' % ( axis[0], src)627 out += 'Scan[%d] (%s) ' % (self.getscan(i), src) 568 628 out += 'Time[%s]:\n' % (tm) 569 if self.nbeam(-1) > 1: out += ' Beam[%d] ' % (axis[1]) 570 if self.nif(-1) > 1: out += ' IF[%d] ' % (axis[2]) 571 if self.npol(-1) > 1: out += ' Pol[%d] ' % (axis[3]) 629 if self.nbeam(-1) > 1: 630 out += ' Beam[%d] ' % (self.getbeam(i)) 631 if self.nif(-1) > 1: out += ' IF[%d] ' % (self.getif(i)) 632 if self.npol(-1) > 1: out += ' Pol[%d] ' % (self.getpol(i)) 572 633 outvec.append(callback(i)) 573 634 out += '= %3.3f\n' % (outvec[i]) 574 out += "--------------------------------------------------\n"635 out += sep+'\n' 575 636 if rcParams['verbose']: 576 asaplog.push( "--------------------------------------------------")637 asaplog.push(sep) 577 638 asaplog.push(" %s" % (label)) 578 asaplog.push( "--------------------------------------------------")639 asaplog.push(sep) 579 640 asaplog.push(out) 580 641 print_log() 581 # disabled because the vector seems more useful582 #retval = {'axesnames': axesnames, 'axes': axes, 'data': outvec}583 642 return outvec 584 643 … … 624 683 none 625 684 """ 626 return self._get_column(self._getinttime, row) 627 685 return self._get_column(self._getinttime, row) 686 628 687 629 688 def get_sourcename(self, row=-1): … … 674 733 """ 675 734 Get a list of Positions on the sky (direction) for the observations. 676 Return a floatfor each integration in the scantable.735 Return a string for each integration in the scantable. 677 736 Parameters: 678 737 row: row no of integration. Default -1 return all rows … … 693 752 return self._get_column(self._getdirectionvec, row) 694 753 754 #@print_log_dec 695 755 def set_unit(self, unit='channel'): 696 756 """ … … 708 768 self._add_history("set_unit", varlist) 709 769 770 #@print_log_dec 710 771 def set_instrument(self, instr): 711 772 """ … … 719 780 print_log() 720 781 782 #@print_log_dec 721 783 def set_feedtype(self, feedtype): 722 784 """ … … 729 791 print_log() 730 792 793 #@print_log_dec 731 794 def set_doppler(self, doppler='RADIO'): 732 795 """ … … 742 805 print_log() 743 806 807 #@print_log_dec 744 808 def set_freqframe(self, frame=None): 745 809 """ … … 747 811 Parameters: 748 812 frame: an optional frame type, default 'LSRK'. Valid frames are: 749 ' REST', 'TOPO', 'LSRD', 'LSRK', 'BARY',813 'TOPO', 'LSRD', 'LSRK', 'BARY', 750 814 'GEO', 'GALACTO', 'LGROUP', 'CMB' 751 815 Examples: 752 816 scan.set_freqframe('BARY') 753 817 """ 754 if frame is None: frame = rcParams['scantable.freqframe'] 755 varlist = vars() 756 valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \ 818 frame = frame or rcParams['scantable.freqframe'] 819 varlist = vars() 820 # "REST" is not implemented in casacore 821 #valid = ['REST', 'TOPO', 'LSRD', 'LSRK', 'BARY', \ 822 # 'GEO', 'GALACTO', 'LGROUP', 'CMB'] 823 valid = ['TOPO', 'LSRD', 'LSRK', 'BARY', \ 757 824 'GEO', 'GALACTO', 'LGROUP', 'CMB'] 758 825 … … 829 896 """ 830 897 varlist = vars() 831 if mask is None: 832 mask = [] 898 mask = mask or [] 833 899 try: 834 900 self._flag(mask, unflag) … … 883 949 else: raise 884 950 self._add_history("clip", varlist) 885 886 def lag_flag(self, frequency, width=0.0, unit="GHz", insitu=None): 951 952 #@print_log_dec 953 def lag_flag(self, start, end, unit="MHz", insitu=None): 954 #def lag_flag(self, frequency, width=0.0, unit="GHz", insitu=None): 887 955 """ 888 956 Flag the data in 'lag' space by providing a frequency to remove. 889 Flagged data in the scantable gets set to 0.0 before the fft.957 Flagged data in the scantable gets interpolated over the region. 890 958 No taper is applied. 891 959 Parameters: 892 frequency: the frequency (really a period within the bandwidth)893 894 width: the width of the frequency to remove, to remove a895 range of frequencies around the centre.896 unit: the frequency unit (default "GHz")960 start: the start frequency (really a period within the 961 bandwidth) or period to remove 962 end: the end frequency or period to remove 963 unit: the frequency unit (default "MHz") or "" for 964 explicit lag channels 897 965 Notes: 898 It is recommended to flag edges of the band or strong 966 It is recommended to flag edges of the band or strong 899 967 signals beforehand. 900 968 """ … … 902 970 self._math._setinsitu(insitu) 903 971 varlist = vars() 904 base = { "GHz": 1000000000., "MHz": 1000000., "kHz": 1000., "Hz": 1. 905 if not base.has_key(unit):972 base = { "GHz": 1000000000., "MHz": 1000000., "kHz": 1000., "Hz": 1.} 973 if not (unit == "" or base.has_key(unit)): 906 974 raise ValueError("%s is not a valid unit." % unit) 907 975 try: 908 s = scantable(self._math._lag_flag(self, frequency*base[unit], 909 width*base[unit])) 976 if unit == "": 977 s = scantable(self._math._lag_flag(self, start, end, "lags")) 978 else: 979 s = scantable(self._math._lag_flag(self, start*base[unit], 980 end*base[unit], "frequency")) 910 981 except RuntimeError, msg: 911 982 if rcParams['verbose']: … … 923 994 return s 924 995 925 996 #@print_log_dec 926 997 def create_mask(self, *args, **kwargs): 927 998 """ … … 952 1023 c) 953 1024 mask only channel 400 954 msk = scan.create_mask([400, 400]) 955 """ 956 row = 0 957 if kwargs.has_key("row"): 958 row = kwargs.get("row") 1025 msk = scan.create_mask([400]) 1026 """ 1027 row = kwargs.get("row", 0) 959 1028 data = self._getabcissa(row) 960 1029 u = self._getcoordinfo()[0] … … 973 1042 and args or args[0] 974 1043 for window in ws: 975 if (len(window) != 2 or window[0] > window[1] ): 976 raise TypeError("A window needs to be defined as [min, max]") 1044 if len(window) == 1: 1045 window = [window[0], window[0]] 1046 if len(window) == 0 or len(window) > 2: 1047 raise ValueError("A window needs to be defined as [start(, end)]") 1048 if window[0] > window[1]: 1049 tmp = window[0] 1050 window[0] = window[1] 1051 window[1] = tmp 977 1052 for i in range(n): 978 1053 if data[i] >= window[0] and data[i] <= window[1]: … … 1127 1202 source and IF basis, use scantable.set_selection() before using 1128 1203 this function. 1129 # provide your scantable is call scan1204 # provide your scantable is called scan 1130 1205 selection = selector() 1131 1206 selection.set_name("ORION*") … … 1188 1263 1189 1264 def shift_refpix(self, delta): 1190 1191 Shift the reference pixel of the Spectra Coordinate by an 1192 1193 1194 1265 """ 1266 Shift the reference pixel of the Spectra Coordinate by an 1267 integer amount. 1268 Parameters: 1269 delta: the amount to shift by 1195 1270 Note: 1196 1197 """ 1198 Scantable.shift(self, delta)1271 Be careful using this with broadband data. 1272 """ 1273 Scantable.shift_refpix(self, delta) 1199 1274 1200 1275 def history(self, filename=None): … … 1249 1324 # Maths business 1250 1325 # 1251 1326 #@print_log_dec 1252 1327 def average_time(self, mask=None, scanav=False, weight='tint', align=False): 1253 1328 """ … … 1275 1350 """ 1276 1351 varlist = vars() 1277 if weight is None: weight = 'TINT' 1278 if mask is None: mask = () 1279 if scanav: scanav = "SCAN" 1280 else: scanav = "NONE" 1352 weight = weight or 'TINT' 1353 mask = mask or () 1354 scanav = (scanav and 'SCAN') or 'NONE' 1281 1355 scan = (self, ) 1282 1356 try: … … 1302 1376 return s 1303 1377 1378 #@print_log_dec 1304 1379 def convert_flux(self, jyperk=None, eta=None, d=None, insitu=None): 1305 1380 """ … … 1321 1396 self._math._setinsitu(insitu) 1322 1397 varlist = vars() 1323 if jyperk is None: jyperk =-1.01324 if d is None: d =-1.01325 if eta is None: eta =-1.01398 jyperk = jyperk or -1.0 1399 d = d or -1.0 1400 eta = eta or -1.0 1326 1401 s = scantable(self._math._convertflux(self, d, eta, jyperk)) 1327 1402 s._add_history("convert_flux", varlist) … … 1330 1405 else: return s 1331 1406 1407 #@print_log_dec 1332 1408 def gain_el(self, poly=None, filename="", method="linear", insitu=None): 1333 1409 """ … … 1373 1449 self._math._setinsitu(insitu) 1374 1450 varlist = vars() 1375 if poly is None: 1376 poly = () 1451 poly = poly or () 1377 1452 from os.path import expandvars 1378 1453 filename = expandvars(filename) … … 1380 1455 s._add_history("gain_el", varlist) 1381 1456 print_log() 1382 if insitu: self._assign(s) 1383 else: return s 1384 1457 if insitu: 1458 self._assign(s) 1459 else: 1460 return s 1461 1462 #@print_log_dec 1385 1463 def freq_align(self, reftime=None, method='cubic', insitu=None): 1386 1464 """ … … 1401 1479 self._math._setinsitu(insitu) 1402 1480 varlist = vars() 1403 if reftime is None: reftime =""1481 reftime = reftime or "" 1404 1482 s = scantable(self._math._freq_align(self, reftime, method)) 1405 1483 s._add_history("freq_align", varlist) … … 1408 1486 else: return s 1409 1487 1410 def opacity(self, tau, insitu=None): 1488 #@print_log_dec 1489 def opacity(self, tau=None, insitu=None): 1411 1490 """ 1412 1491 Apply an opacity correction. The data 1413 1492 and Tsys are multiplied by the correction factor. 1414 1493 Parameters: 1415 tau: Opacity from which the correction factor is1494 tau: (list of) opacity from which the correction factor is 1416 1495 exp(tau*ZD) 1417 where ZD is the zenith-distance 1496 where ZD is the zenith-distance. 1497 If a list is provided, it has to be of length nIF, 1498 nIF*nPol or 1 and in order of IF/POL, e.g. 1499 [opif0pol0, opif0pol1, opif1pol0 ...] 1500 if tau is `None` the opacities are determined from a 1501 model. 1418 1502 insitu: if False a new scantable is returned. 1419 1503 Otherwise, the scaling is done in-situ … … 1423 1507 self._math._setinsitu(insitu) 1424 1508 varlist = vars() 1509 if not hasattr(tau, "__len__"): 1510 tau = [tau] 1425 1511 s = scantable(self._math._opacity(self, tau)) 1426 1512 s._add_history("opacity", varlist) … … 1429 1515 else: return s 1430 1516 1517 #@print_log_dec 1431 1518 def bin(self, width=5, insitu=None): 1432 1519 """ … … 1444 1531 s._add_history("bin", varlist) 1445 1532 print_log() 1446 if insitu: self._assign(s) 1447 else: return s 1448 1449 1533 if insitu: 1534 self._assign(s) 1535 else: 1536 return s 1537 1538 #@print_log_dec 1450 1539 def resample(self, width=5, method='cubic', insitu=None): 1451 1540 """ … … 1470 1559 else: return s 1471 1560 1472 1561 #@print_log_dec 1473 1562 def average_pol(self, mask=None, weight='none'): 1474 1563 """ … … 1482 1571 """ 1483 1572 varlist = vars() 1484 if mask is None: 1485 mask = () 1573 mask = mask or () 1486 1574 s = scantable(self._math._averagepol(self, mask, weight.upper())) 1487 1575 s._add_history("average_pol", varlist) … … 1489 1577 return s 1490 1578 1579 #@print_log_dec 1491 1580 def average_beam(self, mask=None, weight='none'): 1492 1581 """ … … 1500 1589 """ 1501 1590 varlist = vars() 1502 if mask is None: 1503 mask = () 1591 mask = mask or () 1504 1592 s = scantable(self._math._averagebeams(self, mask, weight.upper())) 1505 1593 s._add_history("average_beam", varlist) … … 1507 1595 return s 1508 1596 1597 def parallactify(self, pflag): 1598 """ 1599 Set a flag to inidcate whether this data should be treated as having 1600 been 'parallactified' (total phase == 0.0) 1601 Parameters: 1602 pflag: Bool inidcating whether to turn this on (True) or 1603 off (False) 1604 """ 1605 varlist = vars() 1606 self._parallactify(pflag) 1607 self._add_history("parallactify", varlist) 1608 1609 #@print_log_dec 1509 1610 def convert_pol(self, poltype=None): 1510 1611 """ 1511 1612 Convert the data to a different polarisation type. 1613 Note that you will need cross-polarisation terms for most conversions. 1512 1614 Parameters: 1513 1615 poltype: The new polarisation type. Valid types are: 1514 "linear", " stokes" and "circular"1616 "linear", "circular", "stokes" and "linpol" 1515 1617 """ 1516 1618 varlist = vars() … … 1530 1632 return s 1531 1633 1532 # def smooth(self, kernel="hanning", width=5.0, insitu=None):1533 def smooth(self, kernel="hanning", width=5.0, plot=False, insitu=None):1634 #@print_log_dec 1635 def smooth(self, kernel="hanning", width=5.0, order=2, plot=False, insitu=None): 1534 1636 """ 1535 1637 Smooth the spectrum by the specified kernel (conserving flux). 1536 1638 Parameters: 1537 1639 kernel: The type of smoothing kernel. Select from 1538 'hanning' (default), 'gaussian', 'boxcar' and1539 'rmedian'1640 'hanning' (default), 'gaussian', 'boxcar', 'rmedian' 1641 or 'poly' 1540 1642 width: The width of the kernel in pixels. For hanning this is 1541 1643 ignored otherwise it defauls to 5 pixels. 1542 1644 For 'gaussian' it is the Full Width Half 1543 1645 Maximum. For 'boxcar' it is the full width. 1544 For 'rmedian' it is the half width. 1646 For 'rmedian' and 'poly' it is the half width. 1647 order: Optional parameter for 'poly' kernel (default is 2), to 1648 specify the order of the polnomial. Ignored by all other 1649 kernels. 1545 1650 plot: plot the original and the smoothed spectra. 1546 1651 In this each indivual fit has to be approved, by … … 1558 1663 if plot: orgscan = self.copy() 1559 1664 1560 s = scantable(self._math._smooth(self, kernel.lower(), width ))1665 s = scantable(self._math._smooth(self, kernel.lower(), width, order)) 1561 1666 s._add_history("smooth", varlist) 1562 1667 … … 1601 1706 else: return s 1602 1707 1603 1604 def poly_baseline(self, mask=None, order=0, plot=False, uselin=False, insitu=None): 1708 #@print_log_dec 1709 def poly_baseline(self, mask=None, order=0, plot=False, uselin=False, 1710 insitu=None): 1605 1711 """ 1606 1712 Return a scan which has been baselined (all rows) by a polynomial. … … 1833 1939 return workscan 1834 1940 1941 #@print_log_dec 1835 1942 def rotate_linpolphase(self, angle): 1836 1943 """ … … 1849 1956 return 1850 1957 1851 1958 #@print_log_dec 1852 1959 def rotate_xyphase(self, angle): 1853 1960 """ … … 1866 1973 return 1867 1974 1975 #@print_log_dec 1868 1976 def swap_linears(self): 1869 1977 """ 1870 Swap the linear polarisations XX and YY, or better the first two 1978 Swap the linear polarisations XX and YY, or better the first two 1871 1979 polarisations as this also works for ciculars. 1872 1980 """ … … 1877 1985 return 1878 1986 1987 #@print_log_dec 1879 1988 def invert_phase(self): 1880 1989 """ … … 1887 1996 return 1888 1997 1998 #@print_log_dec 1889 1999 def add(self, offset, insitu=None): 1890 2000 """ … … 1907 2017 return s 1908 2018 2019 #@print_log_dec 1909 2020 def scale(self, factor, tsys=True, insitu=None): 1910 2021 """ … … 1972 2083 self._setsourcetype(stype) 1973 2084 self.set_selection(basesel) 1974 s._add_history("set_sourcetype", varlist) 1975 2085 self._add_history("set_sourcetype", varlist) 2086 2087 #@print_log_dec 1976 2088 def auto_quotient(self, preserve=True, mode='paired', verify=False): 1977 2089 """ … … 1984 2096 preserve: Output = Toff * (on/off) - Toff 1985 2097 remove: Output = Toff * (on/off) - Ton 1986 mode: the on/off detection mode 2098 mode: the on/off detection mode 1987 2099 'paired' (default) 1988 2100 identifies 'off' scans by the … … 2017 2129 return s 2018 2130 2131 #@print_log_dec 2019 2132 def mx_quotient(self, mask = None, weight='median', preserve=True): 2020 2133 """ … … 2028 2141 remove: Output = Toff * (on/off) - Ton 2029 2142 """ 2030 if mask is None: mask =()2143 mask = mask or () 2031 2144 varlist = vars() 2032 2145 on = scantable(self._math._mx_extract(self, 'on')) … … 2039 2152 return q 2040 2153 2154 #@print_log_dec 2041 2155 def freq_switch(self, insitu=None): 2042 2156 """ … … 2058 2172 else: return s 2059 2173 2174 #@print_log_dec 2060 2175 def recalc_azel(self): 2061 2176 """ … … 2071 2186 return 2072 2187 2188 #@print_log_dec 2073 2189 def __add__(self, other): 2074 2190 """ … … 2077 2193 return self._operation( other, "ADD" ) 2078 2194 2195 #@print_log_dec 2079 2196 def __sub__(self, other): 2080 2197 """ … … 2083 2200 return self._operation( other, 'SUB' ) 2084 2201 2202 #@print_log_dec 2085 2203 def __mul__(self, other): 2086 2204 """ … … 2089 2207 return self._operation( other, 'MUL' ) 2090 2208 2209 #@print_log_dec 2091 2210 def __div__(self, other): 2092 2211 """ … … 2120 2239 basesel = self.get_selection() 2121 2240 for i in range(self.nrow()): 2122 sel = selector()+basesel 2123 sel.set_scans(self.getscan(i)) 2124 sel.set_beams(self.getbeam(i)) 2125 sel.set_ifs(self.getif(i)) 2126 sel.set_polarisations(self.getpol(i)) 2127 self.set_selection(sel) 2241 sel = self.get_row_selector(i) 2242 self.set_selection(basesel+sel) 2128 2243 nans = numpy.isnan(self._getspectrum(0)) 2129 2244 if numpy.any(nans): … … 2131 2246 self.flag(bnans) 2132 2247 self.set_selection(basesel) 2133 2248 2249 def get_row_selector(self, rowno): 2250 return selector(beams=self.getbeam(rowno), 2251 ifs=self.getif(rowno), 2252 pols=self.getpol(rowno), 2253 scans=self.getscan(rowno), 2254 cycles=self.getcycle(rowno)) 2134 2255 2135 2256 def _add_history(self, funcname, parameters): -
branches/alma/python/selector.py
r1693 r1757 7 7 scantables to specific rows. 8 8 """ 9 def __init(self): 10 _selector.__init__(self) 9 fields = ["pols", "ifs", "beams", "scans", "cycles", "name", "query"] 10 11 def __init__(self, *args, **kw): 12 if len(args) == 1: 13 if isinstance(args[0], self.__class__) \ 14 or isinstance(args[0], _selector): 15 _selector.__init__(self, args[0]) 16 else: 17 raise TypeError("Argument can only be a selector object") 18 else: 19 _selector.__init__(self) 20 for k,v in kw.items(): 21 if k in self.fields: 22 func = getattr(self, "set_%s" % k) 23 func(v) 11 24 12 25 def reset(self): … … 45 58 else: 46 59 raise TypeError('Unknown pol type. Please use [0,1...] or ["XX","YY"...]') 47 60 48 61 # for the americans 49 62 set_polarizations = set_polarisations … … 220 233 Merge two selections. 221 234 """ 235 if self.is_empty(): 236 return other 237 elif other.is_empty(): 238 return self 222 239 union = selector() 223 240 gets = [[self._getscans(), other._getscans(), union._setscans], -
branches/alma/scons/quietinstall.py
r1184 r1757 1 1 import SCons 2 3 try: 4 from SCons.Environment import installFunc 5 except ImportError: 6 from SCons.Tool.install import installFunc 2 7 3 8 def no_output(target, source, env): … … 27 32 28 33 quietinstaller_builder = env.Builder( 29 action = env.Action( SCons.Environment.installFunc, no_output),34 action = env.Action(installFunc, no_output), 30 35 multi=1 31 36 ) -
branches/alma/scons/utils.py
r1332 r1757 1 import sys 1 2 import os 2 3 import glob 4 import re 5 import platform 3 6 4 7 def generate(env): 5 def SGlob(pattern): 6 path = env.GetBuildPath('SConscript').replace('SConscript', '') 7 return [ i.replace(path, '') for i in glob.glob(path + pattern) ] 8 9 def SGlob(pattern, excludedirs=[], recursive=False): 10 # always exclude .svn 11 excludedirs.append(".svn") 12 path = env.GetBuildPath('SConscript').replace('SConscript', '') 13 if recursive: 14 # remove '*' from pattern is accidentally specified 15 pattern=pattern.replace("*", "") 16 out = [] 17 for d, ld, fls in os.walk(path): 18 # remove directorys to be excluded 19 for exd in excludedirs: 20 if exd in ld: 21 ld.remove(exd) 22 for f in fls: 23 if f.endswith(pattern): 24 drel=d.replace(path,"") 25 out.append(os.path.join(drel,f)) 26 return out 27 else: 28 return [ i.replace(path, '') for i in glob.glob(path + pattern) ] 8 29 env.SGlob = SGlob 9 30 10 def AddCustomPath(path= ""):11 if not len(path)or not os.path.exists(path):12 return31 def AddCustomPath(path=None): 32 if path is None or not os.path.exists(path): 33 env.Exit(1) 13 34 env.PrependUnique(CPPPATH = [os.path.join(path, "include")]) 14 35 env.PrependUnique(LIBPATH = [os.path.join(path, "lib")]) … … 17 38 def AddCustomPackage(pkgname=None): 18 39 if pkgname is None: 19 20 21 22 23 24 25 26 27 28 else:29 30 31 32 33 34 35 36 37 38 39 40 41 42 40 return 41 pkgroot = env.get("%sroot" % pkgname, None) 42 pkgincd = env.get("%sincdir" % pkgname, None) 43 pkglibd = env.get("%slibdir" % pkgname, None) 44 incd = None 45 libd = None 46 if pkgroot is not None: 47 incd = os.path.join(pkgroot, "include") 48 libd = os.path.join(pkgroot, "lib") 49 else: 50 if pkgincd is not None: 51 incd = pkgincd 52 if pkglibd is not None: 53 libd = pkglibd 54 if incd is not None: 55 if not os.path.exists(incd): 56 print "Custom %s include dir '%s' not found" % (pkgname, incd) 57 env.Exit(1) 58 env.PrependUnique(CPPPATH = [incd]) 59 if libd is not None: 60 if not os.path.exists(libd): 61 print "Custom %s lib dir '%s' not found" % (pkgname, libd) 62 env.Exit(1) 63 env.PrependUnique(LIBPATH = [libd]) 43 64 44 65 env.AddCustomPackage = AddCustomPackage 45 66 67 def PlatformIdent(): 68 p = sys.platform 69 # replace the trailing 2 in linux2 70 p = re.sub(re.compile("2$"), "", p) 71 return p + "_" + platform.machine() 72 env.PlatformIdent = PlatformIdent 73 74 def MergeFlags(): 75 def _to_list(xf): 76 if xf.count(","): 77 return xf.split(",") 78 return xf.split() 79 80 xf=env.get("extracppflags", None) 81 if xf: 82 env.AppendUnique(CPPFLAGS=_to_list(xf)) 83 xf=env.get("extralinkflags", None) 84 if xf: 85 env.AppendUnique(LINKFLAGS=_to_list(xf)) 86 env.AppendUnique(SHLINKFLAGS=_to_list(xf)) 87 xf=env.get("extracxxflags", None) 88 if xf: 89 env.AppendUnique(CXXFLAGS=_to_list(xf)) 90 xf=env.get("extrafflags", None) 91 if xf: 92 env.AppendUnique(FORTRANFLAGS=_to_list(xf)) 93 env.AppendUnique(SHFORTRANFLAGS=_to_list(xf)) 94 xf=env.get("extracflags", None) 95 if xf: 96 env.AppendUnique(CCFLAGS=_to_list(xf)) 97 # set the extra flags if available 98 MergeFlags() 99 46 100 def CheckFortran(conf): 47 48 if not conf.env.has_key("FORTRAN"): 49 # auto-detect fortran 50 detect_fortran = conf.env.Detect(['gfortran', 'g77', 'f77']) 51 if not detect_fortran: 52 print "No fortran compiler found. Specify FORTRAN and f2clib." 53 conf.env.Exit(1) 54 conf.env["FORTRAN"] = detect_fortran 101 102 def getf2clib(fc): 55 103 fdict = {'gfortran': 'gfortran', 'g77': 'g2c', 'f77': 'f2c'} 56 f2clib = conf.env.get("f2clib", fdict[detect_fortran]) 57 if not conf.CheckLib(f2clib): 58 env.Exit(1) 59 else: 60 if not conf.env.has_key("f2clib"): 61 print "A custom fortran compiler also needs f2clib defined" 62 env.Exit(1) 63 else: 64 if not conf.CheckLib(env["f2clib"]): 65 env.Exit(1) 66 if conf.env["FORTRAN"].startswith("g77"): 104 return fdict[fc] 105 106 107 if not conf.env.has_key("FORTRAN"): 108 # auto-detect fortran 109 detect_fortran = conf.env.Detect(['gfortran', 'g77', 'f77']) 110 conf.env["FORTRAN"] = detect_fortran 111 f2clib = conf.env.get("f2clib", getf2clib(conf.env["FORTRAN"])) 112 if not conf.CheckLib(f2clib): 113 conf.env.Exit(1) 114 115 if conf.env["FORTRAN"].startswith("g77"): 67 116 fflags = ["-Wno-globals", "-fno-second-underscore"] 68 conf.env.Append(SHFORTRANFLAGS=fflags) 69 conf.env.Append(FORTRANFLAGS=fflags) 117 conf.env.AppendUnique(SHFORTRANFLAGS=fflags) 118 conf.env.AppendUnique(FORTRANFLAGS=fflags) 119 conf.env.AppendUnique(SHFORTRANFLAGS=['-fPIC']) 120 70 121 env.CheckFortran = CheckFortran 71 122 … … 84 135 env.WalkDirTree = WalkDirTree 85 136 137 86 138 def null_action(target, source, env): return 0 87 139 -
branches/alma/src/Makefile
r1704 r1757 123 123 STAsciiWriter.o \ 124 124 STFITSImageWriter.o \ 125 STAtmosphere.o \ 125 126 Scantable.o \ 126 127 Templates.o … … 136 137 python_LineCatalog.o \ 137 138 python_SrcType.o \ 139 python_STAtmosphere.o \ 140 python_STCoordinate.o \ 138 141 python_asap.o 139 142 … … 172 175 STWriter.h \ 173 176 STAsciiWriter.h \ 174 STFITSImageWriter.h 177 STFITSImageWriter.h \ 178 IndexedCompare.h \ 179 STAtmosphere.h \ 180 STCoordinate.h 175 181 176 182 STATICCCLIB := libasap.a -
branches/alma/src/MathUtils.cpp
r1603 r1757 39 39 #include <scimath/Mathematics/MedianSlider.h> 40 40 #include <casa/Exceptions/Error.h> 41 42 #include <scimath/Fitting/LinearFit.h> 43 #include <scimath/Functionals/Polynomial.h> 44 #include <scimath/Mathematics/AutoDiff.h> 45 41 46 42 47 #include "MathUtils.h" … … 183 188 MedianSlider ms(hwidth); 184 189 Slice sl(0, fwidth-1); 185 Float medval = ms.add(const_cast<Vector<Float>& >(in)(sl), 190 Float medval = ms.add(const_cast<Vector<Float>& >(in)(sl), 186 191 const_cast<Vector<Bool>& >(flag)(sl)); 187 192 uInt n = in.nelements(); 188 193 for (uInt i=hwidth; i<(n-hwidth); ++i) { 189 194 // add data value 190 out[i] = ms.add(in[i+hwidth], flag[i+hwidth]); 191 outflag[i] = (ms.nval() == 0); 192 } 193 // replicate edge values from fi srt value with full width of values195 out[i] = ms.add(in[i+hwidth], flag[i+hwidth]); 196 outflag[i] = (ms.nval() == 0); 197 } 198 // replicate edge values from first value with full width of values 194 199 for (uInt i=0;i<hwidth;++i) { 195 200 out[i] = out[hwidth]; 196 outflag[i] = outflag[hwidth]; 201 outflag[i] = outflag[hwidth]; 197 202 out[n-1-i] = out[n-1-hwidth]; 198 outflag[n-1-i] = outflag[n-1-hwidth]; 199 } 200 } 203 outflag[n-1-i] = outflag[n-1-hwidth]; 204 } 205 } 206 207 void mathutil::polyfit(Vector<Float>& out, Vector<Bool>& outmask, 208 const Vector<Float>& in, const Vector<Bool>& mask, 209 float width, int order) 210 { 211 Int hwidth = Int(width+0.5); 212 Int fwidth = hwidth*2+1; 213 out.resize(in.nelements()); 214 outmask.resize(mask.nelements()); 215 LinearFit<Float> fitter; 216 Polynomial<Float> poly(order); 217 fitter.setFunction(poly); 218 Vector<Float> sigma(fwidth); 219 sigma = 1.0; 220 Vector<Float> parms; 221 Vector<Float> x(fwidth); 222 indgen(x); 223 224 uInt n = in.nelements(); 225 226 for (uInt i=hwidth; i<(n-hwidth); ++i) { 227 // add data value 228 if (mask[i]) { 229 Slice sl(i-hwidth, fwidth); 230 const Vector<Float> &y = const_cast<Vector<Float>& >(in)(sl); 231 const Vector<Bool> &m = const_cast<Vector<Bool>& >(mask)(sl); 232 parms = fitter.fit(x, y, sigma, &m); 233 234 poly.setCoefficients(parms); 235 out[i] = poly(x[hwidth]);//cout << in[i] <<"->"<<out[i]<<endl; 236 } else { 237 out[i] = in[i]; 238 } 239 outmask[i] = mask[i]; 240 } 241 // replicate edge values from first value with full width of values 242 for (uInt i=0;i<hwidth;++i) { 243 out[i] = out[hwidth]; 244 outmask[i] = outmask[hwidth]; 245 out[n-1-i] = out[n-1-hwidth]; 246 outmask[n-1-i] = outmask[n-1-hwidth]; 247 } 248 } -
branches/alma/src/MathUtils.h
r1603 r1757 51 51 * @param ignoreOther drop every second channel (NYI) 52 52 */ 53 void hanning(casa::Vector<casa::Float>& out, 53 void hanning(casa::Vector<casa::Float>& out, 54 54 casa::Vector<casa::Bool>& outmask, 55 const casa::Vector<casa::Float>& in, 55 const casa::Vector<casa::Float>& in, 56 56 const casa::Vector<casa::Bool>& mask, 57 57 casa::Bool relaxed=casa::False, … … 60 60 /** 61 61 * Apply a running median to a masked vector. 62 * Edge solution: The first and last hwidth channels will be replicated 62 * Edge solution: The first and last hwidth channels will be replicated 63 63 * from the first/last value from a full window. 64 64 * @param out the smoothed vector … … 68 68 * @param hwidth half-width of the smoothing window 69 69 */ 70 void runningMedian(casa::Vector<casa::Float>& out, 70 void runningMedian(casa::Vector<casa::Float>& out, 71 casa::Vector<casa::Bool>& outflag, 72 const casa::Vector<casa::Float>& in, 73 const casa::Vector<casa::Bool>& flag, 74 float hwidth); 75 76 void polyfit(casa::Vector<casa::Float>& out, 71 77 casa::Vector<casa::Bool>& outmask, 72 const casa::Vector<casa::Float>& in, 78 const casa::Vector<casa::Float>& in, 73 79 const casa::Vector<casa::Bool>& mask, 74 float hwidth );80 float hwidth, int order); 75 81 76 82 // Generate specified statistic -
branches/alma/src/RowAccumulator.cpp
r1603 r1757 67 67 Float totalweight = weight; 68 68 MaskedArray<Float> data(v,m); 69 if ( weightType_ == asap:: VAR ) {69 if ( weightType_ == asap::W_VAR ) { 70 70 if (m.nelements() == userMask_.nelements()) { 71 71 Float fac = 1.0/variance(data(userMask_)); … … 90 90 Float w = 1.0; 91 91 tsysSum_ += v[0]; 92 if ( weightType_ == asap:: TSYS || weightType_ == asap::TINTSYS ) {92 if ( weightType_ == asap::W_TSYS || weightType_ == asap::W_TINTSYS ) { 93 93 w /= (v[0]*v[0]); 94 94 } … … 105 105 Float w = 1.0; 106 106 intervalSum_ += inter; 107 if ( weightType_ == asap:: TINT || weightType_ == asap::TINTSYS ) {107 if ( weightType_ == asap::W_TINT || weightType_ == asap::W_TINTSYS ) { 108 108 w /= Float(inter); 109 109 } -
branches/alma/src/RowAccumulator.h
r1603 r1757 33 33 * Constructor taking a weight type as defined in @ref STDefs 34 34 */ 35 explicit RowAccumulator(WeightType wt = asap:: NONE);35 explicit RowAccumulator(WeightType wt = asap::W_NONE); 36 36 37 37 ~RowAccumulator(); -
branches/alma/src/STAsciiWriter.cpp
r1657 r1757 89 89 90 90 String rootName(fileName); 91 if (rootName.length()==0) rootName = String("ascii");92 91 93 92 Block<String> cols(4); … … 104 103 String dirtype = stable.getDirectionRefString(); 105 104 ostringstream onstr; 106 onstr << "SCAN" << rec.asuInt("SCANNO") 107 << "_CYCLE" << rec.asuInt("CYCLENO") 108 << "_BEAM" << rec.asuInt("BEAMNO") 109 << "_IF" << rec.asuInt("IFNO"); 105 106 if (rootName.length()==0) { 107 rootName = String("ascii"); 108 } 109 if (tab.nrow() > 1) { 110 if (stable.nscan() > 1) 111 onstr << "_SCAN" << rec.asuInt("SCANNO"); 112 if (stable.ncycle(rec.asuInt("SCANNO")) > 1) 113 onstr << "_CYCLE" << rec.asuInt("CYCLENO"); 114 if (stable.nbeam(rec.asuInt("SCANNO")) > 1) 115 onstr << "_BEAM" << rec.asuInt("BEAMNO"); 116 if (stable.nif(rec.asuInt("SCANNO")) > 1) 117 onstr << "_IF" << rec.asuInt("IFNO"); 118 } 119 110 120 String fName = rootName + String(onstr) + String(".txt"); 111 121 ofstream of(fName.chars(), ios::trunc); -
branches/alma/src/STAttr.cpp
r1387 r1757 331 331 TidGainElPoly_(2) = -3.219093e-4; 332 332 333 // 2009-09-15 - 13mm (22.2GHz) receiver 333 334 ParkesGainElPoly_.resize(3); 334 ParkesGainElPoly_(0) = 0.296759e-1;335 ParkesGainElPoly_(1) = -0.293124e-3;336 ParkesGainElPoly_(2) = 0.264295e-6;335 ParkesGainElPoly_(0) = -0.194031; 336 ParkesGainElPoly_(1) = 0.457724e-1; 337 ParkesGainElPoly_(2) = -0.438659e-3; 337 338 } 338 339 -
branches/alma/src/STDefs.h
r1388 r1757 34 34 35 35 namespace asap { 36 enum AxisNo { BeamAxis=0,37 IFAxis,38 PolAxis,39 ChanAxis,40 nAxes};41 36 42 37 enum Instrument {UNKNOWNINST=0, … … 53 48 enum FeedPolType {UNKNOWNFEED, LINEAR, CIRCULAR, N_POL}; 54 49 55 enum WeightType {NONE=0, VAR, TSYS, TINT, TINTSYS, N_WEIGHTTYPES}; 56 57 enum TableType {MEMORY=0, PERSISTENT}; 58 50 enum WeightType {W_NONE=0, W_VAR, W_TSYS, W_TINT, W_TINTSYS, W_N_WEIGHTTYPES}; 59 51 60 52 -
branches/alma/src/STFITSImageWriter.cpp
r1604 r1757 121 121 TableIterator iter(tab, cols); 122 122 // Open data file 123 123 124 while ( !iter.pastEnd() ) { 124 125 Table t = iter.table(); … … 127 128 String dirtype = stable.getDirectionRefString(); 128 129 ostringstream onstr; 129 onstr << "SCAN" << rec.asuInt("SCANNO") 130 << "_CYCLE" << rec.asuInt("CYCLENO") 131 << "_BEAM" << rec.asuInt("BEAMNO") 132 << "_IF" << rec.asuInt("IFNO") 133 << "_POL" << rec.asuInt("POLNO"); 130 if (rootName.length()==0) { 131 rootName = "fits"; 132 } 133 if (tab.nrow() > 1) { 134 if (stable.nscan() > 1) 135 onstr << "_SCAN" << rec.asuInt("SCANNO"); 136 if (stable.ncycle(rec.asuInt("SCANNO")) > 1) 137 onstr << "_CYCLE" << rec.asuInt("CYCLENO"); 138 if (stable.nbeam(rec.asuInt("SCANNO")) > 1) 139 onstr << "_BEAM" << rec.asuInt("BEAMNO"); 140 if (stable.nif(rec.asuInt("SCANNO")) > 1) 141 onstr << "_IF" << rec.asuInt("IFNO"); 142 if (stable.npol(rec.asuInt("SCANNO")) > 1) 143 onstr << "_POL" << rec.asuInt("POLNO"); 144 } 134 145 String fileName = rootName + String(onstr) + String(".fits"); 135 146 int row0 = t.rowNumbers(tab)[0]; … … 260 271 } 261 272 fits_close_file(fptr, &status); 262 273 ostringstream oss; 274 oss << "Wrote " << fileName; 275 pushLog(String(oss)); 263 276 //pushLog(String(oss)); 264 277 ++iter; -
branches/alma/src/STFiller.cpp
r1684 r1757 264 264 freqFrame = "REST"; 265 265 } 266 table_->frequencies().setFrame(freqFrame); 267 266 // set both "FRAME" and "BASEFRAME" 267 table_->frequencies().setFrame(freqFrame, false); 268 table_->frequencies().setFrame(freqFrame,true); 269 //table_->focus().setParallactify(true); 268 270 } 269 271 … … 329 331 if ( status != 0 ) break; 330 332 n += 1; 331 332 333 Regex filterrx(".*[SL|PA]$"); 333 334 Regex obsrx("^AT.+"); … … 391 392 /// @todo this has to change when nchan isn't global anymore 392 393 //id = table_->frequencies().addEntry(Double(header_->nchan/2), 393 // 394 // pksrec.refFreq, pksrec.freqInc); 394 395 if ( pksrec.nchan == 1 ) { 395 396 id = table_->frequencies().addEntry(Double(0), … … 416 417 RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID"); 417 418 *mweatheridCol = id; 419 418 420 RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID"); 419 id = table_->focus().addEntry(pksrec. focusAxi, pksrec.focusTan,420 pksrec.focus Rot);421 id = table_->focus().addEntry(pksrec.parAngle, pksrec.focusAxi, 422 pksrec.focusTan, pksrec.focusRot); 421 423 *mfocusidCol = id; 422 424 RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION"); … … 426 428 RecordFieldPtr<Float> elCol(rec, "ELEVATION"); 427 429 *elCol = pksrec.elevation; 428 429 RecordFieldPtr<Float> parCol(rec, "PARANGLE");430 *parCol = pksrec.parAngle;431 430 432 431 RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA"); … … 542 541 } 543 542 544 // set framekeyword of FREQUENCIES table543 // set FRAME and BASEFRAME keyword of FREQUENCIES table 545 544 if ( header_->freqref != "TOPO" ) { 546 545 table_->frequencies().setFrame( header_->freqref, false ) ; 546 table_->frequencies().setFrame( header_->freqref, true ) ; 547 547 } 548 548 -
branches/alma/src/STFocus.cpp
r957 r1757 34 34 } 35 35 36 asap::STFocus::STFocus( casa::Table tab ) : STSubTable(tab, name_) 36 STFocus::STFocus( casa::Table tab ) : 37 STSubTable(tab, name_) 37 38 { 39 parangleCol_.attach(table_,"PARANGLE"); 38 40 rotationCol_.attach(table_,"ROTATION"); 39 41 axisCol_.attach(table_,"AXIS"); … … 50 52 } 51 53 52 STFocus& asap::STFocus::operator =( const STFocus & other )54 STFocus& STFocus::operator =( const STFocus & other ) 53 55 { 54 56 if (this != &other) { 55 57 static_cast<STSubTable&>(*this) = other; 58 parangleCol_.attach(table_,"PARANGLE"); 56 59 rotationCol_.attach(table_,"ROTATION"); 57 60 axisCol_.attach(table_,"AXIS"); … … 65 68 return *this; 66 69 } 67 void asap::STFocus::setup( )70 void STFocus::setup( ) 68 71 { 69 72 // add to base class table 73 table_.addColumn(ScalarColumnDesc<Float>("PARANGLE")); 70 74 table_.addColumn(ScalarColumnDesc<Float>("ROTATION")); 71 75 table_.addColumn(ScalarColumnDesc<Float>("AXIS")); … … 76 80 table_.addColumn(ScalarColumnDesc<Float>("XYPHASE")); 77 81 table_.addColumn(ScalarColumnDesc<Float>("XYPHASEOFFSET")); 82 table_.rwKeywordSet().define("PARALLACTIFY", False); 78 83 79 84 // new cached columns 85 parangleCol_.attach(table_,"PARANGLE"); 80 86 rotationCol_.attach(table_,"ROTATION"); 81 87 axisCol_.attach(table_,"AXIS"); … … 88 94 } 89 95 90 uInt STFocus::addEntry(Float fax, Float ftan, Float frot, Float hand,91 Float user, Float mount,92 Float xyphase, Float xyphaseoffset)96 uInt STFocus::addEntry( Float pa, Float fax, Float ftan, Float frot, Float hand, 97 Float user, Float mount, 98 Float xyphase, Float xyphaseoffset) 93 99 { 94 Table result = table_( near(table_.col("ROTATION"), frot) 95 && near(table_.col("AXIS"), fax) 96 && near(table_.col("TAN"), ftan) 97 && near(table_.col("HAND"), hand) 98 && near(table_.col("USERPHASE"), user) 99 && near(table_.col("MOUNT"), mount) 100 && near(table_.col("XYPHASE"), xyphase) 101 && near(table_.col("XYPHASEOFFSET"), xyphaseoffset) 102 ); 100 Table result = table_( near(table_.col("PARANGLE"), pa) 101 && near(table_.col("ROTATION"), frot) 102 && near(table_.col("AXIS"), fax) 103 && near(table_.col("TAN"), ftan) 104 && near(table_.col("HAND"), hand) 105 && near(table_.col("USERPHASE"), user) 106 && near(table_.col("MOUNT"), mount) 107 && near(table_.col("XYPHASE"), xyphase) 108 && near(table_.col("XYPHASEOFFSET"), xyphaseoffset) 109 ); 103 110 uInt resultid = 0; 104 111 if ( result.nrow() > 0) { … … 113 120 resultid++; 114 121 } 122 parangleCol_.put(rno, pa); 115 123 rotationCol_.put(rno, frot); 116 124 axisCol_.put(rno, fax); … … 126 134 } 127 135 128 void asap::STFocus::getEntry(Float& rotation, Float& angle, Float& ftan,129 Float& hand, Float& user, Float& mount,130 Float& xyphase, Float& xyphaseoffset,131 uInt id) const136 void STFocus::getEntry( Float& pa, Float& rotation, Float& angle, Float& ftan, 137 Float& hand, Float& user, Float& mount, 138 Float& xyphase, Float& xyphaseoffset, 139 uInt id) const 132 140 { 133 141 Table t = table_(table_.col("ID") == Int(id) ); … … 138 146 // get first row - there should only be one matching id 139 147 const TableRecord& rec = row.get(0); 148 pa = rec.asFloat("PARANGLE"); 140 149 rotation = rec.asFloat("ROTATION"); 141 150 angle = rec.asFloat("AXIS"); … … 149 158 150 159 151 casa::Float asap::STFocus::getTotalFeedAngle( casa::uInt id ) const160 casa::Float STFocus::getTotalAngle( casa::uInt id ) const 152 161 { 153 162 Float total = 0.0f; 154 163 Table t = table_(table_.col("ID") == Int(id) ); 155 164 if (t.nrow() == 0 ) { 156 throw(AipsError("STFocus::getEntry - id out of range")); 165 throw(AipsError("STFocus::getTotalAngle - id out of range")); 166 } 167 if (table_.keywordSet().asBool("PARALLACTIFY")) { 168 return 0.0f; 157 169 } 158 170 ROTableRow row(t); 159 171 // get first row - there should only be one matching id 160 172 const TableRecord& rec = row.get(0); 173 total += rec.asFloat("PARANGLE"); 161 174 total += rec.asFloat("ROTATION"); 162 175 total += rec.asFloat("USERPHASE"); … … 164 177 return total; 165 178 } 166 }167 179 168 casa::Float asap::STFocus::getFeedHand( casa::uInt id ) const 180 181 casa::Float STFocus::getFeedHand( casa::uInt id ) const 169 182 { 170 183 Table t = table_(table_.col("ID") == Int(id) ); … … 177 190 } 178 191 192 void STFocus::setParallactify(bool istrue) { 193 table_.rwKeywordSet().define("PARALLACTIFY", Bool(istrue)); 194 } 195 196 } -
branches/alma/src/STFocus.h
r1353 r1757 37 37 STFocus& operator=(const STFocus& other); 38 38 39 casa::uInt addEntry( casa::Float faxis, casa::Float ftan,39 casa::uInt addEntry( casa::Float pa, casa::Float faxis, casa::Float ftan, 40 40 casa::Float frot, casa::Float hand=1.0f, 41 41 casa::Float mount=0.0f, casa::Float user=0.0f, 42 casa::Float xyphase=0.0f, casa::Float xyphaseoffset=0.0f); 42 casa::Float xyphase=0.0f, 43 casa::Float xyphaseoffset=0.0f); 43 44 44 void getEntry( casa::Float& fax, casa::Float& ftan,45 void getEntry( casa::Float& pa, casa::Float& fax, casa::Float& ftan, 45 46 casa::Float& frot, casa::Float& hand, 46 47 casa::Float& mount, casa::Float& user, … … 48 49 casa::uInt id) const; 49 50 50 casa::Float getTotalFeedAngle(casa::uInt id) const; 51 casa::Float getTotalAngle(casa::uInt id) const; 52 53 casa::Float getParAngle(casa::uInt id) const { 54 return parangleCol_(id); 55 } 51 56 casa::Float getFeedHand(casa::uInt id) const; 57 58 void setParallactify(bool istrue=false); 52 59 53 60 const casa::String& name() const { return name_; } … … 57 64 static const casa::String name_; 58 65 casa::ScalarColumn<casa::Float> rotationCol_, axisCol_, 59 tanCol_,handCol_, 60 mountCol_,userCol_, 61 xyphCol_,xyphoffCol_; 66 tanCol_,handCol_, parangleCol_, 67 mountCol_,userCol_, xyphCol_,xyphoffCol_,; 62 68 }; 63 69 -
branches/alma/src/STFrequencies.cpp
r1603 r1757 170 170 **/ 171 171 SpectralCoordinate 172 asap::STFrequencies::getSpectralCoordinate( const MDirection& md,172 STFrequencies::getSpectralCoordinate( const MDirection& md, 173 173 const MPosition& mp, 174 174 const MEpoch& me, … … 242 242 { 243 243 Vector<Float> offset(1,0.0); 244 Vector<Float> factors(1, 1.0/width);244 Vector<Float> factors(1,width); 245 245 Vector<Int> newshape; 246 246 CoordinateSystem csys; … … 317 317 << rec.asDouble("REFVAL") << setw(7) 318 318 << rec.asDouble("REFPIX") 319 << setw(1 2)319 << setw(15) 320 320 << rec.asDouble("INCREMENT"); 321 321 } … … 324 324 int f = outstr.find_first_not_of(' '); 325 325 int l = outstr.find_last_not_of(' ', outstr.size()); 326 if (f < 0) { 327 f = 0; 328 } 329 if ( l < f || l < f ) { 326 if (f < 0) { 327 f = 0; 328 } 329 if ( l < f || l < f ) { 330 330 l = outstr.size(); 331 331 } … … 439 439 } 440 440 441 void STFrequencies::shiftRefPix(int npix, uInt id) 441 void STFrequencies::shiftRefPix(int npix, uInt id) 442 442 { 443 443 Table t = table_(table_.col("ID") == Int(id) ); -
branches/alma/src/STLineFinder.cpp
r1603 r1757 34 34 #include "STLineFinder.h" 35 35 #include "STFitter.h" 36 #include "IndexedCompare.h" 36 37 37 38 // STL … … 110 111 111 112 protected: 112 // supplementary function to control running mean calculations.113 // It adds a specified channel to the running meanbox and113 // supplementary function to control running mean/median calculations. 114 // It adds a specified channel to the running box and 114 115 // removes (ch-maxboxnchan+1)'th channel from there 115 116 // Channels, for which the mask is false or index is beyond the … … 152 153 // last point of the detected line 153 154 // 155 bool itsUseMedian; // true if median statistics is used 156 // to determine the noise level, otherwise 157 // it is the mean of the lowest 80% of deviations 158 // (default) 159 int itsNoiseSampleSize; // sample size used to estimate the noise statistics 160 // Negative value means the whole spectrum is used (default) 154 161 public: 155 162 … … 157 164 LFAboveThreshold(std::list<pair<int,int> > &in_lines, 158 165 int in_min_nchan = 3, 159 casa::Float in_threshold = 5) throw(); 166 casa::Float in_threshold = 5, 167 bool use_median = false, 168 int noise_sample_size = -1) throw(); 160 169 virtual ~LFAboveThreshold() throw(); 161 170 … … 200 209 /////////////////////////////////////////////////////////////////////////////// 201 210 211 /////////////////////////////////////////////////////////////////////////////// 212 // 213 // LFNoiseEstimator a helper class designed to estimate off-line variance 214 // using statistics depending on the distribution of 215 // values (e.g. like a median) 216 // 217 // Two statistics are supported: median and an average of 218 // 80% of smallest values. 219 // 220 221 struct LFNoiseEstimator { 222 // construct an object 223 // size - maximum sample size. After a size number of elements is processed 224 // any new samples would cause the algorithm to drop the oldest samples in the 225 // buffer. 226 explicit LFNoiseEstimator(size_t size); 227 228 // add a new sample 229 // in - the new value 230 void add(float in); 231 232 // median of the distribution 233 float median() const; 234 235 // mean of lowest 80% of the samples 236 float meanLowest80Percent() const; 237 238 // return true if the buffer is full (i.e. statistics are representative) 239 inline bool filledToCapacity() const { return itsBufferFull;} 240 241 protected: 242 // update cache of sorted indices 243 // (it is assumed that itsSampleNumber points to the newly 244 // replaced element) 245 void updateSortedCache() const; 246 247 // build sorted cache from the scratch 248 void buildSortedCache() const; 249 250 // number of samples accumulated so far 251 // (can be less than the buffer size) 252 size_t numberOfSamples() const; 253 254 // this helper method builds the cache if 255 // necessary using one of the methods 256 void fillCacheIfNecessary() const; 257 258 private: 259 // buffer with samples (unsorted) 260 std::vector<float> itsVariances; 261 // current sample number (<=itsVariances.size()) 262 size_t itsSampleNumber; 263 // true, if the buffer all values in the sample buffer are used 264 bool itsBufferFull; 265 // cached indices into vector of samples 266 mutable std::vector<size_t> itsSortedIndices; 267 // true if any of the statistics have been obtained at least 268 // once. This flag allows to implement a more efficient way of 269 // calculating statistics, if they are needed at once and not 270 // after each addition of a new element 271 mutable bool itsStatisticsAccessed; 272 }; 273 274 // 275 /////////////////////////////////////////////////////////////////////////////// 276 277 202 278 } // namespace asap 279 280 /////////////////////////////////////////////////////////////////////////////// 281 // 282 // LFNoiseEstimator a helper class designed to estimate off-line variance 283 // using statistics depending on the distribution of 284 // values (e.g. like a median) 285 // 286 // Two statistics are supported: median and an average of 287 // 80% of smallest values. 288 // 289 290 // construct an object 291 // size - maximum sample size. After a size number of elements is processed 292 // any new samples would cause the algorithm to drop the oldest samples in the 293 // buffer. 294 LFNoiseEstimator::LFNoiseEstimator(size_t size) : itsVariances(size), 295 itsSampleNumber(0), itsBufferFull(false), itsSortedIndices(size), 296 itsStatisticsAccessed(false) 297 { 298 AlwaysAssert(size>0,AipsError); 299 } 300 301 302 // add a new sample 303 // in - the new value 304 void LFNoiseEstimator::add(float in) 305 { 306 if (isnan(in)) { 307 // normally it shouldn't happen 308 return; 309 } 310 itsVariances[itsSampleNumber] = in; 311 312 if (itsStatisticsAccessed) { 313 // only do element by element addition if on-the-fly 314 // statistics are needed 315 updateSortedCache(); 316 } 317 318 // advance itsSampleNumber now 319 ++itsSampleNumber; 320 if (itsSampleNumber == itsVariances.size()) { 321 itsSampleNumber = 0; 322 itsBufferFull = true; 323 } 324 AlwaysAssert(itsSampleNumber<itsVariances.size(),AipsError); 325 } 326 327 // number of samples accumulated so far 328 // (can be less than the buffer size) 329 size_t LFNoiseEstimator::numberOfSamples() const 330 { 331 // the number of samples accumulated so far may be less than the 332 // buffer size 333 const size_t nSamples = itsBufferFull ? itsVariances.size(): itsSampleNumber; 334 AlwaysAssert( (nSamples > 0) && (nSamples <= itsVariances.size()), AipsError); 335 return nSamples; 336 } 337 338 // this helper method builds the cache if 339 // necessary using one of the methods 340 void LFNoiseEstimator::fillCacheIfNecessary() const 341 { 342 if (!itsStatisticsAccessed) { 343 if ((itsSampleNumber!=0) || itsBufferFull) { 344 // build the whole cache efficiently 345 buildSortedCache(); 346 } else { 347 updateSortedCache(); 348 } 349 itsStatisticsAccessed = true; 350 } // otherwise, it is updated in 'add' using on-the-fly method 351 } 352 353 // median of the distribution 354 float LFNoiseEstimator::median() const 355 { 356 fillCacheIfNecessary(); 357 // the number of samples accumulated so far may be less than the 358 // buffer size 359 const size_t nSamples = numberOfSamples(); 360 const size_t medSample = nSamples / 2; 361 AlwaysAssert(medSample < itsSortedIndices.size(), AipsError); 362 return itsVariances[itsSortedIndices[medSample]]; 363 } 364 365 // mean of lowest 80% of the samples 366 float LFNoiseEstimator::meanLowest80Percent() const 367 { 368 fillCacheIfNecessary(); 369 // the number of samples accumulated so far may be less than the 370 // buffer size 371 const size_t nSamples = numberOfSamples(); 372 float result = 0; 373 size_t numpt=size_t(0.8*nSamples); 374 if (!numpt) { 375 numpt=nSamples; // no much else left, 376 // although it is very inaccurate 377 } 378 AlwaysAssert( (numpt > 0) && (numpt<itsSortedIndices.size()), AipsError); 379 for (size_t ch=0; ch<numpt; ++ch) { 380 result += itsVariances[itsSortedIndices[ch]]; 381 } 382 result /= float(numpt); 383 return result; 384 } 385 386 // update cache of sorted indices 387 // (it is assumed that itsSampleNumber points to the newly 388 // replaced element) 389 void LFNoiseEstimator::updateSortedCache() const 390 { 391 // the number of samples accumulated so far may be less than the 392 // buffer size 393 const size_t nSamples = numberOfSamples(); 394 395 if (itsBufferFull) { 396 // first find the index of the element which is being replaced 397 size_t index = nSamples; 398 for (size_t i=0; i<nSamples; ++i) { 399 AlwaysAssert(i < itsSortedIndices.size(), AipsError); 400 if (itsSortedIndices[i] == itsSampleNumber) { 401 index = i; 402 break; 403 } 404 } 405 AlwaysAssert( index < nSamples, AipsError); 406 407 const vector<size_t>::iterator indStart = itsSortedIndices.begin(); 408 // merge this element with preceeding block first 409 if (index != 0) { 410 // merge indices on the basis of variances 411 inplace_merge(indStart,indStart+index,indStart+index+1, 412 indexedCompare<size_t>(itsVariances.begin())); 413 } 414 // merge with the following block 415 if (index + 1 != nSamples) { 416 // merge indices on the basis of variances 417 inplace_merge(indStart,indStart+index+1,indStart+nSamples, 418 indexedCompare<size_t>(itsVariances.begin())); 419 } 420 } else { 421 // itsSampleNumber is the index of the new element 422 AlwaysAssert(itsSampleNumber < itsSortedIndices.size(), AipsError); 423 itsSortedIndices[itsSampleNumber] = itsSampleNumber; 424 if (itsSampleNumber >= 1) { 425 // we have to place this new sample in 426 const vector<size_t>::iterator indStart = itsSortedIndices.begin(); 427 // merge indices on the basis of variances 428 inplace_merge(indStart,indStart+itsSampleNumber,indStart+itsSampleNumber+1, 429 indexedCompare<size_t>(itsVariances.begin())); 430 } 431 } 432 } 433 434 // build sorted cache from the scratch 435 void LFNoiseEstimator::buildSortedCache() const 436 { 437 // the number of samples accumulated so far may be less than the 438 // buffer size 439 const size_t nSamples = numberOfSamples(); 440 AlwaysAssert(nSamples <= itsSortedIndices.size(), AipsError); 441 for (size_t i=0; i<nSamples; ++i) { 442 itsSortedIndices[i]=i; 443 } 444 445 // sort indices, but check the array of variances 446 const vector<size_t>::iterator indStart = itsSortedIndices.begin(); 447 stable_sort(indStart,indStart+nSamples, indexedCompare<size_t>(itsVariances.begin())); 448 } 449 450 // 451 /////////////////////////////////////////////////////////////////////////////// 203 452 204 453 /////////////////////////////////////////////////////////////////////////////// … … 275 524 } 276 525 277 // supplementary function to control running mean calculations.278 // It adds a specified channel to the running meanbox and526 // supplementary function to control running mean/median calculations. 527 // It adds a specified channel to the running box and 279 528 // removes (ch-max_box_nchan+1)'th channel from there 280 529 // Channels, for which the mask is false or index is beyond the … … 339 588 (meanch2-square(meanch)); 340 589 linmean=coeff*(Float(cur_channel)-meanch)+mean; 341 linvariance=sqrt(sumf2/Float(box_chan_cntr)-square(mean)- 342 square(coeff)*(meanch2-square(meanch))); 590 linvariance=sumf2/Float(box_chan_cntr)-square(mean)- 591 square(coeff)*(meanch2-square(meanch)); 592 if (linvariance<0.) { 593 // this shouldn't happen normally, but could be due to round-off error 594 linvariance = 0; 595 } else { 596 linvariance = sqrt(linvariance); 597 } 343 598 } 344 599 need2recalculate=False; … … 351 606 /////////////////////////////////////////////////////////////////////////////// 352 607 // 353 // LFAboveThreshold - a running mean algorithm for line detection608 // LFAboveThreshold - a running mean/median algorithm for line detection 354 609 // 355 610 // … … 359 614 LFAboveThreshold::LFAboveThreshold(std::list<pair<int,int> > &in_lines, 360 615 int in_min_nchan, 361 casa::Float in_threshold) throw() : 616 casa::Float in_threshold, 617 bool use_median, 618 int noise_sample_size) throw() : 362 619 min_nchan(in_min_nchan), threshold(in_threshold), 363 lines(in_lines), running_box(NULL) {} 620 lines(in_lines), running_box(NULL), itsUseMedian(use_median), 621 itsNoiseSampleSize(noise_sample_size) {} 364 622 365 623 LFAboveThreshold::~LFAboveThreshold() throw() … … 474 732 running_box=new RunningBox(spectrum,mask,edge,max_box_nchan); 475 733 476 477 734 // determine the off-line variance first 478 735 // an assumption made: lines occupy a small part of the spectrum 479 736 480 std::vector<float> variances(edge.second-edge.first); 481 DebugAssert(variances.size(),AipsError); 482 483 for (;running_box->haveMore();running_box->next()) 484 variances[running_box->getChannel()-edge.first]= 485 running_box->getLinVariance(); 486 487 // in the future we probably should do a proper Chi^2 estimation 488 // now a simple 80% of smaller values will be used. 489 // it may degrade the performance of the algorithm for weak lines 490 // due to a bias of the Chi^2 distribution. 491 stable_sort(variances.begin(),variances.end()); 492 493 Float offline_variance=0; 494 uInt offline_cnt=uInt(0.8*variances.size()); 495 if (!offline_cnt) offline_cnt=variances.size(); // no much else left, 496 // although it is very inaccurate 497 for (uInt n=0;n<offline_cnt;++n) 498 offline_variance+=variances[n]; 499 offline_variance/=Float(offline_cnt); 737 const size_t noiseSampleSize = itsNoiseSampleSize<0 ? size_t(edge.second-edge.first) : 738 std::min(size_t(itsNoiseSampleSize), size_t(edge.second-edge.first)); 739 DebugAssert(noiseSampleSize,AipsError); 740 const bool globalNoise = (size_t(edge.second - edge.first) == noiseSampleSize); 741 LFNoiseEstimator ne(noiseSampleSize); 742 743 for (;running_box->haveMore();running_box->next()) { 744 ne.add(running_box->getLinVariance()); 745 if (ne.filledToCapacity()) { 746 break; 747 } 748 } 749 750 Float offline_variance = -1; // just a flag that it is unset 751 752 if (globalNoise) { 753 offline_variance = itsUseMedian ? ne.median() : ne.meanLowest80Percent(); 754 } 500 755 501 756 // actual search algorithm … … 510 765 running_box->next()) { 511 766 const int ch=running_box->getChannel(); 512 if (running_box->getNumberOfBoxPoints()>=minboxnchan) 767 if (!globalNoise) { 768 // add a next point for a local noise estimate 769 ne.add(running_box->getLinVariance()); 770 } 771 if (running_box->getNumberOfBoxPoints()>=minboxnchan) { 772 if (!globalNoise) { 773 offline_variance = itsUseMedian ? ne.median() : ne.meanLowest80Percent(); 774 } 775 AlwaysAssert(offline_variance>0.,AipsError); 513 776 processChannel(mask[ch] && (fabs(running_box->aboveMean()) >= 514 777 threshold*offline_variance), mask); 515 else processCurLine(mask); // just finish what was accumulated before778 } else processCurLine(mask); // just finish what was accumulated before 516 779 517 780 signs[ch]=getAboveMeanSign(); 518 // os<<ch<<" "<<spectrum[ch]<<" "<<fabs(running_box->aboveMean())<<" "<< 519 // threshold*offline_variance<<endl; 520 521 const Float buf=running_box->aboveMean(); 522 if (buf>0) signs[ch]=1; 523 else if (buf<0) signs[ch]=-1; 524 else if (buf==0) signs[ch]=0; 525 //os<<ch<<" "<<spectrum[ch]<<" "<<running_box->getLinMean()<<" "<< 526 // threshold*offline_variance<<endl; 781 //os<<ch<<" "<<spectrum[ch]<<" "<<fabs(running_box->aboveMean())<<" "<< 782 //threshold*offline_variance<<endl; 527 783 } 528 784 if (lines.size()) … … 649 905 // Setting a very large value doesn't usually provide 650 906 // valid detections. 651 // in_box_size the box size for running mean calculation. Default is907 // in_box_size the box size for running mean/median calculation. Default is 652 908 // 1./5. of the whole spectrum size 909 // in_noise_box the box size for off-line noise estimation (if working with 910 // local noise. Negative value means use global noise estimate 911 // Default is -1 (i.e. estimate using the whole spectrum) 912 // in_median true if median statistics is used as opposed to average of 913 // the lowest 80% of deviations (default) 653 914 void STLineFinder::setOptions(const casa::Float &in_threshold, 654 915 const casa::Int &in_min_nchan, 655 916 const casa::Int &in_avg_limit, 656 const casa::Float &in_box_size) throw() 917 const casa::Float &in_box_size, 918 const casa::Float &in_noise_box, 919 const casa::Bool &in_median) throw() 657 920 { 658 921 threshold=in_threshold; … … 660 923 avg_limit=in_avg_limit; 661 924 box_size=in_box_size; 925 itsNoiseBox = in_noise_box; 926 itsUseMedian = in_median; 662 927 } 663 928 … … 683 948 const casa::uInt &whichRow) throw(casa::AipsError) 684 949 { 685 //const int minboxnchan=4;686 950 if (scan.null()) 687 951 throw AipsError("STLineFinder::findLines - a scan should be set first," … … 700 964 throw AipsError("STLineFinder::findLines - in_scan and in_mask have different" 701 965 "number of spectral channels."); 966 967 // taking flagged channels into account 968 vector<bool> flaggedChannels = scan->getMask(whichRow); 969 if (flaggedChannels.size()) { 970 // there is a mask set for this row 971 if (flaggedChannels.size() != mask.nelements()) { 972 throw AipsError("STLineFinder::findLines - internal inconsistency: number of mask elements do not match the number of channels"); 973 } 974 for (size_t ch = 0; ch<mask.nelements(); ++ch) { 975 mask[ch] &= flaggedChannels[ch]; 976 } 977 } 978 702 979 // number of elements in in_edge 703 980 if (in_edge.size()>2) … … 732 1009 throw AipsError("STLineFinder::findLines - box_size is too small"); 733 1010 1011 // number of elements in the sample for noise estimate 1012 const int noise_box = itsNoiseBox<0 ? -1 : int(nchan * itsNoiseBox); 1013 1014 if ((noise_box!= -1) and (noise_box<2)) 1015 throw AipsError("STLineFinder::findLines - noise_box is supposed to be at least 2 elements"); 1016 734 1017 spectrum.resize(); 735 1018 spectrum = Vector<Float>(scan->getSpectrum(whichRow)); … … 755 1038 try { 756 1039 // line find algorithm 757 LFAboveThreshold lfalg(new_lines,avg_factor*min_nchan, threshold );1040 LFAboveThreshold lfalg(new_lines,avg_factor*min_nchan, threshold, itsUseMedian,noise_box); 758 1041 lfalg.findLines(spectrum,temp_mask,edge,max_box_nchan); 759 1042 signs.resize(lfalg.getSigns().nelements()); -
branches/alma/src/STLineFinder.h
r1353 r1757 150 150 // in_box_size the box size for running mean calculation. Default is 151 151 // 1./5. of the whole spectrum size 152 // in_noise_box the box size for off-line noise estimation (if working with 153 // local noise. Negative value means use global noise estimate 154 // Default is -1 (i.e. estimate using the whole spectrum) 155 // in_median true if median statistics is used as opposed to average of 156 // the lowest 80% of deviations (default) 152 157 void setOptions(const casa::Float &in_threshold=sqrt(3.), 153 158 const casa::Int &in_min_nchan=3, 154 159 const casa::Int &in_avg_limit=8, 155 const casa::Float &in_box_size=0.2) throw(); 160 const casa::Float &in_box_size=0.2, 161 const casa::Float &in_noise_box=-1., 162 const casa::Bool &in_median = casa::False) throw(); 156 163 157 164 // set the scan to work with (in_scan parameter) … … 241 248 // a buffer for the spectrum 242 249 mutable casa::Vector<casa::Float> spectrum; 250 251 // the box size for off-line noise estimation (if working with 252 // local noise. Negative value means use global noise estimate 253 // Default is -1 (i.e. estimate using the whole spectrum) 254 casa::Float itsNoiseBox; 255 256 // true if median statistics is used as opposed to average of 257 // the lowest 80% of deviations (default) 258 casa::Bool itsUseMedian; 243 259 }; 244 260 -
branches/alma/src/STMath.cpp
r1719 r1757 52 52 #include "RowAccumulator.h" 53 53 #include "STAttr.h" 54 #include "STSelector.h" 55 54 56 #include "STMath.h" 55 #include "STSelector.h"56 57 57 using namespace casa; 58 58 … … 740 740 } 741 741 742 CountedPtr<Scantable> STMath::binaryOperate(const CountedPtr<Scantable>& left, 743 const CountedPtr<Scantable>& right, 742 CountedPtr<Scantable> STMath::binaryOperate(const CountedPtr<Scantable>& left, 743 const CountedPtr<Scantable>& right, 744 744 const std::string& mode) 745 745 { … … 1379 1379 { 1380 1380 1381 1381 1382 1382 STSelector sel; 1383 1383 CountedPtr< Scantable > ws = getScantable(s, false); … … 1518 1518 // for each row 1519 1519 // assume that the data order are same between sig and ref 1520 RowAccumulator acc( asap:: TINTSYS ) ;1520 RowAccumulator acc( asap::W_TINTSYS ) ; 1521 1521 for ( int i = 0 ; i < sig->nrow() ; i++ ) { 1522 1522 // get values … … 1952 1952 // initialize the lookup table if necessary 1953 1953 if ( lookup.empty() ) { 1954 lookup["NONE"] = asap:: NONE;1955 lookup["TINT"] = asap:: TINT;1956 lookup["TINTSYS"] = asap:: TINTSYS;1957 lookup["TSYS"] = asap:: TSYS;1958 lookup["VAR"] = asap:: VAR;1954 lookup["NONE"] = asap::W_NONE; 1955 lookup["TINT"] = asap::W_TINT; 1956 lookup["TINTSYS"] = asap::W_TINTSYS; 1957 lookup["TSYS"] = asap::W_TSYS; 1958 lookup["VAR"] = asap::W_VAR; 1959 1959 } 1960 1960 … … 2000 2000 String msg; 2001 2001 if ( nc > 0 ) { 2002 ppoly = new Polynomial<Float>(nc );2002 ppoly = new Polynomial<Float>(nc-1); 2003 2003 coeff = coeffs; 2004 2004 msg = String("user"); … … 2006 2006 STAttr sdAttr; 2007 2007 coeff = sdAttr.gainElevationPoly(inst); 2008 ppoly = new Polynomial<Float>( 3);2008 ppoly = new Polynomial<Float>(coeff.nelements()-1); 2009 2009 msg = String("built in"); 2010 2010 } … … 2144 2144 if (d < 0) { 2145 2145 Instrument inst = 2146 STAttr::convertInstrument(tab.keywordSet().asString("AntennaName"), 2146 STAttr::convertInstrument(tab.keywordSet().asString("AntennaName"), 2147 2147 True); 2148 2148 STAttr sda; … … 2207 2207 2208 2208 CountedPtr< Scantable > STMath::opacity( const CountedPtr< Scantable > & in, 2209 floattau )2209 const std::vector<float>& tau ) 2210 2210 { 2211 2211 CountedPtr< Scantable > out = getScantable(in, false); 2212 2212 2213 Table tab = out->table(); 2214 ROScalarColumn<Float> elev(tab, "ELEVATION"); 2215 ArrayColumn<Float> specCol(tab, "SPECTRA"); 2216 ArrayColumn<uChar> flagCol(tab, "FLAGTRA"); 2217 ArrayColumn<Float> tsysCol(tab, "TSYS"); 2218 for ( uInt i=0; i<tab.nrow(); ++i) { 2219 Float zdist = Float(C::pi_2) - elev(i); 2220 Float factor = exp(tau/cos(zdist)); 2221 MaskedArray<Float> ma = maskedArray(specCol(i), flagCol(i)); 2222 ma *= factor; 2223 specCol.put(i, ma.getArray()); 2224 flagCol.put(i, flagsFromMA(ma)); 2225 Vector<Float> tsys; 2226 tsysCol.get(i, tsys); 2227 tsys *= factor; 2228 tsysCol.put(i, tsys); 2213 Table outtab = out->table(); 2214 2215 const uInt ntau = uInt(tau.size()); 2216 std::vector<float>::const_iterator tauit = tau.begin(); 2217 AlwaysAssert((ntau == 1 || ntau == in->nif() || ntau == in->nif() * in->npol()), 2218 AipsError); 2219 TableIterator iiter(outtab, "IFNO"); 2220 while ( !iiter.pastEnd() ) { 2221 Table itab = iiter.table(); 2222 TableIterator piter(outtab, "POLNO"); 2223 while ( !piter.pastEnd() ) { 2224 Table tab = piter.table(); 2225 ROScalarColumn<Float> elev(tab, "ELEVATION"); 2226 ArrayColumn<Float> specCol(tab, "SPECTRA"); 2227 ArrayColumn<uChar> flagCol(tab, "FLAGTRA"); 2228 ArrayColumn<Float> tsysCol(tab, "TSYS"); 2229 for ( uInt i=0; i<tab.nrow(); ++i) { 2230 Float zdist = Float(C::pi_2) - elev(i); 2231 Float factor = exp(*tauit/cos(zdist)); 2232 MaskedArray<Float> ma = maskedArray(specCol(i), flagCol(i)); 2233 ma *= factor; 2234 specCol.put(i, ma.getArray()); 2235 flagCol.put(i, flagsFromMA(ma)); 2236 Vector<Float> tsys; 2237 tsysCol.get(i, tsys); 2238 tsys *= factor; 2239 tsysCol.put(i, tsys); 2240 } 2241 if (ntau == in->nif()*in->npol() ) { 2242 tauit++; 2243 } 2244 piter++; 2245 } 2246 if (ntau >= in->nif() ) { 2247 tauit++; 2248 } 2249 iiter++; 2229 2250 } 2230 2251 return out; … … 2233 2254 CountedPtr< Scantable > STMath::smoothOther( const CountedPtr< Scantable >& in, 2234 2255 const std::string& kernel, 2235 float width 2256 float width, int order) 2236 2257 { 2237 2258 CountedPtr< Scantable > out = getScantable(in, false); … … 2254 2275 mathutil::runningMedian(specout, maskout, spec , mask, width); 2255 2276 convertArray(flag, maskout); 2277 } else if ( kernel == "poly" ) { 2278 mathutil::polyfit(specout, maskout, spec, !mask, width, order); 2279 convertArray(flag, !maskout); 2256 2280 } 2257 2281 flagCol.put(i, flag); … … 2262 2286 2263 2287 CountedPtr< Scantable > STMath::smooth( const CountedPtr< Scantable >& in, 2264 const std::string& kernel, float width ) 2265 { 2266 if (kernel == "rmedian" || kernel == "hanning") { 2267 return smoothOther(in, kernel, width); 2288 const std::string& kernel, float width, 2289 int order) 2290 { 2291 if (kernel == "rmedian" || kernel == "hanning" || kernel == "poly") { 2292 return smoothOther(in, kernel, width, order); 2268 2293 } 2269 2294 CountedPtr< Scantable > out = getScantable(in, false); … … 2351 2376 id = out->molecules().addEntry(rf, name, fname); 2352 2377 molidcol.put(k, id); 2353 Float f rot,fax,ftan,fhand,fmount,fuser, fxy, fxyp;2354 (*it)->focus().getEntry(f ax, ftan, frot, fhand,2378 Float fpa,frot,fax,ftan,fhand,fmount,fuser, fxy, fxyp; 2379 (*it)->focus().getEntry(fpa, fax, ftan, frot, fhand, 2355 2380 fmount,fuser, fxy, fxyp, 2356 2381 rec.asuInt("FOCUS_ID")); 2357 id = out->focus().addEntry(f ax, ftan, frot, fhand,2382 id = out->focus().addEntry(fpa, fax, ftan, frot, fhand, 2358 2383 fmount,fuser, fxy, fxyp); 2359 2384 focusidcol.put(k, id); … … 2399 2424 cols[3] = String("CYCLENO"); 2400 2425 TableIterator iter(tout, cols); 2401 CountedPtr<STPol> stpol = STPol::getPolClass(out->factories_, 2426 CountedPtr<STPol> stpol = STPol::getPolClass(out->factories_, 2402 2427 out->getPolType() ); 2403 2428 while (!iter.pastEnd()) { … … 2405 2430 ArrayColumn<Float> speccol(t, "SPECTRA"); 2406 2431 ScalarColumn<uInt> focidcol(t, "FOCUS_ID"); 2407 ScalarColumn<Float> parancol(t, "PARANGLE");2408 2432 Matrix<Float> pols(speccol.getColumn()); 2409 2433 try { 2410 2434 stpol->setSpectra(pols); 2411 Float fang,fhand ,parang;2412 fang = in->focusTable_.getTotal FeedAngle(focidcol(0));2435 Float fang,fhand; 2436 fang = in->focusTable_.getTotalAngle(focidcol(0)); 2413 2437 fhand = in->focusTable_.getFeedHand(focidcol(0)); 2414 parang = parancol(0); 2415 /// @todo re-enable this 2416 // disable total feed angle to support paralactifying Caswell style 2417 stpol->setPhaseCorrections(parang, -parang, fhand); 2438 stpol->setPhaseCorrections(fang, fhand); 2418 2439 // use a member function pointer in STPol. This only works on 2419 2440 // the STPol pointer itself, not the Counted Pointer so … … 2681 2702 uInt row = tab.rowNumbers()[0]; 2682 2703 stpol->setSpectra(in->getPolMatrix(row)); 2683 Float fang,fhand ,parang;2684 fang = in->focusTable_.getTotal FeedAngle(in->mfocusidCol_(row));2704 Float fang,fhand; 2705 fang = in->focusTable_.getTotalAngle(in->mfocusidCol_(row)); 2685 2706 fhand = in->focusTable_.getFeedHand(in->mfocusidCol_(row)); 2686 parang = in->paraCol_(row); 2687 /// @todo re-enable this 2688 // disable total feed angle to support paralactifying Caswell style 2689 stpol->setPhaseCorrections(parang, -parang, fhand); 2707 stpol->setPhaseCorrections(fang, fhand); 2690 2708 Int npolout = 0; 2691 2709 for (uInt i=0; i<tab.nrow(); ++i) { … … 2737 2755 CountedPtr< Scantable > 2738 2756 asap::STMath::lagFlag( const CountedPtr< Scantable > & in, 2739 double frequency, double width ) 2757 double start, double end, 2758 const std::string& mode) 2740 2759 { 2741 2760 CountedPtr< Scantable > out = getScantable(in, false); … … 2755 2774 Vector<Float> spec = specCol(i); 2756 2775 Vector<uChar> flag = flagCol(i); 2757 Int lag0 = Int(spec.nelements()*abs(inc)/(frequency+width)+0.5);2758 Int lag1 = Int(spec.nelements()*abs(inc)/(frequency-width)+0.5);2776 int fstart = -1; 2777 int fend = -1; 2759 2778 for (unsigned int k=0; k < flag.nelements(); ++k ) { 2760 2779 if (flag[k] > 0) { 2761 spec[k] = 0.0; 2780 fstart = k; 2781 while (flag[k] > 0 && k < flag.nelements()) { 2782 fend = k; 2783 k++; 2784 } 2762 2785 } 2786 Float interp = 0.0; 2787 if (fstart-1 > 0 ) { 2788 interp = spec[fstart-1]; 2789 if (fend+1 < spec.nelements()) { 2790 interp = (interp+spec[fend+1])/2.0; 2791 } 2792 } else { 2793 interp = spec[fend+1]; 2794 } 2795 if (fstart > -1 && fend > -1) { 2796 for (int j=fstart;j<=fend;++j) { 2797 spec[j] = interp; 2798 } 2799 } 2800 fstart =-1; 2801 fend = -1; 2763 2802 } 2764 2803 Vector<Complex> lags; 2765 2804 ffts.fft0(lags, spec); 2766 Int start = max(0, lag0); 2767 Int end = min(Int(lags.nelements()-1), lag1); 2768 if (start == end) { 2769 lags[start] = Complex(0.0); 2805 Int lag0(start+0.5); 2806 Int lag1(end+0.5); 2807 if (mode == "frequency") { 2808 lag0 = Int(spec.nelements()*abs(inc)/(start)+0.5); 2809 lag1 = Int(spec.nelements()*abs(inc)/(end)+0.5); 2810 } 2811 Int lstart = max(0, lag0); 2812 Int lend = min(Int(lags.nelements()-1), lag1); 2813 if (lstart == lend) { 2814 lags[lstart] = Complex(0.0); 2770 2815 } else { 2771 for (int j=start; j <=end ;++j) { 2816 if (lstart > lend) { 2817 Int tmp = lend; 2818 lend = lstart; 2819 lstart = tmp; 2820 } 2821 for (int j=lstart; j <=lend ;++j) { 2772 2822 lags[j] = Complex(0.0); 2773 2823 } -
branches/alma/src/STMath.h
r1680 r1757 146 146 147 147 casa::CountedPtr<Scantable> 148 binaryOperate( const casa::CountedPtr<Scantable>& left, 149 const casa::CountedPtr<Scantable>& right, 148 binaryOperate( const casa::CountedPtr<Scantable>& left, 149 const casa::CountedPtr<Scantable>& right, 150 150 const std::string& mode); 151 151 … … 290 290 casa::CountedPtr<Scantable> 291 291 smooth(const casa::CountedPtr<Scantable>& in, const std::string& kernel, 292 float width );292 float width, int order=2); 293 293 294 294 casa::CountedPtr<Scantable> … … 302 302 303 303 casa::CountedPtr<Scantable> opacity(const casa::CountedPtr<Scantable>& in, 304 floattau);304 const std::vector<float>& tau); 305 305 306 306 casa::CountedPtr<Scantable> … … 338 338 */ 339 339 casa::CountedPtr<Scantable> 340 lagFlag( const casa::CountedPtr<Scantable>& in, double frequency,341 double width);340 lagFlag( const casa::CountedPtr<Scantable>& in, double start, 341 double end, const std::string& mode="frequency"); 342 342 343 343 // test for average spectra with different channel/resolution … … 374 374 bool tokelvin, float cfac); 375 375 376 casa::CountedPtr< Scantable > 376 casa::CountedPtr< Scantable > 377 377 smoothOther( const casa::CountedPtr< Scantable >& in, 378 378 const std::string& kernel, 379 float width );379 float width, int order=2 ); 380 380 381 381 casa::CountedPtr< Scantable > -
branches/alma/src/STMathWrapper.h
r1680 r1757 146 146 147 147 ScantableWrapper 148 smooth(const ScantableWrapper& in, const std::string& kernel, float width) 149 { return ScantableWrapper(STMath::smooth(in.getCP(), kernel, width)); } 148 smooth(const ScantableWrapper& in, const std::string& kernel, float width, 149 int order=2) 150 { return ScantableWrapper(STMath::smooth(in.getCP(), kernel, width, order)); } 150 151 151 152 ScantableWrapper … … 164 165 165 166 ScantableWrapper opacity(const ScantableWrapper& in, 166 floattau)167 const std::vector<float>& tau) 167 168 { return ScantableWrapper(STMath::opacity(in.getCP(), tau)); } 168 169 … … 201 202 202 203 ScantableWrapper lagFlag( const ScantableWrapper& in, 203 double frequency, double width ) 204 { return ScantableWrapper(STMath::lagFlag(in.getCP(), frequency, width)); } 204 double start, double end, 205 const std::string& mode="frequency" ) 206 { return ScantableWrapper(STMath::lagFlag(in.getCP(), start, end, 207 mode)); } 205 208 206 209 // test for average spectra with different channel/resolution -
branches/alma/src/STPol.h
r1015 r1757 35 35 36 36 typedef void (STPol::*polOperation)( casa::Float phase ); 37 STPol(): total feed_(0.0),parangle_(0.0),feedhand_(1.0) {}37 STPol(): totalangle_(0.0),feedhand_(1.0) {} 38 38 virtual ~STPol() {} 39 39 … … 83 83 84 84 85 void setPhaseCorrections(casa::Float parangle=0.0, casa::Float totalfeed=0.0, 86 casa::Float feedhand=1.0) 87 { totalfeed_=totalfeed;parangle_=parangle;feedhand_=feedhand;} 85 void setPhaseCorrections(casa::Float totalang=0.0, casa::Float feedhand=1.0) 86 { totalangle_=totalang;feedhand_=feedhand;} 88 87 89 casa::Float getTotalPhase() const { return total feed_+parangle_; }88 casa::Float getTotalPhase() const { return totalangle_; } 90 89 casa::Float getFeedHand() const { return feedhand_; } 91 90 … … 99 98 static std::map<std::string, std::map<int, std::string> > labelmap_; 100 99 101 casa::Float total feed_,parangle_,feedhand_;100 casa::Float totalangle_,feedhand_; 102 101 std::string mode_; 103 102 casa::Matrix<casa::Float> basespectra_; -
branches/alma/src/STWriter.cpp
r1683 r1757 42 42 #include <atnf/PKSIO/PKSMS2writer.h> 43 43 #include <atnf/PKSIO/PKSSDwriter.h> 44 #include <atnf/PKSIO/SrcType.h> 44 45 45 46 #include <tables/Tables/Table.h> … … 51 52 #include "STAsciiWriter.h" 52 53 #include "STHeader.h" 54 #include "STMath.h" 55 53 56 54 57 #include "STWriter.h" … … 104 107 const std::string &filename) 105 108 { 109 // If we write out foreign formats we have to convert the frequency system 110 // into the output frame, as we do everything related to SPectarlCoordinates 111 // in asap on-the-fly. 112 113 CountedPtr<Scantable> inst = in; 114 if (in->frequencies().getFrame(true) != in->frequencies().getFrame(false)) { 115 STMath stm(false); 116 inst = stm.frequencyAlign(in); 117 } 106 118 107 119 if (format_=="ASCII") { 108 120 STAsciiWriter iw; 121 // ASCII calls SpectralCoordinate::toWorld so no freqAlign use 'in' 109 122 if (iw.write(*in, filename)) { 110 123 return 0; … … 117 130 iw.setClass(True); 118 131 } 119 if (iw.write(*in , filename)) {132 if (iw.write(*inst, filename)) { 120 133 return 0; 121 134 } … … 127 140 // this is a little different from what I have done 128 141 // before. Need to check with the Offline User Test data 129 STHeader hdr = in ->getHeader();142 STHeader hdr = inst->getHeader(); 130 143 //const Int nPol = hdr.npol; 131 144 //const Int nChan = hdr.nchan; 132 std::vector<uint> ifs = in ->getIFNos();133 int nIF = in ->nif();//ifs.size();145 std::vector<uint> ifs = inst->getIFNos(); 146 int nIF = inst->nif();//ifs.size(); 134 147 Vector<uInt> nPol(nIF),nChan(nIF); 135 148 Vector<Bool> havexpol(nIF); 136 149 String fluxUnit = hdr.fluxunit; 137 150 fluxUnit.upcase(); 138 151 nPol = 0;nChan = 0; havexpol = False; 139 152 for (uint i=0;i<ifs.size();++i) { 140 nPol(ifs[i]) = in ->npol();141 nChan(ifs[i]) = in ->nchan(ifs[i]);153 nPol(ifs[i]) = inst->npol(); 154 nChan(ifs[i]) = inst->nchan(ifs[i]); 142 155 havexpol(ifs[i]) = nPol(ifs[i]) > 2; 143 156 } 144 145 const Table table = in->table(); 157 // Vector<String> obstypes(2); 158 // obstypes(0) = "TR";//on 159 // obstypes(1) = "RF TR";//off 160 const Table table = inst->table(); 161 146 162 147 163 // Create the output file and write static data. … … 155 171 throw(AipsError("Failed to create output file")); 156 172 } 157 158 173 159 174 Int count = 0; … … 206 221 String tcalt; 207 222 Vector<String> stmp0, stmp1; 208 in ->frequencies().getEntry(crpix,crval, pksrec.freqInc,223 inst->frequencies().getEntry(crpix,crval, pksrec.freqInc, 209 224 rec.asuInt("FREQ_ID")); 210 in ->focus().getEntry(pksrec.focusAxi, pksrec.focusTan,211 pksrec.focusRot, tmp0,tmp1,tmp2,tmp3,tmp4,212 rec.asuInt("FOCUS_ID"));213 in ->molecules().getEntry(pksrec.restFreq,stmp0,stmp1,225 inst->focus().getEntry(pksrec.parAngle, pksrec.focusAxi, pksrec.focusTan, 226 pksrec.focusRot, tmp0,tmp1,tmp2,tmp3,tmp4, 227 rec.asuInt("FOCUS_ID")); 228 inst->molecules().getEntry(pksrec.restFreq,stmp0,stmp1, 214 229 rec.asuInt("MOLECULE_ID")); 215 in ->tcal().getEntry(pksrec.tcalTime, pksrec.tcal,230 inst->tcal().getEntry(pksrec.tcalTime, pksrec.tcal, 216 231 rec.asuInt("TCAL_ID")); 217 in ->weather().getEntry(pksrec.temperature, pksrec.pressure,232 inst->weather().getEntry(pksrec.temperature, pksrec.pressure, 218 233 pksrec.humidity, pksrec.windSpeed, 219 234 pksrec.windAz, rec.asuInt("WEATHER_ID")); … … 230 245 pksrec.fieldName = rec.asString("FIELDNAME"); 231 246 pksrec.srcName = rec.asString("SRCNAME"); 232 pksrec.obsType = hdr.obstype; 247 //pksrec.obsType = obstypes[rec.asInt("SRCTYPE")]; 248 pksrec.obsType = getObsTypes( rec.asInt("SRCTYPE") ) ; 233 249 pksrec.bandwidth = nchan * abs(pksrec.freqInc); 234 250 pksrec.azimuth = rec.asFloat("AZIMUTH"); 235 251 pksrec.elevation = rec.asFloat("ELEVATION"); 236 pksrec.parAngle = rec.asFloat("PARANGLE");237 252 pksrec.refBeam = rec.asInt("REFBEAMNO") + 1; 238 253 pksrec.sigma.resize(npol); … … 293 308 { 294 309 String poltype = tab.keywordSet().asString("POLTYPE"); 295 if ( poltype == "stokes") { 310 // Full stokes is not supported. Just allow stokes I 311 if ( poltype == "stokes" && tab.nrow() != 1) { 296 312 String msg = "poltype = " + poltype + " not yet supported in output."; 297 313 throw(AipsError(msg)); … … 340 356 } 341 357 342 } 358 // get obsType string from SRCTYPE value 359 String STWriter::getObsTypes( Int srctype ) 360 { 361 String obsType ; 362 switch( srctype ) { 363 case Int(SrcType::PSON): 364 obsType = "PSON" ; 365 break ; 366 case Int(SrcType::PSOFF): 367 obsType = "PSOFF" ; 368 break ; 369 case Int(SrcType::NOD): 370 obsType = "NOD" ; 371 break ; 372 case Int(SrcType::FSON): 373 obsType = "FSON" ; 374 break ; 375 case Int(SrcType::FSOFF): 376 obsType = "FSOFF" ; 377 break ; 378 case Int(SrcType::SKY): 379 obsType = "SKY" ; 380 break ; 381 case Int(SrcType::HOT): 382 obsType = "HOT" ; 383 break ; 384 case Int(SrcType::WARM): 385 obsType = "WARM" ; 386 break ; 387 case Int(SrcType::COLD): 388 obsType = "COLD" ; 389 break ; 390 case Int(SrcType::PONCAL): 391 obsType = "PSON:CALON" ; 392 break ; 393 case Int(SrcType::POFFCAL): 394 obsType = "PSOFF:CALON" ; 395 break ; 396 case Int(SrcType::NODCAL): 397 obsType = "NOD:CALON" ; 398 break ; 399 case Int(SrcType::FONCAL): 400 obsType = "FSON:CALON" ; 401 break ; 402 case Int(SrcType::FOFFCAL): 403 obsType = "FSOFF:CALOFF" ; 404 break ; 405 case Int(SrcType::FSLO): 406 obsType = "FSLO" ; 407 break ; 408 case Int(SrcType::FLOOFF): 409 obsType = "FS:LOWER:OFF" ; 410 break ; 411 case Int(SrcType::FLOSKY): 412 obsType = "FS:LOWER:SKY" ; 413 break ; 414 case Int(SrcType::FLOHOT): 415 obsType = "FS:LOWER:HOT" ; 416 break ; 417 case Int(SrcType::FLOWARM): 418 obsType = "FS:LOWER:WARM" ; 419 break ; 420 case Int(SrcType::FLOCOLD): 421 obsType = "FS:LOWER:COLD" ; 422 break ; 423 case Int(SrcType::FSHI): 424 obsType = "FSHI" ; 425 break ; 426 case Int(SrcType::FHIOFF): 427 obsType = "FS:HIGHER:OFF" ; 428 break ; 429 case Int(SrcType::FHISKY): 430 obsType = "FS:HIGHER:SKY" ; 431 break ; 432 case Int(SrcType::FHIHOT): 433 obsType = "FS:HIGHER:HOT" ; 434 break ; 435 case Int(SrcType::FHIWARM): 436 obsType = "FS:HIGHER:WARM" ; 437 break ; 438 case Int(SrcType::FHICOLD): 439 obsType = "FS:HIGHER:COLD" ; 440 break ; 441 default: 442 obsType = "NOTYPE" ; 443 } 444 445 return obsType ; 446 } 447 448 } -
branches/alma/src/STWriter.h
r1388 r1757 36 36 #include <casa/aips.h> 37 37 #include <casa/Utilities/CountedPtr.h> 38 #include <casa/BasicSL/String.h> 38 39 39 40 #include "Logger.h" … … 84 85 void replacePtTab(const casa::Table& tab, const std::string& fname); 85 86 87 casa::String getObsTypes( casa::Int srctype ) ; 88 86 89 std::string format_; 87 90 PKSwriter* writer_; -
branches/alma/src/Scantable.cpp
r1707 r1757 261 261 td.addColumn(ScalarColumnDesc<Float>("AZIMUTH")); 262 262 td.addColumn(ScalarColumnDesc<Float>("ELEVATION")); 263 td.addColumn(ScalarColumnDesc<Float>("PARANGLE"));264 263 td.addColumn(ScalarColumnDesc<Float>("OPACITY")); 265 264 … … 303 302 elCol_.attach(table_, "ELEVATION"); 304 303 dirCol_.attach(table_, "DIRECTION"); 305 paraCol_.attach(table_, "PARANGLE");306 304 fldnCol_.attach(table_, "FIELDNAME"); 307 305 rbeamCol_.attach(table_, "REFBEAMNO"); 308 306 307 mweatheridCol_.attach(table_,"WEATHER_ID"); 309 308 mfitidCol_.attach(table_,"FIT_ID"); 310 309 mfreqidCol_.attach(table_, "FREQ_ID"); … … 501 500 } 502 501 503 MPosition Scantable::getAntennaPosition 502 MPosition Scantable::getAntennaPosition() const 504 503 { 505 504 Vector<Double> antpos; … … 515 514 /// @todo reindex SCANNO, recompute nbeam, nif, npol 516 515 inname = path.expandedName(); 517 table_.deepCopy(inname, Table::New); 516 // WORKAROUND !!! for Table bug 517 // Remove when fixed in casacore 518 if ( table_.tableType() == Table::Memory && !selector_.empty() ) { 519 Table tab = table_.copyToMemoryTable(generateName()); 520 tab.deepCopy(inname, Table::New); 521 tab.markForDelete(); 522 523 } else { 524 table_.deepCopy(inname, Table::New); 525 } 518 526 } 519 527 … … 646 654 } 647 655 648 std::vector<uint> Scantable::getNumbers( ScalarColumn<uInt>& col)656 std::vector<uint> Scantable::getNumbers(const ScalarColumn<uInt>& col) const 649 657 { 650 658 Vector<uInt> nos(col.getColumn()); … … 840 848 specCol_.get(whichrow, arr); 841 849 } else { 842 CountedPtr<STPol> stpol(STPol::getPolClass(Scantable::factories_, basetype)); 850 CountedPtr<STPol> stpol(STPol::getPolClass(Scantable::factories_, 851 basetype)); 843 852 uInt row = uInt(whichrow); 844 853 stpol->setSpectra(getPolMatrix(row)); 845 854 Float fang,fhand,parang; 846 fang = focusTable_.getTotal FeedAngle(mfocusidCol_(row));855 fang = focusTable_.getTotalAngle(mfocusidCol_(row)); 847 856 fhand = focusTable_.getFeedHand(mfocusidCol_(row)); 848 parang = paraCol_(row); 849 /// @todo re-enable this 850 // disable total feed angle to support paralactifying Caswell style 851 stpol->setPhaseCorrections(parang, -parang, fhand); 857 stpol->setPhaseCorrections(fang, fhand); 852 858 arr = stpol->getSpectrum(requestedpol, ptype); 853 859 } … … 921 927 << setw(15) << "Polarisations:" << setw(4) << npol() 922 928 << "(" << getPolType() << ")" << endl 923 << setw(15) << "Channels:" << setw(4) << nchan() << endl; 924 oss << endl; 929 << setw(15) << "Channels:" << nchan() << endl; 925 930 String tmp; 926 931 oss << setw(15) << "Observer:" … … 967 972 << setw(10) << "Time" << setw(18) << "Integration" << endl; 968 973 oss << setw(5) << "" << setw(5) << "Beam" << setw(3) << "" << dirtype << endl; 969 oss << setw(10) << "" << setw(3) << "IF" << setw( 6) << ""974 oss << setw(10) << "" << setw(3) << "IF" << setw(3) << "" 970 975 << setw(8) << "Frame" << setw(16) 971 << "RefVal" << setw(10) << "RefPix" << setw(12) << "Increment" <<endl; 976 << "RefVal" << setw(10) << "RefPix" << setw(12) << "Increment" 977 << setw(7) << "Channels" 978 << endl; 972 979 oss << asap::SEPERATOR << endl; 973 980 TableIterator iter(table_, "SCANNO"); … … 1004 1011 ROTableRow irow(isubt); 1005 1012 const TableRecord& irec = irow.get(0); 1006 oss << setw( 10) << "";1013 oss << setw(9) << ""; 1007 1014 oss << setw(3) << std::right << irec.asuInt("IFNO") << std::left 1008 << setw(2) << "" << frequencies().print(irec.asuInt("FREQ_ID")) 1015 << setw(1) << "" << frequencies().print(irec.asuInt("FREQ_ID")) 1016 << setw(3) << "" << nchan(irec.asuInt("IFNO")) 1009 1017 << endl; 1010 1018 … … 1040 1048 Double tm; 1041 1049 table_.keywordSet().get("UTC",tm); 1042 return MEpoch(MVEpoch(tm)); 1050 return MEpoch(MVEpoch(tm)); 1043 1051 } 1044 1052 } … … 1047 1055 { 1048 1056 return formatDirection(getDirection(uInt(whichrow))); 1057 } 1058 1059 1060 SpectralCoordinate Scantable::getSpectralCoordinate(int whichrow) const { 1061 const MPosition& mp = getAntennaPosition(); 1062 const MDirection& md = getDirection(whichrow); 1063 const MEpoch& me = timeCol_(whichrow); 1064 //Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow)); 1065 Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow)); 1066 return freqTable_.getSpectralCoordinate(md, mp, me, rf, 1067 mfreqidCol_(whichrow)); 1049 1068 } 1050 1069 … … 1061 1080 return stlout; 1062 1081 } 1063 1064 const MPosition& mp = getAntennaPosition(); 1065 const MDirection& md = getDirection(whichrow); 1066 const MEpoch& me = timeCol_(whichrow); 1067 //Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow)); 1068 Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow)); 1069 SpectralCoordinate spc = 1070 freqTable_.getSpectralCoordinate(md, mp, me, rf, mfreqidCol_(whichrow)); 1082 SpectralCoordinate spc = getSpectralCoordinate(whichrow); 1071 1083 Vector<Double> pixel(nchan); 1072 1084 Vector<Double> world; … … 1225 1237 Sort::QuickSort|Sort::NoDuplicates ); 1226 1238 for (uInt i=0; i<fids.nelements(); ++i) { 1227 frequencies().shiftRefPix(npix, i);1228 } 1229 } 1230 1231 std::string asap::Scantable::getAntennaName() const1239 frequencies().shiftRefPix(npix, fids[i]); 1240 } 1241 } 1242 1243 std::string Scantable::getAntennaName() const 1232 1244 { 1233 1245 String out; … … 1236 1248 } 1237 1249 1238 int asap::Scantable::checkScanInfo(const std::vector<int>& scanlist) const1250 int Scantable::checkScanInfo(const std::vector<int>& scanlist) const 1239 1251 { 1240 1252 String tbpath; … … 1321 1333 } 1322 1334 1323 std::vector<double> asap::Scantable::getDirectionVector(int whichrow) const1335 std::vector<double> Scantable::getDirectionVector(int whichrow) const 1324 1336 { 1325 1337 Vector<Double> Dir = dirCol_(whichrow).getAngle("rad").getValue(); … … 1681 1693 } 1682 1694 1695 std::vector<float> Scantable::getWeather(int whichrow) const 1696 { 1697 std::vector<float> out(5); 1698 //Float temperature, pressure, humidity, windspeed, windaz; 1699 weatherTable_.getEntry(out[0], out[1], out[2], out[3], out[4], 1700 mweatheridCol_(uInt(whichrow))); 1701 1702 1703 return out; 1704 } 1705 1683 1706 } 1684 1707 //namespace asap -
branches/alma/src/Scantable.h
r1707 r1757 22 22 #include <casa/Utilities/CountedPtr.h> 23 23 24 #include <casa/Exceptions/Error.h>25 26 #include <coordinates/Coordinates/SpectralCoordinate.h>27 28 24 #include <tables/Tables/Table.h> 29 25 #include <tables/Tables/ArrayColumn.h> … … 32 28 #include <measures/TableMeasures/ScalarMeasColumn.h> 33 29 30 #include <coordinates/Coordinates/SpectralCoordinate.h> 31 34 32 #include <casa/Arrays/Vector.h> 35 33 #include <casa/Quanta/Quantum.h> 34 35 #include <casa/Exceptions/Error.h> 36 36 37 37 #include "Logger.h" … … 173 173 */ 174 174 casa::MDirection getDirection( int whichrow ) const; 175 175 176 176 /** 177 177 * get the direction type as a string, e.g. "J2000" … … 191 191 * @return a string describing the direction reference 192 192 */ 193 std::string getDirectionRefString() const; 193 std::string getDirectionRefString() const; 194 194 195 195 /** … … 298 298 299 299 int getBeam(int whichrow) const; 300 std::vector<uint> getBeamNos() { return getNumbers(beamCol_); }300 std::vector<uint> getBeamNos() const { return getNumbers(beamCol_); } 301 301 302 302 int getIF(int whichrow) const; 303 std::vector<uint> getIFNos() { return getNumbers(ifCol_); }303 std::vector<uint> getIFNos() const { return getNumbers(ifCol_); } 304 304 305 305 int getPol(int whichrow) const; 306 std::vector<uint> getPolNos() { return getNumbers(polCol_); }307 308 std::vector<uint> getScanNos() { return getNumbers(scanCol_); }306 std::vector<uint> getPolNos() const { return getNumbers(polCol_); } 307 308 std::vector<uint> getScanNos() const { return getNumbers(scanCol_); } 309 309 int getScan(int whichrow) const { return scanCol_(whichrow); } 310 310 … … 335 335 { return azCol_(whichrow); } 336 336 float getParAngle(int whichrow) const 337 { return paraCol_(whichrow); }337 { return focus().getParAngle(mfocusidCol_(whichrow)); } 338 338 int getTcalId(int whichrow) const 339 339 { return mtcalidCol_(whichrow); } … … 384 384 385 385 std::vector<double> getAbcissa(int whichrow) const; 386 387 std::vector<float> getWeather(int whichrow) const; 386 388 387 389 std::string getAbcissaLabel(int whichrow) const; … … 408 410 409 411 void shift(int npix); 412 413 casa::SpectralCoordinate getSpectralCoordinate(int whichrow) const; 410 414 411 415 void convertDirection(const std::string& newframe); … … 443 447 * against the information found in GBT_GO table for 444 448 * scan number orders to get correct pairs. 445 * @param[in] scan list 446 * @return status 449 * @param[in] scan list 450 * @return status 447 451 */ 448 452 int checkScanInfo(const std::vector<int>& scanlist) const; 449 453 450 454 /** 451 * Get the direction as a vector, for a specific row 455 * Get the direction as a vector, for a specific row 452 456 * @param[in] whichrow the row numbyyer 453 * @return the direction in a vector 457 * @return the direction in a vector 454 458 */ 455 459 std::vector<double> getDirectionVector(int whichrow) const; 460 461 /** 462 * Set a flag indicating whether the data was parallactified 463 * @param[in] flag true or false 464 */ 465 void parallactify(bool flag) 466 { focus().setParallactify(flag); } 456 467 457 468 /** … … 523 534 int rowToScanIndex(int therow); 524 535 525 std::vector<uint> getNumbers(c asa::ScalarColumn<casa::uInt>& col);526 527 static const casa::uInt version_ = 2;536 std::vector<uint> getNumbers(const casa::ScalarColumn<casa::uInt>& col) const; 537 538 static const casa::uInt version_ = 3; 528 539 529 540 STSelector selector_; … … 549 560 casa::ScalarColumn<casa::Float> azCol_; 550 561 casa::ScalarColumn<casa::Float> elCol_; 551 casa::ScalarColumn<casa::Float> paraCol_;552 562 casa::ScalarColumn<casa::String> srcnCol_, fldnCol_; 553 563 casa::ScalarColumn<casa::uInt> scanCol_, beamCol_, ifCol_, polCol_, cycleCol_, flagrowCol_; -
branches/alma/src/ScantableWrapper.h
r1707 r1757 20 20 #include "STFit.h" 21 21 #include "Scantable.h" 22 #include "STCoordinate.h" 22 23 23 24 namespace asap { … … 233 234 { return table_->checkScanInfo(scanlist); } 234 235 235 std::vector<double> 236 std::vector<double> getDirectionVector(int whichrow) const 236 237 { return table_->getDirectionVector(whichrow); } 238 239 void parallactify(bool flag) 240 { table_->parallactify(flag); } 241 242 STCoordinate getCoordinate(int row) { 243 return STCoordinate(table_->getSpectralCoordinate(row)); 244 } 245 246 std::vector<float> getWeather(int whichrow) const 247 { return table_->getWeather(whichrow); } 237 248 238 249 void reshapeSpectrum( int nmin, int nmax ) -
branches/alma/src/python_Scantable.cpp
r1707 r1757 133 133 .def("_setsourcetype", &ScantableWrapper::setSourceType) 134 134 .def("_getdirectionvec", &ScantableWrapper::getDirectionVector) 135 .def("_parallactify", &ScantableWrapper::parallactify) 136 .def("get_coordinate", &ScantableWrapper::getCoordinate) 137 .def("_get_weather", &ScantableWrapper::getWeather) 135 138 .def("_reshape", &ScantableWrapper::reshapeSpectrum, 136 139 (boost::python::arg("nmin")=-1, -
branches/alma/src/python_asap.cpp
r1693 r1757 75 75 asap::python::python_LineCatalog(); 76 76 asap::python::python_Logger(); 77 asap::python::python_STCoordinate(); 78 asap::python::python_STAtmosphere(); 77 79 asap::python::python_SrcType(); 78 80 -
branches/alma/src/python_asap.h
r1693 r1757 47 47 void python_LineCatalog(); 48 48 void python_Logger(); 49 void python_STCoordinate(); 50 void python_STAtmosphere(); 49 51 void python_SrcType(); 50 52 -
branches/alma/test
-
Property svn:ignore
set to
.asaprc
-
Property svn:ignore
set to
-
branches/alma/test/file-io.py
r1267 r1757 17 17 18 18 data.save('output/test.asap',overwrite=True) 19 data.save('output/test .ascii',format='ASCII',overwrite=True)19 data.save('output/testascii',format='ASCII',overwrite=True) 20 20 data.save('output/test.sdfits',format='SDFITS',overwrite=True) 21 data.save('output/testfits',format='FITS',overwrite=True) 22 data.save('output/testclass',format='CLASS',overwrite=True) 21 23 22 24 data2 = scantable('output/test.sdfits') -
branches/alma/test/parkes-pol.py
r1038 r1757 47 47 plotter.set_range(-30,0) 48 48 selection.reset() 49 plotter.plot(plotscans) 49 50 selection.set_polarisations(['I','Q', 'U', 'V']) 50 51 plotter.set_selection(selection) 52 plotter.save('output/parkes_iquv.png',dpi=80) 51 53 selection.set_polarisations(['I','Plinear']) 52 54 plotter.set_selection(selection) 55 plotter.save('output/parkes_iplin.png',dpi=80) 53 56 selection.set_polarisations(['RR','LL']) 54 57 plotter.set_selection(selection) 55 plotter.plot(plotscans)56 58 plotter.save('output/parkes_rrll.png',dpi=80) 57 59 -
branches/alma/web/index.html
r1379 r1757 48 48 <h2>Current Release</h2> 49 49 <b class="asap">ASAP</b> latest stable version 2.2 was released on May, 2<sup>nd</sup> 2007. It can be obtained in the <a href="#download">Download</a> section. 50 51 <div style="color: red;"> 52 Note: Due to a bug in this release, Mopra users should follow <a href="https://svn.atnf.csiro.au/trac/asap/wiki/AsapFaq" >these</a> instructions. 53 </div> 54 50 55 51 56 <h2>Screenshots</h2> … … 118 123 <li><b class="asap">ASAP</b> source code is available through our subversion repository 119 124 <pre> 120 svn co http://s ourcecode.atnf.csiro.au/repos/asap/tags/asap2.2.0125 svn co http://svn.atnf.csiro.au/asap/tags/asap2.2.0 121 126 </pre> 122 127 </li>
Note:
See TracChangeset
for help on using the changeset viewer.