USGS

Isis 3.0 Object Programmers' Reference

Home

MiniRF.cpp
Go to the documentation of this file.
1 
22 #include "MiniRF.h"
23 #include "IString.h"
24 #include "iTime.h"
25 #include "IException.h"
26 #include "RadarPulseMap.h"
27 #include "RadarGroundRangeMap.h"
28 #include "RadarSlantRangeMap.h"
29 #include "RadarGroundMap.h"
30 #include "RadarSkyMap.h"
31 
32 using namespace std;
33 
34 namespace Isis {
49  MiniRF::MiniRF(Isis::Cube &cube) : Isis::RadarCamera(cube) {
50 
51  // Get the ground range resolution (ScaledPixelHeight and ScaledPixelWidth
52  // are expected to be equal - mrf2isis checks for this)
53  Pvl &lab = *cube.label();
54  Isis::PvlGroup &inst = lab.findGroup("Instrument", Isis::Pvl::Traverse);
55  double groundRangeResolution = inst["ScaledPixelHeight"]; // meters
56 
57  // Synthesize the pixel pitch to the ground range resolution
58  SetPixelPitch(groundRangeResolution); // meters/pix
59 
60  // Focal length should always be slant range to the current ground
61  // point. This will be set each time the slant range is calculated.
62  // For now, set the focal length to 1.0.
63  SetFocalLength(1.0);
64 
65  // Get the start time from labels (the SpacecraftClockStartCount is set to
66  // is set to UNK in the PDS labels, so StartTime is used instead)
67  SpiceDouble etStart = iTime((QString)inst["StartTime"]).Et();
68 
69  // The line rate is in units of seconds in the PDS label. The exposure
70  // is the sum of the burst and the delay for the return. The movement of the
71  // spacecraft is negligible compared to the speed of light, so we are assuming
72  // the spacecraft hasn't moved between the burst and the return.
73  double lineRate = (double) inst["LineExposureDuration"];
74 
75  // Get the incidence angle at the center of the image
76  double incidenceAngle = (double) inst["IncidenceAngle"];
77  incidenceAngle = incidenceAngle * Isis::PI / 180.0;
78 
79  // Get the azimuth resolution at the center of the image
80  double azimuthResolution = (double) inst["AzimuthResolution"]; // label units are meters
81  azimuthResolution = azimuthResolution / 1000.0; // change to km
82 
83  // Get the range resolution at the center of the image
84  double rangeResolution = (double) inst["RangeResolution"]; // label units are meters
85 
86  // Get the wavelength or frequency of the instrument. This does not
87  // exist in the PDS labels, so it will need to be hardcoded until the
88  // PDS labels are updated. Right now, the mrf2isis program is putting
89  // a frequency value in the labels based on the instrument mode id.
90  double frequency = (double) inst["Frequency"]; // units are htz
91  double waveLength = clight_c() / frequency; // units are km/sec/htz
92 
93  // Setup map from image(sample,line) to radar(sample,time)
94  new RadarPulseMap(this, etStart, lineRate);
95 
96  // Setup map from radar(sample,time) to radar(groundrange,time)
97  Radar::LookDirection ldir = Radar::Right;
98  if((QString)inst["LookDirection"] == "LEFT") {
99  ldir = Radar::Left;
100  }
101  RadarGroundRangeMap::setTransform(naifIkCode(), groundRangeResolution,
102  this->Samples(), ldir);
103  new RadarGroundRangeMap(this, naifIkCode());
104 
105  // Calculate weighting for focal plane coordinates. This is done
106  // because the focal plane coordinates (slant range and Doppler
107  // shift) do not have the same units of measurement and cannot
108  // be used by jigsaw as is. The weighting factors convert the
109  // focal plane coordinates into comparitive values. The weighting
110  // factor for the Doppler shift requires spacecraft pointing and
111  // velocity at the center of the image, so it is calculated
112  // after Spice gets loaded.
113  double range_sigma = rangeResolution * sin(incidenceAngle) * 100; // scaled meters
114  double etMid = etStart + 0.5 * (this->ParentLines() + 1) * lineRate;
115 
116  // Setup the map from Radar(groundRange,t) to Radar(slantRange,t)
117  RadarSlantRangeMap *slantRangeMap = new RadarSlantRangeMap(this,
118  groundRangeResolution);
119  slantRangeMap->SetCoefficients(inst["RangeCoefficientSet"]);
120 
121  // Setup the ground and sky map
122  RadarGroundMap *groundMap = new RadarGroundMap(this, ldir, waveLength);
123  groundMap->SetRangeSigma(range_sigma);
124  new RadarSkyMap(this);
125 
126  // Set the time range to cover the cube
127  // Must be done last as the naif kernels will be unloaded
128  double etEnd = etStart + this->ParentLines() * lineRate + lineRate;
129  etStart = etStart - lineRate;
130  double tol = PixelResolution() / 100.;
131 
132  if(tol < 0.) {
133  // Alternative calculation of .01*ground resolution of a pixel
134  setTime(etMid);
135  tol = PixelPitch() * SpacecraftAltitude() / FocalLength() / 100.;
136  }
137  Spice::createCache(etStart, etEnd, this->ParentLines() + 1, tol);
138  setTime(etMid);
139  SpiceRotation *bodyFrame = this->bodyRotation();
140  SpicePosition *spaceCraft = this->instrumentPosition();
141 
142  SpiceDouble Ssc[6];
143  // Load the state into Ssc
144  vequ_c((SpiceDouble *) & (spaceCraft->Coordinate()[0]), Ssc);
145  vequ_c((SpiceDouble *) & (spaceCraft->Velocity()[0]), Ssc + 3);
146  // Create the J2000 to body-fixed state transformation matrix BJ
147  SpiceDouble BJ[6][6];
148  rav2xf_c(&(bodyFrame->Matrix()[0]), (SpiceDouble *) & (bodyFrame->AngularVelocity()[0]), BJ);
149  // Rotate the spacecraft state from J2000 to body-fixed
150  mxvg_c(BJ, Ssc, 6, 6, Ssc);
151  // Extract the body-fixed position and velocity
152  double Vsc[3];
153  double Xsc[3];
154  vequ_c(Ssc, Xsc);
155  vequ_c(Ssc + 3, Vsc);
156 
158  this->radii(radii);
159  double R = radii[0].kilometers();
160  double height = sqrt(Xsc[0] * Xsc[0] + Xsc[1] * Xsc[1] + Xsc[2] * Xsc[2]) - R;
161  double speed = vnorm_c(Vsc);
162  double dopplerSigma = 2.0 * speed * azimuthResolution / (waveLength *
163  height / cos(incidenceAngle)) * 100.;
164  groundMap->SetDopplerSigma(dopplerSigma);
165  slantRangeMap->SetWeightFactors(range_sigma, dopplerSigma);
166  }
167 
174  int MiniRF::CkFrameId() const {
175  std::string msg = "Cannot generate CK for MiniRF";
177  }
178 
185  int MiniRF::CkReferenceId() const {
186  std::string msg = "Cannot generate CK for MiniRF";
188  }
189 }
190 
202  return new Isis::MiniRF(cube);
203 }