Isis 3.0 Programmer Reference
Back | Home
Sensor.cpp
Go to the documentation of this file.
1 
23 #include "Sensor.h"
24 
25 #include <iomanip>
26 
27 #include <QDebug>
28 #include <QString>
29 
30 #include "Angle.h"
31 #include "Constants.h"
32 #include "CubeManager.h"
33 #include "Distance.h"
34 #include "EllipsoidShape.h"
35 #include "IException.h"
36 #include "IString.h"
37 #include "iTime.h"
38 #include "Latitude.h"
39 #include "Longitude.h"
40 #include "NaifStatus.h"
41 #include "Projection.h"
42 #include "ShapeModel.h"
43 #include "SpecialPixel.h"
44 #include "SurfacePoint.h"
45 #include "Target.h"
47 
48 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
49 
50 using namespace std;
51 
52 namespace Isis {
53 
61  Sensor::Sensor(Cube &cube) : Spice(cube) {
62  }
63 
64 
67  }
68 
69 
75  void Sensor::IgnoreElevationModel(bool ignore) {
76  // if we have an elevation model and are not ignoring it,
77  // set p_hasElevationModel to true
78  if (!ignore) {
79  target()->restoreShape();
80  }
81  else {
83  }
84  }
85 
86 
97 
98  QString message = "Pixel Ifov offsets not implemented for this camera.";
100  }
101 
102 
112  void Sensor::setTime(const iTime &time) {
113  Spice::setTime(time);
115  }
116 
117 
156  bool Sensor::SetLookDirection(const double v[3]) {
157  //std::cout << "Sensor::SetLookDirection()\n";
158  // The look vector must be in the camera coordinate system
159 
160  // copy v to LookC
161  // lookC[0] = v[0];
162  // lookC[1] = v[1];
163  // lookC[2] = v[2];
164  vector<double> lookC(v, v + 3);
165 
166  // Convert it to body-fixed
167  const vector<double> &lookJ = instrumentRotation()->J2000Vector(lookC);
168  const vector<double> &lookB = bodyRotation()->ReferenceVector(lookJ);
169 
170  // This memcpy does:
171  // m_lookB[0] = lookB[0];
172  // m_lookB[1] = lookB[1];
173  // m_lookB[2] = lookB[2];
174  memcpy(m_lookB, &lookB[0], sizeof(double) * 3);
175  m_newLookB = true;
176 
177  // Don't try to intersect the sky
178  if (target()->isSky()) {
179  target()->shape()->setHasIntersection(false);
180  return false;
181  }
182 
183  // See if it intersects the planet
184  const vector<double> &sB = bodyRotation()->ReferenceVector(
186 
187  // double tolerance = resolution() / 100.0; return
188  // target()->shape()->intersectSurface(sB, lookB, tolerance);
189  return target()->shape()->intersectSurface(sB, lookB);
190  }
191 
192 
202  return target()->shape()->hasIntersection();
203  }
204 
205 
211  void Sensor::Coordinate(double p[3]) const {
212  ShapeModel *shape = target()->shape();
213  p[0] = shape->surfaceIntersection()->GetX().kilometers();
214  p[1] = shape->surfaceIntersection()->GetY().kilometers();
215  p[2] = shape->surfaceIntersection()->GetZ().kilometers();
216  }
217 
218 
225  double Sensor::UniversalLatitude() const {
226  return GetLatitude().degrees();
227  }
228 
229 
237  return target()->shape()->surfaceIntersection()->GetLatitude();
238  }
239 
240 
248  double Sensor::UniversalLongitude() const {
249  return GetLongitude().degrees();
250  }
251 
252 
261  return target()->shape()->surfaceIntersection()->GetLongitude();
262  }
263 
264 
271  return *(target()->shape()->surfaceIntersection());
272  }
273 
274 
283  //TODO: We probably need to be validating surface intersect point is not NULL
284  // Here? or in ShapeModel? or what, man?
286  }
287 
288 
301  return target()->shape()->localRadius(lat, lon);
302  }
303 
304 
316  Distance Sensor::LocalRadius(double lat, double lon) {
317  return target()->shape()->localRadius(Latitude(lat, Angle::Degrees),
318  Longitude(lon, Angle::Degrees));
319  }
320 
321 
327  double Sensor::PhaseAngle() const {
328  std::vector<double> sunB(m_uB, m_uB+3);
329  return target()->shape()->phaseAngle(
330  bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()), sunB);
331  }
332 
333 
339  double Sensor::EmissionAngle() const {
340  return target()->shape()->emissionAngle(
341  bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate()));
342  }
343 
344 
350  double Sensor::IncidenceAngle() const {
351  std::vector<double> sunB(m_uB, m_uB+3);
352  return target()->shape()->incidenceAngle(sunB);
353  }
354 
355 
371  bool Sensor::SetUniversalGround(const double latitude,
372  const double longitude,
373  bool backCheck) {
374 
375  ShapeModel *shape = target()->shape();
376  shape->clearSurfacePoint();
377 
378  // Can't intersect the sky
379  if (target()->isSky()) {
380  return false;
381  }
382 
383  // Load the latitude/longitude
384  Latitude lat(latitude, Angle::Degrees);
385  Longitude lon(longitude, Angle::Degrees);
386  shape->surfaceIntersection()->SetSpherical(lat, lon, LocalRadius(lat, lon));
387  return SetGroundLocal(backCheck);
388  }
389 
406  bool Sensor::SetUniversalGround(const double latitude,
407  const double longitude,
408  const double radius,
409  bool backCheck) {
410 
411  ShapeModel *shape = target()->shape();
412  shape->clearSurfacePoint();
413 
414  // Can't intersect the sky
415  if (target()->isSky()) {
416  return false;
417  }
418 
419  Latitude lat(latitude, Angle::Degrees);
420  Longitude lon(longitude, Angle::Degrees);
421  Distance rad(radius, Distance::Meters);
422  shape->surfaceIntersection()->SetSpherical(lat, lon, rad);
423 
424  return SetGroundLocal(backCheck);
425  }
426 
427 
441  bool Sensor::SetGround(const SurfacePoint &surfacePt, bool backCheck) {
442  //std::cout << "Sensor::SetGround()\n";
443  ShapeModel *shape = target()->shape();
444  shape->clearSurfacePoint();
445 
446  // Can't intersect the sky
447  if (target()->isSky()) {
448  return false;
449  }
450 
451  shape->setSurfacePoint(surfacePt);
452 
453  return SetGroundLocal(backCheck);
454  }
455 
456 
469  bool Sensor::SetGroundLocal(bool backCheck) {
470  ShapeModel *shape = target()->shape();
471  // With the 3 spherical value compute the x/y/z coordinate
472  //latrec_c(m_radius, (m_longitude * PI / 180.0), (m_latitude * PI / 180.0), m_pB);
473 
474 
475  if (!(shape->surfaceIntersection()->Valid())) {
476  return false;
477  }
478 
479  // Make sure the point isn't on the backside of the body
480 
481  // This is static purely for performance reasons. A significant speedup
482  // is achieved here.
483  const vector<double> &sB =
485 
486  m_lookB[0] = shape->surfaceIntersection()->GetX().kilometers() - sB[0];
487  m_lookB[1] = shape->surfaceIntersection()->GetY().kilometers() - sB[1];
488  m_lookB[2] = shape->surfaceIntersection()->GetZ().kilometers() - sB[2];
489  m_newLookB = true;
490 
491  // See if the point is on the backside of the target
492 
493  if (backCheck) {
494  // Assume the intersection point is good in order to get the emission angle
495  shape->setHasIntersection(true);
496  if (fabs(shape->emissionAngle(sB)) > 90.) {
497  shape->clearSurfacePoint();
498  shape->setHasIntersection(false);
499  return false;
500  }
501  }
502 
503  // return with success
504  shape->setHasIntersection(true);
505 
506  return true;
507  }
508 
509 
515  void Sensor::LookDirection(double v[3]) const {
516  vector<double> lookC = instrumentRotation()->ReferenceVector(lookDirectionJ2000());
517  v[0] = lookC[0];
518  v[1] = lookC[1];
519  v[2] = lookC[2];
520  }
521 
527  vector<double> Sensor::lookDirectionBodyFixed() const {
528  vector<double> lookB(3);
529  lookB[0] = m_lookB[0];
530  lookB[1] = m_lookB[1];
531  lookB[2] = m_lookB[2];
532  return lookB;
533  }
534 
535 
541  vector<double> Sensor::lookDirectionJ2000() const {
542  vector<double> lookJ = bodyRotation()->J2000Vector(lookDirectionBodyFixed());
543  return lookJ;
544  }
545 
546 
547 
554  if (m_newLookB) computeRaDec();
555  return m_ra;
556  }
557 
558 
565  if (m_newLookB) computeRaDec();
566  return m_dec;
567  }
568 
569 
574  m_newLookB = false;
575  vector<double> lookB(3);
576  lookB[0] = m_lookB[0];
577  lookB[1] = m_lookB[1];
578  lookB[2] = m_lookB[2];
579  vector<double> lookJ = bodyRotation()->J2000Vector(lookB);
580 
581  SpiceDouble range;
582  recrad_c((SpiceDouble *)&lookJ[0], &range, &m_ra, &m_dec);
583  m_ra *= 180.0 / PI;
584  m_dec *= 180.0 / PI;
585  }
586 
587 
596  bool Sensor::SetRightAscensionDeclination(const double ra, const double dec) {
597  vector<double> lookJ(3);
598  radrec_c(1.0, ra * PI / 180.0, dec * PI / 180.0, (SpiceDouble *)&lookJ[0]);
599 
600  vector<double> lookC = instrumentRotation()->ReferenceVector(lookJ);
601  return SetLookDirection((double *)&lookC[0]);
602  }
603 
604 
613  void Sensor::SpacecraftSurfaceVector(double scSurfaceVector[3]) const {
614  scSurfaceVector[0] = m_lookB[0];
615  scSurfaceVector[1] = m_lookB[1];
616  scSurfaceVector[2] = m_lookB[2];
617  }
618 
619 
625  double Sensor::SlantDistance() const {
626  SpiceDouble psB[3], upsB[3];
627  SpiceDouble dist;
628 
629  std::vector<double> sB = bodyRotation()->ReferenceVector(instrumentPosition()->Coordinate());
630 
631  SpiceDouble pB[3];
632  ShapeModel *shape = target()->shape();
633  pB[0] = shape->surfaceIntersection()->GetX().kilometers();
634  pB[1] = shape->surfaceIntersection()->GetY().kilometers();
635  pB[2] = shape->surfaceIntersection()->GetZ().kilometers();
636 
637  vsub_c(pB, (SpiceDouble *) &sB[0], psB);
638  unorm_c(psB, upsB, &dist);
639  return dist;
640  }
641 
642 
649  double slat, slon;
650  subSolarPoint(slat, slon);
651 
652  double lst = UniversalLongitude() - slon + 180.0;
653  lst = lst / 15.0; // 15 degress per hour
654  if (lst < 0.0) lst += 24.0;
655  if (lst > 24.0) lst -= 24.0;
656  return lst;
657  }
658 
659 
665  double Sensor::SolarDistance() const {
666  // Get the sun coord
667  double sB[3];
668  Spice::sunPosition(sB);
669 
670  // Calc the change
671  ShapeModel *shape = target()->shape();
672  double xChange = sB[0] - shape->surfaceIntersection()->GetX().kilometers();
673  double yChange = sB[1] - shape->surfaceIntersection()->GetY().kilometers();
674  double zChange = sB[2] - shape->surfaceIntersection()->GetZ().kilometers();
675 
676  // Calc the distance and convert to AU
677  double dist = sqrt(xChange*xChange + yChange*yChange + zChange*zChange);
678  dist /= 149597870.691;
679  return dist;
680  }
681 
682 
690  // Get the spacecraft coord
691  double spB[3];
693 
694  // Get subspacecraft point
695  double lat, lon;
696  subSpacecraftPoint(lat, lon);
697  double rlat = lat * PI / 180.0;
698  double rlon = lon * PI / 180.0;
699 
700  // Compute radius
701  Distance rad = LocalRadius(lat, lon);
702 
703  // Now with the 3 spherical value compute the x/y/z coordinate
704  double ssB[3];
705  latrec_c(rad.kilometers(), rlon, rlat, ssB);
706 
707  // Calc the change
708  double xChange = spB[0] - ssB[0];
709  double yChange = spB[1] - ssB[1];
710  double zChange = spB[2] - ssB[2];
711 
712  // Calc the distance
713  double dist = sqrt(xChange*xChange + yChange*yChange + zChange*zChange);
714  return dist;
715  }
716 
717 
723 // Distance Sensor::DemRadius(const SurfacePoint &pt) {
724 // return DemRadius(pt.GetLatitude(), pt.GetLongitude());
725 // }
726 
727 
734 // Distance Sensor::DemRadius(const Latitude &lat, const Longitude &lon) {
735 // if (!m_hasElevationModel) return Distance();
736 // //if (!lat.Valid() || !lon.Valid()) return Distance();
737 // m_demProj->SetUniversalGround(lat.degrees(), lon.degrees());
738 // if (!m_demProj->IsGood()) {
739 // return Distance();
740 // }
741 
742 // m_portal->SetPosition(m_demProj->WorldX(), m_demProj->WorldY(), 1);
743 
744 // m_demCube->read(*m_portal);
745 
746 // const double &radius = m_interp->Interpolate(m_demProj->WorldX(),
747 // m_demProj->WorldY(),
748 // m_portal->DoubleBuffer());
749 
750 // return Distance(radius, Distance::Meters);
751 // Distance fred;
752 // return fred;
753 // }
754 
755 
766 // double Sensor::DemRadius(double lat, double lon) {
767 // if (!m_demProj->SetUniversalGround(lat, lon)) {
768 // return Isis::Null;
769 // }
770 
771 // m_portal->SetPosition(m_demProj->WorldX(), m_demProj->WorldY(), 1);
772 // m_demCube->read(*m_portal);
773 
774 // double radius = m_interp->Interpolate(m_demProj->WorldX(),
775 // m_demProj->WorldY(),
776 // m_portal->DoubleBuffer());
777 // if (Isis::IsSpecial(radius)) {
778 // return Isis::Null;
779 // }
780 
781 // return radius / 1000.0;
782 // double fred;
783 // return fred;
784 // }
791 // bool HasElevationModel() {
792 // return m_hasElevationModel;
793 // };
794 
795 }
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:86
double RightAscension()
Returns the right ascension angle (sky longitude).
Definition: Sensor.cpp:553
void IgnoreElevationModel(bool ignore)
This allows you to ignore the cube elevation model and use the ellipse.
Definition: Sensor.cpp:75
void SetSpherical(const Latitude &lat, const Longitude &lon, const Distance &radius, const Angle &latSigma=Angle(), const Angle &lonSigma=Angle(), const Distance &radiusSigma=Distance())
Set surface point and covariance matrix in planetocentric coordinates and convert to rectangular (Lat...
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:245
Parse and return pieces of a time string.
Definition: iTime.h:74
SpicePosition * sunPosition() const
Accessor method for the sun position.
Definition: Spice.cpp:1443
Distance GetLocalRadius() const
Return the radius of the surface point.
virtual QList< QPointF > PixelIfovOffsets()
This method is implemented in Camera which defaults to the (pixel pitch * summing mode ) / 2...
Definition: Sensor.cpp:96
double SlantDistance() const
Return the distance between the spacecraft and surface point in kmv.
Definition: Sensor.cpp:625
Latitude GetLatitude() const
Returns a planetocentric latitude object at the surface intersection point in body fixed...
Definition: Sensor.cpp:236
SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition: Spice.cpp:1476
Longitude GetLongitude() const
Returns a positive east, 0-360 domain longitude object at the surface intersection point in the body ...
Definition: Sensor.cpp:260
SpiceDouble m_dec
Decliation (sky latitude)
Definition: Sensor.h:257
bool hasIntersection()
Returns intersection status.
Definition: ShapeModel.cpp:309
std::vector< double > lookDirectionBodyFixed() const
Returns the look direction in the body fixed coordinate system.
Definition: Sensor.cpp:527
const double PI(3.14159265358979323846)
The mathematical constant PI.
bool SetRightAscensionDeclination(const double ra, const double dec)
Given the ra/dec compute the look direction.
Definition: Sensor.cpp:596
double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:225
bool SetGround(const SurfacePoint &surfacePt, bool backCheck=true)
This overloaded method has the opposite function as SetLookDirection.
Definition: Sensor.cpp:441
SpiceDouble m_lookB[3]
Look direction in body fixed.
Definition: Sensor.h:253
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:59
void computeRaDec()
Computes the ra/dec from the look direction.
Definition: Sensor.cpp:573
SpicePosition * instrumentPosition() const
Accessor method for the instrument position.
Definition: Spice.cpp:1454
bool SetUniversalGround(const double latitude, const double longitude, bool backCheck=true)
This is the opposite routine for SetLookDirection.
Definition: Sensor.cpp:371
bool SetLookDirection(const double v[3])
Sets the look direction of the spacecraft.
Definition: Sensor.cpp:156
bool m_newLookB
flag to indicate we need to recompute ra/dec
Definition: Sensor.h:255
virtual double emissionAngle(const std::vector< double > &sB)
Computes and returns emission angle, in degrees, given the observer position.
Definition: ShapeModel.cpp:126
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
Distance measurement, usually in meters.
Definition: Distance.h:47
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
bool SetGroundLocal(bool backCheck)
Computes look vector.
Definition: Sensor.cpp:469
double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:248
void setHasIntersection(bool b)
Sets the flag to indicate whether this ShapeModel has an intersection.
Definition: ShapeModel.cpp:465
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:52
virtual double phaseAngle(const std::vector< double > &sB, const std::vector< double > &uB)
Computes and returns phase angle, in degrees, given the positions of the observer and illuminator...
Definition: ShapeModel.cpp:265
Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1277
void restoreShape()
Restores the shape to the original after setShapeEllipsoid has overridden it.
Definition: Target.cpp:552
virtual ~Sensor()
Destroys the Sensor.
Definition: Sensor.cpp:66
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:69
std::vector< double > ReferenceVector(const std::vector< double > &jVec)
Given a direction vector in J2000, return a reference frame direction.
SpiceRotation * bodyRotation() const
Accessor method for the body rotation.
Definition: Spice.cpp:1465
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
double EmissionAngle() const
Returns the emission angle in degrees.
Definition: Sensor.cpp:339
double kilometers() const
Get the displacement in kilometers.
void subSolarPoint(double &lat, double &lon)
Returns the sub-solar latitude/longitude in universal coordinates (0-360 positive east...
Definition: Spice.cpp:1238
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
double PhaseAngle() const
Returns the phase angle in degrees.
Definition: Sensor.cpp:327
virtual double incidenceAngle(const std::vector< double > &uB)
Computes and returns incidence angle, in degrees, given the illuminator position. ...
Definition: ShapeModel.cpp:173
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition: Sensor.cpp:112
SurfacePoint GetSurfacePoint() const
Returns the surface point (most efficient accessor).
Definition: Sensor.cpp:270
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition: Sensor.cpp:201
void clearSurfacePoint()
Clears or resets the current surface point.
Definition: ShapeModel.cpp:327
double SpacecraftAltitude()
Returns the distance from the spacecraft to the subspacecraft point in km.
Definition: Sensor.cpp:689
Define shapes and provide utilities for Isis3 targets.
Definition: ShapeModel.h:68
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition: Sensor.cpp:211
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:282
SpiceDouble m_ra
Right ascension (sky longitude)
Definition: Sensor.h:256
std::vector< double > J2000Vector(const std::vector< double > &rVec)
Given a direction vector in the reference frame, return a J2000 direction.
double SolarDistance() const
Returns the distance between the sun and surface point in AU.
Definition: Sensor.cpp:665
void setSurfacePoint(const SurfacePoint &surfacePoint)
Set surface intersection point.
Definition: ShapeModel.cpp:476
void setShapeEllipsoid()
Set the shape to the ellipsoid and save the original shape.
Definition: Target.cpp:570
Isis exception class.
Definition: IException.h:99
Obtain SPICE information for a spacecraft.
Definition: Spice.h:282
The distance is being specified in meters.
Definition: Distance.h:56
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:118
void SpacecraftSurfaceVector(double scSurfaceVector[3]) const
Sets the vector between the spacecraft and surface point in body-fixed.
Definition: Sensor.cpp:613
double LocalSolarTime()
Return the local solar time in hours.
Definition: Sensor.cpp:648
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:592
void LookDirection(double v[3]) const
Returns the look direction in the camera coordinate system.
Definition: Sensor.cpp:515
SpiceDouble m_uB[3]
This contains the sun position (u) in the bodyfixed reference frame (B).
Definition: Spice.h:364
double IncidenceAngle() const
Returns the incidence angle in degrees.
Definition: Sensor.cpp:350
SurfacePoint * surfaceIntersection() const
Returns the surface intersection for this ShapeModel.
Definition: ShapeModel.cpp:299
std::vector< double > lookDirectionJ2000() const
Returns the look direction in the camera coordinate system.
Definition: Sensor.cpp:541
void setTime(const iTime &time)
Sets the ephemeris time and reads the spacecraft and sun position from the kernels at that instant in...
Definition: Spice.cpp:700
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double Declination()
Returns the declination angle (sky latitude).
Definition: Sensor.cpp:564
IO Handler for Isis Cubes.
Definition: Cube.h:158
void subSpacecraftPoint(double &lat, double &lon)
Returns the sub-spacecraft latitude/longitude in universal coordinates (0-360 positive east...
Definition: Spice.cpp:1189

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:28:50