USGS

Isis 3.0 Object Programmers' Reference

Home

ProcessImportPds.cpp
Go to the documentation of this file.
1 
22 #include "ProcessImportPds.h"
23 
24 #include <QString>
25 
26 #include <iostream>
27 #include <QString>
28 #include <sstream>
29 
30 #include "IException.h"
31 #include "ImportPdsTable.h"
32 #include "IString.h"
33 #include "LineManager.h"
34 #include "OriginalLabel.h"
35 #include "PixelType.h"
36 #include "Preference.h"
37 #include "Projection.h"
38 #include "TProjection.h"
39 #include "Pvl.h"
40 #include "PvlObject.h"
41 #include "PvlTokenizer.h"
42 #include "PvlTranslationManager.h"
43 #include "SpecialPixel.h"
44 #include "Table.h"
45 #include "UserInterface.h"
46 
47 using namespace std;
48 namespace Isis {
49 
53  ProcessImportPds::ProcessImportPds() {
54  p_keepOriginalLabel = true;
55  p_encodingType = NONE;
56  p_jp2File.clear();
57 
58  // Set up a translater for PDS file of type IMAGE
59  Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory");
60  p_transDir = (QString) dataDir["Base"];
61  }
62 
63 
64  ProcessImportPds::~ProcessImportPds() {
65  }
66 
67 
82  void ProcessImportPds::SetPdsFile(const Isis::Pvl &pdsLabelPvl,
83  const QString &pdsDataFile,
84  PdsFileType allowedTypes) {
85 
86  // Save the label and file for future use
87  p_pdsLabel = pdsLabelPvl;
88  p_labelFile = pdsDataFile;
89  ProcessLabel(pdsDataFile, allowedTypes);
90  }
91 
92 
110  void ProcessImportPds::SetPdsFile(const QString &pdsLabelFile,
111  const QString &pdsDataFile,
112  Isis::Pvl &pdsLabel,
113  PdsFileType allowedTypes) {
114 
115  // Internalize the PDS label in the PVL that was passed in
116  try {
117  pdsLabel.read(pdsLabelFile);
118  }
119  catch (IException &e) {
120  throw IException(e, IException::User,
121  QObject::tr("This image does not contain a pds label. You will need an "
122  "image with a PDS label or a detached PDS label for this "
123  "image."), _FILEINFO_);
124  }
125 
126  // Save the label and file for future use
127  p_pdsLabel = pdsLabel;
128  p_labelFile = pdsLabelFile;
129  ProcessLabel(pdsDataFile, allowedTypes);
130  }
131 
132 
148  void ProcessImportPds::ProcessLabel(const QString &pdsDataFile, PdsFileType allowedTypes) {
149  // Create a temporary Isis::PvlTranslationManager so we can find out what
150  // type of PDS file this is (i.e., Qube or Image or SpectralQube)
151  stringstream trnsStrm;
152  trnsStrm << "Group = PdsTypeImage" << endl;
153  trnsStrm << " InputPosition = ROOT" << endl;
154  trnsStrm << " InputPosition = FILE" << endl;
155  trnsStrm << " InputPosition = UNCOMPRESSED_FILE" << endl;
156  trnsStrm << " InputKey = ^IMAGE" << endl;
157  trnsStrm << "EndGroup" << endl;
158  trnsStrm << "Group = PdsTypeL0" << endl;
159  trnsStrm << " InputPosition = L0_FILE" << endl;
160  trnsStrm << " InputKey = ^L0_IMAGE" << endl;
161  trnsStrm << "EndGroup" << endl;
162  trnsStrm << "Group = PdsTypeRdn" << endl;
163  trnsStrm << " InputPosition = RDN_FILE" << endl;
164  trnsStrm << " InputKey = ^RDN_IMAGE" << endl;
165  trnsStrm << "EndGroup" << endl;
166  trnsStrm << "Group = PdsTypeLoc" << endl;
167  trnsStrm << " InputPosition = LOC_FILE" << endl;
168  trnsStrm << " InputKey = ^LOC_IMAGE" << endl;
169  trnsStrm << "EndGroup" << endl;
170  trnsStrm << "Group = PdsTypeObs" << endl;
171  trnsStrm << " InputPosition = OBS_FILE" << endl;
172  trnsStrm << " InputKey = ^OBS_IMAGE" << endl;
173  trnsStrm << "EndGroup" << endl;
174  trnsStrm << "Group = PdsTypeQube" << endl;
175  trnsStrm << " InputKey = ^QUBE" << endl;
176  trnsStrm << "EndGroup" << endl;
177  trnsStrm << "Group = PdsTypeSpectralQube" << endl;
178  trnsStrm << " InputKey = ^SPECTRAL_QUBE" << endl;
179  trnsStrm << "EndGroup" << endl;
180  trnsStrm << "Group = PdsEncodingType" << endl;
181  trnsStrm << " InputPosition = COMPRESSED_FILE" << endl;
182  trnsStrm << " InputKey = ENCODING_TYPE" << endl;
183  trnsStrm << " Translation = (*,*)" << endl;
184  trnsStrm << "EndGroup" << endl;
185  trnsStrm << "Group = PdsCompressedFile" << endl;
186  trnsStrm << " InputPosition = COMPRESSED_FILE" << endl;
187  trnsStrm << " InputKey = FILE_NAME" << endl;
188  trnsStrm << " Translation = (*,*)" << endl;
189  trnsStrm << "EndGroup" << endl;
190  trnsStrm << "END";
191 
192  Isis::PvlTranslationManager pdsXlater(p_pdsLabel, trnsStrm);
193 
194  // Check to see if we are dealing with a JPEG2000 file
195  QString str;
196  if (pdsXlater.InputHasKeyword("PdsEncodingType")) {
197  str = pdsXlater.Translate("PdsEncodingType");
198  if (str == "JP2") {
199  p_encodingType = JP2;
200  str = pdsXlater.Translate("PdsCompressedFile");
201  if (pdsDataFile.isEmpty()) {
202  Isis::FileName lfile(p_labelFile);
203  Isis::FileName ifile(lfile.path() + "/" + str);
204  if (ifile.fileExists()) {
205  p_jp2File = ifile.expanded();
206  }
207  else {
208  QString tmp = ifile.expanded();
209  str = str.toLower();
210  ifile = lfile.path() + "/" + str;
211  if (ifile.fileExists()) {
212  p_jp2File = ifile.expanded();
213  }
214  else {
215  QString msg = "Unable to find input file [" + tmp + "] or [" +
216  ifile.expanded() + "]";
217  throw IException(IException::Io, msg, _FILEINFO_);
218  }
219  }
220  }
221  }
222  else {
223  QString msg = "Unsupported encoding type in [" + p_labelFile + "]";
224  throw IException(IException::Io, msg, _FILEINFO_);
225  }
226  }
227 
228  // Call the correct label processing
229  if ((allowedTypes & Image) == Image && pdsXlater.InputHasKeyword("PdsTypeImage")) {
230  ProcessPdsImageLabel(pdsDataFile);
231  }
232  else if ((allowedTypes & Qube) == Qube && pdsXlater.InputHasKeyword("PdsTypeQube")) {
233  ProcessPdsQubeLabel(pdsDataFile, "pdsQube.trn");
234  }
235  else if ((allowedTypes & SpectralQube) == SpectralQube &&
236  pdsXlater.InputHasKeyword("PdsTypeSpectralQube")) {
237  ProcessPdsQubeLabel(pdsDataFile, "pdsSpectralQube.trn");
238  }
239  else if ((allowedTypes & L0) == L0 && pdsXlater.InputHasKeyword("PdsTypeL0")) {
240  ProcessPdsM3Label(pdsDataFile, L0);
241  }
242  else if ((allowedTypes & Rdn) == Rdn && pdsXlater.InputHasKeyword("PdsTypeRdn")) {
243  ProcessPdsM3Label(pdsDataFile, Rdn);
244  }
245  else if ((allowedTypes & Loc) == Loc && pdsXlater.InputHasKeyword("PdsTypeLoc")) {
246  ProcessPdsM3Label(pdsDataFile, Loc);
247  }
248  else if ((allowedTypes & Obs) == Obs && pdsXlater.InputHasKeyword("PdsTypeObs")) {
249  ProcessPdsM3Label(pdsDataFile, Obs);
250  }
251  else {
252  QString msg = "Unknown label type in [" + p_labelFile + "]";
253  throw IException(IException::Io, msg, _FILEINFO_);
254  }
255 
256  // Find out if this is a PDS file or an ISIS2 file
257  IdentifySource(p_pdsLabel);
258 
259  return;
260  }
261 
262 
269  void ProcessImportPds::ProcessDataFilePointer(Isis::PvlTranslationManager & pdsXlater, const bool & calcOffsetOnly) {
270  const PvlKeyword & dataFilePointer = pdsXlater.InputKeyword("DataFilePointer");
271 
272  QString dataFileName;
273  QString units;
274  QString str;
275  int offset = -1;
276 
277  // If only size 1, we either have a file name or an offset
278  // Either way, when we're done with these two ifs, variables offset and
279  // dataFileName will be set.
280  if (dataFilePointer.size() == 1) {
281  try {
282  str = pdsXlater.Translate("DataFilePointer");
283  offset = toInt(str);
284  units = dataFilePointer.unit();
285  // Successful? we have an offset, means current, p_labelFile
286  // is the location of the data as well
287  dataFileName = FileName(p_labelFile).name();
288  }
289  catch(IException &e) {
290  // Failed to parse to an int, means we have a file name
291  // No offset given, so we use 1, offsets are 1 based
292  offset = 1;
293  units = "BYTES";
294  dataFileName = str;
295  }
296  }
297  // We must have a filename and an offset, in that order
298  // Expection ("filname", <offset>)
299  else if (dataFilePointer.size() == 2) {
300  dataFileName = pdsXlater.Translate("DataFilePointer", 0);
301  offset = IString(pdsXlater.Translate("DataFilePointer", 1)).ToInteger();
302  units = dataFilePointer.unit(1);
303  }
304  // Error, no value
305  else if (dataFilePointer.size() == 0) {
306  QString msg = "Data file pointer ^IMAGE or ^QUBE has no value, must"
307  "have either file name or offset or both, in [" +
308  p_labelFile + "]";
309  throw IException(IException::Unknown, msg, _FILEINFO_);
310  }
311  // Error, more than two values
312  else {
313  QString msg = "Improperly formatted data file pointer keyword ^IMAGE or "
314  "^QUBE, in [" + p_labelFile + "], must contain filename "
315  " or offset or both";
316  throw IException(IException::Unknown, msg, _FILEINFO_);
317  }
318 
319  // Now, to handle the values we found
320  // the filename first, only do so if calcOffsetOnly is false
321  if (!calcOffsetOnly) {
322  Isis::FileName labelFile(p_labelFile);
323 
324  // If dataFileName isn't empty, and does start at the root, use it
325  Isis::FileName dataFile;
326  if (dataFileName.size() != 0 && dataFileName.at(0) == '/')
327  dataFile = FileName(dataFileName);
328  // Otherwise, use the path to it and its name
329  else
330  dataFile = FileName(labelFile.path() + "/" + dataFileName);
331 
332  // If it exists, use it
333  if (dataFile.fileExists()) {
334  SetInputFile(dataFile.expanded());
335  }
336  // Retry with downcased name, if still no luck, fail
337  else {
338  QString tmp = dataFile.expanded();
339  dataFileName = dataFileName.toLower();
340  dataFile = FileName(labelFile.path() + "/" + dataFileName);
341  if (dataFile.fileExists()) {
342  SetInputFile(dataFile.expanded());
343  }
344  else {
345  QString msg = "Unable to find input file [" + tmp + "] or [" +
346  dataFile.expanded() + "]";
347  throw IException(IException::Io, msg, _FILEINFO_);
348  }
349  }
350  }
351 
352  // Now, to handle the offset
353  units = units.trimmed();
354  if (units == "BYTES" || units == "B") {
355  SetFileHeaderBytes(offset - 1);
356  }
357  else {
358  QString recSize = pdsXlater.Translate("DataFileRecordBytes");
359  SetFileHeaderBytes((offset - 1) * toInt(recSize));
360  }
361  }
362 
363 
368  void ProcessImportPds::ProcessPixelBitandType(Isis::PvlTranslationManager & pdsXlater) {
369  QString str;
370  str = pdsXlater.Translate("CoreBitsPerPixel");
371  int bitsPerPixel = toInt(str);
372  str = pdsXlater.Translate("CorePixelType");
373  if ((str == "Real") && (bitsPerPixel == 64)) {
374  SetPixelType(Isis::Double);
375  }
376  else if ((str == "Real") && (bitsPerPixel == 32)) {
377  SetPixelType(Isis::Real);
378  }
379  else if ((str == "Integer") && (bitsPerPixel == 8)) {
380  SetPixelType(Isis::UnsignedByte);
381  }
382  else if ((str == "Integer") && (bitsPerPixel == 16)) {
383  SetPixelType(Isis::SignedWord);
384  }
385  else if ((str == "Integer") && (bitsPerPixel == 32)) {
386  SetPixelType(Isis::SignedInteger);
387  }
388  else if ((str == "Natural") && (bitsPerPixel == 8)) {
389  SetPixelType(Isis::UnsignedByte);
390  }
391  else if ((str == "Natural") && (bitsPerPixel == 16)) {
392  SetPixelType(Isis::UnsignedWord);
393  }
394  else if ((str == "Natural") && (bitsPerPixel == 16)) {
395  SetPixelType(Isis::SignedWord);
396  }
397  else if ((str == "Natural") && (bitsPerPixel == 32)) {
398  SetPixelType(Isis::UnsignedInteger);
399  }
400  else {
401  QString msg = "Invalid PixelType and BitsPerPixel combination [" + str +
402  ", " + toString(bitsPerPixel) + "]";
403  throw IException(IException::Io, msg, _FILEINFO_);
404  }
405  }
406 
407 
411  void ProcessImportPds::ProcessSpecialPixels(Isis::PvlTranslationManager & pdsXlater, const bool & isQube) {
412  QString str;
413  // Set any special pixel values
414  double pdsNull = Isis::NULL8;
415  if (pdsXlater.InputHasKeyword("CoreNull")) {
416  str = pdsXlater.Translate("CoreNull");
417  if (str != "NULL") {
418  pdsNull = toDouble(str);
419  }
420  }
421  else if (!isQube && pdsXlater.InputHasKeyword("CoreNull2")) {
422  str = pdsXlater.Translate("CoreNull2");
423  if (str != "NULL") {
424  pdsNull = toDouble(str);
425  }
426  }
427 
428  double pdsLrs = Isis::Lrs;
429  if (pdsXlater.InputHasKeyword("CoreLrs")) {
430  str = pdsXlater.Translate("CoreLrs");
431  if (str != "NULL") {
432  pdsLrs = toDouble(str);
433  }
434  }
435  else if (!isQube && pdsXlater.InputHasKeyword("CoreLrs2")) {
436  str = pdsXlater.Translate("CoreLrs2");
437  if (str != "NULL") {
438  pdsLrs = toDouble(str);
439  }
440  }
441 
442  double pdsLis = Isis::Lis;
443  if (pdsXlater.InputHasKeyword("CoreLis")) {
444  str = pdsXlater.Translate("CoreLis");
445  if (str != "NULL") {
446  pdsLis = toDouble(str);
447  }
448  }
449  else if (!isQube && pdsXlater.InputHasKeyword("CoreLis2")) {
450  str = pdsXlater.Translate("CoreLis2");
451  if (str != "NULL") {
452  pdsLis = toDouble(str);
453  }
454  }
455 
456  double pdsHrs = Isis::Hrs;
457  if (pdsXlater.InputHasKeyword("CoreHrs")) {
458  str = pdsXlater.Translate("CoreHrs");
459  if (str != "NULL") {
460  pdsHrs = toDouble(str);
461  }
462  }
463  else if (!isQube && pdsXlater.InputHasKeyword("CoreHrs2")) {
464  str = pdsXlater.Translate("CoreHrs2");
465  if (str != "NULL") {
466  pdsHrs = toDouble(str);
467  }
468  }
469 
470  double pdsHis = Isis::His;
471  if (pdsXlater.InputHasKeyword("CoreHis")) {
472  str = pdsXlater.Translate("CoreHis");
473  if (str != "NULL") {
474  pdsHis = toDouble(str);
475  }
476  }
477  else if (!isQube && pdsXlater.InputHasKeyword("CoreHis2")) {
478  str = pdsXlater.Translate("CoreHis2");
479  if (str != "NULL") {
480  pdsHis = toDouble(str);
481  }
482  }
483 
484  SetSpecialValues(pdsNull, pdsLrs, pdsLis, pdsHrs, pdsHis);
485  }
486 
487 
499  void ProcessImportPds::ProcessPdsImageLabel(const QString &pdsDataFile) {
500  Isis::FileName transFile(p_transDir + "/translations/pdsImage.trn");
501  Isis::PvlTranslationManager pdsXlater(p_pdsLabel, transFile.expanded());
502 
503  QString str;
504 
505  str = pdsXlater.Translate("CoreLinePrefixBytes");
506  SetDataPrefixBytes(toInt(str));
507 
508  str = pdsXlater.Translate("CoreLineSuffixBytes");
509  SetDataSuffixBytes(toInt(str));
510 
511  ProcessPixelBitandType(pdsXlater);
512 
513  str = pdsXlater.Translate("CoreByteOrder");
514  SetByteOrder(Isis::ByteOrderEnumeration(str));
515 
516  str = pdsXlater.Translate("CoreSamples");
517  int ns = toInt(str);
518  str = pdsXlater.Translate("CoreLines");
519  int nl = toInt(str);
520  str = pdsXlater.Translate("CoreBands");
521  int nb = toInt(str);
522  SetDimensions(ns, nl, nb);
523 
524  // Set any special pixel values, not qube, so use false
525  ProcessSpecialPixels(pdsXlater, false);
526 
527  //-----------------------------------------------------------------
528  // Find the data filename it may be the same as the label file
529  // OR the label file may contain a pointer to the data
530  //-----------------------------------------------------------------
531 
532  // Use the name supplied by the application if it is there
533  if (pdsDataFile.length() > 0) {
534  SetInputFile(pdsDataFile);
535  ProcessDataFilePointer(pdsXlater, true);
536  }
537  // If the data is in JPEG 2000 format, then use the name of the file
538  // from the label
539  else if (p_jp2File.length() > 0) {
540  SetInputFile(p_jp2File);
541  ProcessDataFilePointer(pdsXlater, true);
542  }
543  // Use the "^IMAGE or ^QUBE" label to get the filename for the image data
544  // Get the path portion from user entered label file spec
545  else {
546  // Handle filename and offset
547  ProcessDataFilePointer(pdsXlater, false);
548  }
549 
550  //------------------------------------------------------------
551  // Find the image data base and multiplier
552  //------------------------------------------------------------
553  str = pdsXlater.Translate("CoreBase");
554  SetBase(toDouble(str));
555  str = pdsXlater.Translate("CoreMultiplier");
556  SetMultiplier(toDouble(str));
557 
558  // Find the organization of the image data
559  str = pdsXlater.Translate("CoreOrganization");
560 
561  if (p_encodingType == JP2) {
562  SetOrganization(ProcessImport::JP2);
563  }
564  else if (str == "BSQ") {
565  SetOrganization(ProcessImport::BSQ);
566  }
567  else if (str == "BIP") {
568  SetOrganization(ProcessImport::BIP);
569  }
570  else if (str == "BIL") {
571  SetOrganization(ProcessImport::BIL);
572  }
573  else {
574  QString msg = "Unsupported axis order [" + str + "]";
575  throw IException(IException::Programmer, msg, _FILEINFO_);
576  }
577  }
578 
579 
596  void ProcessImportPds::ProcessPdsQubeLabel(const QString &pdsDataFile,
597  const QString &transFile) {
598 
599  Isis::FileName tFile(p_transDir + "/translations/" + transFile);
600 
601  Isis::PvlTranslationManager pdsXlater(p_pdsLabel, tFile.expanded());
602 
603  QString str;
604 
605  // Find the organization of the image data
606  // Save off which axis the samples, lines and bands are on
607  int linePos = 0;
608  int samplePos = 0;
609  int bandPos = 0;
610  int val = pdsXlater.InputKeyword("CoreOrganization").size();
611  QString tmp = "";
612  for(int i = 0; i < val; i++) {
613  str = pdsXlater.Translate("CoreOrganization", i);
614  tmp += str;
615  if (str == "SAMPLE") {
616  samplePos = i;
617  }
618  else if (str == "LINE") {
619  linePos = i;
620  }
621  else if (str == "BAND") {
622  bandPos = i;
623  }
624  else {
625  QString message = "Unknown file axis name [" + str + "]";
626  throw IException(IException::User, message, _FILEINFO_);
627  }
628  }
629 
630  if (p_encodingType == JP2) {
631  SetOrganization(ProcessImport::JP2);
632  }
633  else if (tmp == "SAMPLELINEBAND") {
634  SetOrganization(ProcessImport::BSQ);
635  }
636  else if (tmp == "BANDSAMPLELINE") {
637  SetOrganization(ProcessImport::BIP);
638  }
639  else if (tmp == "SAMPLEBANDLINE") {
640  SetOrganization(ProcessImport::BIL);
641  }
642  else {
643  PvlKeyword pdsCoreOrg = p_pdsLabel.findKeyword(pdsXlater.
644  InputKeywordName("CoreOrganization"), Pvl::Traverse);
645 
646  stringstream pdsCoreOrgStream;
647  pdsCoreOrgStream << pdsCoreOrg;
648 
649  QString msg = "Unsupported axis order [" + QString(pdsCoreOrgStream.str().c_str()) + "]";
650  throw IException(IException::Programmer, msg, _FILEINFO_);
651  }
652 
653 
654  // Set the number of byte preceding the second dimension (left side plane)
655  // There are no capabilities in a PDS QUBE for this
656  SetDataPrefixBytes(0);
657 
658  // Set the number of bytes following the second dimension (right side plane)
659  str = pdsXlater.Translate("SuffixItemSize");
660  int suffix = toInt(str);
661  str = pdsXlater.Translate("AxisSuffixCount", 0);
662  suffix *= toInt(str);
663  SetDataSuffixBytes(suffix);
664 
665  str = pdsXlater.Translate("SuffixItemSize");
666  int trailer = toInt(str);
667  str = pdsXlater.Translate("AxisSuffixCount", 1);
668  trailer *= toInt(str);
669  str = pdsXlater.Translate("CoreSamples", samplePos);
670  trailer *= toInt(str);
671  trailer += suffix;
672  SetDataTrailerBytes(trailer);
673 
674  ProcessPixelBitandType(pdsXlater);
675 
676  // Set the byte order
677  str = pdsXlater.Translate("CoreByteOrder");
678  SetByteOrder(Isis::ByteOrderEnumeration(str));
679 
680  // Set the number of samples, lines and bands
681  str = pdsXlater.Translate("CoreSamples", samplePos);
682  int ns = toInt(str);
683  str = pdsXlater.Translate("CoreLines", linePos);
684  int nl = toInt(str);
685  str = pdsXlater.Translate("CoreBands", bandPos);
686  int nb = toInt(str);
687  SetDimensions(ns, nl, nb);
688 
689  // Set any special pixels values, qube, so use true
690  ProcessSpecialPixels(pdsXlater, true);
691 
692  //---------------------------------------------------------------
693  // Find the data filename, it may be the same as the label file
694  // Or the label file may contain a pointer to the data
695  //---------------------------------------------------------------
696 
697  // Use the name supplied by the application if it is there
698  if (pdsDataFile.length() > 0) {
699  SetInputFile(pdsDataFile);
700  ProcessDataFilePointer(pdsXlater, true);
701  }
702  // If the data is in JPEG 2000 format, then use the name of the file
703  // from the label
704  else if (p_jp2File.length() > 0) {
705  SetInputFile(p_jp2File);
706  ProcessDataFilePointer(pdsXlater, true);
707  }
708  else {
709  // Handle filename and offset
710  ProcessDataFilePointer(pdsXlater, false);
711  }
712 
713 
714  //------------------------------------------------------------
715  // Find the image data base and multiplier
716  //------------------------------------------------------------
717  // First see if there are base and multiplier in the band bin group
718  if ((pdsXlater.InputHasKeyword("BandBase")) &&
719  (pdsXlater.InputHasKeyword("BandMultiplier"))) {
720  vector<double> bases;
721  vector<double> mults;
722  for(int i = 0; i < pdsXlater.InputKeyword("BandBase").size(); i++) {
723  str = pdsXlater.Translate("BandBase", i);
724  bases.push_back(toDouble(str));
725  str = pdsXlater.Translate("BandMultiplier", i);
726  mults.push_back(toDouble(str));
727  }
728  SetBase(bases);
729  SetMultiplier(mults);
730  }
731  else {
732  str = pdsXlater.Translate("CoreBase");
733  SetBase(toDouble(str));
734  str = pdsXlater.Translate("CoreMultiplier");
735  SetMultiplier(toDouble(str));
736  }
737  }
738 
739 
751  void ProcessImportPds::ProcessPdsM3Label(const QString &pdsDataFile, PdsFileType fileType) {
752  Isis::FileName transFile;
753  if (fileType == L0) {
754  transFile = p_transDir + "/translations/pdsL0.trn";
755  }
756  else if (fileType == Rdn) {
757  transFile = p_transDir + "/translations/pdsRdn.trn";
758  }
759  else if (fileType == Loc) {
760  transFile = p_transDir + "/translations/pdsLoc.trn";
761  }
762  else if (fileType == Obs) {
763  transFile = p_transDir + "/translations/pdsObs.trn";
764  }
765  else {
766  throw IException(IException::Programmer, "ProcessImportPds::ProcessPdsM3Label can only be "
767  "called with file type of L0, Rdn, Loc or Obs.", _FILEINFO_);
768  }
769  Isis::PvlTranslationManager pdsXlater(p_pdsLabel, transFile.expanded());
770 
771  QString str;
772 
773  // L1B (Rdn) products do not have an prefix or suffix data. L0 have 1280 bytes at the
774  // beginning of each line of the BIL formatted file.
775  str = pdsXlater.Translate("CoreLinePrefixBytes");
776  SetDataHeaderBytes(toInt(str));
777 
778  str = pdsXlater.Translate("CoreLineSuffixBytes");
779  SetDataSuffixBytes(toInt(str));
780 
781  ProcessPixelBitandType(pdsXlater);
782 
783  str = pdsXlater.Translate("CoreByteOrder");
784  SetByteOrder(Isis::ByteOrderEnumeration(str));
785 
786  str = pdsXlater.Translate("CoreSamples");
787  int ns = toInt(str);
788  str = pdsXlater.Translate("CoreLines");
789  int nl = toInt(str);
790  str = pdsXlater.Translate("CoreBands");
791  int nb = toInt(str);
792  SetDimensions(ns, nl, nb);
793 
794  // Set any special pixel values, not qube, so use false
795  ProcessSpecialPixels(pdsXlater, false);
796 
797  //-----------------------------------------------------------------
798  // Find the data filename it may be the same as the label file
799  // OR the label file may contain a pointer to the data
800  //-----------------------------------------------------------------
801 
802  // Use the name supplied by the application if it is there
803  if (pdsDataFile.length() > 0) {
804  SetInputFile(pdsDataFile);
805  ProcessDataFilePointer(pdsXlater, true);
806  }
807  // If the data is in JPEG 2000 format, then use the name of the file
808  // from the label
809  else if (p_jp2File.length() > 0) {
810  SetInputFile(p_jp2File);
811  ProcessDataFilePointer(pdsXlater, true);
812  }
813  // Use the "^IMAGE or ^QUBE" label to get the filename for the image data
814  // Get the path portion from user entered label file spec
815  else {
816  // Handle filename and offset
817  ProcessDataFilePointer(pdsXlater, false);
818  }
819 
820  //------------------------------------------------------------
821  // Find the image data base and multiplier
822  //------------------------------------------------------------
823  str = pdsXlater.Translate("CoreBase");
824  SetBase(toDouble(str));
825  str = pdsXlater.Translate("CoreMultiplier");
826  SetMultiplier(toDouble(str));
827 
828  // Find the organization of the image data
829  str = pdsXlater.Translate("CoreOrganization");
830 
831  if (p_encodingType == JP2) {
832  SetOrganization(ProcessImport::JP2);
833  }
834  else if (str == "BSQ") {
835  SetOrganization(ProcessImport::BSQ);
836  }
837  else if (str == "BIP") {
838  SetOrganization(ProcessImport::BIP);
839  }
840  else if (str == "BIL") {
841  SetOrganization(ProcessImport::BIL);
842  }
843  else {
844  QString msg = "Unsupported axis order [" + str + "]";
845  throw IException(IException::Programmer, msg, _FILEINFO_);
846  }
847  }
848 
849 
861  void ProcessImportPds::TranslatePdsProjection(Isis::Pvl &lab) {
862 
863  // Create a temporary Isis::PvlTranslationManager so we can find out what
864  // type of projection labels exist
865  stringstream trnsStrm;
866  trnsStrm << "Group = PdsProjectionTypeImage" << endl;
867  trnsStrm << " InputPosition = IMAGE_MAP_PROJECTION" << endl;
868  trnsStrm << " InputPosition = IMAGE_MAP_PROJECTION_CATALOG" << endl;
869  trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl;
870  trnsStrm << "EndGroup" << endl;
871  trnsStrm << "Group = PdsProjectionTypeQube" << endl;
872  trnsStrm << " InputPosition = (QUBE,IMAGE_MAP_PROJECTION)" << endl;
873  trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl;
874  trnsStrm << "EndGroup" << endl;
875  trnsStrm << "Group = PdsProjectionTypeSpectralQube" << endl;
876  trnsStrm << " InputPosition = (SPECTRAL_QUBE,IMAGE_MAP_PROJECTION)" << endl;
877  trnsStrm << " InputKey = MAP_PROJECTION_TYPE" << endl;
878  trnsStrm << "EndGroup" << endl;
879  trnsStrm << "END";
880 
881  Isis::PvlTranslationManager projType(p_pdsLabel, trnsStrm);
882 
883  // Set up the correct projection translation table for this label
884  Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory");
885  QString transDir = (QString) dataDir["Base"];
886 
887  Isis::FileName transFile;
888  if (projType.InputHasKeyword("PdsProjectionTypeImage")) {
889  transFile = transDir + "/" + "translations/pdsImageProjection.trn";
890  }
891  else if (projType.InputHasKeyword("PdsProjectionTypeQube")) {
892  transFile = transDir + "/" + "translations/pdsQubeProjection.trn";
893  }
894  else if (projType.InputHasKeyword("PdsProjectionTypeSpectralQube")) {
895  transFile = transDir + "/" + "translations/pdsSpectralQubeProjection.trn";
896  }
897  else {
898  return;
899  }
900 
901  Isis::PvlTranslationManager pdsXlater(p_pdsLabel, transFile.expanded());
902 
903  ExtractPdsProjection(pdsXlater);
904 
905  Isis::PvlGroup mapGroup("Mapping");
906  mapGroup += Isis::PvlKeyword("ProjectionName", p_projection);
907  mapGroup += Isis::PvlKeyword("TargetName", p_targetName);
908  mapGroup += Isis::PvlKeyword("EquatorialRadius", toString(p_equatorialRadius), "meters");
909  mapGroup += Isis::PvlKeyword("PolarRadius", toString(p_polarRadius), "meters");
910  mapGroup += Isis::PvlKeyword("LongitudeDirection", p_longitudeDirection);
911  mapGroup += Isis::PvlKeyword("LongitudeDomain", toString(p_longitudeDomain));
912  mapGroup += Isis::PvlKeyword("LatitudeType", p_latitudeType);
913  if (p_minimumLatitude != Isis::NULL8) {
914  mapGroup += Isis::PvlKeyword("MinimumLatitude", toString(p_minimumLatitude));
915  }
916  if (p_maximumLatitude != Isis::NULL8) {
917  mapGroup += Isis::PvlKeyword("MaximumLatitude", toString(p_maximumLatitude));
918  }
919  if (p_minimumLongitude != Isis::NULL8) {
920  mapGroup += Isis::PvlKeyword("MinimumLongitude", toString(p_minimumLongitude));
921  }
922  if (p_maximumLongitude != Isis::NULL8) {
923  mapGroup += Isis::PvlKeyword("MaximumLongitude", toString(p_maximumLongitude));
924  }
925 
926  // if both longitudes exist, verify they are ordered correctly
927  if (p_minimumLongitude != Isis::NULL8 && p_maximumLongitude != Isis::NULL8) {
928  if (p_maximumLongitude <= p_minimumLongitude) {
929  if (p_longitudeDomain == 180) {
930  mapGroup["MinimumLongitude"] = toString(-180);
931  mapGroup["MaximumLongitude"] = toString(180);
932  }
933  else {
934  mapGroup["MinimumLongitude"] = toString(0);
935  mapGroup["MaximumLongitude"] = toString(360);
936  }
937  }
938  }
939 
940  mapGroup += Isis::PvlKeyword("PixelResolution", toString(p_pixelResolution), "meters/pixel");
941  mapGroup += Isis::PvlKeyword("Scale", toString(p_scaleFactor), "pixels/degree");
942  mapGroup += Isis::PvlKeyword("UpperLeftCornerX", toString(p_upperLeftX), "meters");
943  mapGroup += Isis::PvlKeyword("UpperLeftCornerY", toString(p_upperLeftY), "meters");
944  if (p_rotation != 0.0) {
945  mapGroup += Isis::PvlKeyword("Rotation", toString(p_rotation));
946  }
947 
948  // To handle new projections without the need to modify source code
949  // we will construct a filename from the projection. The filename will
950  // contain the projection specific translations from PDS to ISIS for each
951  // projection
952 
953  QString projSpecificFileName = "$base/translations/pdsImport";
954  projSpecificFileName += p_projection + ".trn";
955  Isis::PvlTranslationManager specificXlater(p_pdsLabel, projSpecificFileName);
956 
957  lab.addGroup(mapGroup);
958  specificXlater.Auto(lab);
959 
960  if (lab.findGroup("Mapping").hasKeyword("CenterLongitude")) {
961  PvlKeyword &centerLon = lab.findGroup("Mapping")["CenterLongitude"];
962  if (p_longitudeDomain == 180)
963  centerLon = toString(TProjection::To180Domain((double)centerLon));
964  else
965  centerLon = toString(TProjection::To360Domain((double)centerLon));
966  }
967 
968  if (lab.findGroup("Mapping").hasKeyword("PoleLongitude")) {
969  PvlKeyword &poleLon = lab.findGroup("Mapping")["PoleLongitude"];
970  if (p_longitudeDomain == 180)
971  poleLon = toString(TProjection::To180Domain((double)poleLon));
972  else
973  poleLon = toString(TProjection::To360Domain((double)poleLon));
974  }
975 
976  OutputCubes[0]->putGroup(lab.findGroup("Mapping"));
977  }
978 
979 
1004  void ProcessImportPds::ExtractPdsProjection(Isis::PvlTranslationManager &pdsXlater) {
1005 
1006  QString str;
1007 
1008  if (pdsXlater.InputHasKeyword("ProjectionName")) {
1009  p_projection = pdsXlater.Translate("ProjectionName");
1010  }
1011  else {
1012  QString message = "No projection name in labels";
1013  throw IException(IException::Unknown, message, _FILEINFO_);
1014  }
1015 
1016  if (pdsXlater.InputHasKeyword("TargetName")) {
1017  p_targetName = pdsXlater.Translate("TargetName");
1018  }
1019  else {
1020  QString message = "No target name in labels";
1021  throw IException(IException::Unknown, message, _FILEINFO_);
1022  }
1023 
1024  if (pdsXlater.InputHasKeyword("EquatorialRadius")) {
1025  str = pdsXlater.Translate("EquatorialRadius");
1026  p_equatorialRadius = toDouble(str) * 1000.0;
1027  }
1028  else {
1029  QString message = "No equatorial radius name in labels";
1030  throw IException(IException::User, message, _FILEINFO_);
1031  }
1032 
1033  if (pdsXlater.InputHasKeyword("PolarRadius")) {
1034  str = pdsXlater.Translate("PolarRadius");
1035  p_polarRadius = toDouble(str) * 1000.0;
1036  }
1037  else {
1038  QString message = "No polar radius in labels";
1039  throw IException(IException::User, message, _FILEINFO_);
1040  }
1041 
1042  if (pdsXlater.InputHasKeyword("LongitudeDirection")) {
1043  p_longitudeDirection = pdsXlater.Translate("LongitudeDirection");
1044  }
1045  else {
1046  p_longitudeDirection = pdsXlater.Translate("LongitudeDirection2");
1047  }
1048 
1049  if (p_polarRadius == p_equatorialRadius) {
1050  p_latitudeType = "Planetocentric";
1051  }
1052  else if (pdsXlater.InputHasKeyword("LatitudeType2")) {
1053  p_latitudeType = pdsXlater.Translate("LatitudeType2");
1054  }
1055  else {
1056  p_latitudeType = pdsXlater.Translate("LatitudeType");
1057  }
1058 
1059  if (pdsXlater.InputHasKeyword("MinimumLatitude")) {
1060  str = pdsXlater.Translate("MinimumLatitude");
1061  try {
1062  p_minimumLatitude = toDouble(str);
1063  }
1064  catch(IException &e) {
1065  p_minimumLatitude = Isis::NULL8;
1066  }
1067  }
1068  else {
1069  p_minimumLatitude = Isis::NULL8;
1070  }
1071 
1072  if (pdsXlater.InputHasKeyword("MaximumLatitude")) {
1073  str = pdsXlater.Translate("MaximumLatitude");
1074  try {
1075  p_maximumLatitude = toDouble(str);
1076  }
1077  catch(IException &e) {
1078  p_maximumLatitude = Isis::NULL8;
1079  }
1080  }
1081  else {
1082  p_maximumLatitude = Isis::NULL8;
1083  }
1084 
1085  // This variable represents if the longitudes were read in as
1086  // positive west
1087  bool positiveWest = false;
1088  if (pdsXlater.InputHasKeyword("MinimumLongitude")) {
1089  str = pdsXlater.Translate("MinimumLongitude");
1090  try {
1091  positiveWest = true;
1092  p_minimumLongitude = toDouble(str);
1093  }
1094  catch(IException &e) {
1095  p_minimumLongitude = Isis::NULL8;
1096  }
1097  }
1098  else if (pdsXlater.InputHasKeyword("MinimumLongitude2")) {
1099  str = pdsXlater.Translate("MinimumLongitude2");
1100  try {
1101  p_minimumLongitude = toDouble(str);
1102  }
1103  catch(IException &e) {
1104  p_minimumLongitude = Isis::NULL8;
1105  }
1106  }
1107  else {
1108  p_minimumLongitude = Isis::NULL8;
1109  }
1110 
1111  if (pdsXlater.InputHasKeyword("MaximumLongitude")) {
1112  str = pdsXlater.Translate("MaximumLongitude");
1113  try {
1114  positiveWest = true;
1115  p_maximumLongitude = toDouble(str);
1116  }
1117  catch(IException &e) {
1118  p_maximumLongitude = Isis::NULL8;
1119  }
1120  }
1121  else if (pdsXlater.InputHasKeyword("MaximumLongitude2")) {
1122  str = pdsXlater.Translate("MaximumLongitude2");
1123  try {
1124  p_maximumLongitude = toDouble(str);
1125  }
1126  catch(IException &e) {
1127  p_maximumLongitude = Isis::NULL8;
1128  }
1129  }
1130  else {
1131  p_maximumLongitude = Isis::NULL8;
1132  }
1133 
1134  str = pdsXlater.Translate("LongitudeDomain");
1135  p_longitudeDomain = toInt(str);
1136 
1155  if (positiveWest && (p_longitudeDirection.compare("PositiveEast") == 0)) {
1156  double tmp = p_minimumLongitude;
1157  p_minimumLongitude = p_maximumLongitude;
1158  p_maximumLongitude = tmp;
1159  }
1160 
1161  if (p_minimumLongitude > p_maximumLongitude) {
1162  // Force the change to 180
1163  p_longitudeDomain = 180;
1164  p_minimumLongitude = Isis::TProjection::To180Domain(p_minimumLongitude);
1165  }
1166 
1167  // If either the minimumLongitude or maximumLongitude are < 0, change
1168  // longitude Domain to 180.
1169  if (p_minimumLongitude < 0 || p_maximumLongitude < 0) {
1170  p_longitudeDomain = 180;
1171  }
1172 
1173  str = pdsXlater.Translate("PixelResolution");
1174  p_pixelResolution = toDouble(str);
1175  str = pdsXlater.InputKeyword("PixelResolution").unit().toUpper();
1176  // Assume KM/PIXEL if the unit doesn't exist or is not METERS/PIXEL
1177  if ((str != "METERS/PIXEL") && (str != "M/PIXEL") && (str != "M/PIX")) {
1178  p_pixelResolution *= 1000.0;
1179  }
1180 
1181  str = pdsXlater.Translate("Scale");
1182  p_scaleFactor = toDouble(str);
1183 
1184  try {
1185  str = pdsXlater.Translate("Rotation");
1186  p_rotation = toDouble(str);
1187  }
1188  catch(IException &) {
1189  // assume no rotation if the value isn't a number
1190  p_rotation = 0.0;
1191  }
1192 
1193  // Look for projection offsets/mults to convert between line/samp and x/y
1194  double xoff, yoff, xmult, ymult;
1195  GetProjectionOffsetMults(xoff, yoff, xmult, ymult);
1196 
1197  if (pdsXlater.InputHasKeyword("LineProjectionOffset")) {
1198  str = pdsXlater.Translate("LineProjectionOffset");
1199  }
1200  else {
1201  str = pdsXlater.Translate("LineProjectionOffset2");
1202  }
1203  p_lineProjectionOffset = toDouble(str);
1204  p_upperLeftY = ymult * (p_lineProjectionOffset + yoff) * p_pixelResolution;
1205 
1206  if (pdsXlater.InputHasKeyword("SampleProjectionOffset")) {
1207  str = pdsXlater.Translate("SampleProjectionOffset");
1208  }
1209  else {
1210  str = pdsXlater.Translate("SampleProjectionOffset2");
1211  }
1212  p_sampleProjectionOffset = toDouble(str);
1213  p_upperLeftX = xmult * (p_sampleProjectionOffset + xoff) * p_pixelResolution;
1214 
1215 
1216  }
1217 
1218 
1222  void ProcessImportPds::EndProcess() {
1223  ProcessImportPds::Finalize();
1224  }
1225 
1226 
1232  void ProcessImportPds::Finalize() {
1233  if (p_keepOriginalLabel) {
1234  OriginalLabel ol(p_pdsLabel);
1235  for (unsigned int i = 0; i < OutputCubes.size(); i++) {
1236  OutputCubes[i]->write(ol);
1237  }
1238  }
1239  Process::Finalize();
1240  }
1241 
1242 
1247  void ProcessImportPds::OmitOriginalLabel() {
1248  p_keepOriginalLabel = false;
1249  }
1250 
1251 
1258  void ProcessImportPds::IdentifySource(Isis::Pvl &inputLabel) {
1259 
1260  // Create a temporary Isis::PvlTranslationManager so we can find out what
1261  // type of input file we have
1262  stringstream trnsStrm;
1263  trnsStrm << "Group = PdsFile" << endl;
1264  trnsStrm << " InputPosition = ROOT" << endl;
1265  trnsStrm << " InputKey = PDS_VERSION_ID" << endl;
1266  trnsStrm << "EndGroup" << endl;
1267  trnsStrm << "Group = Isis2File" << endl;
1268  trnsStrm << " InputPosition = ROOT" << endl;
1269  trnsStrm << " InputKey = CCSD3ZF0000100000001NJPL3IF0PDS200000001" << endl;
1270  trnsStrm << "EndGroup" << endl;
1271  trnsStrm << "END";
1272 
1273  Isis::PvlTranslationManager sourceXlater(inputLabel, trnsStrm);
1274 
1275  if (sourceXlater.InputHasKeyword("PdsFile")) {
1276  p_source = PDS;
1277  }
1278  else if (sourceXlater.InputHasKeyword("Isis2File")) {
1279  p_source = ISIS2;
1280  }
1281  else {
1282  p_source = NOSOURCE;
1283  }
1284 
1285  }
1286 
1287 
1296  bool ProcessImportPds::IsIsis2() {
1297 
1298  if (p_source == ISIS2) {
1299  return true;
1300  }
1301  else {
1302  return false;
1303  }
1304  }
1305 
1306 
1314  void ProcessImportPds::TranslateIsis2Labels(Isis::Pvl &lab) {
1315  TranslateIsis2BandBin(lab);
1316  TranslateIsis2Instrument(lab);
1317  }
1318 
1319 
1327  void ProcessImportPds::TranslatePdsLabels(Isis::Pvl &lab) {
1328  TranslatePdsBandBin(lab);
1329  TranslatePdsArchive(lab);
1330  }
1331 
1332 
1339  void ProcessImportPds::TranslateIsis2BandBin(Isis::Pvl &lab) {
1340  // Set up a translater for Isis2 labels
1341  Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory");
1342  QString transDir = (QString) dataDir["Base"];
1343 
1344  Isis::FileName transFile(transDir + "/" + "translations/isis2bandbin.trn");
1345  Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded());
1346 
1347  // Add all the Isis2 keywords that can be translated to the requested label
1348  isis2Xlater.Auto(lab);
1349  }
1350 
1351 
1358  void ProcessImportPds::TranslateIsis2Instrument(Isis::Pvl &lab) {
1359  // Set up a translater for Isis2 labels
1360  Isis::PvlGroup &dataDir = Isis::Preference::Preferences().findGroup("DataDirectory");
1361  QString transDir = (QString) dataDir["Base"];
1362  Isis::FileName transFile(transDir + "/" + "translations/isis2instrument.trn");
1363  Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded());
1364 
1365  // Add all the Isis2 keywords that can be translated to the requested label
1366  isis2Xlater.Auto(lab);
1367 
1368  //Check StartTime for appended 'z' (Zulu time) and remove
1369  Isis::PvlGroup &inst = lab.findGroup("Instrument");
1370 
1371  if (inst.hasKeyword("StartTime")) {
1372  Isis::PvlKeyword &stkey = inst["StartTime"];
1373  QString stime = stkey[0];
1374  stime = stime.remove(QRegExp("[Zz]$"));
1375  stkey = stime;
1376  }
1377  }
1378 
1379 
1386  void ProcessImportPds::TranslatePdsBandBin(Isis::Pvl &lab) {
1387  // Set up a translater for PDS labels
1388  Isis::FileName transFile(p_transDir + "/" + "translations/pdsImageBandBin.trn");
1389  Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded());
1390 
1391  // Add all the Isis2 keywords that can be translated to the requested label
1392  isis2Xlater.Auto(lab);
1393  }
1394 
1395 
1402  void ProcessImportPds::TranslatePdsArchive(Isis::Pvl &lab) {
1403  // Set up a translater for PDS labels
1404  Isis::FileName transFile(p_transDir + "/" + "translations/pdsImageArchive.trn");
1405  Isis::PvlTranslationManager isis2Xlater(p_pdsLabel, transFile.expanded());
1406 
1407  // Add all the Isis2 keywords that can be translated to the requested label
1408  isis2Xlater.Auto(lab);
1409  }
1410 
1411 
1424  void ProcessImportPds::GetProjectionOffsetMults(double &xoff, double &yoff,
1425  double &xmult, double &ymult) {
1426 
1427  xmult = -1.0;
1428  ymult = 1.0;
1429  xoff = -0.5;
1430  yoff = -0.5;
1431 
1432  // Open projectionOffsetMults file
1433  Isis::Pvl p(p_transDir + "/" + "translations/pdsProjectionLineSampToXY.def");
1434 
1435  Isis::PvlObject &projDef = p.findObject("ProjectionOffsetMults",
1436  Pvl::Traverse);
1437 
1438  for(int g = 0; g < projDef.groups(); g++) {
1439  QString key = projDef.group(g)["Keyword"];
1440  if (p_pdsLabel.hasKeyword(key)) {
1441  QString value = p_pdsLabel[key];
1442  QString pattern = projDef.group(g)["Pattern"];
1443  // If value contains pattern, then set the mults to what is in translation file
1444  if (value.contains(pattern)) {
1445  xmult = projDef.group(g)["xMult"];
1446  ymult = projDef.group(g)["yMult"];
1447  xoff = projDef.group(g)["xOff"];
1448  yoff = projDef.group(g)["yOff"];
1449  return;
1450  }
1451  }
1452  }
1453  }
1454 
1455 
1463  Table &ProcessImportPds::ImportTable(QString pdsTableName) {
1464  // No table file given, let ImportPdsTable find it.
1465  ImportPdsTable pdsTable(p_labelFile, "", pdsTableName);
1466  // reformat the table name. If the name ends with the word "Table", remove
1467  // it. (So, for example, INSTRUMENT_POINTING_TABLE gets formatted to
1468  // InstrumentPointingTable and then to InstrumentPointing)
1469  QString isisTableName = pdsTable.getFormattedName(pdsTableName);
1470  int found = isisTableName.lastIndexOf("Table");
1471  if (found == isisTableName.length() - 5) {
1472  isisTableName.remove(found, 5);
1473  }
1474 
1475  Table isisTable = pdsTable.importTable(isisTableName);
1476  p_tables.push_back(isisTable);
1477 
1478  return p_tables.at(p_tables.size() - 1);
1479  }
1480 
1481 
1485  void ProcessImportPds::StartProcess() {
1486  ProcessImport::StartProcess();
1487  for (unsigned int i = 0; i < p_tables.size(); i++) {
1488  OutputCubes[0]->write(p_tables[i]);
1489  }
1490  return;
1491  }
1492 
1493 
1504  void ProcessImportPds::StartProcess(void funct(Isis::Buffer &out)) {
1505  ProcessImport::StartProcess(funct);
1506  return;
1507  }
1508 }