=head1 TITLE

Astro::SpaceTrack::BulkData - Reconstructing Space Track bulk data downloads

=head1 SUMMARY

The purpose of this document is to examine the feasibility of
duplicating the Space Track bulk data downloads through the REST
interface after the bulk data functionality is removed. The short answer
is:

Reasonable (and even trivial) queries appear to exist for C<full>,
C<geosynchronous>, C<iridium>, C<orbcomm>, C<globalstar>, C<intelsat>,
and C<inmarsat>.

Reasonable queries do not appear to exist for C<navigation>, C<weather>,
C<amateur>, and C<special>. The only way I can see to get them is with a
list of OIDs, which would have to be maintained.

The C<visible> data set is a special case. It might be thought possible
to come up with a reasonable facsimile of the list by selecting on
C<RCSVALUE>, but in practice this does not seem to work. The Celestrak
C<visual> list might be an acceptable alternative.

=head1 DETAILS

There are, in general, three possibilities, for duplicating the Space
Track bulk data, of which not all are exclusive:

=over

=item 1) there is an obvious SATCAT query to get the OIDs involved;

=item 2) there is a Celestrak list of the OIDs involved;

=item 3) there is no known source of the OIDs involved.

=back

The SATCAT queries would specify at least
C</basicspacedata/query/class/satcat/CURRENT/Y/DECAY/null-val>. Except
for the C<full> and C<geosynchronous> catalogs, C</OBJECT_TYPE/PAYLOAD>
would also be specified. Predicates could be limited to
C</predicates/NORAD_CAT_ID>, though the construction of NASA-format TLEs
will require predicate C<SATNAME> as well.

The C<full> and C<geosynchronous> queries could be satisfied directly
from class C<tle_current> provided satellite names were not needed.

The individual bulk data sets are:

=head2 full - Full catalog

This is case (1) above, with no additional query arguments. The 'full'
data set includes rocket bodies and debris. In theory this query could
be satisfied from class C<tle_current> if no names were needed.

Interestingly, the obvious query retrieves 15773 bodies, whereas the
prebuilt data set has only 14908. The query as it currently stands took
three or four minutes, but that was going through class C<satcat>. This
will be required if common names are needed. If common names are not
needed, the query directly against C<tle_current> should be faster,
especially since it does not need to be broken up into smaller queries.

=head2 geosynchronous - Geosynchronous bodies

This is case (1) above, though some fiddling is needed. The problem is
that the version 1 definition of a geosynchronous satellite requires
mean motion between 0.99 and 1.01 revolutions per day, and eccentricity
less than 0.01. We kind of have to hit class C<satcat> to find out what
is in orbit, but neither mean motion nor eccentricity are in that class.

The trick is that period in minutes B<is> in C<satcat>, and the required
mean motion corresponds to a period between 1425.6 and 1454.4 (compared
to the specimen query on the version 2 web site, which puts the period
between 1430 and 1450). We do not require the object type to be
C<'PAYLOAD'>, because the version 1 bulk download contains both rocket
bodies and debris.

We can then query the C<tle> or C<tle_current> classes for the OIDs we
have found, but restrict the query by requiring eccentricity less than
0.01.

The result of this combination of queries has 813 bodies in it, the same
as the bulk data for geosynchronous satellites. They are slightly
different lists, though. The following OIDs appear only in the bulk
data:

     OID  Common Name             Period  Object Type
    20315 INTELSAT 602            1454.43 PAYLOAD
    20401 SKYNET 4A               1454.49 PAYLOAD
    23598 DIRECTV 3 (DBS/NIMIQ 3) 1454.56 PAYLOAD

On the other hand, the following OIDs appear only in the results of the
above-described query:

     OID  Common Name             Period  Object Type
    11890 EKRAN 5                 1436.55 PAYLOAD
    12851 SL-12 R/B(2)            1425.65 ROCKET BODY
    29233 SL-12 R/B(2)            1425.69 ROCKET BODY

In theory this query could be satisfied from class C<tle_current> if no
names were needed.

=head2 navigation - Navigation satellites.

This appears B<not> to be case (1) above. One could look for 'NAVSTAR'
and 'GLONASS', but though this would catch the bulk of them, others are
listed, and some of them are simply identified as 'COSMOS' and a number.

This is probably not case (2) either, since Celestrak does not have a
simple 'navigation' list, but a number of them. Except for Celestrak's
'glonass' list, there does not seem to be much overlap between Space
Track's and Celestrak's idea of what is a navigational satellite.

So this appears to be case (3) above.

=head2 weather - Weather satellites

There appears B<not> to be case (1) above. You could query for
C</SATNAME/~~GOES> and C</SATNAME/~~METEOSAT>, but some of the list
entries are simply identified as 'COSMOS' and a number.

Furthermore, case (2) is of limited usefulness, since there is not much
overlap between Celestrak's and Space Track's idea of what a weather
satellite is. Space Track lists 57 weather satellites, whereas Celestrak
lists 34. Moreover, only 12 satellites appear on both lists.

So this appears to be case (3) above.

=head2 iridium - Iridium satellites

This is case (1) above. The query that implements the Space Track
version 1 definition of an Iridium satellite is
C<< /SATNAME/~~IRIDIUM >>. The Celestrak list includes two dummy masses
launched by the Chinese while trying to qualify for an Iridium launch
contract. The dummy masses are not in the Space Track list, but I doubt
that this is significant.

=head2 orbcomm - OrbComm satellites

This is case (1) above, though it takes two queries:
C</SATNAME/~~ORBCOMM> and C</SATNAME/~~VESSELSAT>. The corresponding
Celestrak list omits the two Vesselsats.

=head2 globalstar - Globalstar satellites

This is case (1) above, with query C</SATNAME/~~GLOBALSTAR>. The
corresponding Celestrak list is identical.

=head2 intelsat - Intelsat satellites

This is case (1) above, with query C</SATNAME/~~INTELSAT>.

The corresponding Celestrak list is substantially different, missing
many satellites named 'Intelsat', and adding others (notably, but not
limited to, the 'Galaxy' satellites). Space Track has 89 satellites in
this list, Celestrak has 64, and 44 appear in both lists.

=head2 inmarsat - Inmarsat satellites

This is case (1) above, with query C</SATNAME/~~INMARSAT>. There is no
corresponding Celestrak list.

=head2 amateur - Amateur Radio satellites

This appears B<not> to be case (1) above. There are a bunch of Oscars
and Radios, but 'Oscar' appears in several other lists, and besides
there are the ubiquitous 'Cosmos' satellites.

There is a Celestrak amateur list, but there is not much overlap between
the two, with 51 satellites in the Space Track list, 37 in the Celestrak
list, but only 18 in both lists.

This appears to be case (3) above.

=head2 visible - Visible satellites

This appears B<not> to be case (1) above. I had hoped that something
could be done with C<RCSVALUE>, but this turns out not to be the case.
The minimum C<RCSVALUE> found among the 212 objects in the Space Track
'visible' data set is 1.4205 (as of September 1 2012). But there are
7027 objects in the C<satcat> table having a Radar Cross Section of at
least that value. Now, none of the 212 'visible' objects are debris, but
screening out debris only gets us down to 6328 objects.

The corresponding Celestrak list is called 'visual', but there are
substantial differences between the two lists. The Space Track list
contains 212 satellites, the Celestrak list contains 148, but only 91
satellites are in both lists.

=head2 special - Special satellites

This appears to be case (3) above. The list appears to be a miscellany
with no obvious selection criteria, and there is no corresponding
Celestrak list.

=head1 AUTHOR

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

=head1 COPYRIGHT AND LICENSE

Copyright 2012-2025 by Thomas R. Wyant, III (F<wyant at cpan dot org>).

=head1 LICENSE

This document 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.

=cut

# ex: set textwidth=72 :
