OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_get_T_inst2ecr.c
Go to the documentation of this file.
1 /*
2  * $Log: GEO_get_T_inst2ecr.c,v $
3  * Revision 6.7 2017/03/27 17:01:11 jkuyper
4  * Corrected to treat a return of PGSCSC_W_BAD_TRANSFORM_VALUE from
5  * PGS_CSC_ECItoECR() as an error.
6  *
7  * Revision 6.6 2013/07/24 22:20:58 jkuyper
8  * Corrected initialization of sol_sc.
9  *
10  * Revision 6.5 2013/06/18 20:18:47 jkuyper
11  * Resolved Bug 2473 by using T_sc2ecr rather than attitQuat to convert sol_eci
12  * to sol_sc. This rendered attitQuat unnecessary, and required substantial
13  * rearrangement of the code.
14  *
15  * Revision 6.4 2010/06/29 18:47:03 kuyper
16  * Changed floating point equality tests into inequalities.
17  *
18  * Revision 6.3 2010/03/31 20:20:37 kuyper
19  * Helped resolve Bug 1969 by making rpy an output argument.
20  * Helped resolve Bug 2473 by making eulerAngleOrder an input argument.
21  *
22  * James Kuyper james.kuyper@sigmaspace.com
23  *
24  * Revision 6.2 2009/05/15 16:52:15 xgeng
25  * Minor change.
26  *
27  * Xu Geng ( xu.geng@saic.com )
28  * Revision 6.1 2009/05/11 15:28:30 xgeng
29  * Removed meaningless leading dimensions of "array" parameters.
30  * Changed macro name to MAX_PADDED.
31  * The code updates match the PDL change made in revision 6.1 and 6.2.
32  *
33  * Revision 5.5 2005/01/06 21:58:56 mash
34  * Corrected errors in algorithm for applying solar elevation correction.
35  *
36  * Revision 5.4 2004/11/02 17:38:34 kuyper
37  * Added T_sc2ecr to list of outputs, and initialized with fill values.
38  * Corrected error in handling of H_eci.
39  *
40  * Revision 5.3 2004/10/25 14:02:46 kuyper
41  * Corrected some typos.
42  * Corrected calculation and use of sol_idx.
43  *
44  * Revision 5.2 2004/10/18 16:57:31 kuyper
45  * Added sol_elev_cor and attitQuat to list of input pointer parameters to be
46  * checked.
47  *
48  * Revision 5.1 2004/10/13 21:36:29 kuyper
49  * Changed to apply an adjustment to T_inst2sc based upon the solar "elevation"
50  * angle.
51  *
52  * Revision 4.7 2003/10/07 21:01:06 kuyper
53  * Corrected to set and check for PGSd_GEO_ERROR_VALUE.
54  *
55  * Revision 4.6 2003/08/28 15:59:18 kuyper
56  * Corrected prolog
57  *
58  * Revision 4.5 2003/08/26 20:31:45 kuyper
59  * Corrected offsets to be a pointer to const.
60  *
61  * Revision 4.4 2003/08/22 22:22:15 kuyper
62  * Changed T_sc2ecr into an externally supplied array, to be filled in.
63  *
64  * Revision 4.3 2003/08/22 15:56:46 kuyper
65  * Corrected calculation of sum, to match PDL.
66  *
67  * Revision 4.2 2003/07/30 21:07:08 vlin
68  * updated after code walkthrough.
69  *
70  * Revision 4.1 2003/07/01 18:37:22 vlin
71  * Changed to work from an array of offsets from an ASCII UTC time,
72  * rather than from a single TAI time extracted from the sc_state
73  * Moved creation of T_sc2orb after call to PGS_CSC_ECItoECR(),
74  * allowing that array to be only 3x3. Re-wrote comments and messages.
75  *
76  * Revision 3.2 2002/05/29 21:07:37 kuyper
77  * Removed test for warning status from UTCtoTAI call.
78  * Corrected rpy_times subscripts.
79  * Changed to handle even "impossible" cases safely.
80  * Corrected range of loop indices.
81  *
82  * Revision 1.2 1996/07/18 16:28:23 kuyper
83  * Included self-checking header file.
84  * Changed extern declarations of T_inst2ecr, ecr_sc_position and
85  * ecr_sc_velocity to definitions. Replaced all other extern declarations
86  * with corresponding header files.
87  * Added required header files.
88  * Fixed pointer level problem with GEO_mat_mul call.
89  */
90 
91 #include "GEO_earth.h"
92 #include "GEO_geo.h"
93 #include "GEO_global_arrays.h"
94 #include "PGS_CBP.h"
95 #include "PGS_CSC.h"
96 #include "PGS_MODIS_35251.h"
97 #include "smfio.h"
98 
99 /* Transformation matrix from instrument to spacecraft
100  frame. */
101 static double T_inst2sc[3][3];
102 
103 
104 PGSt_SMF_status GEO_set_T_inst2sc(
105  const internal_coord_trans_struct * const coord_trans,
106  const ECS_metadata_struct * const ECS_metadata
107 ){
108 /*******************************************************************************
109 !C
110 !Description: Interpolates T_inst2sc to the time specified in the ECS
111  metadata for the beginning of a granule.
112 
113 !Input Parameters:
114  coord_trans Contains the base T_inst2sc, and time series
115  data for the interpolation of roll/pitch/yaw
116  corrections to that matrix.
117  ECS_metadata Contains the RangeBeginningDate and Time
118  metadata.
119 
120 !Output Parameters:
121  None.
122 
123 Return Values:
124  MODIS_E_BAD_INPUT_ARG If either argument is NULL
125  MODIS_E_GEO If any subroutine failed.
126  PGS_S_SUCCESS Otherwise
127 
128 Externally Defined:
129  MODIS_E_BAD_INPUT_ARG PGS_MODIS_35251.h
130  MODIS_E_GEO PGS_MODIS_35251.h
131  PGS_S_SUCCESS PGS_SMF.h
132  TIMECODEASIZE smfio.h
133 
134 Called by:
135  GEO_locate_one_granule()
136 
137 Routines Called:
138  modsmf "smfio.h"
139  PGS_TD_UTCtoTAI "PGS_TD.h"
140 
141 !Revision History:
142 See top of file.
143 
144 Requirements:
145 See "Implementation of Time dependent Matrix T_inst2sc by Geolocation Parameter
146 File" by Masahiro Nishihama, 2002-05-10. A copy is is in the SDF for this
147 routine. The requirements process has died through lack of customer support,
148 and this will therefore not be being converted into a formal requirement.
149 
150 !Team-unique Header:
151  This software is developed by the MODIS Science Data Support
152  Team for the National Aeronautics and Space Administration,
153  Goddard Space Flight Center, under contract NAS5-32373.
154 
155 Design Notes:
156  T_inst2sc is a 3x3 double precision global with file scope, shared with
157  GEO_get_T_inst2ecr().
158 
159 !END
160 *******************************************************************************/
161 
162  double adjust[3][3];
163  double rpy[3]={0.0};
164  double cosine[3], sine[3];
165  double fraction;
166  PGSt_double TAI_time;
167  char asciiUTC[TIMECODEASIZE];
168  char msgbuf[256];
169  char filefunc[] = __FILE__ ", GEO_set_T_inst2sc";
170  int i, j, k, axis;
171  int first, last;
172 
173  if(coord_trans == NULL || ECS_metadata == NULL)
174  {
175  sprintf(msgbuf, "coord_trans:%p ECS_metadata:%p",
176  (void *)coord_trans, (void *)ECS_metadata);
177  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
178 
179  return MODIS_E_BAD_INPUT_ARG;
180  }
181 
182  if(coord_trans->rpy_count<1)
183  {
184  memcpy(T_inst2sc, coord_trans->T_inst2sc, sizeof(T_inst2sc));
185 
186  return PGS_S_SUCCESS;
187  }
188 
189  sprintf(asciiUTC, "%sT%s", ECS_metadata->rangebeginningdate,
190  ECS_metadata->rangebeginningtime);
191 
192  if(PGS_TD_UTCtoTAI(asciiUTC, &TAI_time)!= PGS_S_SUCCESS)
193  {
194  sprintf(msgbuf, "PGS_TD_UTCtoTAI(\"%s\")", asciiUTC);
195  modsmf(MODIS_E_GEO, msgbuf, filefunc);
196 
197  return MODIS_E_GEO;
198  }
199 
200  for(first=-1; first < coord_trans->rpy_count-1 &&
201  coord_trans->rpy_times[first+1] < TAI_time; first++);
202  for(last = coord_trans->rpy_count;
203  last > 0 && coord_trans->rpy_times[last-1] >= TAI_time; last--);
204 
205  if(last<=0)
206  memcpy(rpy, coord_trans->rpy_inst2sc[0], sizeof(rpy));
207  else if(first >= coord_trans->rpy_count-1)
208  memcpy(rpy, coord_trans->rpy_inst2sc[ coord_trans->rpy_count-1],
209  sizeof(rpy));
210  else
211  {
212  /* NOT protected against division by 0: we trust the parameter file.*/
213  fraction = (TAI_time-coord_trans->rpy_times[first])/
214  (coord_trans->rpy_times[last] - coord_trans->rpy_times[first]);
215  for(axis = 0; axis<3; axis++)
216  rpy[axis] = fraction*coord_trans->rpy_inst2sc[last][axis] +
217  (1.0-fraction)*coord_trans->rpy_inst2sc[first][axis];
218  }
219 
220  for(axis = 0; axis<3; axis++)
221  {
222  cosine[axis] = cos(rpy[axis]);
223  sine[axis] = sin(rpy[axis]);
224  }
225 
226  adjust[0][0] = cosine[1]*cosine[2]-sine[0]*sine[1]*sine[2];
227  adjust[0][1] = -sine[2]*cosine[0];
228  adjust[0][2] = cosine[2]*sine[1] + sine[2]*sine[0]*cosine[1];
229  adjust[1][0] = sine[2]*cosine[1] + cosine[2]*sine[0]*sine[1];
230  adjust[1][1] = cosine[2]*cosine[0];
231  adjust[1][2] = sine[2]*sine[1] - cosine[2]*sine[0]*cosine[1];
232  adjust[2][0] = -cosine[0]*sine[1];
233  adjust[2][1] = sine[0];
234  adjust[2][2] = cosine[0]*cosine[1];
235 
236  for(i=0; i<3; i++)
237  for(j=0; j<3; j++)
238  {
239  T_inst2sc[i][j] = 0.0;
240  for(k=0; k<3; k++)
241  T_inst2sc[i][j] += adjust[i][k]*coord_trans->T_inst2sc[k][j];
242  }
243 
244  return PGS_S_SUCCESS;
245 }
246 
247 /*===========================================================================*/
248 
249 PGSt_SMF_status GEO_get_T_inst2ecr(
250  PGSt_integer numValues,
251  char asciiutc[],
252  const PGSt_double offsets[],
253  sc_state_struct const sc_state[],
254  double sol_elev_cor[][3],
255  PGSt_integer const eulerAngleOrder[],
256  double T_sc2ecr[][3][3],
257  double T_inst2ecr[][3][3],
258  double ecr_position[][3],
259  double ecr_velocity[][3],
260  PGSt_double rpy[]
261 )
262 
263 /******************************************************************************
264 !C
265 
266 !Description: Routine in the instrument model of the Level-1A geolocation
267  software to calculate transformation matrix from instrument
268  to ECR coordinates. The algorithm is based on the
269  Version 3.0 Geolocation ATBD (section 3.1.4.2).
270 
271 !Input Parameters:
272  numValues The number of time values for which the matrix is to be
273  converted.
274  asciiUTC The base time for the conversion
275  offsets An array of numValues offsets in seconds from the base
276  time.
277  sc_state An array of numValues spacecraft kinematic state
278  records for the specified times.
279  sol_elev_cor Solar elevation-based lookup table for corrections to
280  T_inst2sc.
281  eulerAngleOrder Specification of the order in which euler angles are
282  applied.
283 
284 !Output Parameters:
285  T_sc2ecr An array of numValues tranformation matrices from the
286  spacecraft to ECR coordinates for the spacecraft state.
287  T_inst2ecr An array of numValues transformation matrices from the
288  instrument to ECR coordinates for the spacecraft state.
289  ecr_position An array of numValues spacecraft positions from
290  sc_state converted to ECR coordinates.
291  Optional output (may be null).
292  ecr_velocity An array of numValues spacecraft velocities from
293  sc_state converted to ECR coordinates.
294  Optional output (may be null).
295  rpy Array containing the roll, pitch, and yaw corrections
296  based upon the current solar "elevation" angle.
297 
298 Return value:
299  MODIS_E_BAD_INPUT_ARG If any mandatory input pointer is null
300  MODIS_E_GEO If any subroutine fails.
301  PGS_S_SUCCESS Otherwise
302 
303 Externally defined:
304  MODIS_E_BAD_INPUT_ARG "PGS_MODIS_35251.h"
305  MODIS_E_GEO "PGS_MODIS_35251.h"
306  NUM_SOL_ELEV "GEO_parameters.h"
307  MAX_PADDED "GEO_geo.h"
308  PGS_PI "GEO_geo.h"
309  PGS_S_SUCCESS "PGS_SMF.h"
310  PGS_TRUE "PGS_SMF.h"
311  PGSd_SUN "PGS_CBP.h"
312  PGSd_GEO_ERROR_VALUE "PGS_CSC.h"
313  PITCH "GEO_geo.h"
314  POSITION "GEO_geo.h"
315  ROLL "GEO_geo.h"
316  T_inst2sc "GEO_parameters.h"
317  VELOCITY "GEO_geo.h"
318  YAW "GEO_geo.h"
319 
320 Called by:
321  GEO_interp_ECR
322 
323 Routines called:
324  PGS_CSC_crossProduct "PGS_CSC.h"
325  PGS_CSC_ECItoECR "PGS_CSC.h"
326  PGS_CSC_EulerToQuat "PGS_CSC.h"
327  PGS_CSC_Norm "PGS_CSC.h"
328  PGS_CSC_quatRotate "PGS_CSC.h"
329  PGS_SMF_TestWarningLevel "PGS_SMF.h"
330  PGS_TD_UTCtoTAI "PGS_TD.h"
331  modsmf "smfio.h"
332 
333 !Revision History:
334 See top of file
335 
336 !Team-unique Header:
337  This software is developed by the MODIS Science Data Support
338  Team for the National Aeronautics and Space Administration,
339  Goddard Space Flight Center, under contract NAS5-32373.
340 
341 Requirements:
342  PR03-F-3.2.2-1
343 
344 !END
345 ****************************************************************************/
346 
347 {
348  PGSt_double tveci[MAX_PADDED*2][6] = {0.0};
349  PGSt_double tvecr[MAX_PADDED*2][6] = {0.0};
350  /* ECR vector array for transformation routine */
351  PGSt_double toff[MAX_PADDED*2] = {0.0};
352  /* time offset array for toolkit calls */
353  double T_inst2sc_adj[3][3] = {0.0}; /* adjusted T_inst2sc matrix. */
354  int i, val; /* iteration parameters */
355  PGSt_double sol_eci[6]={0.0};
356  int sc, ecr, inst, orb; /* Loop counters. */
357 
358  char msgbuf[PGS_SMF_MAX_MSGBUF_SIZE] = "";
359  PGSt_SMF_status status;
360  char filefunc[] = __FILE__ ", GEO_get_T_inst2ecr";
361 
362  /*************************************************************
363  calculation from here
364  *************************************************************/
365 
366  if (numValues < 0 || numValues > MAX_PADDED || asciiutc == NULL ||
367  offsets == NULL || sc_state == NULL || sol_elev_cor == NULL ||
368  eulerAngleOrder == NULL || T_sc2ecr == NULL || T_inst2ecr == NULL)
369  {
370  sprintf(msgbuf, "numValues = %d, asciiutc = %p, offsets = %p, \n"
371  "sc_state = %p, sol_elev_cor=%p, eulerAngleOrder=%p, T_sc2ecr=%p "
372  "T_inst2ecr = %p", numValues, (void*)asciiutc, (void*)offsets,
373  (void*)sc_state, (void*)sol_elev_cor, (void*)eulerAngleOrder,
374  (void*)T_sc2ecr, (void*)T_inst2ecr);
375  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
376  return MODIS_E_BAD_INPUT_ARG;
377  }
378 
379  if (numValues == 0)
380  return PGS_S_SUCCESS;
381 
382  if (ecr_position!=NULL)
383  for (val=0; val<numValues; val++)
384  for (ecr=0; ecr<3; ecr++)
385  ecr_position[val][ecr] = PGSd_GEO_ERROR_VALUE;
386 
387  if (ecr_velocity!=NULL)
388  for (val=0; val<numValues; val++)
389  for (ecr=0; ecr<3; ecr++)
390  ecr_velocity[val][ecr] = PGSd_GEO_ERROR_VALUE;
391 
392  for (val=0; val<numValues; val++)
393  for (ecr=0; ecr<3; ecr++)
394  {
395  for (inst=0; inst<3; inst++)
396  {
397  T_sc2ecr[val][ecr][inst] = PGSd_GEO_ERROR_VALUE;
398  T_inst2ecr[val][ecr][inst] = PGSd_GEO_ERROR_VALUE;
399  }
400  }
401 
402  for (val=0; val<numValues; val++)
403  { /* construct the spacecraft to orbit coord. transformation matrix
404  T_sc2orb for the target sample. Get trigonometry terms from euler
405  angles */
406  PGSt_double H_eci[3] = {0.0};
407  /* ECI vector parallel to SC orbital angular momentum in the ECI frame */
408 
409  PGS_CSC_crossProduct((PGSt_double*)sc_state[val].position,
410  (PGSt_double*)sc_state[val].velocity, H_eci);
411  memcpy(&tveci[2*val][POSITION], sc_state[val].position,
412  sizeof(sc_state[val].position));
413  memcpy(&tveci[2*val][VELOCITY], sc_state[val].velocity,
414  sizeof(sc_state[val].velocity));
415  memcpy(&tveci[2*val+1][POSITION], H_eci, sizeof(H_eci));
416  toff[2*val] = offsets[val];
417  toff[2*val+1] = offsets[val];
418 
419  if(val==numValues/2 && PGS_CBP_Earth_CB_Vector(1, asciiutc,
420  (PGSt_double*)offsets+numValues/2, PGSd_SUN,
421  (PGSt_double(*)[3])&sol_eci) !=PGS_S_SUCCESS)
422  {
423  sprintf(msgbuf, "PGS_CBP_Earth_CB_Vector(%s)", asciiutc);
424  modsmf(MODIS_E_GEO, msgbuf, filefunc);
425  return MODIS_E_GEO;
426  }
427  }
428 
429  status = PGS_CSC_ECItoECR(2*numValues, asciiutc, toff, tveci, tvecr);
430  if (status != PGS_S_SUCCESS && status != PGSCSC_W_PREDICTED_UT1){
431  sprintf(msgbuf, "PGS_CSC_ECItoECR(%s)", asciiutc);
432  modsmf(MODIS_E_GEO, msgbuf, filefunc);
433  return MODIS_E_GEO;
434  }
435 
436  for (val=0; val<numValues; val++)
437  {
438  double T_orb2ecr[3][3] = {0.0}; /* orbit to ECR transformation matrix */
439  double T_sc2orb[3][3]; /* Spacecraft to orbit transformation matrix */
440  PGSt_double b1[3]; /* Cross product of the following pair: */
441  PGSt_double b2[3]; /* negative of angular momentum vector direction */
442  PGSt_double b3[3]; /* nadir vector direction */
443  double b2_length, b3_length;
444  double sin_roll, cos_roll; /* sin, cos of the roll */
445  double sin_pitch, cos_pitch; /* sin, cos of the pitch */
446  double sin_yaw, cos_yaw; /* sin, cos of the yaw */
447 
448  if(tveci[2*val][0] >= PGSd_GEO_ERROR_VALUE ||
449  tvecr[2*val][0] >= PGSd_GEO_ERROR_VALUE)
450  continue;
451 
452  if (ecr_position != NULL)
453  for (ecr = 0; ecr < 3; ecr++)
454  ecr_position[val][ecr] = tvecr[2*val][POSITION+ecr];
455  if (ecr_velocity != NULL)
456  for (ecr = 0; ecr < 3; ecr++)
457  ecr_velocity[val][ecr] = tvecr[2*val][VELOCITY+ecr];
458  b3_length = PGS_CSC_Norm(tvecr[2*val]+POSITION);
459  b2_length = PGS_CSC_Norm(tvecr[2*val+1]+POSITION);
460  for (ecr =0; ecr < 3; ecr++) {
461  b3[ecr] = -tvecr[2*val][POSITION+ecr]/b3_length;
462  b2[ecr] = -tvecr[2*val+1][POSITION+ecr]/b2_length;
463  }
464  PGS_CSC_crossProduct(b2, b3, b1);
465 
466  /* construct the orbit to ECR transformation matrix T_orb2ecr with the b1,
467  b2, b3 orbital coordinate unit vectors in the ecr coordinate frame. */
468  for (ecr = 0; ecr < 3; ecr++) {
469  T_orb2ecr[ecr][0] = (double)b1[ecr];
470  T_orb2ecr[ecr][1] = (double)b2[ecr];
471  T_orb2ecr[ecr][2] = (double)b3[ecr];
472  }
473 
474  /* construct the SC to orbit coord. transformation matrix T_sc2ecr */
475  sin_roll = sin(sc_state[val].eulerAngles[ROLL]);
476  cos_roll = cos(sc_state[val].eulerAngles[ROLL]);
477  sin_pitch = sin(sc_state[val].eulerAngles[PITCH]);
478  cos_pitch = cos(sc_state[val].eulerAngles[PITCH]);
479  sin_yaw = sin(sc_state[val].eulerAngles[YAW]);
480  cos_yaw = cos(sc_state[val].eulerAngles[YAW]);
481 
482  /* get trigonometry terms from euler angles */
483  T_sc2orb[0][0] = cos_yaw * cos_pitch - sin_yaw * sin_roll * sin_pitch;
484  T_sc2orb[0][1] = -cos_roll * sin_yaw;
485  T_sc2orb[0][2] = cos_yaw * sin_pitch + sin_yaw * sin_roll * cos_pitch;
486  T_sc2orb[1][0] = sin_yaw * cos_pitch + cos_yaw * sin_roll * sin_pitch;
487  T_sc2orb[1][1] = cos_yaw * cos_roll;
488  T_sc2orb[1][2] = sin_yaw * sin_pitch - cos_yaw * sin_roll * cos_pitch;
489  T_sc2orb[2][0] = -cos_roll * sin_pitch;
490  T_sc2orb[2][1] = sin_roll;
491  T_sc2orb[2][2] = cos_roll * cos_pitch;
492 
493  /* construct the composite transformation matrix T_inst2ecr. Construct
494  * the SC frame to ECR coordinate frame transform matrix, T_sc2ecr, from
495  * the matrix multiplication of the T_sc2orb and T_orb2ecr transform
496  * matrices.
497  */
498  for (ecr=0; ecr<3; ecr++)
499  for (sc=0; sc<3; sc++)
500  {
501  T_sc2ecr[val][ecr][sc] = 0.0;
502  for(orb=0; orb<3; orb++)
503  T_sc2ecr[val][ecr][sc] +=
504  T_orb2ecr[ecr][orb] * T_sc2orb[orb][sc];
505  }
506 
507  if(val==numValues/2)
508  {
509  PGSt_double sol_ecr[6];
510  PGSt_double sol_sc[3]={0.0};
511  int sc, ecr;
512  double sol_elev, extra;
513  int sol_idx;
514  PGSt_double adjust_quat[4];
515 
516  status = PGS_CSC_ECItoECR(1, asciiutc, (PGSt_double*)offsets+val,
517  &sol_eci, &sol_ecr);
518  if (status != PGS_S_SUCCESS && status != PGSCSC_W_PREDICTED_UT1)
519  {
520  sprintf(msgbuf, "PGS_CSC_ECItoECR(%s) new", asciiutc);
521  modsmf(MODIS_E_GEO, msgbuf, filefunc);
522  return MODIS_E_GEO;
523  }
524  else for(sc=0; sc<3; sc++)
525  for(ecr=0; ecr<3; ecr++)
526  sol_sc[sc] += T_sc2ecr[val][ecr][sc]*sol_ecr[ecr];
527 
528  sol_elev = atan2(-sol_sc[2], sol_sc[0]);
529  sol_idx =
530  (int)floor((sol_elev+PGS_PI)*(double)NUM_SOL_ELEV*0.5/PGS_PI);
531  extra = (sol_elev + PGS_PI)/(2.0*PGS_PI/(double)NUM_SOL_ELEV)
532  - (double)sol_idx;
533  for(i=0; i<3; i++) /* interpolate to sol_elev. */
534  rpy[(i+1)%3] = sol_elev_cor[sol_idx%NUM_SOL_ELEV][i]*(1.0-extra)
535  + extra*sol_elev_cor[(sol_idx+1)%NUM_SOL_ELEV][i];
536  if(PGS_CSC_EulerToQuat(rpy, (PGSt_integer*)eulerAngleOrder,
537  adjust_quat) !=PGS_S_SUCCESS)
538  {
539  modsmf(MODIS_E_GEO,"PGS_CSC_EulerToQuat(adjustment)" , filefunc);
540  return MODIS_E_GEO;
541  }
542 
543  for(sc=0; sc<3; sc++)
544  {
545  for(i = 0; i < 3; i++) /* Pulling column vectors out */
546  b1[i] = T_inst2sc[i][sc];
547  if(PGS_CSC_quatRotate(adjust_quat, b1, b2) != PGS_S_SUCCESS)
548  {
549  modsmf(MODIS_E_GEO,"PGS_CSC_quatRotate(adjustment)" ,
550  filefunc);
551  return MODIS_E_GEO;
552  }
553  for(i =0; i < 3; i++)
554  T_inst2sc_adj[i][sc] = b2[i];
555  }
556  }
557  }
558 
559  /* construct the instrument frame to ECR coordinate frame transform matrix
560  for the target spacecraft state, T_inst2ecr, from the matrix
561  multiplication of the T_sc2ecr and T_inst2sc_adj transform matrices. */
562  for (val=0; val<numValues; val++)
563  for (ecr=0; ecr<3; ecr++)
564  for (inst=0; inst<3; inst++)
565  {
566  T_inst2ecr[val][ecr][inst] = 0.0;
567  for (sc=0; sc<3; sc++)
568  T_inst2ecr[val][ecr][inst] +=
569  T_sc2ecr[val][ecr][sc] * T_inst2sc_adj[sc][inst];
570  }
571 
572  return PGS_S_SUCCESS;
573 }
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
#define PITCH
Definition: GEO_geo.h:104
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
#define PGS_PI
Definition: GEO_geo.h:172
char rpy_times[MAX_RPY_COUNT][RPY_TIMECODE_SIZE]
#define MAX_PADDED
Definition: GEO_geo.h:84
#define TIMECODEASIZE
Definition: Metadata.c:59
#define MODIS_E_GEO
#define ROLL
Definition: GEO_geo.h:103
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 to ensure that all gflag bits get accumulated Changed GEO_write_ECS_metadata to write PGEVERSION as Changed GEO_locate_one_granule c to make a failure to find an orbit number in the staged ephemeris files be non fatal Updated GEO_parameters dat to reflect latest estimate of T_inst2sc
Definition: HISTORY.txt:472
PGSt_SMF_status GEO_get_T_inst2ecr(PGSt_integer numValues, char asciiutc[], const PGSt_double offsets[], sc_state_struct const sc_state[], double sol_elev_cor[][3], PGSt_integer const eulerAngleOrder[], double T_sc2ecr[][3][3], double T_inst2ecr[][3][3], double ecr_position[][3], double ecr_velocity[][3], PGSt_double rpy[])
PGSt_SMF_status GEO_set_T_inst2sc(const internal_coord_trans_struct *const coord_trans, const ECS_metadata_struct *const ECS_metadata)
integer, parameter double
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor b1
Definition: HISTORY.txt:576
#define YAW
Definition: GEO_geo.h:105
#define NUM_SOL_ELEV
#define POSITION
Definition: GEO_geo.h:106
#define VELOCITY
Definition: GEO_geo.h:107
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
int k
Definition: decode_rs.h:73