casacore
|
Modules | |
Measures_module_internal_classes | |
Internal Measures_module classes and functions. | |
a module for coordinates
See below for an overview of the classes in this module.
Public interface
The name Measure derives from physical measurements, i.e. values with units and possibly a reference frame attached.
The Measure model deals with measures (i.e. quantities with a reference frame). Measures are handled in the Measure section (see Measure.h).
Including the measures/Measures.h
will take care of all includes necessary for the handling of Units and Quantities, and the general Measure interface. For the use of individual Measures, the appropiate include files should be added. E.g. to be able to handle Directions, the following includes could be given:
An inclusion of the appropiate measure file, will also take care of the connected measure value (in this case MVDirection
). However, if only the value suffices, it can be included on its own (from the Quanta directory).
When doing actual conversions (see MeasConvert later on), by using the explicit Measure::Convert types, the description of the actual conversions (called MCmeasure, e.g. MCEpoch.h) should be included as well; in adition to general MeasConvert.h.
Measures are physical quantities within a certain reference frame. Examples are the Hour-angle and Declination of a source at a certain time and observatory; an Ra/Dec for a certain mean epoch; an apparent frequency at a certain time given in eV; a local sidereal time at an observatory.
Measures can be converted from one reference frame to another (and this possibility is its main reason for existence). A simple B1950-J2000 coordinate conversion example:
or converting an UTC to a local apparent sidereal time:
The examples show the use of the 5 major classes involved in Measures:
Each type of Measure has its own distinct class. Each is (weakly) derived from the Measure base class, and its name starts with an M. Examples are:
Others are being, or could be, considered.
Tip: The current set can be deduced from the class list at the end of the html version of this module description;
The main role of the Measure (and related) classes is to be able to convert an observed (or to be calculated) physical entity from one reference frame to another, e.g. a J2000 coordinate to galactic coordinates, or an TAI time to a local sidereal time (LAST). Simple unit conversions (e.g. an angle from mrad to deg), or calculations with values with attached units, are sufficiently catered for by the Quanta module classes.
Each measure has a value (MeasValue) and a reference (MeasRef). The values are in general measure specific, weakly derived from MeasValue, and named with an initial MV. Examples are:
MeasValue and the MV classes can be found in the Quanta module. In addition some other value classes, not directly used in measures, are available. Examples:
References are measure specific. Each specific reference class is called Measure::Ref (e.g. MEpoch::Ref
). It specifies the full reference frame of the specific measure, i.e. its type, an optional frame of measures (a MeasFrame, consisting of say a time and position), and an optional offset. It has at least a reference code (e.g. MDirection::B1950, MEpoch::LAST), with defaults for each measure (i.e. MDirection::J2000, MEpoch::UTC) if none specified.
In addition the reference can contain a reference frame (MeasFrame) to specify from when and/or where the measure was obtained or calculated.
A third optional element of the reference is an offset measure, which indicates the offset (e.g. a sidereal date) that has to be added to the value referenced before it is used.
Examples of some measures are:
Tip: In the above examples in general explicit MV values have been used to specified the measure's value; In many cases (depending on the actual measure) it can be omitted, and the data can be given directly to the measure constructor; See the constructors for the individual measures for details;
If the reference is simple (i;e; no frame and/or offset) the Measure::Ref can be omitted, and only the code has to be specified;
A MeasFrame is a container for specifying Measures needed to describe the circumstances under which the measure was observed (or for which it has to be calculated). E.g. the position on Earth (an MPosition) is necessary for sidereal time and coordinates like HA/Dec and Az/El; the time (MEpoch) is necessary for non-standard coordinates (apparent, mean, HA/Dec etc); the coordinates (MDirection) for radial velocities; etc.
Although quite often the value has to be in a specific format (e.g. TBD for precession calculations; astronomical longitude for the LAST), the frame values can be given in any known reference format: conversion to the appropiate type will be done automatically if and when necessary.
Frames (and references) are never copied, but act always as containers with shallow copying only (i.e. copied frames will point to identical instances, and changes made in one copy will be visible in all others. This means, e.g., that in the following:
the two frames will be identical, and a change to one means a change to the other. Furthermore, only the information needed for a specific calculation will be used (and calculated). This means that one frame can be used specifying all of e.g. the position (which will probably stay the same for a series of calculations) and time; with the time being set() (if also the reference of the epoch changes) or resetEpoch() (if only the value changes, but the reference and its frame stay the same). A change in the frame will influence automatically any calculation (e.g. conversion to LAST) of which it is part.
The value of a measure (in MV format) can be obtained with the getValue() member function. The value in a variety of formats and units can be obtained with a (specific Measure dependent) series of get() members of both the MV-value and the Measure.
Measures in themselves are not really necessary for proper data reduction and the like. Its real value is the ability to transform a Measure from one reference type (and frame, offset) to another.
Conversion of a measure of a certain kind from one reference to another is done with the aid of special, measure specific, MeasConvert classes. Each conversion class is called Measure::Convert (e.g. MDirection::Convert). A conversion generates from an input reference (or an input measure) and an output reference a conversion functional, that can be used to convert specific values.
Example:
The same could have been done by only setting up the conversion engine, and not specifing the default value to be converted in the Convert constructor by:
Specifying the conversion engine separately, it can be re-used for other values:
A larger example. Say you have the J2000 coordinates for a source (RA=11 deg, DEC= -30 deg), and you want to observe it on May 17, 1996 (MJD=50220) at 8:18 UTC in a place with a Longitude of 150 deg (latitude of 20 deg) at 1000 m high, you could get the apparent RA,DEC, and the LAST at that time (you could also go straight to HA/DEC or so) with (I write the example longer than necessary to indicate the steps, and with explicit reference to MV values):
Some conversions need maybe some fine tuning (e.g. what is the acceptable interval for Nutation linear interpolation: could be different from the default interval; some time calculations will want to use the predicted IERS values rather than the actual determined; some Nutation will maybe use the IERS updates, some maybe the JPL DE databases).
The AipsrcValue class can be used to specify very specific parameters that are used to steer the conversion process beyond what is possible with just a list of measure reference types (that list is already long for some cases). Values, switches can be set()
(and removed) to change the default behaviour of the conversions. In general the user will only need to use the details in very specific cases. The details that can be used are described in the classes that provide calculations (e.g. Nutation), and in the aipsrc-data reference manual entry.
Some details about the different classes follows. In the examples often a specific measure value (e.g. MVEpoch, the MeasValue for MEpoch), or a specific measure (e.g. MDirection, a direction in space) is used. This is only to visualise the use, any other measure could have been used.
The MeasValue class derivatives are all named MVmeasure, e.g. MVFrequency, and represent the internal representation of the specific measure class. Details can be found in the Quanta module.
The Measure class derivatives are all called MMeasure. MDirection (a celestial direction), MPosition (a position on Earth), MFrequency (characteristics of electro-magnetic wave), MEpoch (an instance in time), MDoppler, MRadialVelocity MBaseline, Muvw, MEarthMagnetic, .
A measure has a value (kept in internal units in MVmeasure format) and a definition of the reference frame (MeasRef) of the value. The reference is optional, and will default to Measure::DEFAULT.
All measures have a set of standard constructors:
But also some special ones (e.g. two Quantities for MDirection to specify two angles) depending on type. The MeasRef can be omitted (will then be defaulted to Measure::DEFAULT, e.g. MEpoch::DEFAULT); can be specified as a full reference as a Measure::Ref (e.g. MDirection::Ref) type; or as a simple reference as Measure::TYPE (e.g. MDirection::J2000).
The individual elements of a Measure (i.e the MV value and the reference) can be overwritten (or set) with the set()
methods.
get()
methods (in general get(unit)
to return the internal value in some specified unit as a Quantum; and methods like getAngle()
for e.g. MDirection) enable the user to obtain the value of the measure.
A String tellMe()
will tell the type of Measure; a void assured(String)
and Bool areYou(String)
will check the type; while a String showType(Measure::TYPE)
will return the string value of a reference type code (e.g. J2000).
Recall that a Measure is a value with a reference specified. The MeasConvert engines enable you to convert it into another Measure, with a different reference (e.g. from J2000 to AZEL). The different get() methods (either directly, or indirectly using additional MV get() functions, or Quantum conversion methods, can convert the internal value into a value (or values) with user preferred units.
For reasons of speed (and safety) the allowed reference types for each Measure are enumerated in each measure class. The different reference types for MDirection are, for example:
The MEpoch has a special reference type (MEpoch::RAZE
) that can only be used in conjuncion with another reference type (e.g. MEpoch::UT1+MEpoch::RAZE)
. The meaning is: if a measure with such a reference type is converted to another reference type (say MEpoch::LAST
) the resultant (sidereal time) instance will be razed to an integer number of days; hence providing an easy way to specify sidereal times offset with the beginning of the current sidereal day.
To aid with external data, a Bool giveMe(String, uInt)
will give the correct reference type to be used given the String type. Note that the uInt, rather than the corresponding enum is used, due to templating restrictions in some compilers.
The correct reference (MeasRef) and conversion (MeasConvert) class for each Measure (a frequency cannot be converted into an epoch) are templated, and have specified (and to be used) typedefs: Measure::Ref and Measure::Convert (e.g. MEpoch::Ref, MEpoch::Convert). In addition, Measure::MVType and Measure::MCType are defined for all measures.
In the current implementation, no errors are attached to a Measure. In the original design errors were foreseen, but up till now they have been left out.
The addition of errors is in principle an easy process. They could be attached to either a Measure (as an additial MV value), or the MV's could be expanded to include errors (my preferred option at the moment). An MV being converted will then automatically have its error converted as well.
Before implementing, however, I think it would be worthwhile to look at the whole area of error handling. The easiest way would be to introduce for each of the defined Casacore standard values a corresponding E class (EDouble, EInt, EComplex, EuInt etc), and have all mathematical and logical operators that are defined for the standard classes be defined for the E-classes as well. It would then be easy to introduce errors everywhere.
A MeasFrame is a container with the instance of time (an MEpoch) and/or the position (an MPosition) for a measure reference. (Other Measures, like MDirection and MRadialVelocity are sometimes needed as well). MeasFrames are never actually copied, but only referred to (shallow copy) , so they can be used for all different types of measure reference. They are only necessary, but then essential, if the reference type does not fully specify the frame (like e.g. MDirection::J2000, or MEpoch::TAI do). Examples are the position necessary to go to MEpoch::LAST, the epoch necessary to go to MDirection::APP, the epoch and position necessary to reference an MDirection::AZEL.
A MeasFrame can be constructed empty (and used in references, as long as it is filled properly at the time of an actual conversion), or with one or Measures already defined with: MeasFrame frame(a_Measure,...)
. It can be filled, or re-filled, with set(a_measure,....)
.
The conversion routines use different values of the frame values given (e.g. the precession and nutation will need the epoch in TDB time, the hour-angle constructor local apparent sidereal time, which needs the astronomical longitude etc.). For that reason the specification of an epoch or position in either the constructor or the set() will create conversion engines for conversion of the input measure to all appropiate values that can be asked by the conversion routines. Note that the actual conversion is only done when that value is requested (and is then saved for later use). It is, therefore, safe and probably good practice to have one frame in a certain conversion environment, filled with as much info as is needed at that stage.
To aid and speed up, resetEpoch()
and resetPosition()
methods are available. As arguments they accept the corresponding MV or a variety of Double and Quantum arguments to reset the value of the corresponding frame measure only. In that case the conversion engine won't be redesigned, leading to fast recalculation when necessary, since e.g. nutation values could be re-used.
In an observing environment you could hence setup a proper frame with the Observatory position, and an observing day offset (see MeasRef) time; and do resetEpoch() to update the time if and when necessary.
A MeasRef is a measure specific container (and its class reference is Measure::Ref
, e.g. MFrequency::Ref
) with the measure reference type (e.g. MEpoch::UTC
), an optional (but in some cases necessary) MeasFrame (e.g. to specify where the sidereal time was determined), and, just for convenience, an optional offset (e.g. the MJD for which the time specified in the MEpoch referenced is valid). Note that if no frame or offset is necessary, the Measure::TYPE
can be used everywhere where a Measure::Ref
is needed.
A MeasRef is never copied (all copying and so is done by referencing). This means, for example, that if a specific MeasRef is part of the MEpoch definition for an epoch that is part of a MeasFrame, and you chnage that MeasRef, the change will automatically occur wherever that MeasRef is used (as e.g. in the frame). In most cases that is the expected response, but you should be aware of it, and not re-use a MeasRef for a completely different purpose.
A simple example:
A slighty more involved example, written out a bit:
The reference type can be set with a set() function, and set() functions for the offset and frame will be present as well.
A Bool empty()
checks if the reference is empty; get()
functions provide the information in the reference; and a String showMe()
will return the type of measure (e.g. "Epoch") the MeasRef can be used for.
The MeasConvert class converts Measures from one reference type and frame to another. It gathers all relevant information and analyses it to have fast multiple conversions. The MeasConvert classes are Measure specific, and should be used with the class names Measure::Convert
(e.g. MFrequency::Convert
). The () operator will do the actual conversion; constructors and set() methods will only fill the information necessary to do the conversion. MeasConvert is a non-copying container.
To set up the conversion engine, the MeasConvert object has to know the input data reference (remember the MeasRef contains information about the type, the possible reference frame and a possible offset), and an output reference. Using these references it will communicate with the appropiate Measure class to set up a series of routines that have to be executed in order to attain the goal. (Note that if the input and output reference both define a frame, but different ones, e.g. because you want to convert a sidereal time at one place to a sidereal time at another place, the conversion machinery will always first go to the proper default (UTC in this case), and then go to the goal).
The actual conversion need a value to be converted, and it also can use a default Unit, so that if your frequencies are in nm, you can once specify that they are nm, and then simply convert a Double.
This means that the optimal constructor for a MeasConvert is:
The actual constructors present include ones with the first argument only an input reference, rather than a full Measure. However, in all cases an empty or partial one can be constructed, with set() functions filling in the rest. The conversion engine is only (re-)setup if at least an input and output reference can be found.
After setting up the conversion engine, the () operator can be used with a variety of values to return a converted Measure. Possibilities are:
A simple example to output the J2000 coordinates for a B1950 input (RA=20 deg, DEC=-10 deg):
In this example everything is done in one go (the () at the end does the conversion). Another example, to have a UTC to LAST converter:
For specific purposes it would be very easy to set up a series of simple classes, that would do standard conversions.
A series of help classes are present to aid in the conversion, especially caching information. They are of no direct use for the end user (except maybe a few constants in MeasData).
The classes are:
The Measures module originated to be able to convert ccordinates between different reference frames.