Astro::Coord::ECI::TLE::Set - Represent a set of data for the same ID.


 use Astro::SpaceTrack;
 use Astro::Coord::ECI::TLE;
 use Astro::Coord::ECI::TLE::Set;
 use Astro::Coord::ECI::Utils qw{rad2deg};

 # Get orbital data on the International Space Station and
 # related NASA stuff. 
 my $st = Astro::SpaceTrack->new(
     username => $me,
     password => $secret,
 my $rslt = $st->retrieve( qw{ -last5 25544 } );
     or die "Unable to get data: ", $rslt->status_line;
 # We aggregate the data because we retrieved the last five orbital
 # elements for the body. The Set object will select the correct one for
 # the given time.
 my @sats = Astro::Coord::ECI::TLE::Set->aggregate (
     Astro::Coord::ECI::TLE->parse ($rslt->content));
 my $now = time ();
 # Display current International Space Station (etc)
 # position in terms of latitude, longitude, and altitude.
 # Like all position methods, geodetic() returns angles in
 # radians and distances in kilometers.
 print join ("\t", qw{OID Latitude Longitude Altitude}
    ), "\n";
 foreach my $tle (@sats) {
    my ($lat, $long, $alt) = $tle->universal($now)
    print join ("\t", $tle->get ('id'),
       rad2deg($lat), rad2deg($long), $alt),


This module is intended to represent a set of orbital elements, representing the same NORAD ID at different points in time. It can contain any number of objects of class Astro::Coord::ECI::TLE (or any subclass thereof) provided all contents are of the same class and represent the same NORAD ID.

In addition to the methods documented here, an Astro::Coord::ECI::TLE::Set supports all methods provided by the currently-selected member object, through Perl's AUTOLOAD mechanism. In this way, the object is almost a plug-compatible replacement for an Astro::Coord::ECI::TLE object, but it uses the orbital elements appropriate to the time given. The weasel word 'almost' is expanded on in the "Incompatibilities with Astro::Coord::ECI::TLE" section, below.

When the first member object is added via the add() method, it becomes the currently-selected object. The select() method can be used to select the member that best represents the time passed to the select method. In addition, certain method calls that are delegated to the currently-selected member object can cause a new member to be selected before the delegation is done. These include 'universal', 'dynamical', and any Astro::Coord::ECI::TLE orbital propagation model.

There may be cases where the member class does not want to use the normal delegation mechanism. In this case, it needs to define a _nodelegate_xxxx method, where xxxx is the name of the method that is not to be delegated to. The _nodelegate method is called with the same calling sequence as the original method, but the first argument is a reference to the Astro::Coord::ECI::TLE::Set object, not the member object. Use of this mechanism constitutes a pledge that the _nodelegate method does not make use of any private interfaces to the member objects.

Incompatibilities with Astro::Coord::ECI::TLE


Astro::Coord::ECI::TLE::Set is not a member of the Astro::Coord::ECI inheritance hierarchy, so $set->isa ('Astro::Coord::ECI') is false.

Calling semantics for delegated behaviors

In general, when Astro::Coord::ECI::TLE::Set delegates functionality to a member object, that object's method receives a reference to the member object as its first argument. That is, if $set is the Astro::Coord::ECI::TLE::Set object and $tle is the relevant member object, $set->method (...) becomes $tle->method (...) from the point of view of the called method.

If the member class wishes to see the Astro::Coord::ECI::TLE::Set object as the first argument of method xxxx, it defines method _nodelegate_xxxx, which is called as though by $set->_nodelegate_xxx (...). The _nodelegate_xxx method must use only the public interface to the $tle object (whatever its class). A cheap way to get this method is

 *_nodelegate_xxxx = \&xxxx;

but nothing says the _nodelegate_xxxx method must be defined this way.

The universal and dynamical methods are special-cased in the AUTOLOAD code so that a select() is done before they are called.

Calling semantics for static behaviors

Some Astro::Coord::ECI methods (e.g. universal()) will instantiate an object for you if you call them statically. This will not work with Astro::Coord:ECI::TLE::Set; that is, Astro::Coord::ECI::TLE::Set->universal () is an error.

Return semantics for delegated behaviors

In general, when behavior is delegated to a member object, the return is whatever the delegated method returns. This means that, for methods that return the object they are called on (e.g. universal()) you get back a reference to the member object, not a reference to the containing Astro::Coord::ECI::TLE::Set object.


The following methods should be considered public:

$set = Astro::Coord::ECI::TLE::Set->new ()

This method instantiates a new set. Any arguments are passed to the add() method.

$set->add ($member ...);

This method adds members to the set. The initial member may be any initialized member of the Astro::Coord::ECI::TLE class, or any subclass thereof. Subsequent members must be the same class as the initial member, and represent the same NORAD ID. If not, an exception is thrown. If a prospective member has the same effective date as a current member, the prospective member is silently ignored. If a member does not have an effective date, the epoch is used as a proxy for the effective date.

The first member added becomes the current member for the purpose of delegating method calls. Adding subsequent members does not change the current member, though it may be appropriate to call select() after adding.

@sets = Astro::Coord::ECI::TLE::Set->aggregate ($tle ...);

This method aggregates the given Astro::Coord::ECI::TLE objects into sets by NORAD ID. If there is only one object with a given NORAD ID, it is simply returned intact, not made into a set with one member.

If you should for some reason want sets with one member, do

 $Astro::Coord::ECI::TLE::Set::Singleton = 1;

before you call aggregate(). Actually, any value that Perl will interpret as true will work. You might want a 'local' in front of all this.

Optionally, the first argument may be a hash reference. The hash contains options that modify the function of this method. The only option at the moment is

 select => $time

which causes the object best representing the given time to be selected in any Astro::Coord::ECI::TLE::Set objects.

$set->can ($method);

This method checks to see if the object can execute the given method. If so, it returns a code reference to the subroutine; otherwise it returns undef.

This override to UNIVERSAL::can is necessary because we want to return true for member class methods, but we execute them by autoloading, so they are not in our namespace.

$set->clear ();

This method removes all members from the set, allowing it to be reloaded with a different NORAD ID.

$value = $set->get( $name );

This method returns the value of the named attribute.

If the attribute name is 'tle', it returns the concatenated TLE data of all TLEs in the set. Otherwise it simply returns the named attribute of the selected Astro::Coord::ECI::TLE object.

$time = $set->max_effective_date(...);

This method extends the Astro::Coord::ECI::TLE max_effective_date() method appropriately for sets of elements.

If there are arguments, their maximum is taken, the appropriate member element is set, and max_effective_date() is called on that element, passing the date used to select the element. If there are no arguments, max_effective_date() is called on the current element, with no arguments. If the set has no members, the maximum of the arguments is returned (or undef if there are no arguments).

@tles = $set->members ();

This method returns all members of the set, in ascending order by effective date.


If the set has a current member, this method returns true if the current member represents the given class, or the class name of the current member if no argument is given.

If the set has no current member, an exception is thrown.

See the Astro::Coord::ECI represents() method for the details of the behavior if the set has a current member.

Normally we would just let AUTOLOAD take care of this, but it turned out to be handy to be able to call UNIVERSAL::can on this method.

$set->select ($time);

This method selects the member object that best represents the given time, and returns that member. If called without an argument or with an undefined argument, it simply returns the currently-selected member.

The 'best representative' member for a given time is chosen by considering all members in the set, ordered by ascending effective date. If all epochs are after the given time, the earliest effective date is chosen. If some epochs are on or before the given time, the latest effective date that is not after the given time is chosen.

The 'best representative' algorithm tries to select the element set that would actually be current at the given time. If no element set is current (i.e. all are in the future at the given time) we take the earliest, to minimize peeking into the future. This is done even if that member's 'backdate' attribute is false.

$set->set ($name => $value ...);

This method iterates over the individual name-value pairs. If the name is an attribute of the object's model (that is, if is_model_attribute () returns true), it calls set_selected($name, $value). Otherwise, it calls set_all($name, $value). If the set has no members, this method simply returns.

$set->set_all ($name => $value ...);

This method sets the given attribute values on all members of the set. It is not an error to call this on an object with no members, but neither does it accomplish anything useful.

$set->set_selected ($name => $value ...);

This method sets the given attribute values on the currently-selected member of the set. It is an error to call this on an object with no members.

$valid = $set->validate($options, $time ...);

This method calls validate() on each of the members of the set, removing from the set any members that fail to validate. The number of members remaining in the set is returned.

The $options argument is itself optional. If passed, it is a reference to a hash of option names and values. See the Astro::Coord::ECI::TLE validate() method for the details.

Each member of the set will be validated at the time it would first be used for computations (if that is defined) and at the time its successor in the set (if any) would first be used for computation. In addition, each member will be validated at any of the $time arguments that happens to fall between these two times.

If a member is removed, validate() will call itself recursively to ensure that the new set is still valid.


Support is by the author. Please file bug reports at,, or in electronic mail to the author.


Thomas R. Wyant, III (wyant at cpan dot org)


Copyright (C) 2005-2023 by Thomas R. Wyant, III

This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory LICENSES.

This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.