See below for an overview of the classes in this module.
Part of API
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:
#include <measures/Measures.h> #include <measures/Measures/MDirection.h>
MVDirection). However, if only the value suffices, it can be included on its own (from the Quanta directory).
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:
cout << // output // the conversion of a B1950 direction MDirection::Convert( MDirection( Quantity( 20, "deg"), Quantity(-10, "deg"), MDirection::Ref( MDirection::B1950)), // to J2000 MDirection::Ref( MDirection::J2000)) () // where the constructor sets up a conversion // engine, and the operator() converts << endl;
// Set up the model for the input (default reference is UTC) MEpoch model ( Quantity(0., "d")); // Set up the frame with the observatory position MPosition obs( MVPosition( Quantity( 10, "m"), Quantity( -6, "deg"), Quantity( 50, "deg")), MPosition::Ref(MPosition::WGS84)); Measframe frame( obs); // Set up the output reference MEpoch::Ref outref( MEpoch::LAST, frame); // Set up conversion MEpoch::Convert toLST( model, outref); // Output a series of sidereal times (formatted in ddd::hh:mm:ss) for (Double d = 12345; d<12346; d += 0.1) { cout << "Converted from UTC to LAST: " << d << " : " << toLST(d).getValue() << endl; };
The examples show the use of the 5 major classes involved in Measures:
Base Example Description
------ --------- -------------
Measure MEpoch has a value and a reference
MeasValue MVEpoch value
MeasRef MEpoch::Ref contains type, frame, offset
MeasFrame MeasFrame contains Measures describing frame
MeasConvert MEpoch::Convert contains conversion information and engine
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:
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:
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. // An instance of time expressed in days (MJD) in UTC MEpoch date(MVEpoch(Quantity(50237.29, "d")), MEpoch::Ref(MEpoch::UTC)); // which could also be expressed as: MEpoch date(Quantity(50237.29, "d"), MEpoch::UTC); // or using the default reference type: MEpoch date(Quantity(50237.29, "d")); // or as a time with an offset to a specific date: MEpoch date(Quantity(12.3, "h"), // time MEpoch::Ref(MEpoch::UTC, // reference with MEpoch(Quantity(50237, "d")))); // offset // A position of a telescope MPosition pos(MVPosition(Quantity(25, "m"), // height Quantity(20, "deg"), // East longitude Quantity(53, "deg")), // lattitude MPosition::WGS84); // reference type // Use this position in a frame MeasFrame frame(pos); // Specify an LAST (in MGSD) observed at this position: MEpoch last(Quantity(51000.234, "d"), // time and date MEpoch::Ref(MEpoch::LAST, // indicate LAST frame)); // and where observed // Maybe we know the MJD of the observed sidereal time, // but not its sidereal date. We could then specify it as an // offset to the beginning of the sidereal day in progress at // specified UTC MEpoch last(Quantity(13.45, "h"), // time MEpoch::Ref(MEpoch::LAST, // indicate LAST frame, // where observed MEpoch(51234, // MJD of today MEpoch::Ref(MEpoch::TAI + MEpoch::RAZE))); // where the RAZE indicates that the value will be truncated after // conversion. In this case it will be converted to LAST to be able // to add it as an offset to the specified LAST // // A direction (in RA/Dec) could be: MDirection coord(MVDirection(Quantity(54, "deg"), // RA Quantity(2034, "'")), // DEC arcmin MDirection::Ref(MDirection::J2000)); // J2000 type // If it were apparent coordinates, the time when observed should // have been known. We could just add it to the frame defined above, // and use it: frame.set(date); // add time to frame MDirection acoord(MVDirection(Quantity(54, "deg"), // RA Quantity(2034, "'")), // DEC MDirection::Ref(MDirection::APP, // apparent type frame)); // and when // If it was given in HA/Dec, the position should have been known // as well, but it is already in the frame, hence we could say: MDirection acoord(MVDirection(Quantity(54, "deg"), // HA Quantity(2034, "'")), // DEC MDirection::Ref(MDirection::HADEC, // type frame)); // when/where
MeasFrame frame1(MEpoch(50236.12));
MeasFrame frame2(frame1);
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 MeasureConvert (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:
cout << // output // the conversion of a B1950 direction MDirection::Convert( MDirection( Quantity( 20, "deg"), Quantity(-10, "deg"), MDirection::Ref( MDirection::B1950)), // to J2000 MDirection::Ref( MDirection::J2000)) () // where the constructor sets up a conversion // engine, and the operator() converts << endl;
cout << // output // the conversion of a B1950 direction MDirection::Convert(MDirection::Ref( MDirection::B1950), // to J2000 MDirection::Ref( MDirection::J2000)) // and use conversion on value (MVDirection( Quantity( 20, "deg"), Quantity(-10, "deg"))) // where the operator() converts << endl;
MDirection::Convert conv(MDirection::Ref( MDirection::B1950), MDirection::Ref( MDirection::J2000)); // We have some coordinates from somewhere, say coord(0:N-1): for (Int i=0; i<N; i++) { cout << "B1950: " << coord(i) << "= J2000: " << conv(coord(i)) << endl; };
// The observatory position. Note that the reference is geodetic position MPosition myobs(MVPosition ( Quantity(1, "km") , Quantity(150, "deg"), Quantity(20, "deg")), MPosition::WGS84); // The time I want to observe (note that it could be specified in many // other ways) MEpoch obstime(MVEpoch(MVTime(1996, 5, 17, (8+18./60.)/24.)), MEpoch::UTC); // The frame specification for when and where to observe MeasFrame frame(myobs, obstime); // The reference for a sidereal time (note the frame could be empty and // filled at the actual conversion time) MEpoch::Ref sidref( MEpoch::LAST, frame); // The reference for apparent coordinates: MDirection::Ref appref( MDirection::APP, frame); // The conversion engine for my time to LAST MEpoch::Convert tosid(obstime, sidref); // The conversion to sidereal time of obstime MEpoch sidtime = tosid(); // Conversion of UTC 10.8 h sidtime = tosid(MVEpoch(MVTime(1996, 5, 17, 10.8/24.))); // Show me some time cout << "LAST for UTC = 11:00: " << tosid(MVEpoch( MVTime( 1996, 5, 17, 11, 0))) << endl; // An offset reference (note the RAZE will keep only the integer part of // the day for the conversion result) MEpoch::Ref offtime(obstime.getValue(), MEpoch::UTC+MEpoch::RAZE); // The reference for a sidereal with respect to a specified offset (note // that it is automatically calculated into correct units) MEpoch::Ref sidoffref(MEpoch::LAST, frame, offtime); // Show the offset result cout << "LAST today: " << MEpoch::Convert(11., sidoffref)() << endl; // Coordinate conversion from J2000 cout << "Apparent coordinates: " << MDirection::Convert ( MDirection(Quantum(11,"deg"), Quantum(-30, "deg")), MDirection::Ref( MDirection::APP, frame))() << endl; // Handier to have the conversion engine available MDirection::Convert cvt( MDirection(Quantum(11,"deg"), Quantum(-30, "deg")), MDirection::Ref( MDirection::APP, frame)); // Set another frame time (note it is now sidereal, not UTC. The // frame will automatically convert it (using the frame again for // position) to TDB for precession etc calculations). frame.set(sidtime); // And look what same position is at this new time cout << "Next position: " << cvt() << endl;
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:
M(); // some default, e.g. pole directoon, time ==0)
M(MV, MeasRef);
M(Quantity, MeasRef);
M(Quantum<Vector<Double> >, MeasRef);
M(Vector<Quantity>, MeasRef);
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.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:
MDirection::J2000, MDirection::JMEAN, MDirection::JTRUE, MDirection::APP, MDirection::B1950, MDirection::B1950_VLA, MDirection::BMEAN, MDirection::BTRUE, MDirection::GALACTIC, MDirection::HADEC, MDirection::AZEL, MDirection::DEFAULT = MDirection::J2000
MEpoch::RAZE) that can only be used in conjuncion with another reference type (e.g. MEpoch::UT1+MEpochRAZE). 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.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.
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 aips++ 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:
MEpoch mytime(MVEpoch(50236.5), MEpoch::UTC);
// this will define a time in UTC on MJD 50236, 12 hours. The MVEpoch
// explicit conversion could be left out for most compilers, but some
// have trouble with automatic conversions.
// Another way of doing it would be to use Quantities, which have
// explicit constructors for all measures:
MEpoch mytime(Quantity(50236.5, "d"));
// Specify the location of the observatory (10m high, at given longitude // and latitude as geodetic position) MPosition obs( MVPosition( Quantity( 10, "m"), Quantity( -6, "deg"), Quantity( 52, "deg")), MPosition::WGS84); // If the current time is MJD50236, 12.3 h UTC, it could be specified as: MEpoch tim( MVEpoch( Quantity( 50236, "d"), Quantity( 12.3, "h"))); // Note the default reference // For this example we will also specify it as: MEpoch offtim(tim); offtim.set(MEpoch::DEFAULT+MEpoch::RAZE); // These two could define a frame MeasFrame frame(tim, obs); // Or maybe as (since observatory will stay put) MeasFrame frame1(obs); // and later addition of some time and its reference frame frame1.set(tim); // with a change to another time value at a later stage with frame1.resetEpoch( MVEpoch( Quantity( 50236, "d"), Quantity( 13, "h"))); // At this time we observe a sidereal time of 2.3 h. The actual instance // of time needs a sidereal date to specify, but we are too lazy to // look it up, hence we specify that this time has an offset, equal to // the sidereal time at offtim (which with the RAZE addition will be // converted to an integral number of days in whatever time it is // converted to) MEpoch mylast( MVEpoch( Quantity( 2.3, "h")), MEpoch::Ref( MEpoch::LAST, frame, offtim)); // Which specifies that we have a Local apparent sidereal time of 2.3 h // at the position specified by obs in the frame, at an offset offtim. // Note that the offset is given in UTC (and RAZE). Any conversion of // this mylast value to any other reference type, will always auto start // with a conversion of the offset to the current type (i.e LAST (with // the RAZE taking the integer part only)), and adding it to the value // given. Note that if an output reference has an offset, the resulting // value will be corrected for the specified offset as well.
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 first argument will give the input reference, and, if a Quantum is // used to make the Measure, the default units for inputs to the conversion. // It acts as a 'model' for subsequent input to be converted. // () operator Measure::Convert( Measure(Quantum), // the second argument gives the output reference Measure::Ref);
() // convert the value as specified in the 'model' (Double) // convert the value first to appropiate units (if they // were implicit in 'model' or explicitly set), and // then convert (Vector<Double>)// as Double (Quantity) // convert the full value, including its own units (Quantum<Vector<Double> >) // as Quantity (MeasValue) // convert the specified appropiate MV (Measure) // set up a new conversion chain, using the value as // 'model', and the old output reference, // and then convert (Measure, Measure::Ref) // set up a new conversion chain for the // 'model' given and the output reference given (Measure::Ref) // set up a new conversion chain using the old 'model' // and the output reference given, and convert the // existing model value
cout <<
MDirection::Convert( MDirection( Quantity( 20, "deg")
Quantity(-10, "deg"),
MDirection::Ref( MDirection::B1950)),
MDirection::Ref( MDirection::J2000)) () << endl;
// Set up the model for the input (default reference is UTC) MEpoch model ( Quantity(0., "d")); // Set up the frame with the observatory position MPosition obs( MVPosition( Quantity( 10, "m"), Quantity( -6, "deg"), Quantity( 50, "deg")), MPosition::Ref(MPosition::WGS84)); Measframe frame( obs); // set up the output reference MEpoch::Ref outref( MEpoch::LAST, frame); // Set up conversion MEpoch::Convert toLST( model, outref); // Output a series of sidereal times (formatted in ddd::hh:mm:ss) for (Double d = 12345; d<12346; d += 0.1) { cout << "Converted from UTC to LAST: " << d << toLST(d).getValue() << endl; };
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.
See the individual measures for appropiate examples.
Modules | |
| Measures_internal_classes | |
| Internal Measures classes and functions. | |
Classes | |
| class | casa::Aberration |
| Aberration class and calculations. More... | |
| class | casa::EarthMagneticMachine |
| Calculates magnetic field in a direction. More... | |
| class | casa::MBaseline |
| A Measure: Baseline on Earth. More... | |
| struct | casa::MConvertBase_global_functions_Output |
| Global functions . More... | |
| class | casa::MDirection |
| MDirection::MECLIPTIC -- ecliptic for mean equator of date MDirection::TECLIPTIC -- ecliptic for true equator of date MDirection::SUPERGAL -- supergalactic coordinates MDirection::ITRF -- coordinates wrt ITRF Earth frame MDirection::TOPO -- apparent topocentric position MDirection::ICRS -- International Celestial reference system MDirection::MERCURY -- the planet: has no data attached MDirection::VENUS MDirection::MARS MDirection::JUPITER MDirection::SATURN MDirection::URANUS MDirection::NEPTUNE MDirection::PLUTO MDirection::SUN MDirection::MOON MDirection::COMET -- solar system body: no coordinates attached, only table MDirection::DEFAULT = J2000 More... | |
| class | casa::MDoppler |
| A Measure: Doppler shift. More... | |
| class | casa::MEarthMagnetic |
| A Measure: Magnetic field on Earth. More... | |
| class | casa::MeasConvert< M > |
| Conversion of Measures. More... | |
| class | casa::MeasFrame |
| Container for Measure frame. More... | |
| struct | casa::MeasFrame_global_functions_Output |
| Global functions . More... | |
| class | casa::MeasRef< Ms > |
| Reference frame for physical measures. More... | |
| class | casa::Measure |
| Physical quantities within reference frame. More... | |
| struct | casa::Measure_global_functions_Output |
| Global functions . More... | |
| class | casa::MeasureHolder |
| A holder for Measures to enable record conversions. More... | |
| class | casa::MEpoch |
| A Measure: instant in time. More... | |
| class | casa::MFrequency |
| A Measure: wave characteristics. More... | |
| class | casa::MPosition |
| A Measure: position on Earth. More... | |
| class | casa::MRadialVelocity |
| A Measure: radial velocity. More... | |
| struct | casa::MRBase_global_functions_Output |
| Global functions . More... | |
| class | casa::Muvw |
| A Measure: uvw on Earth. More... | |
| class | casa::Nutation |
| Nutation class and calculations. More... | |
| class | casa::ParAngleMachine |
| Converts a direction into parallactic angle. More... | |
| class | casa::Precession |
| Precession class and calculations. More... | |
| class | casa::SofaTest |
| Wrapping of IAU SOFA Fortran routines and test class. More... | |
| struct | casa::SofaTest_global_functions_IAU_SOFA |
| Global Fortran function wraps . More... | |
| class | casa::SolarPos |
| Solar position class and calculations. More... | |
| class | casa::Stokes |
| Stokes parameter definitions for interface to table data. More... | |
| class | casa::UVWMachine |
| Converts UVW coordinates between coordinate systems. More... | |
| class | casa::VelocityMachine |
| Converts between velocities and frequencies. More... | |
1.5.1