Beispiel #1
0
bool LFIIOSource::initFile( )
{
  KstObject::UpdateType updateType;
  bool                  bRetVal = false;
  int                   iResult = 0;

  _numFrames = 0;

  //
  // read the metadata
  //
  if( !_filename.isNull( ) && !_filename.isEmpty( ) )
  {
    QString   str;
    fitsfile* ffits;
    int       iStatus = 0;

    if( _first )
    {
      iResult = fits_open_table( &ffits, _filename.toAscii( ), READONLY, &iStatus );
      if( iResult == 0 )
      {
        int keysexist;
        int morekeys;

        iResult = fits_get_hdrspace( ffits, &keysexist, &morekeys, &iStatus );
        if( iResult == 0 )
        {
          char  keyname[FLEN_KEYWORD];
          char  value[FLEN_VALUE];
          char  comment[FLEN_COMMENT];
          int   keynum;

          for( keynum=1; keynum <= keysexist; ++keynum )
          {
            iResult = fits_read_keyn( ffits, keynum, keyname, value, comment, &iStatus );
            if( iResult == 0 )
            {
              KstString *metaString;

              str.sprintf( "%s %s", value, comment );
              metaString = new KstString( KstObjectTag( keyname, tag() ), this, str );
              _metaData.insert( keyname, *metaString );
            }
          }

          _first = false;
        }
      }
    }
  }

  updateType = update( );
  if( updateType == KstObject::UPDATE )
  {
    bRetVal = true;
  }

  return bRetVal;
}
Beispiel #2
0
void WMAPSource::addToMetadata( fitsfile *ffits, int &iStatus )
{
  QString   str;
  int iResult;
  int keysexist;
  int morekeys;

  iResult = fits_get_hdrspace( ffits, &keysexist, &morekeys, &iStatus );
  if( iResult == 0 )
  {
    QString strTable;
    KstObjectTag tableTag( strTable, tag( ) );
    char keyname[FLEN_KEYWORD];
    char value[FLEN_VALUE];
    char comment[FLEN_COMMENT];
    int keynum;

    for( keynum=1; keynum<=keysexist; ++keynum )
    {
      iResult = fits_read_keyn( ffits, keynum, keyname, value, comment, &iStatus );
      if( iResult == 0 )
      {
        KstString *metaString;
        KstObjectTag newTag( keyname, tag( ) );

        str.sprintf( "%s %s", value, comment );
        metaString = new KstString( newTag, this, str );
        _metaData.insert( keyname, metaString );
      }
    }
  }
}
std::string FitsFile::GetKeywordComment(int keywordNumber)
{
	char keyName[FLEN_KEYWORD], keyValue[FLEN_VALUE], keyComment[FLEN_COMMENT];
	int status = 0;
	fits_read_keyn(_fptr, keywordNumber, keyName, keyValue, keyComment, &status);
	CheckStatus(status);
	return std::string(keyComment);
}
std::string FitsFile::GetKeyword(int keywordNumber)
{
	char keyName[FLEN_KEYWORD], keyValue[FLEN_VALUE];
	int status = 0;
	fits_read_keyn(_fptr, keywordNumber, keyName, keyValue, NULL, &status);
	CheckStatus(status);
	return std::string(keyName);
}
std::string FitsFile::GetKeywordValue(int keywordNumber)
{
	char keyName[FLEN_KEYWORD], keyValue[FLEN_VALUE];
	int status = 0;
	fits_read_keyn(_fptr, keywordNumber, keyName, keyValue, NULL, &status);
	CheckStatus(status);
	std::string val(keyValue);
	if(val.length() >= 2 && *val.begin()=='\'' && *val.rbegin()=='\'')
	{
		val = val.substr(1, val.length()-2);
		boost::trim(val);
	}
	return val;
}
int appendheader ( char *outfile, char *infile )
{
	fitsfile *infptr, *outfptr;         /* FITS file pointer, defined in fitsio.h */
	char card[FLEN_CARD];   /* Standard string lengths defined in fitsio.h */
	int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
	int nkeys, ii;
	char keyword[FLEN_KEYWORD], keyvalue[FLEN_VALUE], keycomment[FLEN_COMMENT];
	char temp[FLEN_KEYWORD];

	strcpy(temp,"COMMENT");
	if (!fits_open_file(&infptr, infile, READONLY, &status))
	{
		if (!fits_open_file(&outfptr, outfile, READWRITE, &status))
		{
			fits_get_hdrspace(infptr, &nkeys, NULL, &status); /* get # of keywords */

			for (ii = 1; ii <= nkeys; ii++) { /* Read and write each keywords */

				if (fits_read_record(infptr, ii, card, &status))break;
				fits_read_keyn(infptr, ii, keyword, keyvalue, keycomment, &status);

                                /* check if this is a protected keyword that must not be changed */
				if (*card && fits_get_keyclass(card) == TYP_STRUC_KEY)
					printf("%s - Protected keyword cannot be modified.\n", keyword);
				else
				{	if (!strcmp(temp, keyword)) 
					{	/* do not overwrite COMMENTs */
						fits_write_record(outfptr, card, &status);
					}
					else
					{
						fits_update_card(outfptr, keyword, card, &status);
					}
                                        printf("Writing - %s\n", card);
				}

			}
			fits_close_file(outfptr, &status);
		}

		if (status == END_OF_FILE)  status = 0; /* Reset after normal error */

		fits_close_file(infptr, &status);
	}
}
Beispiel #7
0
void loadPrimaryHeader(fitsfile *fp,dSet *data)
{
  int status=0;
  int nkey=-1;
  int morekeys=-1;
  int i;
  char keyname[128],val[128],comment[128];

  fits_get_hdrspace(fp,&nkey,&morekeys,&status);
  data->pheaderSet = 1;

  data->phead.nhead = nkey;
  // Allocate memory
  data->phead.keyname = (char **)malloc(sizeof(char *)*nkey);
  data->phead.val = (char **)malloc(sizeof(char *)*nkey);
  data->phead.comment = (char **)malloc(sizeof(char *)*nkey);
  for (i=0;i<nkey;i++)
    {
      data->phead.keyname[i] = (char *)malloc(sizeof(char)*128);
      data->phead.val[i] = (char *)malloc(sizeof(char)*128);
      data->phead.comment[i] = (char *)malloc(sizeof(char)*128);
    }
  data->pheaderSet=1;

  // Complete allocating memory

  for (i=1;i<=nkey;i++)
    {
      fits_read_keyn(fp,i+1,data->phead.keyname[i-1],data->phead.val[i-1],data->phead.comment[i-1],&status);
      if (strcmp(data->phead.keyname[i-1],"OBSFREQ")==0)
	sscanf(data->phead.val[i-1],"%f",&(data->phead.freq));
      else if (strcmp(data->phead.keyname[i-1],"STT_IMJD")==0)
	sscanf(data->phead.val[i-1],"%d",&(data->phead.imjd));
      else if (strcmp(data->phead.keyname[i-1],"STT_SMJD")==0)
	sscanf(data->phead.val[i-1],"%f",&(data->phead.smjd));
      else if (strcmp(data->phead.keyname[i-1],"STT_OFFS")==0)
	sscanf(data->phead.val[i-1],"%f",&(data->phead.stt_offs));
      else if (strcmp(data->phead.keyname[i-1],"OBSBW")==0)
	sscanf(data->phead.val[i-1],"%f",&(data->phead.bw));
    }
  // Read specific parameters
  fits_read_key(fp,TSTRING,"OBS_MODE",data->phead.obsMode,NULL,&status);
  fits_read_key(fp,TSTRING,"SRC_NAME",data->phead.source,NULL,&status);
  if (status)
    {
      fits_report_error(stderr,status);
      exit(1);
    }

  // Now load information from the subintegration table
  fits_movnam_hdu(fp,BINARY_TBL,"SUBINT",1,&status);
  if (status)
    {
      printf("No subintegration table\n");
      data->subintTable=0;
      status=0;
    }
  else
    {
      data->subintTable=1;
      fits_read_key(fp,TINT,"NAXIS2",&(data->phead.nsub),NULL,&status);
      if (status)
	{
	  printf("Reading naxis2\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}     
      fits_read_key(fp,TINT,"NCHAN",&(data->phead.nchan),NULL,&status);
      if (status)
	{
	  printf("Reading nchan\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}
      
      fits_read_key(fp,TFLOAT,"ZERO_OFF",&(data->phead.zeroOff),NULL,&status);
      if (status)
	{
	  printf("Reading zero_off\n");
	  fits_report_error(stderr,status);
	  data->phead.zeroOff = 0;
	  status=0;
	}

      fits_read_key(fp,TINT,"NBITS",&(data->phead.nbits),NULL,&status);
      if (status)
	{
	  printf("Reading nbits\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}

      fits_read_key(fp,TINT,"NPOL",&(data->phead.npol),NULL,&status);
      if (status)
	{
	  printf("Reading npol\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}
      
      fits_read_key(fp,TINT,"NSBLK",&(data->phead.nsblk),NULL,&status);
      if (status)
	{
	  printf("Reading nsblk\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}

      fits_read_key(fp,TINT,"NBIN",&(data->phead.nbin),NULL,&status);
      if (status)
	{
	  printf("Reading nbin\n");
	  fits_report_error(stderr,status);
	  exit(1);
	}

      //      printf("nbin = %d (%d)\n",data->phead.nbin,status);
      fits_read_key(fp,TFLOAT,"CHAN_BW",&(data->phead.chanbw),NULL,&status);
      if (data->phead.chanbw < 0 && data->phead.bw > 0)
	data->phead.bw*=-1;
      
      fits_read_key(fp,TFLOAT,"TBIN",&(data->phead.tsamp),NULL,&status);
      
    }
  fits_movnam_hdu(fp,BINARY_TBL,"PSRPARAM",1,&status);
  if (status)
    {
      printf("No PSRPARM table\n");
      data->psrparamTable=0;
      status=0;
    }
  else
    {
      int len,i,colnum;
      char **line,str1[1024],str2[1024];
      data->psrparamTable=1;
      char nval[128]="UNKNOWN";
      int anynul=0;
      float tt;
      fits_read_key(fp,TINT,"NAXIS2",&len,NULL,&status);

      fits_get_colnum(fp,CASEINSEN,"PARAM",&colnum,&status);
      if (status) {
	printf("Unable to find data in the psrparam table in FITS file\n");
	exit(1);
      }

      line = (char **)malloc(sizeof(char *));
      line[0] = (char *)malloc(sizeof(char)*1024); 

      for (i=0;i<len;i++)
	{
	  fits_read_col_str(fp,colnum,i+1,1,1,nval,line,&anynul,&status);
	  if (sscanf(line[0],"%s %s",str1,str2)==2)
	    {
	      if (strcasecmp(str1,"DM")==0)
		sscanf(str2,"%f",&(data->phead.dm));
	      if (strcasecmp(str1,"F0")==0)
		{
		  sscanf(str2,"%f",&tt);
		  data->phead.period = 1.0/tt;
		}
	    }
	  //	  printf("Read: %s\n",line[0]);
	}
      //      printf("Lenght = %d\n",len);
  free(line[0]);
  free(line);

    }
    
}
Beispiel #8
0
int checkHdr(char *infile, int hdrflag, int hdu)
{
   int       i, len, ncard, morekeys;

   int       status = 0;

   char     *keyword;
   char     *value;

   char      fitskeyword[80];
   char      fitsvalue  [80];
   char      fitscomment[80];
   char      tmpstr     [80];

   char     *end;

   char      line  [1024];
   char      pline [1024];

   char     *ptr1;
   char     *ptr2;

   FILE     *fp;
   fitsfile *infptr;

   static int maxhdr;

   if(!mHeader)
   {
      mHeader = malloc(MAXHDR);
      maxhdr = MAXHDR;
   }

   havePLTRAH  = 0;

   haveSIMPLE  = 0;
   haveBITPIX  = 0;
   haveNAXIS   = 0;
   haveNAXIS1  = 0;
   haveNAXIS2  = 0;
   haveCTYPE1  = 0;
   haveCTYPE2  = 0;
   haveCRPIX1  = 0;
   haveCRPIX2  = 0;
   haveCDELT1  = 0;
   haveCDELT2  = 0;
   haveCD1_1   = 0;
   haveCD1_2   = 0;
   haveCD2_1   = 0;
   haveCD2_2   = 0;
   haveCRVAL1  = 0;
   haveCRVAL2  = 0;
   haveBSCALE  = 0;
   haveBZERO   = 0;
   haveBLANK   = 0;
   haveEPOCH   = 0;
   haveEQUINOX = 0;


   /****************************************/
   /* Initialize the WCS transform library */
   /* and find the pixel location of the   */
   /* sky coordinate specified             */
   /****************************************/

   errorCount = 0;

   if(hdrCheck_outfile)
   {
      fout = fopen(hdrCheck_outfile, "w+");

      if(fout == (FILE *)NULL)
      {
         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Cannot open output file %s.\"]\n", hdrCheck_outfile);
         fflush(fstatus);
         exit(1);
      }
   }

   strcpy(mHeader, "");

   if(fits_open_file(&infptr, infile, READONLY, &status) == 0)
   {
      if(CHdebug)
      {
         printf("\nFITS file\n");
         fflush(stdout);
      }

      if(hdrflag == HDR)
      {
       fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"FITS file (%s) cannot be used as a header template\"]\n",
                infile);
         fflush(fstatus);
         exit(1);
      }

      if(hdu > 0)
      {
         if(fits_movabs_hdu(infptr, hdu+1, NULL, &status))
            FITSerror(status);
      }

      if(fits_get_hdrspace (infptr, &ncard, &morekeys, &status))
         FITSerror(status);
      
      if(ncard > 1000)
         mHeader = realloc(mHeader, ncard * 80 + 1024);

      if(CHdebug)
      {
         printf("ncard = %d\n", ncard);
         fflush(stdout);
      }

      for (i=1; i<=ncard; i++)
      {
         if(fits_read_keyn (infptr, i, fitskeyword, fitsvalue, fitscomment, &status))
            FITSerror(status);

         if(fitsvalue[0] == '\'')
         {
            strcpy(tmpstr, fitsvalue+1);

            if(tmpstr[strlen(tmpstr)-1] == '\'')
               tmpstr[strlen(tmpstr)-1] =  '\0';
         }
         else
            strcpy(tmpstr, fitsvalue);

         fitsCheck(fitskeyword, tmpstr);

         sprintf(line, "%-8s= %20s", fitskeyword, fitsvalue);

         if(strncmp(line, "COMMENT", 7) != 0)
            strAdd(mHeader, line);
      }

      strAdd(mHeader, "END");

      if(fits_close_file(infptr, &status))
         FITSerror(status);
   }
   else
   {
      if(CHdebug)
      {
         printf("\nTemplate file\n");
         fflush(stdout);
      }

      if(hdrflag == FITS)
      {
         fp = fopen(infile, "r");

         if(fp == (FILE *)NULL)
         {
            fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File %s not found.\"]\n", infile);
            fflush(fstatus);
            exit(1);
         }

         fclose(fp);

         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File (%s) is not a FITS image\"]\n",
                infile);
         fflush(fstatus);
         exit(1);
      }

      fp = fopen(infile, "r");

      if(fp == (FILE *)NULL)
      {
         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File %s not found.\"]\n", infile);
         fflush(fstatus);
         exit(1);
      }

      while(1)
      {
         if(fgets(line, 1024, fp) == (char *)NULL)
            break;

         if(line[(int)strlen(line)-1] == '\n')
            line[(int)strlen(line)-1]  = '\0';
         
         if(line[(int)strlen(line)-1] == '\r')
            line[(int)strlen(line)-1]  = '\0';
         
         strcpy(pline, line);

         if((int)strlen(line) > 80)
         {
            fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"FITS header lines cannot be greater than 80 characters.\"]\n");
            fflush(fstatus);
            exit(1);
         }

         len = (int)strlen(pline);

         keyword = pline;

         while(*keyword == ' ' && keyword < pline+len)
            ++keyword;

         end = keyword;

         while(*end != ' ' && *end != '=' && end < pline+len)
            ++end;

         value = end;

         while((*value == '=' || *value == ' ' || *value == '\'')
               && value < pline+len)
            ++value;

         *end = '\0';
         end = value;

         if(*end == '\'')
            ++end;

         while(*end != ' ' && *end != '\'' && end < pline+len)
            ++end;

         *end = '\0';

         fitsCheck(keyword, value);

         strAdd(mHeader, line);
         
         if((int)strlen(mHeader) + 160 > maxhdr)
         {
            maxhdr += MAXHDR;
            mHeader = realloc(mHeader, maxhdr);
         }
      }

      fclose(fp);
   }


   /********************************************************/
   /*                                                      */
   /* Check to see if we have the minimum FITS header info */
   /*                                                      */
   /********************************************************/

   if(!haveBITPIX)
      errorOutput("No BITPIX keyword in FITS header");

   if(!haveNAXIS)
      errorOutput("No NAXIS keyword in FITS header");

   if(!haveNAXIS1)
      errorOutput("No NAXIS1 keyword in FITS header");

   if(!haveNAXIS2)
      errorOutput("No NAXIS2 keyword in FITS header");

   if(havePLTRAH)
   {
      /* If we have this parameter, we'll assume this is a DSS header  */
      /* the WCS checking routine should be able to verify if it isn't */

      free(mHeader);

      maxhdr = 0;
      
      mHeader = (char *)NULL;

      return(0);
   }

   if(!haveCTYPE1)
      errorOutput("No CTYPE1 keyword in FITS header");

   if(!haveCTYPE2)
      errorOutput("No CTYPE2 keyword in FITS header");

   if(!haveCRPIX1)
      errorOutput("No CRPIX1 keyword in FITS header");

   if(!haveCRPIX2)
      errorOutput("No CRPIX2 keyword in FITS header");

   if(!haveCRVAL1)
      errorOutput("No CRVAL1 keyword in FITS header");

   if(!haveCRVAL2)
      errorOutput("No CRVAL2 keyword in FITS header");

   if(!haveCD1_1 
   && !haveCD1_2 
   && !haveCD2_1 
   && !haveCD2_2)
   {
      if(!haveCDELT1)
         errorOutput("No CDELT1 keyword (or incomplete CD matrix) in FITS header");
      else if(!haveCDELT2)
         errorOutput("No CDELT2 keyword (or incomplete CD matrix) in FITS header");
   }

   if(strlen(ctype1) < 8)
      errorOutput("CTYPE1 must be at least 8 characters");

   if(strlen(ctype2) < 8)
      errorOutput("CTYPE2 must be at least 8 characters");

   ptr1 = ctype1;

   while(*ptr1 != '-' && *ptr1 != '\0') ++ptr1;
   while(*ptr1 == '-' && *ptr1 != '\0') ++ptr1;

   ptr2 = ctype2;

   while(*ptr2 != '-' && *ptr2 != '\0') ++ptr2;
   while(*ptr2 == '-' && *ptr2 != '\0') ++ptr2;

   if(strlen(ptr1) == 0
   || strlen(ptr2) == 0)
      errorOutput("Invalid CTYPE1 or CTYPE2 projection information");

   if(strcmp(ptr1, ptr2) != 0)
      errorOutput("CTYPE1, CTYPE2 projection information mismatch");

   if(hdrStringent)
   {
      if(strlen(ptr1) != 3)
         errorOutput("Invalid CTYPE1 projection information");

      if(strlen(ptr2) != 3)
         errorOutput("Invalid CTYPE2 projection information");
   }


   /****************************************/
   /* Initialize the WCS transform library */
   /* and find the pixel location of the   */
   /* sky coordinate specified             */
   /****************************************/

   /*
   if(CHdebug)
   {
      printf("header = \n%s\n", mHeader);
      fflush(stdout);
   }
   */

   hdrCheck_wcs = wcsinit(mHeader);

   checkWCS(hdrCheck_wcs, 0);

   if(errorCount > 0)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"%d Errors\"]\n", 
         errorCount);
      fflush(fstatus);
      exit(1);
   }

   return(0);
}
Beispiel #9
0
std::vector<ImportDescriptor*> FitsImporter::getImportDescriptors(const std::string& fname)
{
   std::string filename = fname;
   std::vector<std::vector<std::string> >& errors = mErrors[fname];
   std::vector<std::vector<std::string> >& warnings = mWarnings[fname];
   errors.clear();
   warnings.clear();
   int status=0;
   std::vector<ImportDescriptor*> descriptors;

   FitsFileResource pFile(filename);
   if (!pFile.isValid())
   {
      errors.resize(1);
      errors[0].push_back(pFile.getStatus());
      RETURN_DESCRIPTORS;
   }

   int hduCnt = 0;
   int specificHdu = 0;
   int hdu = 1;
   if (!splitFilename(filename, hduCnt, specificHdu, hdu, pFile, errors, warnings))
   {
      RETURN_DESCRIPTORS;
   }
   errors.resize(hduCnt+1);
   warnings.resize(hduCnt+1);

   for(; hdu <= hduCnt; ++hdu)
   {
      std::string datasetName = filename + "[" + StringUtilities::toDisplayString(hdu) + "]";
      int hduType;
      CHECK_FITS(fits_movabs_hdu(pFile, hdu, &hduType, &status), hdu, false, continue);
      ImportDescriptorResource pImportDescriptor(static_cast<ImportDescriptor*>(NULL));
      FactoryResource<DynamicObject> pMetadata;
      VERIFYRV(pMetadata.get() != NULL, descriptors);
      { // scope
         std::vector<std::string> comments;
         char pCard[81];
         char pValue[81];
         char pComment[81];
         int nkeys = 0;
         CHECK_FITS(fits_get_hdrspace(pFile, &nkeys, NULL, &status), hdu, true, ;);
         for(int keyidx = 1; keyidx <= nkeys; ++keyidx)
         {
            CHECK_FITS(fits_read_keyn(pFile, keyidx, pCard, pValue, pComment, &status), hdu, true, continue);
            std::string name = StringUtilities::stripWhitespace(std::string(pCard));
            std::string val = StringUtilities::stripWhitespace(std::string(pValue));
            std::string comment = StringUtilities::stripWhitespace(std::string(pComment));
            if (!val.empty())
            {
               pMetadata->setAttributeByPath("FITS/" + name, val);
            }
            else if (!comment.empty())
            {
               comments.push_back(comment);
            }
         }
         if (!comments.empty())
         {
            // ideally, this would add a multi-line string but Opticks doesn't display this properly
            // pMetadata->setAttributeByPath("FITS/COMMENT", StringUtilities::join(comments, "\n"));
            for(unsigned int idx = 0; idx < comments.size(); ++idx)
            {
               pMetadata->setAttributeByPath("FITS/COMMENT/" + StringUtilities::toDisplayString(idx), comments[idx]);
            }
         }
      }
      switch(hduType)
      {
      case IMAGE_HDU:
      {
         pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<RasterElement>());
         VERIFYRV(pImportDescriptor.get() != NULL, descriptors);

         EncodingType fileEncoding;
         InterleaveFormatType interleave(BSQ);
         unsigned int rows=0;
         unsigned int cols=0;
         unsigned int bands=1;

         int bitpix;
         int naxis;
         long axes[3];
         CHECK_FITS(fits_get_img_param(pFile, 3, &bitpix, &naxis, axes, &status), hdu, false, continue);
         switch(bitpix)
         {
         case BYTE_IMG:
            fileEncoding = INT1UBYTE;
            break;
         case SHORT_IMG:
            fileEncoding = INT2SBYTES;
            break;
         case LONG_IMG:
            fileEncoding = INT4SBYTES;
            break;
         case FLOAT_IMG:
            fileEncoding = FLT4BYTES;
            break;
         case DOUBLE_IMG:
            fileEncoding = FLT8BYTES;
            break;
         default:
            warnings[hdu].push_back("Unsupported BITPIX value " + StringUtilities::toDisplayString(bitpix) + ".");
            continue;
         }
         EncodingType dataEncoding = checkForOverflow(fileEncoding, pMetadata.get(), hdu, errors, warnings);
         if (naxis == 1)
         {
            // 1-D data is a signature
            pImportDescriptor = ImportDescriptorResource(datasetName, TypeConverter::toString<Signature>());
            pMetadata->setAttributeByPath(METADATA_SIG_ENCODING, dataEncoding);
            pMetadata->setAttributeByPath(METADATA_SIG_LENGTH, axes[0]);

            RasterUtilities::generateAndSetFileDescriptor(pImportDescriptor->getDataDescriptor(), filename,
               StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER);

            // add units
            SignatureDataDescriptor* pSigDd =
               dynamic_cast<SignatureDataDescriptor*>(pImportDescriptor->getDataDescriptor());
            if (pSigDd != NULL)
            {
               FactoryResource<Units> pUnits;
               pUnits->setUnitName("Custom");
               pUnits->setUnitType(CUSTOM_UNIT);
               pSigDd->setUnits("Reflectance", pUnits.get());
            }

            break; // leave switch()
         }
         else if (naxis == 2)
         {
            cols = axes[0];
            rows = axes[1];
         }
         else if (naxis == 3)
         {
            cols = axes[0];
            rows = axes[1];
            bands = axes[2];
         }
         else
         {
            errors[hdu].push_back(StringUtilities::toDisplayString(naxis) + " axis data not supported.");
         }

         RasterDataDescriptor* pDataDesc = RasterUtilities::generateRasterDataDescriptor(
            datasetName, NULL, rows, cols, bands, interleave, dataEncoding, IN_MEMORY);
         pImportDescriptor->setDataDescriptor(pDataDesc);
         if (specificHdu == 0 && hdu == 1 && naxis == 2 && (axes[0] <= 5 || axes[1] <= 5))
         {
            // use 5 as this is a good top end for the number of astronomical band pass filters
            // in general usage. this is not in a spec anywhere and is derived from various sample
            // FITS files for different astronomical instruments.
            //
            // There's a good chance this is really a spectrum. (0th HDU)
            // We'll create an import descriptor for the spectrum version of this
            // And disable the raster descriptor by default
            pImportDescriptor->setImported(false);
            ImportDescriptorResource pSigDesc(datasetName, TypeConverter::toString<SignatureLibrary>());
            DynamicObject* pSigMetadata = pSigDesc->getDataDescriptor()->getMetadata();
            pSigMetadata->merge(pMetadata.get());
            std::vector<double> centerWavelengths;
            unsigned int cnt = (axes[0] <= 5) ? axes[1] : axes[0];
            double startVal = StringUtilities::fromDisplayString<double>(
               dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MINWAVE"), "0.0"));
            double endVal = StringUtilities::fromDisplayString<double>(
               dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/MAXWAVE"), "0.0"));
            double incr = (endVal == 0.0) ? 1.0 : ((endVal - startVal) / static_cast<double>(cnt));
            centerWavelengths.reserve(cnt);
            for (unsigned int idx = 0; idx < cnt; idx++)
            {
               centerWavelengths.push_back(startVal + (idx * incr));
            }
            pSigMetadata->setAttributeByPath(CENTER_WAVELENGTHS_METADATA_PATH, centerWavelengths);

            // Units
            std::string unitsName = dv_cast<std::string>(pMetadata->getAttributeByPath("FITS/BUNIT"), std::string());
            if (!unitsName.empty())
            {
               FactoryResource<Units> units;
               units->setUnitName(unitsName);
               units->setUnitType(RADIANCE);
               SignatureDataDescriptor* pSigDd =
                  dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor());
               if (pSigDd != NULL)
               {
                  pSigDd->setUnits("Reflectance", units.get());
               }
            }

            RasterUtilities::generateAndSetFileDescriptor(pSigDesc->getDataDescriptor(),
               filename, StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER);

            // If units are not available, set custom units into the data descriptor so that the user can
            // modify them - this must occur after the call to RasterUtilities::generateAndSetFileDescriptor()
            // so that the file descriptor will still display no defined units
            if (unitsName.empty())
            {
               FactoryResource<Units> units;
               units->setUnitName("Custom");
               units->setUnitType(CUSTOM_UNIT);
               SignatureDataDescriptor* pSigDd = dynamic_cast<SignatureDataDescriptor*>(pSigDesc->getDataDescriptor());
               if (pSigDd != NULL)
               {
                  pSigDd->setUnits("Reflectance", units.get());
               }
            }

            descriptors.push_back(pSigDesc.release());
         }

         RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(
            RasterUtilities::generateAndSetFileDescriptor(pDataDesc, filename,
            StringUtilities::toDisplayString(hdu), BIG_ENDIAN_ORDER));
         if (pFileDescriptor != NULL)
         {
            unsigned int bitsPerElement = RasterUtilities::bytesInEncoding(fileEncoding) * 8;
            pFileDescriptor->setBitsPerElement(bitsPerElement);
         }

         break; // leave switch()
      }
      case ASCII_TBL:
      case BINARY_TBL:
         warnings[hdu].push_back("Tables not supported. [HDU " + StringUtilities::toDisplayString(hdu) + "]");
         continue;
      default:
         warnings[hdu].push_back("HDU " + StringUtilities::toDisplayString(hdu) + " is an unknown type.");
         continue;
      }

      pImportDescriptor->getDataDescriptor()->setMetadata(pMetadata.release());
      pImportDescriptor->setImported(errors[hdu].empty());
      descriptors.push_back(pImportDescriptor.release());
   }