OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
sunpos.c
Go to the documentation of this file.
1 /*
2  *----------------------------------------------------------------------
3  * @(#) sunpos.c 1.0 22 Oct 93 <shc>
4  * Copyright (c) 1993, CSIRO Division of Oceanography
5  *----------------------------------------------------------------------
6  *
7  * sunpos --
8  *
9  * Position of the Sun.
10  *
11  * Results:
12  *
13  * Given a modified Julian dynamical time TJD, this function
14  * set the elements of R to the mean-of-date rectangular coordinates
15  * (in metres) of the sun and returns 0. Otherwise, ERRSTR is set to
16  * point to an error message and -1 is returned.
17  *
18  * Side effects:
19  * None.
20  *
21  * References:
22  * "Astronomical Formulae for Calculators", Jean Meeus.
23  *
24  * History:
25  * 1.0 22 Oct 93 <shc>
26  * Initial version.
27  *
28  * 1.0 22 Oct 93 <shc>
29  * Added errmsg stuff for integration with Python
30  *
31  *----------------------------------------------------------------------
32  */
33 
34 #include "orbit.h"
35 
36 /* Prototypes of internal functions */
37 static void oearth(double tjd, struct KEPLER *kep);
38 static void cearth(double tjd, double *el, double *er);
39 
40 int
41 sunpos(tjd, r, errmsg)
42 double tjd;
43 double r[3];
44 char **errmsg;
45 {
46  double ea, ta, helon, rad, x, y, z, obl, cobl, sobl;
47  struct KEPLER kep;
48 
49  /* Get equinox-of-date orbital elements for the earth */
50  (void) oearth(tjd, &kep);
51 
52  /* Calculate eccentric anomaly and true anomaly */
53  ea = eanom(kep.man, kep.ecc, errmsg);
54  if (ea == FP_ERRVAL)
55  return -1;
56  ta = 2 * atan(sqrt((1 + kep.ecc) / (1 - kep.ecc)) * tan(ea / 2));
57 
58  /* Calculate heliocentric ecliptic longitude and radius */
59  helon = AN2PI(ta + kep.arp);
60  rad = kep.sma * (1 - kep.ecc * kep.ecc) / (1 + kep.ecc * cos(ta));
61 
62  /* Add perturbations */
63  (void) cearth(tjd, &helon, &rad);
64 
65  /* Calculate heliocentric ecliptic cartesian coordinates */
66  x = rad * cos(helon);
67  y = rad * sin(helon);
68  z = 0;
69 
70  /*
71  * Rotate around X-axis through obliquity of date to convert to
72  * heliocentric equatorial coordinates. Take negatives to get
73  * coordinates of sun relative to earth and convert from AUs
74  * to metres.
75  */
76  (void) obliq(tjd, &obl, (double *) NULL);
77  cobl = cos(obl);
78  sobl = sin(obl);
79 
80  r[0] = -AU * x;
81  r[1] = -AU * (cobl * y - sobl * z);
82  r[2] = -AU * (sobl * y + cobl * z);
83 
84  return 0;
85 }
86 
87 /*
88  * This routine returns the equinox-of-date orbital elements for
89  * the earth. Time is barycentric dynamical.
90  */
91 static void
92 oearth(tjd, kep)
93 double tjd;
94 struct KEPLER *kep;
95 {
96  double t, a0, a1;
97 
98  /* Centuries from 1900 January 0, 12h UT */
99  t = (tjd - 15020e0) / 36525e0;
100 
101  /* Mean anomaly of the earth (and sun) and argument of perihelion */
102  a0 = ((-3.3e-6 * t - 1.5e-4) * t + 35999.04975e0) * t + 358.47583e0;
103  a1 = (3.025e-4 * t + 36000.76892e0) * t + 99.69668e0 - a0;
104 
105  kep->sma = 1.0000002e0;
106  kep->ecc = (-1.26e-7 * t - 4.18e-5) * t + 1.675104e-2;
107  kep->inc = 0.0;
108  kep->arp = DTOR(AN360(a1));
109  kep->ran = 0.0;
110  kep->man = DTOR(AN360(a0));
111 
112  return;
113 }
114 
115 /*
116  * Perturbations of the earth's orbit added in after solving Kepler's
117  * equation. These adjust the earth's ecliptic longitude and radius.
118  */
119 static void
120 cearth(tjd, el, er)
121 double tjd;
122 double *el, *er;
123 {
124  double t, a, b, c, d, e, h, a0;
125 
126  /* Centuries from 1900 January 0, 12h UT */
127  t = (tjd - 15020e0) / 36525e0;
128 
129  /* Perturbations due to Venus: */
130  a = DTOR(22518.7541e0 * t + 153.23e0);
131  b = DTOR(45037.5082e0 * t + 216.57e0);
132 
133  /* Due to Jupiter: */
134  c = DTOR(32964.3577e0 * t + 312.69e0);
135  h = DTOR(65928.7155e0 * t + 353.40e0);
136 
137  /* Due to the moon: */
138  d = DTOR((-1.44e-3 * t + 445267.1142e0) * t + 350.74e0);
139 
140  /* Long period perturbation: */
141  e = DTOR(20.20e0 * t + 231.19e0);
142 
143  /* Corrections to earth's longitude */
144  a0 = 1.34e-3 * cos(a) +
145  1.54e-3 * cos(b) +
146  2.00e-3 * cos(c) +
147  1.79e-3 * sin(d) +
148  1.78e-3 * sin(e);
149 
150  *el = *el + DTOR(a0);
151 
152  /* Corrections to earth's radius vector (in AU) */
153  a0 = 5.430e-6 * sin(a) +
154  1.575e-5 * sin(b) +
155  1.627e-5 * sin(c) +
156  3.076e-5 * cos(d) +
157  9.270e-6 * sin(h);
158 
159  *er = *er + a0;
160 }
int r
Definition: decode_rs.h:73
data_t t[NROOTS+1]
Definition: decode_rs.h:77
int sunpos(double tjd, r, char **errmsg)
Definition: sunpos.c:41
#define AN360(X)
Definition: orbit.h:63
double ran
Definition: orbit.h:131
double eanom(double manom, double ecc, char **errmsg)
Definition: eanom.c:53
#define NULL
Definition: decode_rs.h:63
#define FP_ERRVAL
Definition: orbit.h:48
float h[MODELMAX]
Definition: atrem_corl1.h:131
double sma
Definition: orbit.h:127
Definition: orbit.h:126
#define DTOR(X)
Definition: orbit.h:51
double arp
Definition: orbit.h:130
double man
Definition: orbit.h:132
#define AN2PI(X)
Definition: orbit.h:57
double inc
Definition: orbit.h:129
data_t b[NROOTS+1]
Definition: decode_rs.h:77
double ecc
Definition: orbit.h:128
void obliq(double tjd, double *mood, double *dmood)
Definition: obliq.c:35
#define AU
Definition: lunsol.h:19
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
el
Definition: decode_rs.h:168