Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
Version 1.9 Build 1556 |
|
Wim Brouw
20 May 2000
A postscript version of this note is available (220kB).
This guide gives a short overview of the background and use of the Measures module in C++. Detailed information can be found in the Measures module description, and in the individual header files of the classes in this module.
Section 2 explains what a Measure consists of, and why; section 3 discusses conversion; section 4 some notes on efficient use and section 5 gives the common interface of Measures and their values. Appendices give some details per Measure.
Currently the following measures exist:
A specific Measure class is indicated with an M, e.g. a direction measure is an MDirection.
A Measure consists of a VALUE and a REFERENCE. The VALUE of a Measure is a vector of double floating point numbers, in some internal format, independent of the units used to create them. The VALUE is called a MeasValue, and specific ones are indicated with the letters MV, e.g. MVDirection 1. Appendix A gives the various internal values.
A VALUE can be constructed in many different ways. An MVDirection can, e.g. be constructed from 2 angles or from 3 direction cosines; an MVFrequency from a wavelength or the wave energy.
Some Measures can often also be obtained from a catalog, especially a list of
observatories, a source list and a spectral line list. They can be
obtained as:
MDirection source; MFrequency line; MPosition obs; if (MeasTable::Observatory(obs, "ATCA")) {}; if (MeasTable::Line(line, "HI")) {}; if (MeasTable::Source(source, "0008-421")) {}; |
The REFERENCE consists of up to 3 fields:
A REFERENCE is created as a specialized MeasRef object, using the
Measure::Ref alias (e.g. MDirection::Ref). A full
reference could be:
// A time in MJD MEpoch epoch(Quantity("50500.5d"), MEpoch::UTC); MPosition obs; MeasTable::Observatory(obs, "WSRT"); MeasFrame frame(obs, epoch); MDirection::Ref ref(MDirection::VENUS, frame); |
Example:
MDirection::Convert(MDirection::Ref(MDirection::VENUS, frame), MDirection::Ref(MDirection::J2000)); |
Note that if a frame is necessary, it suffices to give it with either one of the two REFERENCES. Unless, of course, they are different for the two REFERENCES, like converting the AZEL at one telescope to that at another. The latter case (i.e. two different reference frames for the input and output values), is handled by always converting first the input value to the default for the class (e.g. J2000 for directions), and then convert this value to the appropriate output type and frame.
The from REFERENCE can also be specified as a complete Measure. In that case that VALUE of the Measure will act as the default VALUE to be converted.
Constructing a conversion object will set up a series of conversions that have to be done to get from the from to the to REFERENCE. This state-machine like approach is to be able to use less than the required odd 400 conversion routines for say 20 different allowable reference codes.
The conversion object is executed with the () operator. The actual conversion done depends on the argument of the operator:
If the conversion needs information, it will cache anything it calculates, either in the conversion object (like calculated Nutation), or in the frame (like e.g. the sidereal time of a frame MEpoch specified in UTC). This information will be re-used if possible and feasible in subsequent conversions with the same conversion object or using the same frame.
It is also worth noting that frames are handled internally by
reference rather than by value (e.g. when copied) (the
same is true for Measure::Ref objects). One consequence is that
a conversion knows about any change you make to a frame, and will use
it. So, if by a frame.set(MEpoch)
the time of a frame is
changed, a subsequent conversion which had that frame given as the
frame to be used, will automatically use the new time.
The efficiency of the use of the Measures and related classes can vary greatly. By using the appropriate interface, by fine-tuning with the aid of aipsrc variables, and by making sure the caching system is used optimally, there can be a large reduction in resource use.
It is not always necessary to use a full-fledged Measure. It often suffices to use a MeasValue (or maybe even a Quantity or just a simple Double.
As an example, consider a frequency container object:
As a rule of thumb the above could be summarised as:
Similar arguments can be used for the other Measures.
From the point of view of the programmer, a frame is just a container of Measures to indicate when, where, in what direction and at what frequency a certain Measure was made or referred to. However, in actual fact it is also an engine and cache for a lot of calculations. Imagine that you want to convert from right-ascension and declination to hour-angle and declination, and that you have provided an epoch in UTC in the frame. The actual conversion object will request (probably among other things), the sidereal time from the frame. The first request will set up a conversion object within the frame (from UTC to LAST) and cache it for later use. After that it will use this conversion object to obtain the sidereal time, and cache the result (for maybe a subsequent call). The conversion needs nutation, polar motion and a few other calculations. Again, all of these are cached for subsequent use in other calls to the frame for information.
Efficient use of Measures is only possible if the lifetime of a frame is as long as possible. Which suggests that in many cases a frame should be created at the highest level possible (maybe even globally). Re-use of a frame, e.g. for a different time, is made possible by the set() methods, e.g. set(MEpoch), which will try to minimize the re-calculations necessary. The fact that frames are always used internally by reference (see earlier), which also means that any change made to a frame will automatically be used by any subsequent conversion which knows about this frame, makes in principle for an efficient machinery for many different purposes. However, it could also easily lead to misunderstandings. If you plan to do any special conversions, the detailed information provided in the various Measure classes should be perused.
Similar to the frame discussed in the previous section, a conversion object (e.g. MDirection::Convert) is a repository of the necessary state-machine to make the conversion possible, and any intermediate calculation results. To make efficient use of this information, the same conversion object should be used if more than one conversion of the same type has to be done.
Although the official MeasConvert objects are very versatile, using them can be quite a job. For that reason a set of specialized ``Conversion engines'' have been put together for easy use. The three engines available at the moment are described in the following paragraphs. They have all a basic format:
The EarthMagneticMachine calculates the Earth' magnetic field in a certain direction at a certain height above the Earth' surface.
The machine object's constructor needs in principle:
The () operator will produce the line-of-sight component of the magnetic field (see the header files for details). Other methods exist to get the complete magnetic field; the longitude of the point specified and the position on Earth of the point. The following example calculates the magnetic field at 200km height at the Compact Array:
// Define a time/position frame MEpoch epo(MVEpoch(MVTime(98,5,16,0.5).day())); MPosition pos; MeasTable::Observatory(pos, "ATCA"); MeasFrame frame(epo, pos); // Note that the time in the frame can be changed later // Set up a machine EarthMagneticMachine exec(MDirection::B1950, Quantity(200, "km"), frame); // Given a current observational direction MDirection indir(Quantity(3.25745692, "rad"), Quantity(0.040643336,"rad"), MDirection::Ref(MDirection::B1950)); // The field in this direction is calculated exec.calculate(indir.getValue()); // Show some data cout << "Parallel field: " << exec.getLOSField() << " nT" << endl; cout << "Sub-ionosphere long: " << exec.getLong("deg") << endl;
The () operator has an MVFrequency, an MVDoppler or a Quantity as argument. Depending on if it is a velocity or a frequency, the argument is converted to the other representation. makeFrequency and makeVelocity exist to create a vector of velocities or frequencies from a vector of Doubles.
An example:
// Define a time/position frame MEpoch epo(MVEpoch(MVTime(98,5,16,0.5).day())); MPosition pos; MeasTable::Observatory(pos, "ATCA"); MeasFrame frame(epo, pos); // // Note that the time in the frame can be changed later // Specify the frequency reference MFrequency::Ref fr(MFrequency::LSR); // // Specify the velocity reference MDoppler::Ref vr(MDoppler::OPT); // // Specify the default units Unit fu("eV"); Unit vu("AU/a"); // // Get the rest frequency MVFrequency rfrq(QC::HI); // // Set up a machine (no conversion of reference frame) VelocityMachine exec(fr, fu, rfrq, vr, vu, frame); // // or as (with conversion of reference frame it // could have been) // VelocityMachine exec(fr, fu, rfrq, MFrequency::TOPO, // vr, vu, frame); // Given a current observational frequency of // 5.87432837e-06 eV // its velocity will be (in AU/yr) cout << "Velocity: " << exec.makeVelocity(5.87432837e-06) << endl; // // Introducing an offset MFrequency foff(MVFrequency(Quantity(5.87432837e-06, "eV")), MFrequency::LSR); // // and setting it in the reference, and regenerating // machine: fr.set(foff); exec.set(fr); // // the following will give the same result: cout << "Velocity: " << exec.makeVelocity(0.0) << endl;
The UVWMachine can convert UVW-coordinates between coordinate systems. In addition it can provide the phase rotation necessary on the data to have a new fringe-stopping center. A simple conversion of UVW coordinates will be executed if only the coordinate reference frame is changed (e.g. from a J2000 to a Galactic or an AzEl coordinate system). If also the actual position on the sky is changed, the phase rotation necessary on the data is provided as well. Fringe stopping centers can be centered on other bodies as well (e.g. a planet). Read the caveats in the detailed help file.
The constructor of the machine needs the following input:
The output of the machine can be one or all of the following:
Example:
// Given a current phase stopping Center MDirection indir(Quantity(3.25745692, "rad"), Quantity(0.040643336,"rad"), MDirection::Ref(MDirection::B1950)); // Conversion to J2000 is set by: UVWMachine uvm(MDirection::Ref(MDirection::J2000), indir); // The rotation matrix to go to new UVW is obtained by: RotMatrix rm(uvm.rotationUVM()); // If an UVW specified: MVPosition uvw(-739.048461, -1939.10604, 1168.62562); // This can be converted by e.g.: uvw *= rm; // Or, alternatively, by e.g.: uvm.convertUVW(uvw);
The precision of a Measure conversion can be influenced by the use of aipsrc variables. The relevant variables can be found in the aipsrcdata section of the standard User Reference Manual. (see here). Changing the precision will influence the efficiency of the Measures conversion.
Parameters that can be used are, a.o., the length of periods over which computations can be re-used; if it is necessary to use IERS tables for precise calculation of time and polar motion, or that the simple model suffices.
A few examples:
Name | Description | Default |
measures.nutation.d_interval | interval in days over which linear interpolation of nutation calculation is appropriate | 0.04d |
measures.nutation.b_useiers | use the IERS Earth orientation parameters tables to calculate nutation | false |
measures.nutation.b_usejpl | use the JPL DE database (use measures.jpl.ephemeris to specify which one) to calculate nutation | false |
measures.measiers.b_notable | do not use the IERSeop97 or IERSpredict tables at all for calculations | false |
The interface to the different Measures have a large set of identical methods. Only when values are clearly related to a specific Measure (like e.g. a latitude) does the method to obtain not exist for e.g. a frequency. Constructors of Measures have often specializations (like one with a longitude and latitude for a direction), but they all have also standard ones. The standard ones are described in the Measures.h class description.
The various value that are contained in the Measure object can be obtained by the following calls:
General calls are available to obtain the information contained in the Measure::Ref object:
set() methods are available to fill in the fields in the Measure::Ref object.
Each MeasValue has methods to obtain the internal data in a standard way. Some have additional ones available when appropriate (like getLong()):
Vector<Double>
Vector<Double>
, depending on the dimension of the internal
value. The units of the value returned will be the internally used
ones (e.g. m for a position, s for a time.
Vector<Double>
. If a quantity, the default units are the
interanls one, but the output units can be selected as well.
The frame can be used as an automatic converter. An example could be
the automatic conversion to a sidereal time from a civil time (like
UTC). All conversions that are used internally by the various conversion
engines are available. Of course, the epoch should have been put into
the frame for it to be converted; and in this case also the position
should have been put into it. Available information from the frame:
// Get the epoch pointer (0 if not present) const Measure *const epoch() const; // Get the position pointer (0 if not present) const Measure *const position() const; // Get the direction pointer (0 if not present) const Measure *const direction() const; // Get the radial velocity pointer (0 if not present) const Measure *const radialVelocity() const; // Get the comet pointer (0 if not present) const MeasComet *const comet() const; // Get data from frame. // Only available if appropriate measures are set, // and the frame is in a calculating state. // <group> // Get TDB in days Bool getTDB(Double &tdb); // Get the longitude (in rad) Bool getLong(Double &tdb); // Get the latitude (in rad) Bool getLat(Double &tdb); // Get the position Bool getITRF(MVPosition &tdb); // Get the geocentric position (in m) Bool getRadius(Double &tdb); // Get the LAST (in days) Bool getLAST(Double &tdb); // Get the LAST (in rad) Bool getLASTr(Double &tdb); // Get J2000 coordinates (direction cosines) Bool getJ2000(MVDirection &tdb); // Get B1950 coordinates (direction cosines) Bool getB1950(MVDirection &tdb); // Get apparent coordinates (direction cosines) Bool getApp(MVDirection &tdb); // Get LSR radial velocity (m/s) Bool getLSR(Double &tdb); // Get the comet table reference type Bool getCometType(uInt &tdb); // Get the comet coordinates Bool getComet(MVPosition &tdb); // </group> |
In the above reference is made to the calculating state of the
frame. This state is set when the frame has been actively used by a
Measure::Convert engine (i.e. have at least one operator()
executed); or if you do it explicitly with:
MCFrame::make(frame);
.
More information on the different astronomical conventions and data
can be found in:
Time, Coordinates
Positions
Frequency, Doppler, Velocity
Magnetic field
Baseline, uvw
In the following some comments are made per Measure type. A list is given of the known reference codes, and the frame information necessary to convert from/to each code is indicated.
An epoch in time. Internally maintained as an absolute time as a Modified Julian Day (or a Greenwich Sidereal Date) in two
Double numbers. Formatting of an MEpoch (or any time
expressed in time or angle units) can be done with the MVTime
class.
MEpoch | ||
Code | Description | Frame info |
LAST | Local Apparent Sidereal Time | MPosition |
LMST | Local Mean Sidereal Time | MPosition |
GMST1 | Greenwich Mean ST1 | |
GAST | Greenwich Apparent ST | |
UT1 | ||
UT2 | ||
UTC | ||
TAI | ||
TDT | ||
TCG | ||
TDB | ||
TCB | ||
IAT | = TAI | |
GMST | = GMST1 | MPosition |
TT | = TDT | |
UT | = UT1 | |
ET | = TT | |
DEFAULT | = UTC |
A special code modifier MEpoch::RAZE exist. Its result is that after a conversion to a code with the RAZE bit set, the result will be truncated to integer days. Useful to find a sidereal time offset for a specific UTC date.
A 3-dimensional vector, especially a position on (or rather w.r.t. Earth). Internally represented as a Vector<Double>
with
assumed units of m, independent of the constructing units. Normally
given as a longitude, latitude and height (geodetic), or as a vector
with origin in center of Earth.
The internal value of the MPosition class (i.e. MVPosition) is also the base class for the contents of the other 3-dimensional position and direction classes:
MPosition | ||
Code | Description | Frame info |
ITRF | International Terrestrial Reference Frame | |
WGS84 | World Geodetic System | |
DEFAULT | = ITRF |
A 3-dimensional vector of unit length, indicating a direction, especially a direction in space (note that for the Solar system bodies the distance to the bodies is inherently known).
The solar system bodies' directions are virtual directions. They
have no value until explicitly converted to a real coordinate
system like J2000, AZEL, ...
MDirection | ||
Code | Description | Frame info |
J2000 | mean equator, equinox J2000.0 | |
JMEAN | mean equator, equinox epoch | MEpoch |
JTRUE | true equator, equinox epoch | MEpoch |
APP | apparent geocentric | MEpoch |
B1950 | mean equator, equinox B1950.0 | |
BMEAN | mean equator, equinox epoch | MEpoch |
BTRUE | true equator, equinox epoch | MEpoch |
GALACTIC | galactic coordinates | |
HADEC | topocentric HA/Dec | MEpoch MPosition |
AZEL | topocentric Az/El (N E) | MEpoch MPosition |
AZELSW | topocentric Az/El (S W) | MEpoch MPosition |
AZELNE | = AZEL | MEpoch |
JNAT | geocentric natural frame | MEpoch |
ECLIPTIC | ecliptic for J2000.0 equator, equinox | |
MECLIPTIC | ecliptic for mean equator of date | MEpoch |
TECLIPTIC | ecliptic for true equator of date | MEpoch |
SUPERGAL | supergalactic coordinates | |
ITRF | direction in ITRF Earth frame | MEpoch MPosition |
TOPO | apparent topocentric | MEpoch |
MERCURY | from JPL DE table | MEpoch |
VENUS | MEpoch | |
MARS | MEpoch | |
JUPITER | MEpoch | |
SATURN | MEpoch | |
URANUS | MEpoch | |
NEPTUNE | MEpoch | |
PLUTO | MEpoch | |
SUN | MEpoch | |
MOON | MEpoch | |
COMET | any solar-system body | MEpoch Table2 |
DEFAULT | = J2000 |
A 3-dimensional vector, indicating a direction with a length (but no
defined zero point). In principle they are identical to the MDirection directions. At the momemt the solar system bodies are not
a valid baseline direction, but that could change.
MBaseline | ||
Code | Description | Frame info |
J2000 | mean equator, equinox J2000.0 | |
JMEAN | mean equator, equinox epoch | MEpoch |
JTRUE | true equator, equinox epoch | MEpoch |
APP | apparent geocentric | MEpoch |
B1950 | mean equator, equinox B1950.0 | |
BMEAN | mean equator, equinox epoch | MEpoch |
BTRUE | true equator, equinox epoch | MEpoch |
GALACTIC | galactic coordinates | |
HADEC | topocentric HA/Dec | MEpoch MPosition |
AZEL | topocentric Az/El (N E) | MEpoch MPosition |
AZELSW | topocentric Az/El (S W) | MEpoch MPosition |
AZELNE | = AZEL | MEpoch |
JNAT | geocentric natural frame | MEpoch |
ECLIPTIC | ecliptic for J2000.0 equator, equinox | |
MECLIPTIC | ecliptic for mean equator of date | MEpoch |
TECLIPTIC | ecliptic for true equator of date | MEpoch |
SUPERGAL | supergalactic coordinates | |
ITRF | direction in ITRF Earth frame | MEpoch MPosition |
DEFAULT | = ITRF |
A 3-dimensional vector, indicating a UVW-coordinate.
Muvw | ||
Code | Description | Frame info |
J2000 | mean equator, equinox J2000.0 | |
JMEAN | mean equator, equinox epoch | MEpoch |
JTRUE | true equator, equinox epoch | MEpoch |
APP | apparent geocentric | MEpoch |
B1950 | mean equator, equinox B1950.0 | |
BMEAN | mean equator, equinox epoch | MEpoch |
BTRUE | true equator, equinox epoch | MEpoch |
GALACTIC | galactic coordinates | |
HADEC | topocentric HA/Dec | MEpoch MPosition |
AZEL | topocentric Az/El (N E) | MEpoch MPosition |
AZELSW | topocentric Az/El (S W) | MEpoch MPosition |
AZELNE | = AZEL | MEpoch |
JNAT | geocentric natural frame | MEpoch |
ECLIPTIC | ecliptic for J2000.0 equator, equinox | |
MECLIPTIC | ecliptic for mean equator of date | MEpoch |
TECLIPTIC | ecliptic for true equator of date | MEpoch |
SUPERGAL | supergalactic coordinates | |
ITRF | direction in ITRF Earth frame | MEpoch MPosition |
DEFAULT | = ITRF |
A 3-dimensional vector: the value of the Earth' magnetic field. The
model used to calculate the field is the International Geomagnetic
Reference Field. The IGRF field is a virtual field, without
any value. It obtains its value after an explicit conversion to a
normal, real coordinate system.
MEarthMagnetic | ||
Code | Description | Frame info |
IGRF | the international reference field model | MEpoch MPosition |
J2000 | mean equator, equinox J2000.0 | |
JMEAN | mean equator, equinox epoch | MEpoch |
JTRUE | true equator, equinox epoch | MEpoch |
APP | apparent geocentric | MEpoch |
B1950 | mean equator, equinox B1950.0 | |
BMEAN | mean equator, equinox epoch | MEpoch |
BTRUE | true equator, equinox epoch | MEpoch |
GALACTIC | galactic coordinates | |
HADEC | topocentric HA/Dec | MEpoch MPosition |
AZEL | topocentric Az/El (N E) | MEpoch MPosition |
AZELSW | topocentric Az/El (S W) | MEpoch MPosition |
AZELNE | = AZEL | MEpoch |
JNAT | geocentric natural frame | MEpoch |
ECLIPTIC | ecliptic for J2000.0 equator, equinox | |
MECLIPTIC | ecliptic for mean equator of date | MEpoch |
TECLIPTIC | ecliptic for true equator of date | MEpoch |
SUPERGAL | supergalactic coordinates | |
ITRF | direction in ITRF Earth frame | MEpoch MPosition |
DEFAULT | = ITRF |
The MFrequency class describes the characteristics of an electro-magnetic wave. Internally the value is in Hz, but an MFrequency object can be constructed from any characteristic that is understood (period, frequency, angular frequency, wavelength, wave number, energy, momentum).
The MFrequency class has special methods to convert the frequency
from an MDoppler object, if a rest frequency is known.
MFrequency | ||
Code | Description | Frame info |
REST | spectral line rest frequency | MDirection MRadialVelocity |
LSR | dynamic local standard of rest | MDirection |
LSRK | kinematic local standard of rest | MDirection |
BARY | barycentric frequency | MDirection |
GEO | geocentric frequency | MDirection MEpoch |
TOPO | topocentric frequency | MDirection MEpoch MPosition |
GALACTO | galactocentric frequency | MDirection |
DEFAULT | = LSR |
The MRadialVelocity class describes the radial velocity of an
astronomical object. Internally the value is in m/s. Methods are
available (if the rest frequency of a spectral line is known), to
convert the velocity to a frequency. Also, the radial velocity can be
derived from an MDoppler object, which has the radial velocity
in the often better known redshift or radio-astronomical Doppler shift.
MRadialVelocity | ||
Code | Description | Frame info |
LSR | dynamic local standard of rest | MDirection |
LSRK | kinematic local standard of rest | MDirection |
BARY | barycentric frequency | MDirection |
GEO | geocentric frequency | MDirection MEpoch |
TOPO | topocentric frequency | MDirection MEpoch MPosition |
GALACTO | galactocentric frequency | MDirection |
DEFAULT | = LSR |
The MDoppler class describes the radial velocity of an astronomical object in a variety of special astronomical ``Doppler'' shifts. It can be generated from quasi velocities; or from a dimensionless quantity, interpreted as a fraction of the velocity of light.
Conversion to a ``real'' radial velocity is possible with this class.
In the following F stands for
/, where
is the
rest frequency.
MDoppler | ||
Code | Description | Frame info |
RADIO | radio definition: 1 - F | |
Z | redshift: -1 + 1/F | |
RATIO | frequency ratio: F | |
BETA | relativistic: (1 - F2)/(1 + F2) | |
GAMMA | (1 + F2)/2F | |
OPTICAL | = Z | |
RELATIVISTIC | = BETA | |
DEFAULT | = RADIO |