*Please note Middle European Time (MET) is -2:00 GMT | |||||||||||||||||||||||||||||||||||||||||||||||||
August 1998 | |||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
Pulsar Data in AIPS++ Rick Fisher - NRAO, Green Bank The AIPS++ tool-box offers the possibility of analyzing pulsar data for time of arrival, flux density, profile shape, dispersion, and other parameters of interest. I have used it look at pulsar data from the 140-ft spectral processor using Glish routines and my own solar system ephemeris client (also see The Glish Software Bus in this issue of the Newsletter to see an example of how to implement Glish clients). This note is a brief description of how you can build your own pulsar analysis scripts in Glish. Some of the functions that I originally wrote in Glish are now available as faster C++ modules in AIPS++. This is often a good migration path for new routines because Glish is a reasonably powerful mathematics engine by itself. Eventually, we'd like to add pulsar analysis to the single dish part of AIPS++ with a proper GUI and other support. In pulsar timing mode the spectral processor's output is a set of 2-D matrices of intensity as a function of sky frequency and pulsar phase with one matrix for each receiver channel. Feel free to contact me for the details on how to create an AIPS++ table from the spectral processor FITS files, but for this example let's assume that one matrix and the necessary header information has been loaded into Glish variables as follows: data matrix of 256 frequency channels by 128 time bins utcstart UTC time of the leading edge of the first time bin in seconds mjd modified Julian date that goes with utcstart phasetime spacing or width of time bins in seconds freqres spacing of frequency channels in Hz ctrfreq sky frequency of the center of frequency channel 129, where the channel numbers run from 1 to 256 dispmeas pulsar dispersion measure in parsec/cm^3 rfsideb R.F. sideband, 0 = upper, 1 = lower ifsideb I.F. sideband, 0 = upper, 1 = lower template an array of 128 bins which contains the pulsar's profile template First, we do a rough normalization of the data by dividing each frequency channel column by the average power in that column. This removes the receiver passband shape to first order.
- for (ch in 1:data::shape[1]) { - avg := sum(data[ch,]) / data::shape[2] - data[ch,] /:= avg - } Now, if you display the normalized 2-D array, you will see the pulse in the frequency/pulse phase plane. If there is much dispersion at the observed frequency, the track will be a diagonal across the image.
- dd.array(data) To dedisperse the pulse each frequency column must be shifted in time to line up with the center frequency column. The amount of shift depends on the dispersion measure, center frequency, frequency offset, and time bin width. The shift operation is done with the AIPS++ mathematics module FFT server's shift function. This shift is actually an array rotation, which is what we want.
- fftserv := fftserver() - dm_coef := 0.0041494 * dispmeas - one_over_cf_sq := 1.0e18 / ctrfreq^2 - freq_step := freqres - if (rfsideb != ifsideb) freq_step := - freq_step - for (ch in 1:data::shape[1]) { - ch_offset := as_double(ch - (data::shape[1] / 2) - 1) - freq := ctrfreq + (freq_step * ch_offset) - time_shift := dm_coef * ( 1.0e18 / (freq^2) - one_over_cf_sq) - bin_shift := -time_shift / phasetime - data[ch,] := fftserv.shift(data[ch,], bin_shift) - } Now, to look at the pulse profile all we need to do is sum the frequency bins in each time bin row.
- profile := array(0.0, data::shape[2]) - for (bin in 1:data::shape[2]) { - profile[bin] := sum(data[,bin]) / data::shape[1] - } - dp.ploty(profile, style_='lines') The pulse arrival time can be found by cross-correlating the dedispersed profile with the profile template.
- cc := fftserv.crosscorr(profile - 1.0, template) - dp.ploty(cc, style_='lines') Then solve for the time of the cross-correlation peak offset by fitting a y-axis parabola through the three points nearest the peak
- nch := length(cc) - peak_ch := order(cc)[nch] - if ((ch := peak_ch - 1) < 1) ch := nch - y1 := cc[ch] - y2 := cc[peak_ch] - y3 := cc[(peak_ch % nch) + 1] - k := (y3 + y1 - 2.0 * y2) / 2.0 - x0 := (y1 - y3) / (4.0 * k) + peak_ch - 1.0 and then add that time offset to the UTC of the beginning of the data array to get the pulse time of arrival.
- toa := utcstart + x0 * phasetime - if (toa = 86400.0) { - toa -:= 86400.0; - mjd +:= 1; - } - print 'TOA: MJD', mjd, 'UTC', toa, 'seconds' This time of arrival may then be corrected to the solar system barycenter for comparison with other measurements of the same pulsar. The JPL solar system ephemeris will soon be part of the AIPS++ measures module with a function that returns the barycenter delay. In the meantime you are welcome to use the Glish client ephemeris, that I wrote for this purpose, as described in http://www.gb.nrao.edu/~rfisher/Glish/solar_system.html. I have also written a Glish script that elaborates on this code using two AIPS++ tables containing pulsar data. | ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
Project News Summary Tim Cornwell - NRAO, Socorro
The next, third, beta release continues to consume much of our time. We know that users are eagerly awaiting this release, and we'll be pleased to finally get it done. The response to the first release in February 1997 was substantial and we learned a lot about how users viewed the system. The second beta release in September 1997 elicited less comment, presumably because the incremental changes were small. Hence the main goal for the third release is to make substantial improvements in user interface, functionality and documentation. Much of the necessary work has been completed and tested but we have still to complete the following:
We expect these to be largely completed in August or September 1998, and the third beta release will occur soon after. If no large new changes are required, a fourth beta will follow within 3-4 months, and then a first public release some time in the first half of 1999. Our main concern is with the user interface. If this is seen to require more work, then the first public release will be further delayed. | ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
Programmer's Corner - Part 3 Brian Glendenning - NRAO, Socorro We now will finish our example of using Glish to convolve planes of any orientation from an image of any shape. This chapter is somewhat more involved than the previous segments (Part 1, Part 2). To recap, how do you loop over all planes of the image (that is, set up blc and trc appropriately so that you can call the getchunk method of image)? Let's suppose for the sake of argument that you have a cube with a shape [512,512,4,128]. A cube like this might be a spectral line image cube with full polarization, i.e. RA,DEC,POL,FREQ, and 128 frequency channels. If you are interested in getting at the RA,DEC planes from the image, then you need to generate the following series of BLC and TRC values:
BLC (RA,DEC,POL,FREQ)| TRC (RA,DEC,POL,FREQ) =========================================== 1,1,1,1 | 512,512,1,1 1,1,2,1 | 512,512,2,1 1,1,3,1 | 512,512,3,1 1,1,4,1 | 512,512,4,1 1,1,1,2 | 512,512,1,2 ... | ... 1,1,3,128 | 512,512,3,128 1,1,4,128 | 512,512,4,128 How can you do this? First, let's note that you can index into a Glish array with both a scalar and array. For example:
- a := 1:5
Indexing with an array is just like looping over all indices in that array, however it is considerably faster and more concise. Besides indexing with an array of "indices", you can also index with a mask, which is an array of booleans. Array values are kept only where the mask is True. For example:
- a := 1:5 Since the logic of incrementing an index is kind of complicated, let's put it into a function called bump:
bump := function(where, shape, axis=1) { where[axis] +:= 1; if (where[axis] shape[axis] && axis < length(shape)) { # If we are beyond the end of the current axis, set it to one and # ancrement the next axis. where[axis] := 1; return bump(where, shape, axis+1); } else { return where; } } In the example, shape is [4,128] and where runs from [1,1] to [4,128]. Note that this is an example where it is somewhat easier to write the function using recursion. Now you can finally write a loop to go through all planes of the image:
while (!any(blc[mask] > lengths[mask])) { #1 pixels := im.getchunk(blc,trc); #2 # ... convolve as before ... #3 blc[mask] := bump(blc[mask], lengths[mask]); #4 trc[mask] := blc[mask]; #5 } The following steps are accomplished with this Glish code.
That's it for this article and series. I had intended to move next into GUI programming and other advanced topics. However, as was announced in the last AIPS++ Newsletter, I have moved to the MMA project, so I will bring this series to a halt, at least for the moment. | ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
The Glish Software Bus
Darrell Schiebel - NRAO, Charlottesville
Glish's vector oriented command language is very powerful. A large portion of AIPS++ is written in Glish. The language has arrays, records, and all of the basic types. However, it is not the Glish scripting language which makes Glish unique, but rather the underlying "software bus". I would like to close out this series of articles on the "Story of Glish" by discussing Glish's software bus in a little more detail. Because of its roots as software for controlling distributed physics experiments, Glish has a very flexible event transport layer integrated into the language. This integration of distributed control makes Glish unique. Few other languages attempt this level of process control. CORBA (Common Object Resource Broker Architecture) and other libraries are now attempting to make this sort of control functionality available, but they were not available when AIPS++ adopted Glish. Glish can start programs, called clients, on either the local host or remote hosts, and then interact with these programs. Clients are "plug-compatible" because of the way they can accept and generate events. Glish controls clients by sending events to them. An event is simply a name plus a value. By limiting the interaction between Glish and the clients to a series of discrete events, it is easy to substitute one client for another. As long as the new client accepts the same events, the substitution can be made without affecting Glish or the other clients. The clients are an encapsulation of a particular functionality. For AIPS++, clients are typically written in C++. The following is a simple example which returns the current time. The source code for this client looks like: int main( int argc, char** argv ) { Client c( argc, argv ); timeval tval; for ( GlishEvent* e; (e = c.NextEvent()); ) { if ( ! strcmp(e-Name(),"time") ) { if ( gettimeofday( &tval, 0 ) <0 ) c.Error( "couldn't get current time" ); else if ( e->IsRequest() ) c.Reply( ctime( &tval.tv_sec ) ); else c.PostEvent( "result", ctime( &tval.tv_sec ) ); } else c.Unrecognized( ); } return 0; } The client class is the connection which C++ clients use to communicate with the Glish interpreter. The NextEvent()function is used to get events as they are sent from the interpreter. In this case, the client has a loop for accepting events. NextEvent()returns a null pointer when the client should exit. Reply(), PostEvent(), Error(), and Unrecognized() are all member functions of client, and they are used to send events back to the Glish interpreter.
In Glish, the use of this client (if compiled into an executable called time_client) looks like:
- x := client('time_client') With the print statement, Reply() is invoked in time_client because the Glish interpreter is waiting for a reply. In the next statement, another time event is sent to the client. In this case no result is needed, so the interpreter continues, and later receives the result event generated in the time_client by the call to PostEvent(). The Error() member function of Client is to indicate that an error has occurred, in this case due to a problem with gettimeofday(). The Unrecognized()member function is called to indicate that the event received has an unrecognized event name, in this case any event name other than time. Once created, clients greatly enhance the capabilities of Glish. This is the mechanism through which much of the functionality of the AIPS++ libraries, written in C++, is made available to Glish. These clients can run transparently on local or remote machines. The resources provided by each of the clients can be utilized and combined in Glish scripts to solve complicated problems in ways unanticipated by the authors of the individual clients. This sort of flexibility and plug-compatibility is achieved because each client has a well-defined interface. Separate processes do a nice job of enforcing encapsulation. Existing stand-alone programs can be made into Glish clients by adding the C++ code necessary to generate the events by which Glish and the "program" initiate and return results. | ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
Recipe of the Month - Glish Matrix Operations Doing Least Squares Fitting with Error Analysis Bob Hjellming - NRAO, Socorro
Some of the advanced mathematical operations in Glish are in packages like matrix and mathematics. In this recipe we show how you can read in a table of (x,y) data and do least squares fitting to these data with complete error analysis including not only estimation of the errors in the polynomial coefficients, but also computation of the covariance matrix and correlation coefficients. This is also an example of using a matrix object to carry out matrix operations.
Click on image to obtain larger view
Contributions of recipes or other material for a prototype AIPS++ Cookbook are welcome. Please send to rhjellmi@nrao.edu. | ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
What's New in AIPS++ Athol Kemball and Tim Cornwell - NRAO, Socorro The following personnel changes have occurred in the AIPS++ Project:
The following changes have been made in AIPS++:
| ||||||||||||||||||||||||||||||||||||||||||||||||
Pulsar Data in AIPS++ |
Dan Briggs: A Professional Remembrance
Tim Cornwell- NRAO, Socorro We were shocked and saddened by the tragic news that Dan Briggs of the NCSA/BIMA AIPS++ group was killed in a sky-diving accident on July 4. Dan was well-known to many of us as a colleague and friend. Dan's many friends have put together a memorial page that you can find at http://www.nmt.edu/~pio/dbriggs/ This memorial page describes Dan's attitude towards life and many personal accomplishments. Here I'd like to say something about my memories of his professional career. I'd personally known Dan for a long time in a number of different roles: as a stilt-walker in Socorro parades, as a student at New Mexico Tech, as my Ph.D. student in the early 90's, and then as a collaborator and colleague within AIPS++. He came to Socorro as a graduate student in physics after completing degrees in physics and mathematics at Caltech. My first contact with him was to see him walking on stilts in a parade in Socorro, a picture that is accessible from his memorial page. In the late eighties, he began spending time at NRAO, working with Rick Perley and then Craig Walker on different projects. He eventually came to me to ask about doing a Ph.D. on radio-astronomical imaging, something that I readily agreed to once I realized his great range of talents. For his Ph.D., and then later on in his career, he worked as what I would call a technical radio-astronomer, interested more in the techniques of astronomy rather than the results. Dan had an excellent combination of attributes for a researcher: great basic intelligence, varied technical skills, persistence, a judicious amount of perfectionism, and an enormous appetite for hard work. His Ph.D. from New Mexico Tech, which was overseen by myself and Jean Eilek, showed the quality of work that he was capable of producing (his thesis is available on the web at http://www.aoc.nrao.edu/ftp/dissertations/dbriggs/diss.html). It covers the image processing of moderately resolved sources observed with radio-interferometric arrays. It's a stunningly complete piece of work, in which each substantive assertion is carefully described, analyzed and demonstrated. It contains two things that deserve to be called by his name. First, an analysis of the effect whereby deconvolution errors on moderately resolved sources can masquerade as calibration errors. Second, a new form of weighting, which he called robust weighting, whereby resolution and sidelobe-level could be traded one against the other, thus obtaining a compromise of improved resolution and signal-to-noise which optimizes the use of telescope time. Robust weighting was immediately recognized by others as a very useful technique and has been adopted in many reduction packages. In recognition of Dan's contribution, it has been suggested that the term Briggs' weighting to be used in place of robust weighting. After his Ph.D. was completed in Socorro, Dan moved to Washington, D.C., to work at the Naval Research Lab as a postdoc, first on the Big Optical Array, and then on low-frequency imaging with the VLA (in collaboration with Namir Kassim, Kurt Weiler and others). In the latter work, Dan developed an existing, limited package for wide-field imaging from VLA B-configuration 327 MHz data into a well-engineered, very capable package for A-configuration data, that could run in a reasonable amount of time on a parallel machine. This exploited many of his skills: understanding of the physics and mathematics, expertise at meeting the complicated computing requirements, and appreciation of the resulting science.
Following his time at NRL, he moved on to work with the NCSA/BIMA group
on parallelization of code, and he was just starting to implement wide-field
imaging in |