[375] | 1 | Quick and Dirty ATNF Spectra line Analysis Package Cookbook
|
---|
| 2 |
|
---|
| 3 |
|
---|
| 4 | The following "cookbook" is intended to help asap testers get up and
|
---|
| 5 | running. It is not intended to be a comprehensive user guide. If
|
---|
| 6 | anything is not clear please get in contact with
|
---|
| 7 | Chris.Phillips@csiro.au or Malte.Marquarding@csiro.au.
|
---|
| 8 |
|
---|
| 9 | ***********
|
---|
| 10 | * General *
|
---|
| 11 | ***********
|
---|
| 12 |
|
---|
| 13 | The asap user interface is the python scripting language (ipython to
|
---|
| 14 | be exact). It currently uses an object oriented approach for the user
|
---|
| 15 | interface. One job of the testers is to give feed back to how they
|
---|
| 16 | like this or what they would prefer as the command line interface.
|
---|
| 17 |
|
---|
| 18 | The main object in use is a scantable which initially contains the
|
---|
| 19 | scans from a set of observations as individual correlator
|
---|
| 20 | cycles. There are currently some limitations on how this data can be
|
---|
| 21 | averaged. For practical purposes at the moment each scan has to be
|
---|
| 22 | copied from the initial scan table before averaging or other
|
---|
| 23 | reduction.
|
---|
| 24 |
|
---|
| 25 | Asap comes with built in help (help functionname), see the examples
|
---|
| 26 | further down in this document. ipython allows you to run shell
|
---|
| 27 | built-ins (ls, pwd, cd, etc). It also allows tab completion of function
|
---|
| 28 | names etc, so if you cannot remember full command name you can just
|
---|
| 29 | type the first few characters and type tab (eg pol<tab>).
|
---|
| 30 |
|
---|
| 31 | Asap unses "zero-based" indexing. This means the first scan in a
|
---|
| 32 | scantable is scan 0. The first IF, polarisation and beam would have
|
---|
| 33 | index [0,0,0].
|
---|
| 34 |
|
---|
| 35 | ****************
|
---|
| 36 | * Running asap *
|
---|
| 37 | ****************
|
---|
| 38 |
|
---|
| 39 | Currently in the testing phase, asap only runs on Linux at the ATNF.
|
---|
| 40 |
|
---|
| 41 | Ssh onto brage or vulcan at Epping.
|
---|
| 42 |
|
---|
| 43 | > source /nfs/aips++/weekly/aipsinit.csh # Tempory measure
|
---|
| 44 | > asap
|
---|
| 45 |
|
---|
| 46 | This will start up the asap ipython interpretor.
|
---|
| 47 |
|
---|
| 48 | ****************
|
---|
| 49 | * Reading data *
|
---|
| 50 | ****************
|
---|
| 51 |
|
---|
| 52 | To read data from disk, a reader object needs to be created then the
|
---|
| 53 | scans copied into a scan table. This scan table will contain the
|
---|
| 54 | averaged (!) correlator cycles for every scan in the rpfits file.
|
---|
| 55 |
|
---|
| 56 | ASAP> scans = scantable('2003-03-16_082048_t0002.rpf')
|
---|
| 57 |
|
---|
| 58 | The scantable contains all the data from the rpfits file. To reduce
|
---|
| 59 | the data you need to separate the individual scans. Before you do this
|
---|
| 60 | is is advisable to set the restfrequency etc on all scans.
|
---|
| 61 |
|
---|
| 62 | ASAP> scans.set_restfreqs([1665.4018], 'MHz')
|
---|
| 63 | ASAP> scans.set_freqframe('LSRK')
|
---|
| 64 |
|
---|
| 65 | This will set the rest frequency and tell asap to use LSR velocity
|
---|
| 66 | reference.
|
---|
| 67 |
|
---|
| 68 |
|
---|
| 69 | ********************************************
|
---|
| 70 | * Extract scans and make a quotient spectra *
|
---|
| 71 | ********************************************
|
---|
| 72 |
|
---|
| 73 | ASAP> q = scans.get_scan(0)
|
---|
| 74 | ASAP> s = scans.get_scan(1)
|
---|
| 75 |
|
---|
| 76 | This copies the data for the first and second scan.
|
---|
| 77 |
|
---|
| 78 | ASAP> scan = quotient(s, q)
|
---|
| 79 |
|
---|
| 80 | "scan" now contains the quotient spectrum, which you might want to look at.
|
---|
| 81 | The default display is to have polarisation colour stacked and scans across panels.
|
---|
| 82 |
|
---|
| 83 | ASAP> plotter.plot(scan)
|
---|
| 84 |
|
---|
| 85 | *******************************
|
---|
| 86 | * Time average separate scans *
|
---|
| 87 | *******************************
|
---|
| 88 |
|
---|
| 89 | If you have observed the source with multiple source/reference cycles you
|
---|
| 90 | will want to average the quotient spectra together.
|
---|
| 91 | **Note** - You have to have time_averaged the individual scans before you
|
---|
| 92 | average different scans. But you had to time average the individual
|
---|
| 93 | scans before you do the quotient spectra, so you should be OK.
|
---|
| 94 | - When time averaging multiple scans, asap uses rms weighting.
|
---|
| 95 | Generally you have to set a mask so it can calculate the rms.
|
---|
| 96 | - The default setting for a mask it to specify the channel
|
---|
| 97 | range you want to *include* in the fit. The "invert=True" option
|
---|
| 98 | below lets to choose the range you want to exclude (rather than
|
---|
| 99 | include).
|
---|
| 100 |
|
---|
| 101 | ASAP> msk = s1.create_mask([0,100],[450,550],[900,1024]) # Include these
|
---|
| 102 | ASAP> msk = s1.create_mask([250,450],[550,750],invert=True) # or exclude these
|
---|
| 103 |
|
---|
| 104 | ASAP> av = average_time(s1, s2, s3, mask=msk)
|
---|
| 105 |
|
---|
| 106 | *******************
|
---|
| 107 | * Baseline fitting *
|
---|
| 108 | ********************
|
---|
| 109 |
|
---|
| 110 | To make a baseline fit, you must first create a mask of channels to
|
---|
| 111 | use in the baseline fit. Remember that the default is the range to
|
---|
| 112 | exclude, not include.
|
---|
| 113 |
|
---|
| 114 | ASAP> msk = scan.create_mask([1600,1700],[1900,2000])
|
---|
| 115 | ASAP> scan2 = poly_baseline(scan, msk, 1)
|
---|
| 116 |
|
---|
| 117 | This will fit and subtract a first order polynomial to the masked region
|
---|
| 118 |
|
---|
| 119 | *****************************
|
---|
| 120 | * Average the polarisations *
|
---|
| 121 | *****************************
|
---|
| 122 |
|
---|
| 123 | If you are just interested in highest SNR for total intensity you
|
---|
| 124 | want to average the parallel polarisations together.
|
---|
| 125 |
|
---|
| 126 | ASAP> iav = average_pol(s)
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 | *********************
|
---|
| 130 | * Plotting the data *
|
---|
| 131 | *********************
|
---|
| 132 |
|
---|
| 133 | You can plot the data at any time.
|
---|
| 134 | ASAP> plotter.plot(s)
|
---|
| 135 |
|
---|
| 136 | This will bring up a plot window (a separate one for each scantable at
|
---|
| 137 | the moment).
|
---|
| 138 |
|
---|
| 139 | The plot window has 6 buttons on the bottom left hand side.
|
---|
| 140 |
|
---|
| 141 | - Home: This will unzoom the window to the original zoom factor. A current
|
---|
| 142 | bug means that if you change the axis units (say from channel
|
---|
| 143 | to velocity) strange things happen
|
---|
| 144 |
|
---|
| 145 | - Plot history (left ad right arrow). The left arrow sets the plot zoom
|
---|
| 146 | to the previous value. The right arrow returns it. This allows you
|
---|
| 147 | to zoom in on one feature then return the plot to how it was
|
---|
| 148 | previously.
|
---|
| 149 |
|
---|
| 150 | - Pan: The Cross sets the cursor to pan, or scroll mode allowing you to shift
|
---|
| 151 | the plot within the window. Useful when zoomed in on a feature.
|
---|
| 152 |
|
---|
| 153 | - Zoom (the letter with the magnifying glass) lets you draw a rectangle around
|
---|
| 154 | a region of interest then zooms in on that region. Use the plot
|
---|
| 155 | history to unzoom again.
|
---|
| 156 | plotter.set_range(100,500)
|
---|
| 157 | sets a permanent viewing window on the abcissa between in the range 100 to 500 in the current unit.
|
---|
| 158 | plotter.set_range()
|
---|
| 159 | resets this
|
---|
| 160 |
|
---|
| 161 | - Save (floppy disk). Save the plot as a postscript or .png file.
|
---|
| 162 | plotter.save('myfile.ps') doers the same from the command line
|
---|
| 163 |
|
---|
| 164 |
|
---|
| 165 | ***********
|
---|
| 166 | * Fitting *
|
---|
| 167 | ***********
|
---|
| 168 |
|
---|
| 169 | Currently multicomponent Gaussian function is available. This is done
|
---|
| 170 | by creating a fitting object, setting up the fit and actually fitting
|
---|
| 171 | the data.
|
---|
| 172 |
|
---|
| 173 | ASAP> f = fitter()
|
---|
| 174 | ASAP> f.set_function(gauss=1)
|
---|
| 175 | ASAP> f.set_scan(s)
|
---|
| 176 | ASAP> f.fit()
|
---|
| 177 | ASAP> f.plot()
|
---|
| 178 | ASAP> f.get_parameters()
|
---|
| 179 |
|
---|
| 180 | If you want to confine the fitting to a smaller range (e.g. to avoid
|
---|
| 181 | band edge effects or RFI
|
---|
| 182 |
|
---|
| 183 | ASAP> f = fitter()
|
---|
| 184 | ASAP> f.set_function(gauss=2)
|
---|
| 185 | ASAP> msk = s.create_mask([2000,2100])
|
---|
| 186 | ASAP> f.set_scan(s,msk)
|
---|
| 187 | ASAP> f.fit()
|
---|
| 188 | ASAP> f.plot()
|
---|
| 189 | ASAP> f.get_parameters()
|
---|
| 190 |
|
---|
| 191 | If you want to set the initial paramter guesses and fix specific parameters:
|
---|
| 192 |
|
---|
| 193 | ASAP> f = fitter()
|
---|
| 194 | ASAP> f.set_function(gauss=2)
|
---|
| 195 | ASAP> f.set_scan(s,msk)
|
---|
| 196 | ASAP> f.fit()
|
---|
| 197 | ASAP> p = [1.2,160.,50.,0.7,280.,100]
|
---|
| 198 | # order is: [peak0,centre0,FWHM0,peak1,centre1,FWHM1]
|
---|
| 199 | ASAP> fxd = [0,1,0,0,1,0] # fix the centres
|
---|
| 200 | ASAP> f.set_parameters(p,fxd) # set the parameters
|
---|
| 201 | ASAP> f.fit()
|
---|
| 202 |
|
---|
| 203 | *********
|
---|
| 204 | * Units *
|
---|
| 205 | *********
|
---|
| 206 |
|
---|
| 207 | Restfrequency, preferred velocity frame and active units need to be set
|
---|
| 208 | for plotting etc to give sensible velocity units.
|
---|
| 209 |
|
---|
| 210 | * Set the rest frequency of the transition (in MHz, GHz etc).
|
---|
| 211 |
|
---|
| 212 | ASAP> s.set_restfreqs([1666.4018], 'MHz')
|
---|
| 213 |
|
---|
| 214 | * Set the preferred velocity reference frame ('REST', 'TOPO', 'LSRD',
|
---|
| 215 | 'LSRK', 'BARY', 'GEO', 'GALACTO', 'LGROUP', 'CMB')
|
---|
| 216 |
|
---|
| 217 | ASAP> s.set_freqframe('LSRK')
|
---|
| 218 |
|
---|
| 219 | * Set the units for plotting, mask selection etc ('km/s', 'channel', 'MHz')
|
---|
| 220 |
|
---|
| 221 | ASAP> s.set_unit('km/s')
|
---|
| 222 |
|
---|
| 223 | **NOTE** When the unit has been set to, say, km/s then this is the unit used
|
---|
| 224 | for the create_mask function etc, ie give the mask range in km/s
|
---|
| 225 | and not channels.
|
---|
| 226 |
|
---|
| 227 | ***************************
|
---|
| 228 | * Miscellaneous reduction *
|
---|
| 229 | ***************************
|
---|
| 230 |
|
---|
| 231 | * Scale a spectra by a fixed amount
|
---|
| 232 |
|
---|
| 233 | ASAP> ss = scale(s, 1.2)
|
---|
| 234 |
|
---|
| 235 | * Hanning smooth the spectrum
|
---|
| 236 |
|
---|
| 237 | ASAP> ss = hanning(s)
|
---|
| 238 |
|
---|
| 239 | * Bin average the spectrum and reduce the number of spectral points
|
---|
| 240 |
|
---|
| 241 | ASAP> ss = bin(s, 4)
|
---|
| 242 |
|
---|
| 243 | * Save a scan
|
---|
| 244 |
|
---|
| 245 | ASAP> s.save('scan.asap')
|
---|
| 246 |
|
---|
| 247 | * Read a saved scan from disk
|
---|
| 248 |
|
---|
| 249 | ASAP> s = scantable('scan.asap')
|
---|
| 250 |
|
---|
| 251 | * Execute a python script named 'myscript'
|
---|
| 252 |
|
---|
| 253 | ASAP> execfile('myscript')
|
---|
| 254 |
|
---|
| 255 | * To see a summary of a individual or set of scans
|
---|
| 256 |
|
---|
| 257 | ASAP> print s
|
---|
| 258 |
|
---|
| 259 | or alternatively:
|
---|
| 260 |
|
---|
| 261 | ASAP> s.summary()
|
---|
| 262 |
|
---|
| 263 | * Get all (reference) scans which match the pattern '*_R':
|
---|
| 264 |
|
---|
| 265 | ASAP> s = scans.get_scan('*_R')
|
---|
| 266 |
|
---|
| 267 | * Or just and individual:
|
---|
| 268 |
|
---|
| 269 | ASAP> s = scans.get_scan('232p621_S')
|
---|
| 270 |
|
---|
| 271 |
|
---|
| 272 | *******************
|
---|
| 273 | * Object clean up *
|
---|
| 274 | *******************
|
---|
| 275 |
|
---|
| 276 | A asap session has the potential to create a lot of scantable
|
---|
| 277 | objects. To list the current objects and remove unneeded ones use the
|
---|
| 278 | list_scan and del functions. Overwriting deletes the old one automatically
|
---|
| 279 |
|
---|
| 280 | ASAP> list_scan
|
---|
| 281 | ----> list_scans()
|
---|
| 282 | The user created scantables are:
|
---|
| 283 | ['av', 'q1', 's2', 'scans', 'q2', 's', 'ss', 'r1', 'r2', 's1']
|
---|
| 284 |
|
---|
| 285 | ASAP> del s1
|
---|
| 286 | ASAP> del s2
|
---|
| 287 | ASAP> del q1
|
---|
| 288 | ASAP> del q2
|
---|
| 289 |
|
---|
| 290 | ****************
|
---|
| 291 | * Builtin help *
|
---|
| 292 | ****************
|
---|
| 293 |
|
---|
| 294 | All asap functions have built-in documentation. To get a summary of
|
---|
| 295 | all functions use
|
---|
| 296 |
|
---|
| 297 | ASAP> commands
|
---|
| 298 |
|
---|
| 299 | To get help on individual tasks use the help command. For the Maths
|
---|
| 300 | functions do this as:
|
---|
| 301 |
|
---|
| 302 | ASAP> help quotient
|
---|
| 303 |
|
---|
| 304 | For the scantable or fitter functions use the syntax
|
---|
| 305 |
|
---|
| 306 | ASAP> help scantable.set_freqframe
|
---|
| 307 | ASAP> help fitter.set_scan
|
---|
| 308 |
|
---|
| 309 | **NOTE** If you type "help" only, you get ipython help. To exit this mode
|
---|
| 310 | you need to type ^-d (control-d).
|
---|
| 311 |
|
---|
| 312 | * Notes
|
---|
| 313 |
|
---|
| 314 | - Only does one IF/Pol/Beam. Need to change cursor
|
---|
| 315 |
|
---|
| 316 |
|
---|
| 317 | ******************
|
---|
| 318 | * Worked example *
|
---|
| 319 | ******************
|
---|
| 320 |
|
---|
| 321 | commands
|
---|
| 322 | scans = scantable('2001-10-07_0337.rpf')
|
---|
| 323 | # data is auto-averaged
|
---|
| 324 | print scans
|
---|
| 325 | scans.set_restfreqs([90.663543], 'GHz')
|
---|
| 326 | scans.set_freqframe('LSRK')
|
---|
| 327 | r1 = scans.get_scan(0)
|
---|
| 328 | s1 = scans.get_scan(1)
|
---|
| 329 | r2 = scans.get_scan(2)
|
---|
| 330 | s2 = scans.get_scan(3)
|
---|
| 331 | q1 = quotient(s1,r1)
|
---|
| 332 | q2 = quotient(s2,r2)
|
---|
| 333 | del s1,s2
|
---|
| 334 | del r1,r2
|
---|
| 335 | plotter.plot(q1)
|
---|
| 336 | msk = q1.create_mask([100,500],[620,1024])
|
---|
| 337 | help scantable.average_time
|
---|
| 338 | av = average_time(q1, q2, mask=msk)
|
---|
| 339 | plotter.plot(av)
|
---|
| 340 | # reuse the old mask as data range hasn't changed
|
---|
| 341 | s = poly_baseline(av,msk,1)
|
---|
| 342 | plotter.plot(s)
|
---|
| 343 | ss = average_pol(s)
|
---|
| 344 | plotter.plot(ss)
|
---|
| 345 | ss.save('asap.test')
|
---|
| 346 |
|
---|
| 347 | f = fitter()
|
---|
| 348 | f.set_function(gauss=1)
|
---|
| 349 | f.set_scan(ss)
|
---|
| 350 | f.fit()
|
---|
| 351 | f.plot()
|
---|
| 352 | f.get_parameters()
|
---|
| 353 | ^d
|
---|