int FitsFile::GetCurrentHDU()
{
	CheckOpen();
	int hdunum = 0;
	fits_get_hdu_num(_fptr, &hdunum);
	return hdunum;
}
Exemple #2
0
// gotoFITSHDU: try to go to a reasonable HDU if the primary is useless
// we look for specified extensions and if not found, go to hdu #2
// this is how xray binary tables are imaged automatically
fitsfile *gotoFITSHDU(fitsfile *fptr, char *extlist, int *hdutype, int *status){
  int hdunum, naxis, thdutype, gotext;
  char *ext, *textlist;
  // if this is the primary array and it does not contain an image,
  // try to move to something more reasonble
  fits_get_hdu_num(fptr, &hdunum); *status = 0;
  fits_get_img_dim(fptr, &naxis, status); *status = 0;
  if( (hdunum == 1) && (naxis == 0) ){ 
    // look through the extension list
    if( extlist ){
      gotext = 0;
      textlist = (char *)strdup(extlist);
      for(ext=(char *)strtok(textlist, " "); ext != NULL; 
	  ext=(char *)strtok(NULL," ")){
	fits_movnam_hdu(fptr, ANY_HDU, ext, 0, status);
	if( *status == 0 ){
	  gotext = 1;
	  break;
	} else {
	  *status = 0;
	}
      }
      free(textlist);      
    }
    if( !gotext ){
      // if all else fails, move to extension #2 and hope for the best
      fits_movabs_hdu(fptr, 2, &thdutype, status);
    }
  }
  fits_get_hdu_type(fptr, hdutype, status);
  return fptr;
}
int main(int argc, char *argv[]) {
  fitsfile *fitsFilePtr;         
  char card[FLEN_CARD]; 
  int status, numKey, numHDU, curKey, curHDU, hduType;

  status = 0; /* Must initialize status before use */

  if(argc < 2) {
    printf("ERROR\n");
    exit(11);
  }

  /* Open the fits file */
  fits_open_file(&fitsFilePtr, argv[1], READONLY, &status);
  reportAndExitOnFITSerror(status);

  /* Get the number of HDUs -- usually only one */
  fits_get_num_hdus(fitsFilePtr, &numHDU, &status);
  reportAndExitOnFITSerror(status);
  printf("Number of headers in file: %d\n", numHDU);

  /* Get the current HDU number.  This first one is '1', not '0'. */
  fits_get_hdu_num(fitsFilePtr, &curHDU);
  reportAndExitOnFITSerror(status);
  printf("Working on header number: %d\n", curHDU);

  fits_get_hdu_type(fitsFilePtr,  &hduType, &status);
  reportAndExitOnFITSerror(status);
  switch(hduType) {
    case IMAGE_HDU : printf("HDU Type: IMAGE\n");        break;
    case ASCII_TBL : printf("HDU Type: ASCII Table\n");  break;
    case BINARY_TBL: printf("HDU Type: Binary Table\n"); break;
    default        : printf("HDU Type: UNKNOWN\n");      break;
  }

  /* Get the size (number of keys) of the header space */
  fits_get_hdrspace(fitsFilePtr, &numKey, NULL, &status);
  reportAndExitOnFITSerror(status);
  printf("Number of keys in current HDU: %d\n", numKey);

  /* One can traverse all the lines like this: */
  for(curKey = 1; curKey <= numKey; curKey++)  { 
    /* read the current keyword */
    fits_read_record(fitsFilePtr, curKey, card, &status); 
    reportAndExitOnFITSerror(status);
    printf("%5d: %s\n", curKey, card);
  }
  printf("END\n\n");

  /* We are done.  Close the file. */
  fits_close_file(fitsFilePtr, &status);
  reportAndExitOnFITSerror(status);

  /* If we get here, everything worked! */
  return 0;
}
Exemple #4
0
int main(int argc, char *argv[])
{
    fitsfile *fptr;       /* pointer to the FITS file, defined in fitsio.h */

    int status, nkeys, keypos, hdutype, ii, jj;
    char filename[FLEN_FILENAME];    /* input FITS file */
    char card[FLEN_CARD];   /* standard string lengths defined in fitsioc.h */

    status = 0;

    if (argc == 1)
        strcpy(filename, "-");  /* no command line name, so assume stdin */
    else
        strcpy(filename, argv[1] );   /* name of file to list */


    if ( fits_open_file(&fptr, filename, READONLY, &status) ) 
         printerror( status );

    /* get the current HDU number */
    fits_get_hdu_num(fptr, &ii);

    /* attempt to move to next HDU, until we get an EOF error */
    for (; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++) 
    {
        /* get no. of keywords */
        if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) )
            printerror( status );

        printf("Header listing for HDU #%d:\n", ii);
        for (jj = 1; jj <= nkeys; jj++)  {
            if ( fits_read_record(fptr, jj, card, &status) )
                 printerror( status );

            printf("%s\n", card); /* print the keyword card */
        }
        printf("END\n\n");  /* terminate listing with END */
    }

    if (status == END_OF_FILE)   /* status values are defined in fitsio.h */
        status = 0;              /* got the expected EOF error; reset = 0  */
    else
       printerror( status );     /* got an unexpected error                */

    if ( fits_close_file(fptr, &status) )
         printerror( status );

    return(0);
}
Exemple #5
0
/* Wrapper to fits_get_hdu_num */
SEXP
cfitsio_get_hdu_num (SEXP fits_object)
{
    fits_file_t * fits = R_ExternalPtrAddr (fits_object);

    if (NULL != fits && NULL != fits->cfitsio_ptr)
    {
	int hdu_num;

	fits_get_hdu_num (fits->cfitsio_ptr, &hdu_num);
	return ScalarInteger (hdu_num);
    }
    else
	return ScalarInteger (-1);
}
int psrfits_remove_ephem(struct psrfits *pf) {
    // Delete the ephemeris table
    
    int *status = &(pf->status);

    // Save current HDU, move to polyco table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "PSREPHEM", 0, status);

    // Delete it
    fits_delete_hdu(pf->fptr, NULL, status);

    // Go to the SUBINT HDU
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "SUBINT", 0, status);

    return *status;
}
Exemple #7
0
void PLANCKIDEFSource::addToFieldList( fitsfile *ffits, const int iNumCols, int &iStatus )
{
  QString str;
  char charTemplate[ FLEN_CARD ];
  char charName[ FLEN_CARD ];
  long lRepeat;
  long lWidth;
  int iHDUNumber;
  int iTypeCode;
  int iColNumber;
  int iResult;
  int table;
  int col;

  table = fits_get_hdu_num( ffits, &iHDUNumber );

  for( col=0; col<iNumCols; col++ )
  {
    iResult = fits_get_coltype( ffits, col+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
    if( iResult == 0 )
    {
      sprintf( charTemplate, "%d", col+1 );
      iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
      if( iResult == 0 )
      {
        if( lRepeat == 1 )
        {
          field *fld = new field;

          fld->table = table;
          fld->column = iColNumber;

          str = charName;
          if( _fields.find( str ) != 0L )
          {
            str += QString("_%1").arg( iHDUNumber );
          }
          _fields.insert( str, fld );
          _fieldList.append( str );
        }
      }
    }
  }
}
Exemple #8
0
fitsfile* fits_init(char *filename, int iomode, int *nrelhdu, int *status) {
  *status = 0;
  fitsfile *fptr;
  if (fits_open_file(&fptr, filename, iomode, status)) {
    fits_print_error(*status);
    return 0;
  }

  /* Get the current HDU position and number of HDUs*/
  int hdupos, nhdu;
  fits_get_hdu_num (fptr, &hdupos);
  fits_get_num_hdus(fptr, &nhdu, status);

  /* will process only a single header if a specific extension was given, 
     otherwise all HDUs */ 
  if  (hdupos != 1 || strchr(filename, '[') || nhdu == 1) 
    *nrelhdu = 0;
  else *nrelhdu = nhdu-hdupos;

  return fptr;
}
Exemple #9
0
int main(int argc, char **argv)
{

  int             i_file,i_scan,i_chan,i_bin,n_omit,status=0;
  int             NFirstTable, NumHDU, NDumps, TotDumps=0, hdutype;
  // int             OutChans;
  int             spk;
  int             got_bins=0, got_mjd1=0; //, zeroed_outprofs=0;
  long            NPtsProf=0, FirstNPtsProf=0;
  float           Weight=1.0, TotWeight=0.;
  // int             ProfSum=0;
  double          x, ptype;
  double          MJD_first=0., MJD_last=0., MJD_mid;
  double          IMJDMid, MJDSecsMid;
  double          SBase,Srms,Duty,SPeak,FinalMask[NBINMAX];
  double          OutFreq;
  char            ProgName[32];
  char            Outfile[128];
  char            Header[256];  
  struct ASPHdr   *Hdr;
  struct SubHdr   Subhdr;
  struct StdProfs *InProfile, OutProfile;
  struct RunVars  RunMode;
  fitsfile        **Fin;
  FILE            *Fout, *Fcheck;
  Cmdline         *Cmd;


  /* Get command line variables */
  Cmd = parseCmdline(argc, argv);  

  /* Normally use this somewhere, and not showOptionValues */
  Cmd->tool = Cmd->tool;

  strcpy(ProgName, argv[0]);

  Fin = (fitsfile **)malloc(Cmd->InfileC*sizeof(fitsfile));
  Hdr = (struct ASPHdr *)malloc(Cmd->InfileC*sizeof(struct ASPHdr));

  /* Dynamically allocate RunMode variables */
  if (AllocRunMode(&RunMode) < 0){
    printf("Could not allocate RunMode structure.  Exiting...\n");
    exit(2);
  }
  strcpy(RunMode.Infile,Cmd->Infile); 
  

 //    if(!zeroed_outprofs) {
      /*     if(Cmd->SortChansP){
	     OutChans=Hdr[0].obs.NChan;
	     } 
	     else{ */
  // OutChans=1;
  // }
  // OutProfile=(struct StdProfs *)malloc(OutChans*sizeof(struct StdProfs));
  // TotWeight=(float *)malloc(OutChans*sizeof(float));
  
  /* Zero out profiles */
  //     for(i_chan=0;i_chan<OutChans;i_chan++){
  FZero(OutProfile.rstds,NBINMAX);
  FZero(OutProfile.rstdq,NBINMAX);
  FZero(OutProfile.rstdu,NBINMAX);
  FZero(OutProfile.rstdv,NBINMAX);
  // }
  //zeroed_outprofs=1;
      //    }

  /* Create an output file to check omissions if in vebose mode */
  if (Cmd->VerboseP || Cmd->CheckOmitP){
    if((Fcheck = fopen("check_omit.dat","w")) == 0)
       { printf("Cannot open %s. Exiting...\n",Outfile); exit(1); }   
  }


  /* read in all input files and add each to the final profile */

  /* read in all input file headers */
  NPtsProf=0;
  for (i_file=0;i_file<Cmd->InfileC;i_file++){
    n_omit=0;
    status=0;    
    if(fits_open_file(&Fin[i_file], Cmd->Infile[i_file], READONLY, &status)){
      printf("Error opening FITS file %s !!!\n", Cmd->Infile[i_file]);
      exit(1);
    }
    if(ReadASPHdr(&Hdr[i_file], Fin[i_file]) < 0){
      printf("%s> Unable to read Header from file %s.  Exiting...\n",
	     ProgName,Cmd->Infile[i_file]);
      exit(1);
    }

    /* Write file name in verbose-mode omit check file */
    if(Cmd->VerboseP || Cmd->CheckOmitP) 
      fprintf(Fcheck, "\n%s\n",Cmd->Infile[i_file]);


    /* for now just check if all files have same number of channels */
    /* if(Cmd->SortChansP)
        if(i_file>0 && Hdr[i_file].obs.NChan!=Hdr[0].obs.NChan){
        fprintf(stderr,"%s> Different numbers of channels in different files:\n\n",
        ProgName);
        fprintf(stderr,"%s: %d channels,  %s: %d channels\n",
	Cmd->Infile[0],Hdr[0].obs.NChan,
	Cmd->Infile[i_file],Hdr[i_file].obs.NChan);
	} */
    
    /* now find the number of dumps in the file */    
    fits_get_num_hdus(Fin[i_file], &NumHDU, &status);
    if(!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0")){
      NDumps = NumHDU-3;  /* the "3" is temporary, depending on how 
				   many non-data tables we will be using */
    }
    else if(!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0.1")){
      NDumps = (NumHDU-3)/2;
    }
    else{
      fprintf(stderr,"%s> Do not recognize FITS file version in header.\n",
	      ProgName);
      fprintf(stderr,"This header is %s. Exiting...\n",Hdr[i_file].gen.HdrVer);
      exit(1);
    }

    printf("File %s:\n",Cmd->Infile[i_file]);
    printf("     Number of channels:  %d\n",Hdr[i_file].obs.NChan) ;
    printf("     Number of dumps:     %d\n",NDumps);

    /* Move to the first data table HDU in the fits file */
    if(!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0"))
      fits_movnam_hdu(Fin[i_file], BINARY_TBL, "STOKES0", 0, &status);
    else if (!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0.1"))
      fits_movnam_hdu(Fin[i_file], ASCII_TBL, "DUMPREF0", 0, &status);

    /* Get the current HDU number */
    fits_get_hdu_num(Fin[i_file], &NFirstTable);

    /* Set up Profile structure size */


    for(i_scan=0;i_scan<NDumps;i_scan++){
      
      InProfile=(struct StdProfs *)malloc(Hdr[i_file].obs.NChan*
					sizeof(struct StdProfs));
     /* move to next dump's data */
      if(!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0")){
	fits_movabs_hdu(Fin[i_file], NFirstTable+i_scan, &hdutype, &status); 
      }
      else if(!strcmp(Hdr[i_file].gen.HdrVer,"Ver1.0.1")){
	/* if we've reached the end of the FITS file then increase FileNo */
	fits_movabs_hdu(Fin[i_file],NFirstTable+(i_scan%MAXDUMPS)*2+1,&hdutype,
			&status);
	fits_get_num_rows(Fin[i_file], &NPtsProf, &status);status=0; 
	fits_movrel_hdu(Fin[i_file], -1, NULL, &status);
      }
      
      /* IF not done so, use number of bins from first file to compare to 
	 the rest of the files */
      if(got_bins==0){
	FirstNPtsProf=NPtsProf;  
	got_bins=1;
      }

      /**********  FIX:  SKIP THIS WITHOUT DOING THE OMIT THING ***********/
      /**********         AND DON'T ADD TO NUMBER COUNT  ************/
      if(NPtsProf != FirstNPtsProf) {
	fprintf(stderr,"Warning: Skipping scan %d (%ld bins ",
		i_scan,NPtsProf);
	fprintf(stderr,"vs. %ld bins in others).\n",FirstNPtsProf);
		
	n_omit += Hdr[i_file].obs.NChan;
      }
      else{
	
	/* find NPtsProf */
	ReadASPStokes(&Hdr[i_file], &Subhdr, Fin[i_file], NPtsProf, 
		      InProfile, i_scan, Cmd->VerboseP);
	
	
	/* Add this profile onto running output profile */
	
	for(i_chan=0;i_chan<Hdr[i_file].obs.NChan;i_chan++){
	  
	  /* Bad scans are zeroed so if summ of the profile is zero, it's 
	     not to be used in summation */
	  //	  ProfSum = FSum(&InProfile[i_chan].rstds[0], NPtsProf);
	  //	  ProfSum = 0;
	  // ProfSum = ArrayZero(InProfile[i_chan].rstds, NPtsProf);
	  //	  if(ProfSum != 0.0) { // i.e. good data
	  /* Test that all bins in current profile are not zeroed */
	  if(!ArrayZero(InProfile[i_chan].rstds, NPtsProf)) { // i.e. good data
	    //	  if(InProfile[i_chan].rstds[0] > -99998.) { // i.e. good data
	    
	    /* If first MJD has not been registered, then do so since this 
	       would be the first non-omitted scan */
	    if (got_mjd1==0) {
	      MJD_first = (double)Hdr[i_file].obs.IMJDStart + 
		Subhdr.DumpMiddleSecs/86400.;
	      got_mjd1=1;
	    }
	    if (i_scan==NDumps-1) {
	      /* Just keep overwriting MJD_last every i_file -- that way we 
		 ensure getting the last MJD of the FINAL non-omitted scan 
		 used */
	      MJD_last = (double)Hdr[i_file].obs.IMJDStart + 
		Subhdr.DumpMiddleSecs/86400.;
	    }

	    /* Get SNR for each Profile if we want to use weighting; 
	       otherwise weights will all be 1.0 */
	    if(Cmd->WeightP) {
	      Duty = DutyLookup(Hdr[i_file].target.PSRName);
	      BMask(InProfile[i_chan].rstds,&Hdr[i_file].redn.RNBinTimeDump,
		    &Duty,FinalMask);
	      Baseline(InProfile[i_chan].rstds,FinalMask,
		       &Hdr[i_file].redn.RNBinTimeDump,&SBase,&Srms);
	      SPeak =  FindPeak(InProfile[i_chan].rstds,
				&Hdr[i_file].redn.RNBinTimeDump,&spk);
	      InProfile[i_chan].SNR = SPeak*Srms;
	      //	      Weight = InProfile[i_chan].SNR;
	      Weight = Srms; // which is actually 1/RMS.
	    }
	    // printf("SNR %d = %lf\n",i_chan,InProfile[i_chan].SNR);
	    
	    /* Need to figure out how to organize input channels to match 
	     *  output channels */
	    /* if(Cmd->SortChansP){
	          for(i_bin=0;i_bin<NPtsProf;i_bin++) {
	             OutProfile[i_chan].rstds[i_bin] +=
		     Weight*InProfile[i_chan].rstds[i_bin];
		     OutProfile[i_chan].rstdq[i_bin] +=
		     Weight*InProfile[i_chan].rstdq[i_bin];
		     OutProfile[i_chan].rstdu[i_bin] +=
		     Weight*InProfile[i_chan].rstdu[i_bin];
		     OutProfile[i_chan].rstdv[i_bin] +=
		     Weight*InProfile[i_chan].rstdv[i_bin];
		  }
	       } 
	       else{ */
	    for(i_bin=0;i_bin<NPtsProf;i_bin++) {
	      OutProfile.rstds[i_bin] += 
		Weight*InProfile[i_chan].rstds[i_bin];
	      OutProfile.rstdq[i_bin] += 
		Weight*InProfile[i_chan].rstdq[i_bin];
	      OutProfile.rstdu[i_bin] += 
		Weight*InProfile[i_chan].rstdu[i_bin];
	      OutProfile.rstdv[i_bin] += 
		Weight*InProfile[i_chan].rstdv[i_bin];  
	      //   printf("%f\n",OutProfile[0].rstds[i_bin]);fflush(stdout);
	    }
	    //  }
	    TotWeight += Weight;  // for now keep at zero index
	    /* Print profile weights for each scan, for each channel */
	    if(RunMode.Verbose) {
	      if(i_chan==0) printf("Profile weights -- scan %d: \n   ",i_scan);
	      printf("%6.2f  ",Weight);
	      if(i_chan==Hdr[i_file].obs.NChan-1) printf("\n");fflush(stdout);
	    }
	  }
	  else {
	    n_omit++;
	    if(Cmd->VerboseP || Cmd->CheckOmitP){
	      fprintf(Fcheck, "%6d     %.1lf\n",
		      i_scan,Hdr[i_file].obs.ChanFreq[i_chan]);
	 /* printf("File %d, Dump %d, Channel %d (%lf MHz) were found to be\n",
		   i_file,i_scan,i_chan,Hdr[i_file].obs.ChanFreq[i_chan]);
	    printf("  zeroed and so are not included.\n");fflush(stdout); */
	    }
	  }
	  //    if(i_chan==0) {for(i=0;i<50;i++) printf("%lf  ",OutProfile[0].rstds[i]);printf("\n\n");fflush(stdout);};
	}
	
	/*****************/
	
	/*     }  */
	
	
      } /* else from positive check on NPtsProf */
     free(InProfile);
    }    
    /****** maybe bring this inside the ELSE where entire scans aren't being omitted ******/
    /* if (Cmd->SortChansP) 
      TotDumps += (NDumps - n_omit);
      else */ 
    TotDumps += (NDumps*Hdr[i_file].obs.NChan - n_omit); 
    //free(InProfile);
    
    printf("Reading of file %s complete and successful.\n",
	     Cmd->Infile[i_file]);
    printf("%d scans omitted.\n\n",n_omit);fflush(stdout);
  }

  if(Cmd->VerboseP || Cmd->CheckOmitP) fclose(Fcheck);

  /* Appease the format of the MakePol routine by making up these RunMode 
     structure members */
  strcpy(RunMode.Source,Hdr[0].target.PSRName);
  RunMode.Verbose = Cmd->VerboseP;
  RunMode.FlipPA = 0;
  RunMode.NoBase = Cmd->NoBaseP;
  /* divide out total number of dumps to get the average */
  // for(i_chan=0;i_chan<OutChans;i_chan++){
   
  printf("Totdumps = %d\n",TotDumps);
  fflush(stdout);
  
  for(i_bin=0;i_bin<NPtsProf;i_bin++) {
    OutProfile.rstds[i_bin] /= TotWeight;
    OutProfile.rstdq[i_bin] /= TotWeight;
    OutProfile.rstdu[i_bin] /= TotWeight;
    OutProfile.rstdv[i_bin] /= TotWeight;
  }
  
  MakePol(&RunMode, (int)NPtsProf, &OutProfile);
  /* Open file for writing */
  sprintf(Outfile,"AddProf.out");
  
  /* now write the output ascii added profile */
  if ((Fout = fopen(Outfile,"w")) == 0)
    { printf("Cannot open %s. Exiting...\n",Outfile); exit(1); }
  
  /* take average MJD of first to last scan */
  MJD_mid = (MJD_first + MJD_last)/2.;
  IMJDMid = floor(MJD_mid);
  MJDSecsMid = (MJD_mid - IMJDMid)*86400.;
  
  printf("MJD_mid = %lf, IMJDMid = %lf, MJDSecsMid = %lf\n",MJD_mid,IMJDMid,MJDSecsMid);fflush(stdout); 

  /* to choose a channel to put in the header for now, ust use the average 
     of the first datafile's channels */ 
  OutFreq=0.;
  for(i_chan=0; i_chan<Hdr[0].obs.NChan; i_chan++){
    OutFreq += Hdr[0].obs.ChanFreq[i_chan];
  }
  OutFreq /= Hdr[0].obs.NChan;

  /* Create and print header line for output file(s) */
  sprintf(Header,"# %.1f %.7f %.10f %ld %.3f %.3f %d %s %d %9s %.10f",
	  IMJDMid, 
	  MJDSecsMid, 
	  //	  Subhdr.DumpRefPeriod[i_chan],
	  0.,
	  (long)1, OutFreq,
	  //	    Hdr[0].obs.DM, Hdr[i_file].redn.RNBinTimeDump,
	  Hdr[0].obs.DM, (int)NPtsProf,
	  Hdr[0].obs.ObsvtyCode, 1, Hdr[0].target.PSRName, 
	  0.);             
  //	  Subhdr.DumpRefPhase[i_chan]);             
  fprintf(Fout,"%s\n",Header);
  
  for(i_bin=0;i_bin<NPtsProf;i_bin++) {
    /* see how strong the linear polarization is */
    x = OutProfile.stdlin[i_bin]*OutProfile.Srms; 
    ptype = 43.1;
    if (x > 1.) ptype=43.2;
    if (x > 2.) ptype=43.3;
    if (x > 3.) ptype=43.4;
    if (x > 4.) ptype=43.5;
    if (x > 5.) ptype=43.6;
    fprintf(Fout,"%5d%15.7f%15.7f%15.7f%15.7f%15.7f%15.7f%15.7f%6.1f\n",i_bin,
	    OutProfile.rstds[i_bin],OutProfile.rstdq[i_bin],
	    OutProfile.rstdu[i_bin],
	    OutProfile.rstdv[i_bin],
	    /* phi in degrees */
	    OutProfile.stdlin[i_bin],
	    OutProfile.stdphi[i_bin]*180.0/TWOPI, 
	    OutProfile.stdphierr[i_bin]*180.0/TWOPI,ptype);
  }
  printf("Created output file %s\n",Outfile);
  fclose(Fout);
  // }
  
  /* Write all this to file */
  
  
  printf("\nCompleted successfully.\n\n");fflush(stdout);
  
  exit(0);

}
Exemple #10
0
int cfits_get_hdu_num (cfitsfile *fptr, int *hdu_num)
{
   /* apparently, failure is not an option */
   (void) fits_get_hdu_num ((fitsfile *)fptr, hdu_num);
   return 0;
}
int psrfits_write_ephem(struct psrfits *pf, FILE *parfile) {
    // Read a pulsar ephemeris (par file) and put it into
    // the psrfits PSREPHEM table.  Only minimal checking
    // is done.
   
    // Get status
    int *status = &(pf->status);

    // Save current HDU, move to psrephem table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "PSREPHEM", 0, status);

    // Loop over lines in par file
    int row=1, col, dtype;
    double dval;
    int ival;
    long double ldval;
    char line[256], *ptr, *saveptr, *key, *val;
    while (fgets(line, 256, parfile)!=NULL) {

        // Convert tabs to spaces
        while ((ptr=strchr(line,'\t'))!=NULL) { *ptr=' '; }

        // strip leading whitespace
        ptr = line;
        while (*ptr==' ') { ptr++; }

        // Identify comments or blank lines
        if (line[0]=='\n' || line[0]=='#' || 
                (line[0]=='C' && line[1]==' '))
            continue;

        // Split into key/val (ignore fit flag and error)
        key = strtok_r(line,  " ", &saveptr);
        val = strtok_r(NULL, " ", &saveptr);
        if (key==NULL || val==NULL) continue; // TODO : complain?

        // Deal with any special cases here
        if (strncmp(key, "PSR", 3)==0)  {

            // PSR(J) -> PSR_NAME
            fits_get_colnum(pf->fptr,CASEINSEN,"PSR_NAME",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "RA", 2)==0) {

            // RA -> RAJ
            fits_get_colnum(pf->fptr,CASEINSEN,"RAJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "DEC", 3)==0) {

            // DEC -> DECJ
            fits_get_colnum(pf->fptr,CASEINSEN,"DECJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (key[0]=='E' && key[1]=='\0') {

            // E -> ECC
            dval = atof(val);
            fits_get_colnum(pf->fptr,CASEINSEN,"ECC",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "F0", 2)==0) {

            // F is converted to mHz and split into int/frac
            ldval = strtold(val,NULL) * 1000.0; // Hz->mHz
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"IF0",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"FF0",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "TZRMJD", 6)==0) {

            // TZRMJD is split into int/frac
            ldval = strtold(val,NULL);
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRIMJD",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRFMJD",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else {

            // Find column, skip/warn if this one isn't present
            fits_get_colnum(pf->fptr,CASEINSEN,key,&col,status);
            if (*status==COL_NOT_FOUND) {
#if (DEBUGOUT)
                fprintf(stderr, 
                        "psrfits_write_epherm warning: Couldn't find keyword %s "
                        "in ephemeris table.\n",
                        key);
#endif
                *status=0;
                continue;
            }

            // Need to convert string to appropriate column data type
            // and then write it to the column.  These should all be
            // either double int or string.
            fits_get_coltype(pf->fptr,col,&dtype,NULL,NULL,status);
            if (dtype==TDOUBLE || dtype==TFLOAT) { 
                dval = atof(val);
                fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);
            } else if (dtype==TINT || dtype==TLONG || dtype==TSHORT) {
                ival = atoi(val);
                fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            } else if (dtype==TSTRING) {
                fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);
            } else {
                fprintf(stderr, "psrfits_write_ephem warning: "
                        "Unhandled column datatype (key=%s)\n", key);
                continue;
            }
        }

        // sucess/failure
        if (*status) {
            fprintf(stderr, "psrfits_write_ephem failed: key=%s val=%s\n",
                    key, val);
            fits_report_error(stderr, *status);
            *status=0;
        } 
#if 0  // DEBUG
        else {
            fprintf(stderr, "psrfits_write_ephem success: key=%s val=%s\n",
                    key, val);
        }
#endif

    }

    // Go back to orig HDU
    fits_movabs_hdu(pf->fptr, hdu, NULL, status);

    return *status;
}
int main(int argc, char *argv[])
{
  fitsfile *fptr = 0;         /* FITS file pointer, defined in fitsio.h */
  char keyname[FLEN_KEYWORD], colname[FLEN_VALUE], coltype[FLEN_VALUE];
  int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
  int single = 0, hdupos = 0, hdutype = 0, bitpix = 0, naxis = 0, ncols = 0, ii = 0;
  long naxes[10], nrows = 0;

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 2) {
    fprintf(stderr, "Usage:  %s filename[ext] \n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "List the structure of a single extension, or, if ext is \n");
    fprintf(stderr, "not given, list the structure of the entire FITS file.  \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Note that it may be necessary to enclose the input file\n");
    fprintf(stderr, "name in single quote characters on the Unix command line.\n");
    return (0);
  }

  FILE *fout = popen(PAGER, "w");
  if (fout == NULL) {
    fprintf(stderr, "Could not execute '%s'\n", PAGER);
    return (1);
  }

  if (!fits_open_file(&fptr, argv[1], READONLY, &status)) {
    fits_get_hdu_num(fptr, &hdupos);  /* Get the current HDU position */

    /* List only a single structure if a specific extension was given */
    if (strchr(argv[1], '[') || strchr(argv[1], '+')) {
      single++;
    }

    for (; !status; hdupos++) { /* Main loop for each HDU */
      fits_get_hdu_type(fptr, &hdutype, &status);  /* Get the HDU type */

      fprintf(fout, "\nHDU #%d  ", hdupos);
      if (hdutype == IMAGE_HDU) { /* primary array or image HDU */
        fits_get_img_param(fptr, 10, &bitpix, &naxis, naxes, &status);

        fprintf(fout, "Array:  NAXIS = %d,  BITPIX = %d\n", naxis, bitpix);
        for (ii = 0; ii < naxis; ii++) {
          fprintf(fout, "   NAXIS%d = %ld\n",ii+1, naxes[ii]);
        }
      } else { /* a table HDU */
        fits_get_num_rows(fptr, &nrows, &status);
        fits_get_num_cols(fptr, &ncols, &status);

        if (hdutype == ASCII_TBL) {
          fprintf(fout, "ASCII Table:  ");
        } else {
          fprintf(fout, "Binary Table:  ");
        }

        fprintf(fout, "%d columns x %ld rows\n", ncols, nrows);
        fprintf(fout, " COL NAME             FORMAT\n");

        for (ii = 1; ii <= ncols; ii++) {
          fits_make_keyn("TTYPE", ii, keyname, &status); /* make keyword */
          fits_read_key(fptr, TSTRING, keyname, colname, NULL, &status);
          fits_make_keyn("TFORM", ii, keyname, &status); /* make keyword */
          fits_read_key(fptr, TSTRING, keyname, coltype, NULL, &status);

          fprintf(fout, " %3d %-16s %-16s\n", ii, colname, coltype);
        }
      }

      if (single) {
        break;  /* quit if only listing a single HDU */
      }

      fits_movrel_hdu(fptr, 1, NULL, &status);  /* try move to next ext */
    }

    if (status == END_OF_FILE) {
      status = 0;  /* Reset normal error */
    }
    fits_close_file(fptr, &status);
  }

  pclose(fout);

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
Exemple #13
0
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::BAbrirClick(TObject *Sender)
{
  fitsfile *fptr = 0;       /* pointer to the FITS file, defined in fitsio.h */
  int status, nkeys, keypos, hdutype, ii, jj;
  char filename[FLEN_FILENAME];    /* input FITS file */
  char card[FLEN_CARD];   /* standard string lengths defined in fitsioc.h */

  char aux[300];
  int ejes = 0;
  long ajes[4] = {0,0,0,0};
  int tipo;

  if(fptr != 0)
  {
    status = 0;
    if ( fits_close_file(fptr, &status) )
    {
      printerror( status );
      return;
    }
  }
  if(OD1->Execute())
  {
    status = 0;
    if ( fits_open_file(&fptr, OD1->FileName.c_str(), READWRITE, &status) )
    {
       printerror(status);
       return;
    }
  }
  else
    return;
  fits_get_hdu_num(fptr, &ii); // get the current HDU number
  Memo1->Lines->Add("HDU NUMBER: " + AnsiString(ii));
    // attempt to move to next HDU, until we get an EOF error
  status = 0;
  for (; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++)
  {
    status = 0;
    if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) )// get no. of keywords
    {
      printerror( status );
      return;
    }
    wsprintf(aux, "Header listing for HDU #%d:", ii);
    Memo1->Lines->Add(aux);
    for (jj = 1; jj <= nkeys; jj++)
    {
      status = 0;
      if ( fits_read_record(fptr, jj, card, &status) )
      {
        printerror( status );
        return;
      }
      Memo1->Lines->Add(card); // print the keyword card
    }
    printf("END\n\n");  /* terminate listing with END */
  }
  if (status == END_OF_FILE)   /* status values are defined in fitsio.h */
    status = 0;              /* got the expected EOF error; reset = 0  */
  else
  {
    printerror( status );     /* got an unexpected error                */
    return;
  }
  status = 0;
  if(ffgipr(fptr,  2, &tipo, &ejes, ajes, &status))
  {
    printerror( status );
    return;
  }

  Memo1->Lines->Add("------");
  Memo1->Lines->Add("Tipo : " + AnsiString(tipo));
  Memo1->Lines->Add("EJES : " + AnsiString(ejes));
  Memo1->Lines->Add("AJES0: " + AnsiString(ajes[0]));
  Memo1->Lines->Add("AJES1: " + AnsiString(ajes[1]));

  ejex = ajes[0];
  ejey = ajes[1];
  //////////////////////////////////////////////////////

  NumeroColumnas = ejex/* / Binin*/;
  NumeroFilas = ejey /*/ Binin*/;
  X1 = X1F = 0;
  Y1 = Y1F = 0;
  X2 = X2F = NumeroColumnas;
  Y2 = Y2F = NumeroFilas;
  PB1->Width = X2 + 4;
  PB1->Height = Y2 + 4;
  PX1->Caption = X1;
  PX2->Caption = X2;
  PY1->Caption = Y1;
  PY2->Caption = Y2;
  PFil->Caption = NumeroFilas;
  PCol->Caption = NumeroColumnas;

  delete BM1;
  BM1 = new Graphics::TBitmap();
  BM1->Height = NumeroFilas;
  BM1->Width = NumeroColumnas;
  BM1->PixelFormat = pf8bit;
  BM1->Palette = CreatePalette(&SysPal.lpal);
  for (int y = 0; y < NumeroFilas; y++)
  {
    for (int x = 0; x < NumeroColumnas; x++)
    {
      Foto[y][x] = 0;
    }
  }

  long primer_elemento = 1;
  long numelem = ejex*ejey;
  int cualquiernull = 0;
  Byte *ptr;
  short sust = 0;
  unsigned short *datos;

  datos = new unsigned short [ejex*ejey];
  memset(datos, 0, ejex*ejey*2);
  status = 0;
  if(fits_read_img(fptr, TSHORT, primer_elemento, numelem,
                   &sust, //valor por el que se sustituira los indefinidos
                   &datos[primer_elemento],
                   &cualquiernull, // 1 si hay alguna sustitucion
                   &status))
  {
    printerror( status );
  }
  long n = numelem;
  for(int py = 0; py < ejey; py++)
  {
    for (int px = ejex; px > 0; px--)
    {
      Foto[py][px] = datos[n--];
    }
  }
  delete datos;
  PB1->Repaint();

}
int psrfits_write_polycos(struct psrfits *pf, struct polyco *pc, int npc) {

    // Usual setup
    int *status = &(pf->status);

    // If mode!=fold, exit?

    // Save current HDU, move to polyco table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "POLYCO", 0, status);

    int itmp;
    double dtmp;
    char datestr[32], ctmp[32];
    char *cptr;
    fits_get_system_time(datestr, &itmp, status);
    int i, col, n_written=0; 
    long row;
    fits_get_num_rows(pf->fptr, &row, status); // Start at end of table
    for (i=0; i<npc; i++) {

        // Only write polycos that were used
        if (!pc[i].used) continue; 

        // Go to next row (1-based index)
        row++;

        cptr = datestr;
        fits_get_colnum(pf->fptr,CASEINSEN,"DATE_PRO",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        sprintf(ctmp, "11.005"); // Tempo version?
        cptr = ctmp;
        fits_get_colnum(pf->fptr,CASEINSEN,"POLYVER",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"NSPAN",&col,status);
        fits_write_col(pf->fptr,TINT,col,row,1,1,&(pc[i].nmin),status);

        fits_get_colnum(pf->fptr,CASEINSEN,"NCOEF",&col,status);
        fits_write_col(pf->fptr,TINT,col,row,1,1,&(pc[i].nc),status);

        sprintf(ctmp,"%d", pc[i].nsite); // XXX convert to letter?
        cptr = ctmp;
        fits_get_colnum(pf->fptr,CASEINSEN,"NSITE",&col,status);
        fits_write_col(pf->fptr,TSTRING,col,row,1,1,&cptr,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_FREQ",&col,status);
        fits_write_col(pf->fptr,TFLOAT,col,row,1,1,&(pc[i].rf),status);

        // XXX needs to be accurate??
        dtmp=0.0;
        fits_get_colnum(pf->fptr,CASEINSEN,"PRED_PHS",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        dtmp = (double)pc[i].mjd + pc[i].fmjd;
        fits_get_colnum(pf->fptr,CASEINSEN,"REF_MJD",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_PHS",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&(pc[i].rphase),status);

        fits_get_colnum(pf->fptr,CASEINSEN,"REF_F0",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&(pc[i].f0),status);

        // XXX don't parse this yet
        dtmp=-6.0;
        fits_get_colnum(pf->fptr,CASEINSEN,"LGFITERR",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dtmp,status);

        fits_get_colnum(pf->fptr,CASEINSEN,"COEFF",&col,status);
        fits_write_col(pf->fptr,TDOUBLE,col,row,1,pc[i].nc,pc[i].c,status);

        n_written++;
    }

    // Update polyco block count, only if new info was added
    if (n_written) {
        itmp = row;
        fits_get_colnum(pf->fptr,CASEINSEN,"NPBLK",&col,status);
        for (i=1; i<=row; i++) 
            fits_write_col(pf->fptr,TINT,col,i,1,1,&itmp,status);
    }

    // Flush buffers (so files are valid as they are created)
    fits_flush_file(pf->fptr, status);

    // Go back to orig HDU
    fits_movabs_hdu(pf->fptr, hdu, NULL, status);

    return *status;
}
Exemple #15
0
int main(int argc, char *argv[])
{
  fitsfile *fptr;         /* 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 single = 0, hdupos = 0, nkeys = 0, ii = 0;

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 2) {
    fprintf(stderr, "Usage:  %s filename[ext] \n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "List the FITS header keywords in a single extension, or, if \n");
    fprintf(stderr, "ext is not given, list the keywords in all the extensions. \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Examples: \n");
    fprintf(stderr, "   %s file.fits      - list every header in the file \n", argv[0]);
    fprintf(stderr, "   %s file.fits[0]   - list primary array header \n", argv[0]);
    fprintf(stderr, "   %s file.fits[2]   - list header of 2nd extension \n", argv[0]);
    fprintf(stderr, "   %s file.fits+2    - same as above \n", argv[0]);
    fprintf(stderr, "   %s file.fits[GTI] - list header of GTI extension\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Note that it may be necessary to enclose the input file\n");
    fprintf(stderr, "name in single quote characters on the Unix command line.\n");
    return (0);
  }

#if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE)
  FILE *fout = popen(PAGER, "w");
  if (fout == NULL) {
    fprintf(stderr, "Could not execute '%s'\n", PAGER);
    return (1);
  }
#else
  FILE *fout = stdout;
#endif

  if (!fits_open_file(&fptr, argv[1], READONLY, &status)) {
    fits_get_hdu_num(fptr, &hdupos);  /* Get the current HDU position */

    /* List only a single header if a specific extension was given */
    if (hdupos != 1 || strchr(argv[1], '[')) {
      single = 1;
    }

    for (; !status; hdupos++) { /* Main loop through each extension */
      fits_get_hdrspace(fptr, &nkeys, NULL, &status); /* get # of keywords */

      fprintf(fout, "Header listing for HDU #%d:\n", hdupos);

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

        if (fits_read_record(fptr, ii, card, &status)) {
          break;
        }
        fprintf(fout, "%s\n", card);
      }
      fprintf(fout, "END\n\n");  /* terminate listing with END */

      if (single) {
        break;  /* quit if only listing a single header */
      }

      fits_movrel_hdu(fptr, 1, NULL, &status);  /* try to move to next HDU */
    }

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

    fits_close_file(fptr, &status);
  }

#if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE)
  pclose(fout);
#endif

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
Exemple #16
0
int DoIt(){
 
    /* Variable declarations */

    /* Generic use variables */

    int i,j,k;					/* Generic loop counters */

    /* DRMS/JSOC variables */

	char *harpnum,*time_range;					/* SHARPs ID and time range from module_args[] */
	char *drms_query;							/* The DRMS query we are going to send */
	double umb_sig, pen_sig;					/* Cutoffs for sunspots */
	int num_query_chars;						/* Number of characters in total query for malloc definition */
	CmdParams_t *params=&cmdparams;				/* For the module_args stuff */
	DRMS_RecordSet_t *drms_ids;					/* Holds the id structure of the records */
	DRMS_Record_t *drms_record;					/* Holds specific record information */
	DRMS_Segment_t *drms_segment;				/* Segment information */
	int drms_status;							/* Status variable */
	int num_records;							/* Number of records and variables to get the segment locations we need */
	
	/* cfitsio-related variables */

    fitsfile *c_ptr,*i_ptr;				/* Pointers for FITS files */
    int c_status, i_status;				/* Status checker for opening files */
    int hdu_pos,num_hdus;				/* HDU number and location */
    int needed_hdu;						/* The HDU we want to be on */
    int any_nulls;						/* Nonzero if there are null values in data */
    char i_filename[DRMS_MAXPATHLEN+1],c_filename[DRMS_MAXPATHLEN+1];	/* Containers for the filenames */
    double nulval;							/* Container for what null values in data should be set to */
	

    /* Needed FITS keywords */

    int naxis1,naxis2,naxis;			/* Length of axes */
    double crpix1,crpix2;				/* SHARPs CRPIX is the center of the sun relative to the lower left (fortran: 1,1) of patch */
    double cdelt1		;				/* HMI pixel sizes in as */
    double rsun_obs;					/* Radius of the sun, observed at t_obs */
    double blank;						/* Values of bad data */
    TIME t_obs;							/* Observation time, ZULU */
    char **t_obs_s;						/* String version of observation time */
    long *quality;						/* QUALITY keyword */
    
    /* Data-related variables */
    
    double **con_dat, **inc_dat;			/* Data arrays, size defined once naxis1/2 are known */
    int **p_mask, **n_mask;					/* Mask for each polarity of umbrae within continuum data */ 
    double *c_pixel_strip;					/* Strip of pixels read from the continuum data */
    double *i_pixel_strip;					/* Strip of pixels read from the inclination data */
    long fpixel[2];							/* Holds the location of pixel to be read */
    LONGLONG nelements;						/* Number of elements in a strip to be read (naxis2) */
    FILE *outptr,*bad_outptr;				/* Pointer to the outfile */
    char outfile_name[29];					/* Name of the outfile */
    char bad_outfile_name[24];				/* Name of the outfile for bad quality*/    
    
    /* Variables related to the actual task */
    
    double rllx,rlly;				/* Disk center, patch coordinates */
    double **radius;				/* Array to hold where the Sun's boundaries are, column major order */
    double rsun_pix,xx,yy,r;		/* Variables associated with radial boundaries */
    double umb,pen;					/* Intensity cutoffs for the umbra and penumbra */
    double num_good;				/* The number of nonzero continuum values in a sunspot region */
    double *p_spots,*n_spots;		/* Number of sunspots of each polarity within an active region */
    double mu;						/* Angle from solar center */
    long *t_secs;					/* T_OBS time converted to seconds since UNIX epoch */
    int noaa_ar;					/* Active region number */
    
    /* Initialise variables that need it */

    i=j=k=0;
    drms_status=0;

	/* Grab values from module_args[] */

	harpnum=strdup(params_get_str(params,"harpnum"));
	time_range=strdup(params_get_str(params,"time_range"));
	umb_sig=params_get_double(params,"umb_sig");
	pen_sig=params_get_double(params,"pen_sig");

	/* Now we start the main program. The rough layout is as follows: 
	   
	   1. Query drms. Based on what we learn, either exit or grab what we need from it.
	   2. Loop through the files, determining the number of sunspots in each polarity.
	   3. Print out a table of values at the end.				   */
	
	/* Forge the DRMS query. */
	
	num_query_chars=16+strlen(harpnum);		/* hmi.sharp_720s[] is 16 characters */
	
	if (time_range!="[]"){
		
		num_query_chars+=strlen(time_range);
		
	}
	
	drms_query=calloc(num_query_chars,sizeof(char));
	strcat(drms_query,"hmi.sharp_720s[");
	strcat(drms_query,harpnum);
	strcat(drms_query,"]");
	
	if (time_range!="[]"){
	
		strcat(drms_query,time_range);
		
	}
	
	/* Query DRMS for the records. */
	
	printf("Querying DRMS. This may take some time.\n");
	
	if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){
		
		printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		free(drms_query);
		return 0;
		
	}

	free(drms_query);

	num_records=drms_ids->n;
	printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records);

	drms_record=drms_ids->records[0];

	if (!(drms_segment_lookup(drms_record,"continuum"))){
		
		printf("Continuum segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"inclination"))){
		
		printf("Inclination segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}
	
	/* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */
	
	/* First set the size of some of the pointers that are intended to be arrays. */
	
	/* Data-related arrays */
	p_spots=malloc(num_records*sizeof(double));
	n_spots=malloc(num_records*sizeof(double));
	
	/* Time-related arrays */
	
	t_secs=malloc(num_records*sizeof(long));
	t_obs_s=malloc(num_records*sizeof(char *));
	
	for (i=0;i<num_records;i++){
		
		t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char));
		
	}
	
	/* Quality */
	
	quality=malloc(num_records*sizeof(long));
		
	for (k=0;k<num_records;k++){ 

		drms_record=drms_ids->records[k];
		
		/* Check to see if we have data for a particular observation time */
		
		if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){
					
			printf("Keyword %s not present! Exiting.\n","T_OBS");
			drms_close_records(drms_ids,DRMS_FREE_RECORD);
			return 0;
		
		}
		
		if (time_is_invalid(t_obs)){
			
			printf("Bad record, skipping.\n");
			
		} else {

			if (k == 0){
				
				/* Get active region number for pregame info */
			
				if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){
					
					printf("Keyword %s not present! Exiting.\n","NOAA_AR");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
		
				}
				
				/* Create data output filename */
			
				sprintf(outfile_name,"AR%d.spotcount-output.dat",noaa_ar);
				sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar);
				
				/* Print out some stats before we run */
			
				printf("Pre-analysis details:\n");
				printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar);
				printf("Output file: %s\n",outfile_name);
			
				if (time_range == "[]"){
				
					printf("We are covering the entire data set.\n");
			
				} else {
				
					printf("Time range: %s\n",time_range);
			
				}

					printf("\n\n");
			
			}
			
			printf("Processing record %d of %d.\n",k+1,num_records);
		
			/* Fill keywords */
			
			if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){
			
				quality[k]=0;
		
			}
	
			if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){
			
				printf("Keyword %s not present! Exiting.\n","CRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","RSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","BLANK");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			sprint_ut(t_obs_s[k],t_obs);		/* Convert to string */
			
			if (quality[k] == 0){
		
				/* Ok, now we get the file locations for the data from DRMS. Originally I attempted
				* to pull the data directly from DRMS but there were vague free() and malloc() issues
				* possibly due to icc and multithreading. */
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){
			
					printf("Problem opening the continuum segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,c_filename);
			
				/* naxis1 and naxis2 we get from segment information */
		
				naxis1=(int)drms_segment->axis[0];
				naxis2=(int)drms_segment->axis[1];
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){
			
					printf("Problem opening the inclination segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,i_filename);
		
				/* Now open the FITS files and get to work. */
	
				c_status=i_status=0;

				if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){
				
					printf("Cannot open %s! Exiting.\n",c_filename);
					exit(0);

				}

				if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){
				
					printf("Cannot open %s! Exiting.\n",i_filename);
					fits_close_file(c_ptr,&c_status);
					exit(0);

				}

				printf(" Opening FITs files.\n");

				/* Walk through the HDUs until we get to one with NAXIS=2 */

				/* Number of headers and which one we are on */

				fits_get_num_hdus(c_ptr,&num_hdus,&c_status);
				fits_get_hdu_num(c_ptr,&hdu_pos);

				/* Find the one with two naxes */

				naxis=0;
			
				for (i=1;i<=num_hdus;i++){
				
					fits_movabs_hdu(c_ptr,i,NULL,&c_status);
					fits_read_key(c_ptr,TINT,"NAXIS",&naxis,NULL,&c_status);
				
					if (naxis == 2){
	
						needed_hdu=i;
	
					}
				}

				/* Set all to the needed HDU */

				if (naxis == 0){
		
					printf("HDU problems: can't find one with the required number of axes.\n");
					fits_close_file(c_ptr,&c_status);
					fits_close_file(i_ptr,&i_status);
					exit(0);

				} else {

					fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status);
					fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status);

				}

				/* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */
	
				p_mask=malloc(naxis2*sizeof(int *));
				n_mask=malloc(naxis2*sizeof(int *));
				con_dat=malloc(naxis2*sizeof(double *));
				inc_dat=malloc(naxis2*sizeof(double *));
				radius=malloc(naxis2*sizeof(double *));
				
				c_pixel_strip=calloc(naxis1,sizeof(double));
				i_pixel_strip=calloc(naxis1,sizeof(double));
	
				for (j=0;j<naxis2;j++){
		
					p_mask[j]=calloc(naxis1,sizeof(int));
					n_mask[j]=calloc(naxis1,sizeof(int));
					con_dat[j]=calloc(naxis1,sizeof(double));
					inc_dat[j]=calloc(naxis1,sizeof(double));
					radius[j]=calloc(naxis1,sizeof(double));
		
				}
    
				/* Next, put data in the arrays, clear out blank values and NaNs from the data */
	
				fpixel[0]=1;		/* cfitsio uses fortran reference instead of c when accessing data */
				nelements=naxis1;
				nulval=0;
				any_nulls=0;
    
				for (j=0;j<naxis2;j++){
		
					fpixel[1]=j+1;	/* Add 1 to account for fortran FITS indexing */
					fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status);
					fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status);
		
					for (i=0;i<naxis1;i++){
			
						/* Kill blank values if present, if not assign to the correct place in array */
			
						if (c_pixel_strip[i] == blank){
				
							con_dat[j][i]=0.0;
					
						} else {
					
							con_dat[j][i]=c_pixel_strip[i];
			
						}
			
						if (i_pixel_strip[i] == blank){
				
							inc_dat[j][i]=0.0;
				
						} else {
					
							inc_dat[j][i]=i_pixel_strip[i];
			
						}
					
					}
				}
		
				printf(" Analyzing data.\n");
	
				/* We now have filled arrays of data about the SHARPs patch and all of the needed keywords. */
	
				/* Coordinate variable definitions for future use. See the declaration section */
				/* at the front of the code to understand what these refer to. */
	
				rllx=(crpix1-1);
				rlly=(crpix2-1);
	
				/* Fill the radius array, handle limb darkening, find max value in patch. */
	
				rsun_pix=rsun_obs/cdelt1;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
			
						xx=(double)i-rllx;
						yy=(double)j-rlly;
						r=sqrt(xx*xx+yy*yy);
				
						if (r <= rsun_pix){
				
							radius[j][i]=r;
							mu=sqrt(1-pow(r/rsun_pix,2.0));
							con_dat[j][i]=con_dat[j][i]/limb_darken(mu);
					
						}
					}
				}
	
				/* Create the actual masks for sunspot counting */
			
				spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig);

				num_good=0;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
		
						if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){
				
							num_good++;
			
						}
					}
				}

				p_spots[k]=n_spots[k]=0.0;
	
				if (num_good > 0){
		
					/* We have a region. */
		
					for (i=0;i<naxis1;i++){
					
						for (j=0;j<naxis2;j++){
				
							/* On the solar disk, with continuum values at or below the cutoff for
							* the penumbra */
				
							if ((radius[j][i] > 0)&&(con_dat[j][i] <= umb)&&(con_dat[j][i] > 0)){
						
								/* "Positive" sunspot polarities. */
							
								if (inc_dat[j][i] < 90){
							
									p_mask[j][i]=1;
					
								}
					
								/* "Negative" sunspot polarities. */
					
								if (inc_dat[j][i] > 90){
							
									n_mask[j][i]=1;
					
								}
							}
						}
					}
				
					/* Now find the number of unique spots */
				
					p_spots[k]=connected_component_detect(p_mask,naxis1,naxis2);
					n_spots[k]=connected_component_detect(n_mask,naxis1,naxis2);
			
				}

			
				/* Free up dynamic arrays and close the files for the next iteration. */

				for (i=0;i<naxis2;i++){

					free(p_mask[i]);
					free(n_mask[i]);
					free(con_dat[i]);
					free(inc_dat[i]);
					free(radius[i]);
				
				}

				free(p_mask);
				free(n_mask);
				free(con_dat);
				free(inc_dat);
				free(radius);

				free(c_pixel_strip);
				free(i_pixel_strip);
				
				fits_close_file(c_ptr,&c_status);
				fits_close_file(i_ptr,&i_status);

			}
	
		}
		printf(" Completed run %d of %d.\n",k+1,num_records);
	}
	
	/* Output the results to a text file. */
	
	/* First, convert t_obs to a more reasonable product. */
	
	for (i=0;i<num_records;i++){			
	
		t_secs[i]=isotime(t_obs_s[i]);

	}

	printf("Writing to file %s.\n",outfile_name);
	
	outptr=fopen(outfile_name,"w");
	bad_outptr=fopen(bad_outfile_name,"w");
	
	fprintf(outptr,"Active Region: %d\n",noaa_ar);
	fprintf(outptr,"Full UT Time            time(s)  num pos  num neg\n");
	fprintf(outptr,"----------------------  -------  -------  -------\n");
	
	fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar);
	fprintf(bad_outptr,"Full UT Time            quality  time(s)  number\n");
	fprintf(bad_outptr,"----------------------  -------  -------  ------\n");
	
	for (i=0;i<num_records;i++){
		
		/* Make times relative to the first recorded one. */
		
		if (quality[i] == 0){
		
			fprintf(outptr,"%s  %7ld  %6.2lf  %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],p_spots[i],n_spots[i]);
	
		} else {
			
			fprintf(bad_outptr,"%s  0x%08lX  %7ld  %d\n",t_obs_s[i],quality[i],t_secs[i],i+1);
			
		}
	}
	
	fclose(outptr);
	fclose(bad_outptr);
	
	printf("Done!\n");
	
	/* Free memory associated with dynamic arrays. */
    
	free(p_spots);
	free(n_spots);

	free(t_secs);
	free(t_obs_s);
	
	free(quality);
	
	/* Close the drms records connection */
	
	drms_close_records(drms_ids,DRMS_FREE_RECORD);
    
	/* Done! */
    
	return 0;
}
Exemple #17
0
int DoIt(){
 
    /* Variable declarations */

    /* Generic use variables */

    int i,j,k,l,n;								/* Generic loop counters */

    /* DRMS/JSOC variables */

	char *harpnum,*time_range;					/* SHARPs ID and time range from module_args[] */
	double umb_sig, pen_sig;					/* Cutoffs for sunspots */
	int num_divs;								/* Number of divisions to break a data strip into for trend removal */
	char *drms_query;							/* The DRMS query we are going to send */
	int num_query_chars;						/* Number of characters in total query for malloc definition */
	CmdParams_t *params=&cmdparams;				/* For the module_args stuff */
	DRMS_RecordSet_t *drms_ids;					/* Holds the id structure of the records */
	DRMS_Record_t *drms_record;					/* Holds specific record information */
	DRMS_Segment_t *drms_segment;				/* Segment information */
	int drms_status;							/* Status variable */
	int num_records;							/* Number of records and variables to get the segment locations we need */
	
	/* cfitsio-related variables */

    fitsfile *v_ptr,*i_ptr,*c_ptr;		/* Pointers for FITS files */
    fitsfile *info_ptr;		
    int v_status,i_status,c_status;		/* Status checker for opening files */
    int info_status;					
    int hdu_pos,num_hdus;				/* HDU number and location */
    int needed_hdu;						/* The HDU we want to be on */
    int any_nulls;						/* Nonzero if there are null values in data */
    char i_filename[DRMS_MAXPATHLEN+1],v_filename[DRMS_MAXPATHLEN+1];		/* Containers for the filenames */
	char c_filename[DRMS_MAXPATHLEN+1],info_filename[DRMS_MAXPATHLEN+1];
	double nulval;							/* Container for what null values in data should be set to */
	long l_nulval;

    /* Needed FITS keywords */

    int naxis1,naxis2,naxis;			/* Length of axes */
    double crpix1,crpix2;				/* SHARPs CRPIX is the center of the Sun relative to the lower left of the patch (fortranL 1,1) */
    double imcrpix1,imcrpix2;			/* SHARPs IMCRPIX is the center of the Sun in full plate coordinates (fortran) */
    double cdelt1,cdelt2;				/* HMI pixel sizes in as */    double blank;						/* Values of bad data */
    double crota2,crln_obs,crlt_obs;	/* Rotation, carrington observer location */
    double dsun_obs,rsun_obs;			/* Distance to and radius of the sun, observed at t_obs */
    double obs_vr,obs_vw,obs_vn;		/* Satellite velocity keywords */
    TIME t_obs;							/* Observation time, ZULU */
    char **t_obs_s;						/* String version of observation time */
    long *quality;						/* Data quality keyword */
    
    /* Data-related variables */
    
    double **vlos_dat, **inc_dat;			/* Data arrays, size defined once naxis1/2 are known */
    double **con_dat;
    long **info_dat;
    double *v_pixel_strip;					/* Strip of pixels read from the field data */
    double *i_pixel_strip;					/* Strip of pixels read from the inclination data */
    double *c_pixel_strip;					/* Strip of pixels read from the continuum data */
    long *info_pixel_strip;					/* Strip of pixels read from the continuum data */
    long fpixel[2];							/* Holds the location of pixel to be read */
    LONGLONG nelements;						/* Number of elements in a strip to be read (naxis2) */
    FILE *outptr,*bad_outptr;				/* Pointer to the outfile */
    char outfile_name[25];					/* Name of the outfile */
    char bad_outfile_name[24];				/* Name of the outfile for bad quality*/
    
    /* Variables related to the actual task */
    
    double rscx,rscy;				/* Disk center, plate coordinates */
    double rllx,rlly;				/* Disk center, patch coordinates */
    double rpllx,rplly;				/* Lower left of patch, plate coordinates */
    double **radius;				/* Array to hold where the Sun's boundaries are, column major order */
	double umb,pen;					/* Intensity cutoffs for the umbra and penumbra */
    double num_good;				/* The number of nonzero continuum values in a sunspot region */
    double mu;						/* Angle from solar center */
    double rsun_pix,xx,yy,r;		/* Variables associated with radial boundaries */
    long *t_secs;					/* T_OBS time converted to seconds since UNIX epoch */
    double *umb_p_vel,*umb_n_vel;	/* Umbral LOS velocities */
    double *pen_p_vel,*pen_n_vel;	/* Penumbral LOS velocities */
    double umb_p_counter,umb_n_counter;	/* Counters for averages */
    double pen_p_counter,pen_n_counter;
    double vr,vn,vw,vt;				/* Various LOS velocities due to satellite motion and solar rotation */
    double vlos;					/* VLOS after removing all of the satellite motion and solar rotation */
    double **y_axis;				/* Array to be looped over wrt naxis2 to remove trends */
    double **y_error;				/* Error on y axis, taken as 1 */
    double **x_axis;				/* Array to be looped over that holds naxis1 information for fitting */
    double x,y;						/* Pixel location on the solar disk */
    double ttx,tty,tx,ty,zz;		/* Intermediate variables for coordinate conversions */
    double lat,lon;					/* Carrington coordinate latitude and longitude */
    double p,t;						/* Spherical phi and theta coordinates */
	int noaa_ar;					/* Active region number */
	mp_result result;				/* Fitting result structure */
	mp_config config;				/* Configuration options for fitting structure */
	double perror[2];				/* Error on fitting coefficients */
	double fit_params[2];			/* Fitting coefficients */
	struct vars_struct v;			/* Private data, shared between main and functions */
	int fit_status;					/* Fitting returned status */
	int inv_len;					/* Interval length for breaking data up */
	
       
    /* Initialise variables that need it */

    drms_status=0;
    
	memset(&result,0,sizeof(result));
	memset(&config,0,sizeof(config));
	
	/* Set the error stuff for cmfit */
	
	result.xerror=perror;
	
	/* Set the default options for cmfit */
	
	config.ftol=1.49012e-08;
	config.xtol=1.49012e-08;
	config.gtol=0.0;
	config.maxfev=0;
    
	/* Grab values from module_args[] */

	harpnum=strdup(params_get_str(params,"harpnum"));
	time_range=strdup(params_get_str(params,"time_range"));
	umb_sig=params_get_double(params,"umb_sig");
	pen_sig=params_get_double(params,"pen_sig");
	num_divs=params_get_int(params,"num_divs");
	
	/* Now we start the main program. The rough layout is as follows: 
	   
	   1. Query drms. Based on what we learn, either exit or grab what we need from it.
	   2. Loop through the files, calculate field stuff.
	   3. Print out a table of values at the end.				   */
	
	/* Forge the DRMS query. */
	
	num_query_chars=16+strlen(harpnum);		/* hmi.sharp_720s[] is 16 characters */
	
	if (time_range!="[]"){
		
		num_query_chars+=strlen(time_range);
		
	}
	
	drms_query=calloc(num_query_chars,sizeof(char));
	strcat(drms_query,"hmi.sharp_720s[");
	strcat(drms_query,harpnum);
	strcat(drms_query,"]");
	
	if (time_range!="[]"){
	
		strcat(drms_query,time_range);
		
	}
	
	/* Query DRMS for the records. */
	
	printf("Querying DRMS. This may take some time.\n");
	
	if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){
		
		printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		free(drms_query);
		return 0;
		
	}

	free(drms_query);

	num_records=drms_ids->n;
	printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records);

	drms_record=drms_ids->records[0];

	if (!(drms_segment_lookup(drms_record,"vlos_mag"))){
		
		printf("vlos_mag segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"inclination"))){
		
		printf("Inclination segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"continuum"))){
		
		printf("Continuum segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"info_map"))){
		
		printf("Info_map segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;

	}

	/* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */
	
	/* First set the size of some of the pointers that are intended to be arrays. */
	
	/* Time-related arrays */
	
	t_secs=malloc(num_records*sizeof(long));
	t_obs_s=malloc(num_records*sizeof(char *));
	
	for (i=0;i<num_records;i++){
		
		t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char));
		
	}
	
	/* Data-related arrays */
	
	umb_p_vel=malloc(num_records*sizeof(double));
	pen_p_vel=malloc(num_records*sizeof(double));
	umb_n_vel=malloc(num_records*sizeof(double));
	pen_n_vel=malloc(num_records*sizeof(double));

	/* Record quality */
	
	quality=malloc(num_records*sizeof(long));
	
	for (k=0;k<num_records;k++){ 

		drms_record=drms_ids->records[k];
		
		/* Check to see if we have data for a particular observation time */
		
		if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){
					
			printf("Keyword %s not present! Exiting.\n","T_OBS");
			drms_close_records(drms_ids,DRMS_FREE_RECORD);
			return 0;
		
		}
		
		if (time_is_invalid(t_obs)){
			
			printf("Bad record, skipping.\n");
			
		} else {
			
			if (k == 0){
				
				/* Get active region number for pregame info */
			
				if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){
					
					printf("Keyword %s not present! Exiting.\n","NOAA_AR");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
		
				}
				
				/* Create data output filename */
			
				sprintf(outfile_name,"AR%d.fvlos-output.dat",noaa_ar);
				sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar);
							
				/* Print out some stats before we run */
			
				printf("Pre-analysis details:\n");
				printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar);
				printf("Output file: %s\n",outfile_name);
			
				if (time_range == "[]\0"){
				
					printf("We are covering the entire data set.\n");
			
				} else {
				
					printf("Time range: %s\n",time_range);
			
				}

				printf("\n\n");	
			}
			
			printf("Processing record %d of %d.\n",k+1,num_records);
		
			/* Fill keywords */
			
			if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){
			
				quality[k]=0;
		
			}
	
			if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){
			
				printf("Keyword %s not present! Exiting.\n","CRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
		
			if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(cdelt2=drms_getkey_double(drms_record,"CDELT2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(imcrpix1=drms_getkey_double(drms_record,"IMCRPIX1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","IMCRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(imcrpix2=drms_getkey_double(drms_record,"IMCRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","IMCRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","RSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(dsun_obs=drms_getkey_double(drms_record,"DSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","DSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(obs_vr=drms_getkey_double(drms_record,"OBS_VR",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VR");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(obs_vn=drms_getkey_double(drms_record,"OBS_VN",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VN");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(obs_vw=drms_getkey_double(drms_record,"OBS_VW",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","OBS_VW");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(crota2=drms_getkey_double(drms_record,"CROTA2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CROTA2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(crln_obs=drms_getkey_double(drms_record,"CRLN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRLN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(crlt_obs=drms_getkey_double(drms_record,"CRLT_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRLT_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}

			if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","BLANK");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			sprint_ut(t_obs_s[k],t_obs);		/* Convert to string */
		
			printf(" Checking quality.\n");
			
			if (quality[k] == 0){
		
				/* Ok, now we get the file locations for the data from DRMS. Originally I attempted
				* to pull the data directly from DRMS but there were vague free() and malloc() issues
				* possibly due to icc and multithreading, or library problems. */
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"vlos_mag"))){
			
					printf("Problem opening the vlos_mag segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,v_filename);
			
				if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){
				
					printf("Problem opening the continuum segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,c_filename);
			
				/* naxis1 and naxis2 we get from segment information */
		
				naxis1=(int)drms_segment->axis[0];
				naxis2=(int)drms_segment->axis[1];
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){
			
					printf("Problem opening the inclination segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,i_filename);
			
				if (!(drms_segment=drms_segment_lookup(drms_record,"info_map"))){
			
					printf("Problem opening the info_map segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
			
				drms_segment_filename(drms_segment,info_filename);
			
				printf(" Opening FITs files.\n");
		
				/* Now open the FITS files and get to work. */
	
				v_status=0;
				i_status=0;
				c_status=0;
				info_status=0;
				any_nulls=0;

				if (fits_open_file(&v_ptr,v_filename,READONLY,&v_status)){
				
					printf("Cannot open %s! Exiting.\n",v_filename);
					exit(0);

				}

				if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){
				
					printf("Cannot open %s! Exiting.\n",i_filename);
					fits_close_file(i_ptr,&i_status);
					exit(0);

				}
			
				if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){
				
					printf("Cannot open %s! Exiting.\n",c_filename);
					fits_close_file(c_ptr,&c_status);
					exit(0);

				}
			
				if (fits_open_file(&info_ptr,info_filename,READONLY,&info_status)){
				
					printf("Cannot open %s! Exiting.\n",info_filename);
					fits_close_file(info_ptr,&info_status);
					exit(0);

				}
				
				
				/* Walk through the HDUs until we get to one with NAXIS=2 */

				/* Number of headers and which one we are on */

				fits_get_num_hdus(v_ptr,&num_hdus,&v_status);
				fits_get_hdu_num(v_ptr,&hdu_pos);

				/* Find the one with two naxes */

				naxis=0;

				for (i=1;i<=num_hdus;i++){
				
					fits_movabs_hdu(v_ptr,i,NULL,&v_status);
					fits_read_key(v_ptr,TINT,"NAXIS",&naxis,NULL,&v_status);
				
					if (naxis == 2){
	
						needed_hdu=i;
	
					}
				}


				/* Set all to the needed HDU */

				if (naxis == 0){
		
					printf("HDU problems: can't find one with the required number of axes.\n");
					fits_close_file(v_ptr,&v_status);
					fits_close_file(i_ptr,&i_status);
					fits_close_file(c_ptr,&c_status);
					fits_close_file(info_ptr,&info_status);
					exit(0);

				} else {

					fits_movabs_hdu(v_ptr,needed_hdu,NULL,&v_status);
					fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status);
					fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status);
					fits_movabs_hdu(info_ptr,needed_hdu,NULL,&info_status);

				}


				/* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */
				
				inv_len=naxis1/num_divs;
				
				vlos_dat=malloc(naxis2*sizeof(double *));
				inc_dat=malloc(naxis2*sizeof(double *));
				con_dat=malloc(naxis2*sizeof(double *));
				radius=malloc(naxis2*sizeof(double *));
				info_dat=malloc(naxis2*sizeof(long *));
				y_axis=malloc(num_divs*sizeof(double *));
				y_error=malloc(num_divs*sizeof(double *));
				x_axis=malloc(num_divs*sizeof(double *));
			
				v_pixel_strip=calloc(naxis1,sizeof(double));
				i_pixel_strip=calloc(naxis1,sizeof(double));
				c_pixel_strip=calloc(naxis1,sizeof(double));
				info_pixel_strip=calloc(naxis1,sizeof(long));
	
				for (j=0;j<naxis2;j++){
		
					vlos_dat[j]=calloc(naxis1,sizeof(double));
					inc_dat[j]=calloc(naxis1,sizeof(double));
					con_dat[j]=calloc(naxis1,sizeof(double));
					radius[j]=calloc(naxis1,sizeof(double));
					info_dat[j]=calloc(naxis1,sizeof(long));
		
				}
				
				for (j=0;j<(num_divs-1);j++){
					
					x_axis[j]=calloc((inv_len),sizeof(double));
					y_axis[j]=calloc((inv_len),sizeof(double));
					y_error[j]=calloc((inv_len),sizeof(double));
					
				}
				
				x_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				y_axis[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				y_error[num_divs-1]=calloc((inv_len + naxis1%num_divs),sizeof(double));
				
				/* Next, put data in the arrays, clear out blank values and NaNs from the data */
	
				fpixel[0]=1;		/* cfitsio uses fortran reference instead of c when accessing data */
				nelements=naxis1;
				nulval=0;
				l_nulval=0;
				any_nulls=0;
    
				for (j=0;j<naxis2;j++){
		
					fpixel[1]=j+1;	/* Add 1 to account for fortran FITS indexing */
					fits_read_pix(v_ptr,TDOUBLE,fpixel,nelements,&nulval,v_pixel_strip,&any_nulls,&v_status);
					fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status);
					fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status);
					fits_read_pix(info_ptr,TLONG,fpixel,nelements,&l_nulval,info_pixel_strip,&any_nulls,&info_status);
		
					for (i=0;i<naxis1;i++){
			
						/* Kill blank values if present, if not assign to the correct place in array */
			
						if (v_pixel_strip[i] == blank){
				
							vlos_dat[j][i]=0.0;
					
						} else {
				
							vlos_dat[j][i]=v_pixel_strip[i];
			
						}
			
						if (i_pixel_strip[i] == blank){
				
							inc_dat[j][i]=0.0;
				
						} else {
					
							inc_dat[j][i]=i_pixel_strip[i];
			
						}

						if (c_pixel_strip[i] == blank){
				
							con_dat[j][i]=0.0;
			
						} else {
					
							con_dat[j][i]=c_pixel_strip[i];
			
						}
					
						info_dat[j][i]=info_pixel_strip[i];
					
					}
				}
				
		
				printf(" Analyzing data.\n");
	
				/* Coordinate variable definitions for future use. See the declaration section */
				/* at the front of the code to understand what these refer to. */
	
				rscx=(imcrpix1-1.0);
				rscy=(imcrpix2-1.0);
				rllx=(crpix1-1.0);
				rlly=(crpix2-1.0);
				rpllx=(rscx-rllx);
				rplly=(rscy-rlly);
	
				/* Fill the radius array, handle limb darkening */
	
				rsun_pix=rsun_obs/cdelt1;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
			
						xx=(double)i-rllx;
						yy=(double)j-rlly;
						r=sqrt(xx*xx+yy*yy);
				
						if (r <= rsun_pix){
				
							radius[j][i]=r;
							mu=sqrt(1-pow(r/rsun_pix,2.0));
							con_dat[j][i]=con_dat[j][i]/limb_darken(mu);
					
						}
					}
				}
			
				/* Determine if we actually have an active region here. */
			
				spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig);
			
				num_good=0;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
		
						if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){
				
							num_good++;
			
						}
					}
				}
	
				/* Now find the average LOS velocities. */
			
				umb_p_vel[k]=0;
				pen_p_vel[k]=0;
				umb_n_vel[k]=0;
				pen_n_vel[k]=0;
				
				umb_p_counter=0.0;
				umb_n_counter=0.0;
				pen_p_counter=0.0;
				pen_n_counter=0.0;
			
				if (num_good > 0){
					
					/* We're going to do these loops twice - first to remove any satellite and differential 
					 * rotation effects, then again to fit and remove trends. */
			
					/* First the satellite motion and the differential rotation */
			
					for (i=0;i<naxis1;i++){
				
						for (j=0;j<naxis2;j++){
							
							if ((radius[j][i] > 0)&&(good_pixel(info_dat[j][i]))){
								
								/* Get the pixel location in HPL coordinates */
							
								x=rpllx+(double)i;
								y=rplly+(double)j;
								
								/* Stonyhurst/carrington needed for photospheric velocity calcs */
							
								pixel2hpl(x,y,crota2,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty);	
								hpl2stony(tx,ty,dsun_obs,crln_obs,crlt_obs,&lat,&lon);
								
								/* Photospheric rotation removal */
								
								vt=v_t(lat,0,0,0)*along_phi(t,p,dsun_obs); /*0's are for default coefficients */
							
								/* Convert to spherical with no rotation to account for sat orientation and handle LOS stuff */
							
								pixel2hpl(x,y,0.0,imcrpix1,imcrpix2,cdelt1,cdelt2,&tx,&ty);
								hpl2hpc(tx,ty,&ttx,&tty);
								hpc2hcc(ttx,tty,dsun_obs,&xx,&yy,&zz);
								hcc2sphere(xx,yy,zz,&t,&p);
							
								/* LOS satellite velocity components */
							
								vr=obs_vr*along_obs(t,p,dsun_obs);
								vn=obs_vn*along_north(t,p,dsun_obs);
								vw=obs_vw*along_west(t,p,dsun_obs);
								
								/* vlos after removing all of the doppler effects. The 
								 * division by 100 is to convert cm/s to m/s. */
								
								vlos_dat[j][i]=(vlos_dat[j][i]/100)-vr-vn-vw-vt;
								
							}
						}
					}
					
					/* Next we fit a function across x, not including points that would be in a sunspot or off-disk points.
					 * Then we subtract this trend from the remaining data. */
					 
					for (j=0;j<naxis2;j++){
				
						/* Fill the arrays along x */
				
						for (i=0;i<num_divs;i++){
							
							if (i < (num_divs-1)){
								
								/* There are a total of num_divs segments in a data strip.
								 * To handle remainders when determining how many points to 
								 * place in a segment, we first do the remainderless ones.
								 * The last may or may not have a remainder, but that's where
								 * one would go if it did, so we do it separately. */
							
								for (l=0;l<inv_len;l++){
									
									n=i*inv_len+l;
									y_error[i][l]=1;
									x_axis[i][l]=(double)n;
									
							
									if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){
								
										y_axis[i][l]=vlos_dat[j][n];
								
									} else {
								
										y_axis[i][l]=0.0;
								
									}
						
								}
								
							} else {
								
								/* Handle the one that might have a remainder */
								
								for (l=0;l<(inv_len + naxis1%num_divs);l++){
									
									n=(num_divs-1)*inv_len+l;
									y_error[num_divs-1][l]=1;
									x_axis[num_divs-1][l]=(double)n;
									
							
									if ((radius[j][n] > 0)&&(con_dat[j][n] > pen)&&(good_pixel(info_dat[j][n]))){
								
										y_axis[num_divs-1][l]=vlos_dat[j][n];
								
									} else {
								
										y_axis[num_divs-1][l]=0.0;
								
									}
						
								}
								
							}
							
						}
						
						/* Now we fit, but in strips determined by num_divs */
						
						for (i=0;i<num_divs;i++){
							
							if (i < (num_divs-1)){
									
								v.x=x_axis[i];
								v.y=y_axis[i];
								v.ey=y_error[i];
	
								fit_status=mpfit(fit_me,inv_len,2,fit_params,0,&config,(void *)&v,&result);
								
								for (l=0;l<inv_len;l++){
									
									n=i*inv_len+l;
									vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[i][l]+fit_params[1]);	/* Subtract trend */
									
								}
								
							} else {
								
								v.x=x_axis[num_divs-1];
								v.y=y_axis[num_divs-1];
								v.ey=y_error[num_divs-1];
	
								fit_status=mpfit(fit_me,inv_len + naxis1%num_divs,2,fit_params,0,&config,(void *)&v,&result);
							
								for (l=0;l<(inv_len + naxis1%num_divs);l++){
									
									n=(num_divs-1)*inv_len+l;
									vlos_dat[j][n]=vlos_dat[j][n]-(fit_params[0]*x_axis[num_divs-1][l]+fit_params[1]);	/* Subtract trend */
									
								}
								
							}
						}	
								
					}
					
					/* Finally, we have a clean data set. Now get to work on it. */
					 
					 
					for (i=0;i<naxis1;i++){
				
						for (j=0;j<naxis2;j++){
							
							if ((radius[j][i] > 0)&&(con_dat[j][i] < pen)&&(good_pixel(info_dat[j][i]))){
						
								/* "Positive" sunspot polarities. */
								
								vlos=vlos_dat[j][i];
							
								if (inc_dat[j][i] < 90){
								
									if (con_dat[j][i] <= umb){
									
										umb_p_vel[k]+=vlos;
										umb_p_counter++;
								
									}
								
									if (con_dat[j][i] > umb){
									
										pen_p_vel[k]+=vlos;
										pen_p_counter++;
									
									}
								
					
								}
					
								/* "Negative" sunspot polarities. */
					
								if (inc_dat[j][i] > 90){
							
								
									if (con_dat[j][i] <= umb){
									
										umb_n_vel[k]+=vlos;
										umb_n_counter++;
								
									}
								
									if (con_dat[j][i] > umb){
									
										pen_n_vel[k]+=vlos;
										pen_n_counter++;
									
									}
					
								}
							
							}
						}
					}
				
				}
				
				if (umb_p_counter > 0){
					
					umb_p_vel[k]/=umb_p_counter;
					
				} else {
					
					umb_p_vel[k]=0;
					
				}
			
				if (umb_n_counter > 0){
					
					umb_n_vel[k]/=umb_n_counter;
					
				} else {
					
					umb_n_vel[k]=0;
					
				}
				
				if (pen_p_counter > 0){
					
					pen_p_vel[k]/=pen_p_counter;
					
				} else {
					
					pen_p_vel[k]=0;
					
				}

				if (pen_n_counter > 0){
					
					pen_n_vel[k]/=pen_n_counter;
					
				} else {
					
					pen_n_vel[k]=0;
					
				}
				
			
				/* Free up dynamic arrays and close the files for the next iteration. */
				
				for (i=0;i<naxis2;i++){
				
					free(vlos_dat[i]);
					free(inc_dat[i]);
					free(con_dat[i]);
					free(radius[i]);
					free(info_dat[i]);
					
				}
				
				free(vlos_dat);
				free(inc_dat);
				free(con_dat);
				free(radius);
				free(info_dat);
				
				
				free(v_pixel_strip);
				free(i_pixel_strip);
				free(c_pixel_strip);
				free(info_pixel_strip);
				
				free(x_axis);
				free(y_axis);
				free(y_error);
			
				fits_close_file(v_ptr,&v_status);
				fits_close_file(i_ptr,&i_status);
				fits_close_file(c_ptr,&c_status);
				fits_close_file(info_ptr,&info_status);

			}
	
		}
	
		printf(" Completed run %d of %d.\n",k+1,num_records);
		
	}
	
	/* Output the results to a text file. */
	
	/* First, convert t_obs to a more reasonable product. */
	
	for (i=0;i<num_records;i++){			
	
		t_secs[i]=isotime(t_obs_s[i]);

	}

	printf("Writing to file %s.\n",outfile_name);
	
	outptr=fopen(outfile_name,"w");
	bad_outptr=fopen(bad_outfile_name,"w");
	
	fprintf(outptr,"Active Region: %d\tVelocities are in m/s, fvlos is scaled to remove limb effects.\n",noaa_ar);
	fprintf(outptr,"Full UT Time            time(s)  vlos pumb  vlos ppen  vlos numb  vlos npen\n");
	fprintf(outptr,"----------------------  -------  ---------  ---------  ---------  ---------\n");

	fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar);
	fprintf(bad_outptr,"Full UT Time            quality  time(s)  number\n");
	fprintf(bad_outptr,"----------------------  -------  -------  ------\n");
	
	for (i=0;i<num_records;i++){
		
		/* Make times relative to the first recorded one. */
		
		if (quality[i] == 0){
		
			fprintf(outptr,"%s  %7ld  %6.2lf  %6.2lf  %6.2lf  %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],umb_p_vel[i],pen_p_vel[i],umb_n_vel[i],pen_n_vel[i]);
		
		} else {
			
			fprintf(bad_outptr,"%s  0x%08lX  %7ld  %d\n",t_obs_s[i],quality[i],t_secs[i],i+1);		
		
		}

	}
	
	fclose(outptr);
	fclose(bad_outptr);
	
	printf("Done!\n");
	
	/* Free memory associated with dynamic arrays. */

	free(t_secs);
	free(t_obs_s);
	
	free(umb_p_vel);
	free(pen_p_vel);
	free(umb_n_vel);
	free(pen_n_vel);
	
	free(quality);
	
	
	/* Close the drms records connection */
	
	drms_close_records(drms_ids,DRMS_FREE_RECORD);
    
	/* Done! */
    
	return 0;
}
Exemple #18
0
void write_profiles(float *prof,int nbins, int nchan, int nifs, FILE *out)/*includefile*/
{
  int i,j,c,b,k,m,year,month,day;
  float *profile,scale,offset,rms,epoch;
  double usec,tbin,tres,psec;
  static int first=1;
  struct EPN epn;

  int sta=0;
  short int sj;
  float x,binned_freq[16384],binned_weight[16384],
    binned_offset[16384],binned_scale[16384],binned_data[16384];
  int bitpix=8, naxis=0, nrcvr, nrows, ncols, col;
  static int subint_cnt;
  char datestr[10],timestr[8];
  char Cstr16[16], Estr16[16], Istr16[16];
  char *ttype[20], *tform[20], *tunit[20];
  long naxes[4];
  int junk,rah,ram,ded,dem,subint_hdu,hh,mm;
  float ss;
  int last_scanhdr_hdu;
  double ras,des,dx;
  char rastr[80], destr[80], sra[80], sde[80];
  char date_time[24];
  char *pch[MAX_BLKS];
  char site[MAX_BLKS][2];
  short int nspan[MAX_BLKS];
  short int ncoeff[MAX_BLKS];
  double rfreq[MAX_BLKS];
  double rmjd[MAX_BLKS];
  double rphase[MAX_BLKS];
  double lgfiterr[MAX_BLKS];
  double f0[MAX_BLKS];
  double coeff[MAX_BLKS][MAX_COEFF];
  static double srcl, srcb;
  /* For Pulsar History BINTABLE */
 
  static char *PHtype[18] = {
    "DATE_PRO","PROC_CMD","POL_TYPE","NPOL    ","NBIN    ","NBIN_PRD","TBIN    ","CTR_FREQ",
    "NCHAN   ","CHAN_BW ","PAR_CORR","RM_CORR ","DEDISP  ","DDS_MTHD","SC_MTHD ","CAL_MTHD",
    "CAL_FILE","RFI_MTHD"
  };
  
  static char *PHform[18] = {
    "24A     ","80A     ","8A      ","1I      ","1I      ","1I      ","1D      ","1D      ",
    "1I      ","1D      ","1I      ","1I      ","1I      ","32A     ","32A     ","32A     ",
    "32A     ","32A     "
  };
  
  static char *PHunit[18] = {
    "        ","        ","        ","        ","        ","        ","s       ","MHz     ",
    "        ","MHz     ","        ","        ","        ","        ","        ","        ",
    "        ","        "
  };

  /* subtract baseline from outgoing profiles if requested */
  if (userbase != 0.0) for (i=0;i<multiple*nbins*nifs*nchans;i++) 
    prof[i]-=userbase;

  /* multiply outgoing profiles by Jansky calibration factor if supplied */
  if (jyfactor != 0.0) for (i=0;i<multiple*nbins*nifs*nchans;i++) 
    prof[i]*=jyfactor;

  /* sum first two polarizations together if requested */
  if (totalpower && (nifs > 1)) {
    for (i=0;i<multiple*nbins*nchans;i++) 
      prof[i]+=prof[i+multiple*nbins*nchans];
    nifs=1;
  }

  if (binary) {
    /* write out profiles in binary format */
    folding_period=pfld0*1000.0;
    tadd=tstart;
    tstart=tstart+tsta/86400.0;
    npuls=pulsecount;
    fold_header();
    tstart=tadd;
    for (i=0; i<nifs; i++) {
      for (c=0; c<nchan; c++) {
	for (b=0; b<nbins; b++) 
	  fwrite(&prof[i*nchan*nbins+c*nbins+b],sizeof(float),1,out);
      }
    }
  } else if (stream) {
    /* write out profiles as ASCII streams with START/STOP boundaries */
    k=0;
    for (i=0;i<nifs;i++) {
      for (c=0;c<nchan;c++) {
	fprintf(out,"#START %d %f %f\n",nbins,tsta,fch1+foff*(float)c);
	for (m=0;m<multiple;m++) {
	  for (b=0;b<nbins;b++) {
	    fprintf(out,"%d %f\n",b+m*nbins,prof[i*nchan*nbins+c*nbins+b]);
	  }
	}
	fprintf(out,"#STOP\n");
      }
    }
  } else if (asciipol) {
    /* write profiles in format for Jim's polarization code */
    for (b=0;b<nbins;b++) 
      for (i=0;i<nifs;i++)
	for (c=0;c<nchan;c++) 
	  fprintf(out,"%d %d %d %f\n",b,i,c,prof[i*nchan*nbins+c*nbins+b]);
  } else if (ascii) {
    fprintf(output,"# %.1f %.7f %.10f %ld %.3f %.3f %d %c %d %s\n",
     floor(tstart),(tstart-floor(tstart))*86400.0+tsta,pfld0,pulsecount,fch1,refdm,nbins,tempo_site(telescope_id),1,source_name);
    for (b=0;b<nbins;b++) {
      fprintf(out,"%d",b+1);
      for (i=0;i<nifs;i++) {
	for (c=0;c<nchan;c++) fprintf(out," %f",prof[i*nchan*nbins+c*nbins+b]);
      }
      fprintf(out,"\n");
    }
#ifdef PSRFITS
  } else if (psrfits) {
    if (first) {
      first=0;
      /* write profile in PSRFITS format */
      fits_create_file(&fits, "stdout", &sta);
      fits_create_img(fits,bitpix,naxis,naxes,&sta);
      fits_write_date(fits,&sta);
      /* Get DateTime string - required in various BINTABLEs */
      fits_get_system_time(date_time,&junk,&sta);
      fits_update_key(fits,TSTRING,"HDRVER","1.19","Header version",&sta);
      fits_update_key(fits,TSTRING,"OBSERVER",culprits,
		      "Observer name(s)",&sta);
      fits_update_key(fits,TSTRING,"PROJID",project,"Project name",&sta);
      fits_update_key(fits,TSTRING,"TELESCOP",telescope_name(telescope_id),
		      "Telescope name", &sta);
      fits_update_key(fits,TSTRING,"BACKEND",backend_name(machine_id),
		      "Backend ID",&sta);
      if (nifs>1) 
	nrcvr=2;
      else
	nrcvr=1;
      fits_update_key(fits,TINT,"NRCVR",&nrcvr,
		      "Number of receiver channels (I)",&sta);
      fits_update_key(fits,TSTRING,"OBS_MODE", "PSR",
		      "(PSR, CAL, SEARCH)", &sta);
      fits_update_key(fits,TSTRING,"SRC_NAME", source_name,
		      "Source or scan ID", &sta);
      fits_update_key(fits,TSTRING,"COORD_MD", "J2000",
		      "Coordinate mode (J2000, Gal, Ecliptic, etc.)", &sta);
      
      angle_split(src_raj,&rah,&ram,&ras);
      if (ras<10.0) 
	sprintf(sra,"0%.3f",ras);
      else
	sprintf(sra,"%.3f",ras);
      sprintf(rastr,"%02d:%02d:%s",rah,ram,sra);
      angle_split(src_dej,&ded,&dem,&des);
      if (des<10.0) 
	sprintf(sde,"0%.3f",des);
      else
	sprintf(sde,"%.3f",des);
      sprintf(destr,"%02d:%02d:%s",ded,dem,sde);
      cel2gal(rah,ram,ras,ded,dem,des,&srcl,&srcb);

      fits_update_key(fits, TSTRING, "STT_CRD1", rastr,
		      "Start coord 1 (hh:mm:ss.sss or ddd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "STT_CRD2", destr,
		      "Start coord 2 (-dd:mm:ss.sss or -dd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "TRK_MODE", "TRACK",
		      "Track mode (TRACK, SCANGC, SCANLAT)", &sta);
      fits_update_key(fits, TSTRING, "STP_CRD1", rastr,
		      "Stop coord 1 (hh:mm:ss.sss or ddd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "STP_CRD2", destr,
		      "Stop coord 2 (-dd:mm:ss.sss or -dd.ddd)", &sta);
      fits_update_key(fits, TSTRING, "CAL_MODE", "OFF",
		      "Cal mode (OFF, SYNC, EXT1, EXT2)", &sta);
      fits_create_tbl(fits,BINARY_TBL,0,18,PHtype,
		      PHform,PHunit,"HISTORY",&sta);
      pch[0] = date_time;
      fits_write_col(fits,  TSTRING, 1, 1, 1, 1, pch, &sta);
      pch[0] = "SIGPROC";
      fits_write_col(fits,  TSTRING, 2, 1, 1, 1, pch, &sta);
      pch[0] = "??";
      fits_write_col(fits,  TSTRING, 3, 1, 1, 1, pch, &sta);
      /* Nr of pols  - i.e. actually written out */
      sj = nifs;
      fits_write_col(fits, TSHORT, 4, 1, 1, 1, &sj, &sta );
      
      /* Nr of bins per product (0 for SEARCH mode) */
      sj = nbins;
      fits_write_col( fits, TSHORT, 5, 1, 1, 1, &sj, &sta );
      
      /* Nr of bins per period */
      fits_write_col( fits, TSHORT, 6, 1, 1, 1, &sj, &sta );
      
      /* Bin time */
      dx =  folding_period/sj;
      fits_write_col( fits, TDOUBLE, 7, 1, 1, 1, &dx, &sta );
      
      /* Centre freq. */
      dx = ((double)(nchans/2)-1.0)*foff+fch1;
      fits_write_col( fits, TDOUBLE, 8, 1, 1, 1, &dx, &sta );
      
      /* Number of channels */
      sj = nchans;
      fits_write_col( fits, TSHORT, 9, 1, 1, 1, &sj, &sta );
      
      /* Channel bandwidth */
      dx = foff;
      fits_write_col( fits, TDOUBLE, 10, 1, 1, 1, &dx, &sta );
      
      /* Create frequency array for later */
      /* Get freq. of first channel */
      if ((fch1==0.0) && (foff==0.0)) {
	for (i=0; i<nchans; i++) binned_freq[i]=(float) frequency_table[i];
      } else {
	for (i=0; i<nchans; i++) 
	  binned_freq[i]=fch1+i*foff;
      }
      
      for (i=0; i<16384; i++) {
	binned_scale[i]=1.0;
	binned_offset[i]=0.0;
	binned_weight[i]=1.0;
      }
      
      sj = 0;
      /* Parallactic angle correction applied */
      fits_write_col( fits, TSHORT, 11, 1, 1, 1, &sj, &sta );
      /* RM correction applied */
      fits_write_col( fits, TSHORT, 12, 1, 1, 1, &sj, &sta );
      /* Data dedispersed */
      fits_write_col( fits, TSHORT, 13, 1, 1, 1, &sj, &sta );
      /* Dedispersion method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 14, 1, 1, 1, pch, &sta );
      /* Scattered power correction method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 15, 1, 1, 1, pch, &sta );
      /* Calibration method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 16, 1, 1, 1, pch, &sta );
      /* Name of calibration file */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 17, 1, 1, 1, pch, &sta );
      /* RFI excision method */
      pch[0] = "NONE";
      fits_write_col( fits, TSTRING, 18, 1, 1, 1, pch, &sta );
      /* Store last header hdu number */
      fits_get_hdu_num( fits, &last_scanhdr_hdu );

      subint_cnt=1;
      /* Add START TIME to primary HDU */
      /* Move to primary HDU */
      fits_movabs_hdu( fits, 1, NULL, &sta );
      cal(tstart,&epn.year,&epn.month,&epn.day);
      sprintf(datestr,"%4d-%02d-%02d",epn.year,epn.month,epn.day);
      fits_update_key( fits, TSTRING, "STT_DATE", datestr,
		       "Start UT date (YYYY-MM-DD)", &sta);
      uttime(tstart,&hh,&mm,&ss);
      sprintf(timestr,"%02d:%02d:%02d",hh,mm,ss);
      fits_update_key( fits, TSTRING, "STT_TIME", timestr,
		       "Start UT (hh:mm:ss)", &sta);
      dx=86400*(tstart-floor(tstart));
      fits_update_key( fits, TINT, "STT_SMJD", &dx,
		     "[s] Start time (sec past UTC 00h) (J)", &sta);
      /* Move to last created HDU in scan header */
      fits_movabs_hdu( fits, last_scanhdr_hdu, NULL, &sta );

      /* Create SUBINT BINTABLE */
      ttype[0] = "ISUBINT ";/* Subint number. If NAXIS=-1, 0 indicates EOD. */
      tform[0] = "1J      ";
      tunit[0] = "";
      ttype[1] = "INDEXVAL";    /* Optionally used if INT_TYPE != TIME */
      tform[1] = "1D      ";
      tunit[1] = "";
      ttype[2] = "TSUBINT ";    /* [s] Length of subintegration */
      tform[2] = "1D      ";
      tunit[2] = "";
      ttype[3] = "OFFS_SUB"; /* [s] Offset from Start UTC of subint centre */
      tform[3] = "1D      ";
      tunit[3] = "";
      ttype[4] = "LST_SUB ";    /* [s] LST at subint centre */
      tform[4] = "1D      ";
      tunit[4] = "";
      ttype[5] = "RA_SUB  ";    /* [turns] RA (J2000) at subint centre */
      tform[5] = "1D      ";
      tunit[5] = "";
      ttype[6] = "DEC_SUB ";    /* [turns] Dec (J2000) at subint centre */
      tform[6] = "1D      ";
      tunit[6] = "";
      ttype[7] = "GLON_SUB";    /* [deg] Gal longitude at subint centre */
      tform[7] = "1D      ";
      tunit[7] = "";
      ttype[8] = "GLAT_SUB";    /* [deg] Gal latitude at subint centre */
      tform[8] = "1D      ";
      tunit[8] = "";
      ttype[9] = "FD_ANG  ";    /* [deg] Feed angle at subint centre */
      tform[9] = "1E      ";
      tunit[9] = "";
      ttype[10] = "POS_ANG ";/*[deg] Position angle of feed at subint centre */
      tform[10] = "1E      ";
      tunit[10] = "";
      ttype[11] = "PAR_ANG ";    /* [deg] Parallactic angle at subint centre */
      tform[11] = "1E      ";
      tunit[11] = "";
      ttype[12] = "TEL_AZ  ";    /* [deg] Telescope azimuth at subint centre */
      tform[12] = "1E      ";
      tunit[12] = "";
      ttype[13] = "TEL_ZEN ";/*[deg] Telescope zenith angle at subint centre */
      tform[13] = "1E      ";
      tunit[13] = "";

      sprintf( Cstr16, "%dE", nchans );
      ttype[14] = "DAT_FREQ";
      tform[14] = Cstr16;
      tunit[14] = "";
      ttype[15] = "DAT_WTS ";
      tform[15] = Cstr16;
      tunit[15] = "";
      
      sprintf( Estr16, "%dE", nifs*nchans );
      ttype[16] = "DAT_OFFS";
      tform[16] = Estr16;
      tunit[16] = "";
      ttype[17] = "DAT_SCL ";
      tform[17] = Estr16;
      tunit[17] = "";
      
      sprintf( Istr16, "%dE", nifs*nchans*nbins );
      ttype[18] = "DATA    ";
      tform[18] = Istr16;
      tunit[18] = "Jy      ";
      
      nrows = 0; /* naxis2 - Let CFITSIO sort this out */
      ncols = 19; /* tfields */
      fits_create_tbl( fits, BINARY_TBL, nrows, ncols, 
		       ttype, tform, tunit, "SUBINT  ", &sta);
      
      /* Add dimensions of column 'ncols' = SUBINT Data */
      naxes[0] = nbins;
      naxes[1] = nchans;
      naxes[2] = nifs;
    
      fits_write_tdim( fits, ncols, 3, naxes, &sta );
      
      /* Add keywords */
      fits_update_key( fits, TSTRING, "INT_TYPE", "TIME",
		       "Time axis (TIME, BINPHSPERI, BINLNGASC, etc)", &sta);
      
      fits_update_key( fits, TSTRING, "INT_UNIT", "SEC",
		       "Unit of time axis (SEC, PHS (0-1), DEG)", &sta);
      
      fits_update_key( fits, TINT, "NCH_FILE", &nchans,
		       "Number of channels/sub-bands in this file (I)", &sta);
      j = 0;
      fits_update_key( fits, TINT, "NCH_STRT", &j,
		     "Start channel/sub-band number (0 to NCHAN-1) (I)", &sta);
    
      /* Store subint hdu number */
      fits_get_hdu_num( fits, &subint_hdu );
    }
    
    /* Write SUBINT BINTABLE columns */
    
    /* Fill in columns of table */
    col = 1;
    
    /* Subint number. If NAXIS=-1, 0 indicates EOD. */
    j=subint_cnt;
    fits_write_col( fits, TINT, col, subint_cnt, 1, 1, &j, &sta );
    col++;
    
    /* INDEXVAL - Optionally used if INT_TYPE != TIME */
    dx = 0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [s] Length of subint */
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dump_time, &sta );
    col++;
    
    /* [s] Offset from Start UTC of subint centre */
    dx = 0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [s] LST at subint centre */
    dx=0.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [turns] RA (J2000) at subint centre */
    dx=src_raj/360.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [turns] Dec (J2000) at subint centre */
    dx=src_dej/360.0;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;
    
    /* [deg] Gal longitude at subint centre */
    dx=srcl;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;

    /* [deg] Gal latitude at subint centre */
    dx=srcb;
    fits_write_col( fits, TDOUBLE, col, subint_cnt, 1, 1, &dx, &sta );
    col++;

    /* [deg] Feed angle at subint centre */
    x=0.0;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Parallactic angle at subint centre */

    /* [deg] Position angle of feed at subint centre */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Parallactic angle at subint centre */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Telescope azimuth at subint centre */
    x=(float) az_start;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* [deg] Telescope zenith angle at subint centre */
    x=(float) za_start;
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, 1, &x, &sta );
    col++;

    /* Centre freq. for each channel - NCHAN floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1,nchans,binned_freq,&sta );
    col++;

    /* Weights for each channel -  NCHAN floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans,
		    binned_weight, &sta );
    col++;

    /* Data offset for each channel - NCHAN*NPOL floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans*nifs,
		    binned_offset, &sta );
    col++;

    /* Data scale factor for each channel - NCHAN*NPOL floats */
    fits_write_col( fits, TFLOAT, col, subint_cnt, 1, nchans*nifs, 
		    binned_scale, &sta );
    col++;

    /* Subint data table - Dimensions of data table = (NBIN,NCHAN,NPOL) */
    for (i=0;i<nchans*nifs*nbins;i++) binned_data[i]=prof[i];

    fits_write_col(fits,TFLOAT,col, subint_cnt, 1, nbins*nchans*nifs, 
		   binned_data, &sta );

    subint_cnt++;
    if (sta) fits_report_error(stderr,sta);
#endif
  } else {
    /* EPN format requested - set up some general EPN variables */
    sprintf(epn.history,"%s %s fast-sampled data reduced using fold",
	    telescope_name(telescope_id),backend_name(machine_id));
    while (strlen(epn.history)<65) strcat(epn.history," ");
    strcpy(epn.jname,"");
    strcpy(epn.cname,"");
    epn.pbar=pfld0;
    epn.dm=refdm;
    epn.rm=0.0;
    strcpy(epn.catref,"none");
    strcpy(epn.bibref,"none");
    epn.raj=0.0;
    epn.dec=0.0;
    strcpy(epn.telname,telescope_name(telescope_id));
    epn.epoch=(float) floor(tstart);
    epn.opos=0.0;
    epn.paflag=' ';
    epn.timflag='U';
    epn.xtel=0.0;
    epn.ytel=0.0;
    epn.ztel=0.0;
    cal((double)epn.epoch,&epn.year,&epn.month,&epn.day);
    epn.scanno=0;
    epn.subscan=0;
    epn.npol=nifs;
    epn.nfreq=nchan;
    epn.nbins=nbins;
    epn.tbin=1.0e6*pfld0/(double)nbins;
    epn.nint=0;
    epn.ncal=0;
    epn.lcal=0;
    epn.tres=epn.tbin;
    epn.fluxflag='U';
    epn.navg=1;
    strcpy(epn.uf,"MHz ");
    epn.df=1000.0*fabs(foff);
    strcpy(epn.ud,"kHz ");
    if (epn.df>=10000.0) {
      epn.df/=1000.0;
      strcpy(epn.ud,"MHz ");
    }
    epn.tstart=(tstart-floor(tstart))*86400.0+tsta;
    epn.tstart*=1.0e6;
    epn.iprofile=(unsigned long *) malloc(epn.nbins*sizeof(long));
    profile = (float *) malloc(sizeof(float)*nbins);
    for (i=0;i<nifs;i++) {
      strcpy(epn.idfield,"I");
      for (c=0;c<nchan;c++) {
	for (b=0;b<nbins;b++) {
	  profile[b]=prof[i*nchan*nbins+c*nbins+b];
	}
	scale_prof(profile,nbins,epn.iprofile,&epn.scale,&epn.offset);
	epn.f0=fch1+foff*c;
	epn.nband=c+1;
	epn.papp=pfld0;
	epn.rms=0.0;
	epn.tres=tbin=1.0e6*pfld0*window/(double)nbins;
	if (c==0) write_epn_header(out,epn);
	write_epn_subheader(out,epn);
      }
    }
    fflush(out);
    free(profile);
    free(epn.iprofile);
  }
}
Exemple #19
0
int main(int argc, char *argv[])
{
    fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
    int status = 0, ii = 1, iteration = 0, single = 0, hdupos;
    int hdutype, bitpix, bytepix, naxis = 0, nkeys, datatype = 0, anynul;
    long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
    long first, totpix = 0, npix;
    double *array, bscale = 1.0, bzero = 0.0, nulval = 0.;
    char card[81];

    if (argc != 3)
    {
 printf("\n");
 printf("Usage:  imcopy inputImage outputImage[compress]\n");
 printf("\n");
 printf("Copy an input image to an output image, optionally compressing\n");
 printf("or uncompressing the image in the process.  If the [compress]\n");
 printf("qualifier is appended to the output file name then the input image\n");
 printf("will be compressed using the tile-compressed format.  In this format,\n");
 printf("the image is divided into rectangular tiles and each tile of pixels\n");
 printf("is compressed and stored in a variable-length row of a binary table.\n");
 printf("If the [compress] qualifier is omitted, and the input image is\n");
 printf("in tile-compressed format, then the output image will be uncompressed.\n");
 printf("\n");
 printf("If an extension name or number is appended to the input file name, \n");
 printf("enclosed in square brackets, then only that single extension will be\n");
 printf("copied to the output file.  Otherwise, every extension in the input file\n");
 printf("will be processed in turn and copied to the output file.\n");
 printf("\n");
 printf("Examples:\n");
 printf("\n");
 printf("1)  imcopy image.fit 'cimage.fit[compress]'\n");
 printf("\n");
 printf("    This compresses the input image using the default parameters, i.e.,\n");
 printf("    using the Rice compression algorithm and using row by row tiles.\n");
 printf("\n");
 printf("2)  imcopy cimage.fit image2.fit\n");
 printf("\n");
 printf("    This uncompress the image created in the first example.\n");
 printf("    image2.fit should be identical to image.fit if the image\n");
 printf("    has an integer datatype.  There will be small differences\n");
 printf("    in the pixel values if it is a floating point image.\n");
 printf("\n");
 printf("3)  imcopy image.fit 'cimage.fit[compress GZIP 100,100;4]'\n");
 printf("\n");
 printf("    This compresses the input image using the following parameters:\n");
 printf("         GZIP compression algorithm;\n");
 printf("         100 X 100 pixel compression tiles;\n");
 printf("         noise_bits = 4 (only used with floating point images)\n");
 printf("\n");
 printf("The full syntax of the compression qualifier is:\n");
 printf("    [compress ALGORITHM TDIM1,TDIM2,...; NOISE_BITS]\n");
 printf("where the allowed ALGORITHM values are Rice, GZIP, PLIO, \n");
 printf("and TDIMn is the size of the compression tile in each dimension,\n");
 printf("and NOISE_BITS = 1, 2, 3, or 4 and controls the amount of noise\n");
 printf("suppression when compressing floating point images. \n");
 printf("\n");
 printf("Note that it may be necessary to enclose the file names\n");
 printf("in single quote characters on the Unix command line.\n");
      return(0);
    }

    /* Open the input file and create output file */
    fits_open_file(&infptr, argv[1], READONLY, &status);
    fits_create_file(&outfptr, argv[2], &status);

    if (status != 0) {    
        fits_report_error(stderr, status);
        return(status);
    }

    fits_get_hdu_num(infptr, &hdupos);  /* Get the current HDU position */

    /* Copy only a single HDU if a specific extension was given */ 
    if (hdupos != 1 || strchr(argv[1], '[')) single = 1;

    for (; !status; hdupos++)  /* Main loop through each extension */
    {

      fits_get_hdu_type(infptr, &hdutype, &status);

      if (hdutype == IMAGE_HDU) {

          /* get image dimensions and total number of pixels in image */
          for (ii = 0; ii < 9; ii++)
              naxes[ii] = 1;

          fits_get_img_param(infptr, 9, &bitpix, &naxis, naxes, &status);

          totpix = naxes[0] * naxes[1] * naxes[2] * naxes[3] * naxes[4]
             * naxes[5] * naxes[6] * naxes[7] * naxes[8];
      }

      if (hdutype != IMAGE_HDU || naxis == 0 || totpix == 0) { 

          /* just copy tables and null images */
          fits_copy_hdu(infptr, outfptr, 0, &status);

      } else {

          /* Explicitly create new image, to support compression */
          fits_create_img(outfptr, bitpix, naxis, naxes, &status);
          if (status) {
                 fits_report_error(stderr, status);
                 return(status);
          }
	  	    
          /* copy all the user keywords (not the structural keywords) */
          fits_get_hdrspace(infptr, &nkeys, NULL, &status); 

          for (ii = 1; ii <= nkeys; ii++) {
              fits_read_record(infptr, ii, card, &status);
              if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
                  fits_write_record(outfptr, card, &status);
          }

          switch(bitpix) {
              case BYTE_IMG:
                  datatype = TBYTE;
                  break;
              case SHORT_IMG:
                  datatype = TSHORT;
                  break;
              case LONG_IMG:
                  datatype = TINT;
                  break;
              case FLOAT_IMG:
                  datatype = TFLOAT;
                  break;
              case DOUBLE_IMG:
                  datatype = TDOUBLE;
                  break;
          }

          bytepix = abs(bitpix) / 8;

          npix = totpix;
          iteration = 0;

          /* try to allocate memory for the entire image */
          /* use double type to force memory alignment */
          array = (double *) calloc(npix, bytepix);

          /* if allocation failed, divide size by 2 and try again */
          while (!array && iteration < 10)  {
              iteration++;
              npix = npix / 2;
              array = (double *) calloc(npix, bytepix);
          }

          if (!array)  {
              printf("Memory allocation error\n");
              return(0);
          }

          /* turn off any scaling so that we copy the raw pixel values */
          fits_set_bscale(infptr,  bscale, bzero, &status);
          fits_set_bscale(outfptr, bscale, bzero, &status);

          first = 1;
          while (totpix > 0 && !status)
          {
             /* read all or part of image then write it back to the output file */
             fits_read_img(infptr, datatype, first, npix, 
                     &nulval, array, &anynul, &status);

             fits_write_img(outfptr, datatype, first, npix, array, &status);
             totpix = totpix - npix;
             first  = first  + npix;
          }
          free(array);
      }

      if (single) break;  /* quit if only copying a single HDU */
      fits_movrel_hdu(infptr, 1, NULL, &status);  /* try to move to next HDU */
    }

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

    fits_close_file(outfptr,  &status);
    fits_close_file(infptr, &status);

    /* if error occurred, print out error message */
    if (status)
       fits_report_error(stderr, status);
    return(status);
}
Exemple #20
0
void WMAPSource::addToFieldList( fitsfile *ffits, const int iNumCols, const long lNumRows, const long lNumBaseRows, int &iStatus )
{
  QString str;
  char charTemplate[ FLEN_CARD ];
  char charName[ FLEN_CARD ];
  long lRepeat;
  long lWidth;
  int iHDUNumber;
  int iTypeCode;
  int iColNumber;
  int iResult;
  int table;
  int entry;
  int col;

  table = fits_get_hdu_num( ffits, &iHDUNumber );

  for( col=0; col<iNumCols; col++ )
  {
    iResult = fits_get_coltype( ffits, col+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
    if( iResult == 0 )
    {
      sprintf( charTemplate, "%d", col+1 );
      iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
      if( iResult == 0 )
      {
        if( lRepeat == 1 )
        {
          field *fld = new field;

          fld->table = table;
          fld->column = iColNumber;
          fld->entry = 1;
          fld->entries = lRepeat;
          fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
          fld->numFrames = lNumBaseRows;

          str = charName;
          if( _fields.find( str ) != 0L )
          {
            str += QString("_%1").arg( iHDUNumber );
          }
          _fields.insert( str, fld );
          _fieldList.append( str );
        }
        else if( lRepeat == 3 )
        {
          for( entry=0; entry<lRepeat; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = lRepeat;
            fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(QChar('X'+entry));
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
        else if( strcmp( charName, "QUATERN" ) == 0 )
        {
          for( entry=0; entry<4; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = 4;
            fld->numSamplesPerFrame = ( lRepeat / 4 ) - 3;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(QChar('a'+entry));
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
        else
        {
          for( entry=0; entry<lRepeat; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = lRepeat;
            fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(entry);
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
      }
    }
  }
}
Exemple #21
0
int	ngp_read_xtension(fitsfile *ff, int parent_hn, int simple_mode)
 { int		r, exflg, l, my_hn, tmp0, incrementor_index, i, j;
   int		ngph_dim, ngph_bitpix, ngph_node_type, my_version;
   char		incrementor_name[NGP_MAX_STRING], ngph_ctmp;
   char 	*ngph_extname = 0;
   long		ngph_size[NGP_MAX_ARRAY_DIM];
   NGP_HDU	ngph;
   long		lv;

   incrementor_name[0] = 0;			/* signal no keyword+'#' found yet */
   incrementor_index = 0;

   if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r);

   if (NGP_OK != (r = ngp_read_line(0))) return(r);	/* EOF always means error here */
   switch (NGP_XTENSION_SIMPLE & simple_mode)
     {
       case 0:  if (NGP_TOKEN_XTENSION != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT);
		break;
       default:	if (NGP_TOKEN_SIMPLE != ngp_keyidx) return(NGP_TOKEN_NOT_EXPECT);
		break;
     }
       	
   if (NGP_OK != (r = ngp_hdu_insert_token(&ngph, &ngp_linkey))) return(r);

   for (;;)
    { if (NGP_OK != (r = ngp_read_line(0))) return(r);	/* EOF always means error here */
      exflg = 0;
      switch (ngp_keyidx)
       { 
	 case NGP_TOKEN_SIMPLE:
	 		r = NGP_TOKEN_NOT_EXPECT;
			break;
	 		                        
	 case NGP_TOKEN_END:
         case NGP_TOKEN_XTENSION:
         case NGP_TOKEN_GROUP:
         		r = ngp_unread_line();	/* WARNING - not break here .... */
         case NGP_TOKEN_EOF:
			exflg = 1;
 			break;

         default:	l = strlen(ngp_linkey.name);
			if ((l >= 2) && (l <= 6))
			  { if ('#' == ngp_linkey.name[l - 1])
			      { if (0 == incrementor_name[0])
			          { memcpy(incrementor_name, ngp_linkey.name, l - 1);
			            incrementor_name[l - 1] = 0;
			          }
			        if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1)))
			          { incrementor_index++;
			          }
			        sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index);
			      }
			  }
			r = ngp_hdu_insert_token(&ngph, &ngp_linkey);
 			break;
       }
      if ((NGP_OK != r) || exflg) break;
    }

   if (NGP_OK == r)
     { 				/* we should scan keywords, and calculate HDU's */
				/* structure ourselves .... */

       ngph_node_type = NGP_NODE_INVALID;	/* init variables */
       ngph_bitpix = 0;
       ngph_extname = NULL;
       for (i=0; i<NGP_MAX_ARRAY_DIM; i++) ngph_size[i] = 0;
       ngph_dim = 0;

       for (i=0; i<ngph.tokcnt; i++)
        { if (!strcmp("XTENSION", ngph.tok[i].name))
            { if (NGP_TTYPE_STRING == ngph.tok[i].type)
                { if (!ngp_strcasencmp("BINTABLE", ngph.tok[i].value.s,8)) ngph_node_type = NGP_NODE_BTABLE;
                  if (!ngp_strcasencmp("TABLE", ngph.tok[i].value.s,5)) ngph_node_type = NGP_NODE_ATABLE;
                  if (!ngp_strcasencmp("IMAGE", ngph.tok[i].value.s,5)) ngph_node_type = NGP_NODE_IMAGE;
                }
            }
          else if (!strcmp("SIMPLE", ngph.tok[i].name))
            { if (NGP_TTYPE_BOOL == ngph.tok[i].type)
                { if (ngph.tok[i].value.b) ngph_node_type = NGP_NODE_IMAGE;
                }
            }
          else if (!strcmp("BITPIX", ngph.tok[i].name))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)  ngph_bitpix = ngph.tok[i].value.i;
            }
          else if (!strcmp("NAXIS", ngph.tok[i].name))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)  ngph_dim = ngph.tok[i].value.i;
            }
          else if (!strcmp("EXTNAME", ngph.tok[i].name))	/* assign EXTNAME, I hope struct does not move */
            { if (NGP_TTYPE_STRING == ngph.tok[i].type)  ngph_extname = ngph.tok[i].value.s;
            }
          else if (1 == sscanf(ngph.tok[i].name, "NAXIS%d%c", &j, &ngph_ctmp))
            { if (NGP_TTYPE_INT == ngph.tok[i].type)
		if ((j>=1) && (j <= NGP_MAX_ARRAY_DIM))
		  { ngph_size[j - 1] = ngph.tok[i].value.i;
		  }
            }
        }

       switch (ngph_node_type)
        { case NGP_NODE_IMAGE:
			if (NGP_XTENSION_FIRST == ((NGP_XTENSION_FIRST | NGP_XTENSION_SIMPLE) & simple_mode))
			  { 		/* if caller signals that this is 1st HDU in file */
					/* and it is IMAGE defined with XTENSION, then we */
					/* need create dummy Primary HDU */			  
			    fits_create_img(ff, 16, 0, NULL, &r);
			  }
					/* create image */
			fits_create_img(ff, ngph_bitpix, ngph_dim, ngph_size, &r);

					/* update keywords */
			if (NGP_OK == r)  r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY);
			break;

          case NGP_NODE_ATABLE:
          case NGP_NODE_BTABLE:
					/* create table, 0 rows and 0 columns for the moment */
			fits_create_tbl(ff, ((NGP_NODE_ATABLE == ngph_node_type)
					     ? ASCII_TBL : BINARY_TBL),
					0, 0, NULL, NULL, NULL, NULL, &r);
			if (NGP_OK != r) break;

					/* add columns ... */
			r = ngp_append_columns(ff, &ngph, 0);
			if (NGP_OK != r) break;

					/* add remaining keywords */
			r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY);
			if (NGP_OK != r) break;

					/* if requested add rows */
			if (ngph_size[1] > 0) fits_insert_rows(ff, 0, ngph_size[1], &r);
			break;

	  default:	r = NGP_BAD_ARG;
	  		break;
	}

     }

   if ((NGP_OK == r) && (NULL != ngph_extname))
     { r = ngp_get_extver(ngph_extname, &my_version);	/* write correct ext version number */
       lv = my_version;		/* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */
       fits_write_key(ff, TLONG, "EXTVER", &lv, "auto assigned by template parser", &r); 
     }

   if (NGP_OK == r)
     { if (parent_hn > 0)
         { fits_get_hdu_num(ff, &my_hn);
           fits_movabs_hdu(ff, parent_hn, &tmp0, &r);	/* link us to parent */
           fits_add_group_member(ff, NULL, my_hn, &r);
           fits_movabs_hdu(ff, my_hn, &tmp0, &r);
           if (NGP_OK != r) return(r);
         }
     }

   if (NGP_OK != r)					/* in case of error - delete hdu */
     { tmp0 = 0;
       fits_delete_hdu(ff, NULL, &tmp0);
     }

   ngp_hdu_clear(&ngph);
   return(r);
 }
Exemple #22
0
int	fits_execute_template(fitsfile *ff, char *ngp_template, int *status)
 { int		r, exit_flg, first_extension, i, my_hn, tmp0, keys_exist, more_keys, used_ver;
   char		grnm[NGP_MAX_STRING], used_name[NGP_MAX_STRING];
   long		luv;

   if (NULL == status) return(NGP_NUL_PTR);
   if (NGP_OK != *status) return(*status);

   if ((NULL == ff) || (NULL == ngp_template))
     { *status = NGP_NUL_PTR;
       return(*status);
     }

   ngp_inclevel = 0;				/* initialize things, not all should be zero */
   ngp_grplevel = 0;
   master_grp_idx = 1;
   exit_flg = 0;
   ngp_master_dir[0] = 0;			/* this should be before 1st call to ngp_include_file */
   first_extension = 1;				/* we need to create PHDU */

   if (NGP_OK != (r = ngp_delete_extver_tab()))
     { *status = r;
       return(r);
     }

   fits_get_hdu_num(ff, &my_hn);		/* our HDU position */
   if (my_hn <= 1)				/* check whether we really need to create PHDU */
     { fits_movabs_hdu(ff, 1, &tmp0, status);
       fits_get_hdrspace(ff, &keys_exist, &more_keys, status);
       fits_movabs_hdu(ff, my_hn, &tmp0, status);
       if (NGP_OK != *status) return(*status);	/* error here means file is corrupted */
       if (keys_exist > 0) first_extension = 0;	/* if keywords exist assume PHDU already exist */
     }
   else
     { first_extension = 0;			/* PHDU (followed by 1+ extensions) exist */

       for (i = 2; i<= my_hn; i++)
        { *status = NGP_OK;
          fits_movabs_hdu(ff, 1, &tmp0, status);
          if (NGP_OK != *status) break;

          fits_read_key(ff, TSTRING, "EXTNAME", used_name, NULL, status);
          if (NGP_OK != *status)  continue;

          fits_read_key(ff, TLONG, "EXTVER", &luv, NULL, status);
          used_ver = luv;			/* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */
          if (VALUE_UNDEFINED == *status)
            { used_ver = 1;
              *status = NGP_OK;
            }

          if (NGP_OK == *status) *status = ngp_set_extver(used_name, used_ver);
        }

       fits_movabs_hdu(ff, my_hn, &tmp0, status);
     }
   if (NGP_OK != *status) return(*status);
                                                                          
   if (NGP_OK != (*status = ngp_include_file(ngp_template))) return(*status);

   for (i = strlen(ngp_template) - 1; i >= 0; i--) /* strlen is > 0, otherwise fopen failed */
    { 
#ifdef MSDOS
      if ('\\' == ngp_template[i]) break;
#else
      if ('/' == ngp_template[i]) break;
#endif
    } 
      
   i++;
   if (i > (NGP_MAX_FNAME - 1)) i = NGP_MAX_FNAME - 1;

   if (i > 0)
     { memcpy(ngp_master_dir, ngp_template, i);
       ngp_master_dir[i] = 0;
     }


   for (;;)
    { if (NGP_OK != (r = ngp_read_line(1))) break;	/* EOF always means error here */
      switch (ngp_keyidx)
       {
         case NGP_TOKEN_SIMPLE:
			if (0 == first_extension)	/* simple only allowed in first HDU */
			  { r = NGP_TOKEN_NOT_EXPECT;
			    break;
			  }
			if (NGP_OK != (r = ngp_unread_line())) break;
			r = ngp_read_xtension(ff, 0, NGP_XTENSION_SIMPLE | NGP_XTENSION_FIRST);
			first_extension = 0;
			break;

         case NGP_TOKEN_XTENSION:
			if (NGP_OK != (r = ngp_unread_line())) break;
			r = ngp_read_xtension(ff, 0, (first_extension ? NGP_XTENSION_FIRST : 0));
			first_extension = 0;
			break;

         case NGP_TOKEN_GROUP:
			if (NGP_TTYPE_STRING == ngp_linkey.type)
			  { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING); }
			else
			  { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++); }
			grnm[NGP_MAX_STRING - 1] = 0;
			r = ngp_read_group(ff, grnm, 0);
			first_extension = 0;
			break;

	 case NGP_TOKEN_EOF:
			exit_flg = 1;
			break;

         default:	r = NGP_TOKEN_NOT_EXPECT;
			break;
       }
      if (exit_flg || (NGP_OK != r)) break;
    }

/* all top level HDUs up to faulty one are left intact in case of i/o error. It is up
   to the caller to call fits_close_file or fits_delete_file when this function returns
   error. */

   ngp_free_line();		/* deallocate last line (if any) */
   ngp_free_prevline();		/* deallocate cached line (if any) */
   ngp_delete_extver_tab();	/* delete extver table (if present), error ignored */
   
   *status = r;
   return(r);
 }
Exemple #23
0
int	ngp_read_group(fitsfile *ff, char *grpname, int parent_hn)
 { int		r, exitflg, l, my_hn, tmp0, incrementor_index;
   char		grnm[NGP_MAX_STRING];			/* keyword holding group name */
   char		incrementor_name[NGP_MAX_STRING];
   NGP_HDU	ngph;

   incrementor_name[0] = 0;			/* signal no keyword+'#' found yet */
   incrementor_index = 6;			/* first 6 cols are used by group */

   ngp_grplevel++;
   if (NGP_OK != (r = ngp_hdu_init(&ngph))) return(r);

   r = NGP_OK;
   if (NGP_OK != (r = fits_create_group(ff, grpname, GT_ID_ALL_URI, &r))) return(r);
   fits_get_hdu_num(ff, &my_hn);
   if (parent_hn > 0)
     { fits_movabs_hdu(ff, parent_hn, &tmp0, &r);	/* link us to parent */
       fits_add_group_member(ff, NULL, my_hn, &r);
       fits_movabs_hdu(ff, my_hn, &tmp0, &r);
       if (NGP_OK != r) return(r);
     }

   for (exitflg = 0; 0 == exitflg;)
    { if (NGP_OK != (r = ngp_read_line(0))) break;	/* EOF always means error here */
      switch (ngp_keyidx)
       {
	 case NGP_TOKEN_SIMPLE:
	 case NGP_TOKEN_EOF:
			r = NGP_TOKEN_NOT_EXPECT;
			break;

         case NGP_TOKEN_END:
         		ngp_grplevel--;
			exitflg = 1;
			break;

         case NGP_TOKEN_GROUP:
			if (NGP_TTYPE_STRING == ngp_linkey.type)
			  { strncpy(grnm, ngp_linkey.value.s, NGP_MAX_STRING);
			  }
			else
			  { sprintf(grnm, "DEFAULT_GROUP_%d", master_grp_idx++);
			  }
			grnm[NGP_MAX_STRING - 1] = 0;
			r = ngp_read_group(ff, grnm, my_hn);
			break;			/* we can have many subsequent GROUP defs */

         case NGP_TOKEN_XTENSION:
         		r = ngp_unread_line();
         		if (NGP_OK != r) break;
         		r = ngp_read_xtension(ff, my_hn, 0);
			break;			/* we can have many subsequent HDU defs */

         default:	l = strlen(ngp_linkey.name);
			if ((l >= 2) && (l <= 6))
			  { if ('#' == ngp_linkey.name[l - 1])
			      { if (0 == incrementor_name[0])
			          { memcpy(incrementor_name, ngp_linkey.name, l - 1);
			            incrementor_name[l - 1] = 0;
			          }
			        if (((l - 1) == (int)strlen(incrementor_name)) && (0 == memcmp(incrementor_name, ngp_linkey.name, l - 1)))
			          { incrementor_index++;
			          }
			        sprintf(ngp_linkey.name + l - 1, "%d", incrementor_index);
			      }
			  }
         		r = ngp_hdu_insert_token(&ngph, &ngp_linkey); 
			break;			/* here we can add keyword */
       }
      if (NGP_OK != r) break;
    }

   fits_movabs_hdu(ff, my_hn, &tmp0, &r);	/* back to our HDU */

   if (NGP_OK == r)				/* create additional columns, if requested */
     r = ngp_append_columns(ff, &ngph, 6);

   if (NGP_OK == r)				/* and write keywords */
     r = ngp_keyword_all_write(&ngph, ff, NGP_NON_SYSTEM_ONLY);

   if (NGP_OK != r)			/* delete group in case of error */
     { tmp0 = 0;
       fits_remove_group(ff, OPT_RM_GPT, &tmp0);
     }

   ngp_hdu_clear(&ngph);		/* we are done with this HDU, so delete it */
   return(r);
 }
Exemple #24
0
int CDfits_write_scanhdr( void )
{
  int status;
  int i, j, k, m, n;
  short int sj;
  
  double dx, dy, dz;
  
  long lk;
    
  int nrows, ncols;
  long naxes[3];

  char *ttype[4], *tform[4], *tunit[4];

  char str[16], Istr[16], *qch, *rch, *sch, *tch;

  int chan_inc, first_normal_group, npols, pol;
      
  float x;

#undef POINT_PAR
#ifdef POINT_PAR

  float xa[12];

#endif
  
  FILE *fp;
  char filename[80];
  
#define GSTR_LEN 88
  char gstr[GSTR_LEN];
  char astr[80];
  
  void *pv;

  char date_time[24];

#define MAX_BLKS 20
  char *pch[MAX_BLKS];
  char site[MAX_BLKS][2];
  short int nspan[MAX_BLKS];
  short int ncoeff[MAX_BLKS];
  double rfreq[MAX_BLKS];
  double rmjd[MAX_BLKS];
  double rphase[MAX_BLKS];
  double lgfiterr[MAX_BLKS];
  double f0[MAX_BLKS];
#define MAX_COEFF 15
  double coeff[MAX_BLKS][MAX_COEFF];


  /* For Pulsar History BINTABLE */
 
  static char *PHtype[18] = {
    "DATE_PRO","PROC_CMD","POL_TYPE","NPOL    ","NBIN    ","NBIN_PRD","TBIN    ","CTR_FREQ",
    "NCHAN   ","CHAN_BW ","PAR_CORR","RM_CORR ","DEDISP  ","DDS_MTHD","SC_MTHD ","CAL_MTHD",
    "CAL_FILE","RFI_MTHD"
  };
  
  static char *PHform[18] = {
    "24A     ","80A     ","8A      ","1I      ","1I      ","1I      ","1D      ","1D      ",
    "1I      ","1D      ","1I      ","1I      ","1I      ","32A     ","32A     ","32A     ",
    "32A     ","32A     "
  };
  
  static char *PHunit[18] = {
    "        ","        ","        ","        ","        ","        ","s       ","MHz     ",
    "        ","MHz     ","        ","        ","        ","        ","        ","        ",
    "        ","        "
  };


  /* For Pulsar Epmemeris BINTABLE */

  static char *PEtype[56] = {
    "DATE_PRO", "PROC_CMD", "EPHVER", "PSR_NAME", "RAJ", "DECJ", "PMRA", "PMDEC", 
    "PX", "POSEPOCH", "IF0", "FF0", "F1", "F2", "F3", "PEPOCH",
    "DM", "DM1", "RM", "BINARY", "T0", "PB", "A1", "OM", 
    "OMDOT", "ECC", "PBDOT", "GAMMA", "SINI", "M2", "T0_2", "PB_2",
    "A1_2", "OM_2", "ECC_2", "DTHETA", "XDOT", "EDOT", "TASC", "EPS1",
    "EPS2", "START", "FINISH", "TRES", "NTOA", "CLK", "EPHEM", "TZRIMJD",
    "TZRFMJD", "TZRFRQ", "TZRSITE", "GLEP_1", "GLPH_1", "GLF0_1", "GLF1_1", "GLF0D_1"
  };
  
  static char *PEform[56] = {
    "24A     ", "80A     ", "16A     ", "16A     ", "24A     ", "24A     ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1J      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "8A      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "1I      ", "12A     ", "12A     ", "1J      ",
    "1D      ", "1D      ", "1A      ", "1D      ", "1D      ", "1D      ", "1D      ", "1D      "
  };
  
  /* For Pulsar Polyco BINTABLE */

  static char *PPtype[13] = {
    "DATE_PRO", "POLYVER ", "NSPAN   ", "NCOEF   ", "NPBLK   ", "NSITE   ", "REF_FREQ", "PRED_PHS",
    "REF_MJD ", "REF_PHS ", "REF_F0  ", "LGFITERR", "COEFF   "
  };
    
  static char *PPform[13] = {
    "24A     ", "16A     ", "1I      ", "1I      ", "1I      ", "1A      ", "1D      ", "1D      ",
    "1D      ", "1D      ", "1D      ", "1D      ", "15D     ",
  };

  /* BEGIN */

  status = 0;

  /* Get DateTime string - required in various BINTABLEs */
  fits_get_system_time( date_time, &n, &status );
  
  if( new_file ) {

    /* Add required keywords to primary header */

    /* fits_update_key( cfitsptr, TSTRING, "ORIGIN", "RNM", 
       "Output class", &status); */

    fits_update_key( cfitsptr, TSTRING, "OBSERVER", header.observer, 
		     "Observer name(s)", &status);
    fits_update_key( cfitsptr, TSTRING, "PROJID", supplhdr.project, 
		     "Project name", &status);
    fits_update_key( cfitsptr, TSTRING, "TELESCOP", supplhdr.site_name,
		     "Telescope name", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_X", &header.antenna[0].x,
		     "[m] Antenna ITRF X-coordinate (D)", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_Y", &header.antenna[0].y,
		     "[m] Antenna ITRF Y-coordinate (D)", &status);
    fits_update_key( cfitsptr, TDOUBLE, "ANT_Z", &header.antenna[0].z,
		     "[m] Antenna ITRF Z-coordinate (D)", &status);
    fits_update_key( cfitsptr, TSTRING, "FRONTEND", supplhdr.frontend, 
		     "Rx and feed ID", &status);

    fits_update_key( cfitsptr, TSTRING, "FD_POLN", supplhdr.polzn,
		     "LIN or CIRC", &status);
    x = 0.0;
    fits_update_key( cfitsptr, TFLOAT, "XPOL_ANG", &x,
		     "[deg] Angle of X-probe wrt platform zero (E)", &status);

    fits_update_key( cfitsptr, TSTRING, "BACKEND", supplhdr.backend, 
		     "Backend ID", &status);
    fits_update_key( cfitsptr, TSTRING, "BECONFIG", (*c_c).config_menu_name,
		     "Backend configuration file name", &status);

    /* Basic cycle time for integration */
    dx = (*c_c).integ_time / 1.0E06;
    fits_update_key( cfitsptr, TDOUBLE, "TCYCLE", &dx,
		     "[s] Correlator cycle time (D)", &status);

    /* Find the first normal group in band */
    first_normal_group = -1;
    i = (*c_c).band[0].first_group;
    k = i + (*c_c).band[0].num_group - 1;
    while( ( i <= k ) && ( first_normal_group < 0 ) ) {
      if( (*c_c).product[ (*c_c).prod_group[i].first_prod ].type < POL_CAL_OFF ) {
	first_normal_group = i;
      }
      i++;
    }
    if( first_normal_group < 0 ) first_normal_group = 0;

    npols = (*c_c).prod_group[first_normal_group].num_prod;

    /* Receiver channels - best guess */
    if( npols == 1 ) nrcvr = 1;
    else nrcvr = 2;
    
    fits_update_key( cfitsptr, TINT, "NRCVR", &nrcvr,
		     "Number of receiver channels (I)", &status);
    fits_update_key( cfitsptr, TSTRING, "OBS_MODE", supplhdr.obsmode,
		     "(PSR, CAL, SEARCH)", &status);
    /* fits_update_key( cfitsptr, TSTRING, "DATATYPE", "FOLD",
                     "FOLD or DUMP", &status);  */
    fits_update_key( cfitsptr, TSTRING, "SRC_NAME", header.source,
		     "Source or scan ID", &status);
    fits_update_key( cfitsptr, TSTRING, "COORD_MD", header.epoch,
		     "Coordinate mode (J2000, Gal, Ecliptic, etc.)", &status);

    /* J2000 or B1950 */
    if( header.epoch[0] == 'J' || header.epoch[0] == 'B') j = 0;
    /* All others */
    else j = 2;

    rads_to_str( gstr, 16, supplhdr.start_long, j );

    /*
    gstr[17] = '\0';
    printf("\n rads_to_str(mode0) on %f = '%s'", supplhdr.start_long, gstr );
    */

    fits_update_key( cfitsptr, TSTRING, "STT_CRD1", gstr,
		     "Start coord 1 (hh:mm:ss.sss or ddd.ddd)", &status);

    rads_to_str( gstr, 16, supplhdr.start_lat, j+1 );
    fits_update_key( cfitsptr, TSTRING, "STT_CRD2", gstr,
		     "Start coord 2 (-dd:mm:ss.sss or -dd.ddd)", &status);
   
    fits_update_key( cfitsptr, TSTRING, "TRK_MODE", supplhdr.trackmode,
		     "Track mode (TRACK, SCANGC, SCANLAT)", &status);

    rads_to_str( gstr, 16, supplhdr.stop_long, j );
    fits_update_key( cfitsptr, TSTRING, "STP_CRD1", gstr,
		     "Stop coord 1 (hh:mm:ss.sss or ddd.ddd)", &status);

    rads_to_str( gstr, 16, supplhdr.stop_lat, j+1 );
    fits_update_key( cfitsptr, TSTRING, "STP_CRD2", gstr,
		     "Stop coord 2 (-dd:mm:ss.sss or -dd.ddd)", &status);
   
    x = supplhdr.scan_cycles * ( (*c_c).integ_time / 1.0E06 );
    fits_update_key( cfitsptr, TFLOAT, "SCANLEN ", &x,
		     "[s] Requested scan length (E)", &status);
    
    fits_update_key( cfitsptr, TSTRING, "FD_MODE", supplhdr.fdmode,
		     "Feed track mode - Const FA, CPA, GPA", &status);

    fits_update_key( cfitsptr, TFLOAT, "FA_REQ", &supplhdr.xpolang,
		     "[deg] Feed/Posn angle requested (E)", &status);

    fits_update_key( cfitsptr, TFLOAT, "ATTEN_A", &supplhdr.atten_a,
		     "[db] Attenuator, Poln A (E)", &status);

    fits_update_key( cfitsptr, TFLOAT, "ATTEN_B", &supplhdr.atten_b,
		     "[db] Attenuator, Poln B (E)", &status);

    fits_update_key( cfitsptr, TSTRING, "CAL_MODE", supplhdr.calmode,
		     "Cal mode (OFF, SYNC, EXT1, EXT2)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_frequency;
    fits_update_key( cfitsptr, TFLOAT, "CAL_FREQ", &x,
		     "[Hz] Cal modulation frequency (E)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_duty_cycle;
    fits_update_key( cfitsptr, TFLOAT, "CAL_DCYC", &x,
		     "Cal duty cycle (E)", &status);

    x = (float) (*c_c).pulsar_ncal_sig_start_phase;
    fits_update_key( cfitsptr, TFLOAT, "CAL_PHS ", &x,
		     "Cal phase (wrt start time) (E)", &status);
    

    new_file = 0;

  }

#ifdef POINT_PAR

  /* Add Pointing Parameters BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 1; /* tfields */
  ttype[0] = "PPAR    ";
  tform[0] = "12E     ";

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, NULL, "POINTPAR", &status);

  /* Pointing parameters */
  for( n=0; n<11; n++ ) xa[n] = (float) supplhdr.pointing_parameter[n];
  xa[11] = 0.0;
  fits_write_col( cfitsptr, TFLOAT, 1, 1, 1, 12, xa, &status );

#endif

  /* Add Processing History BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 18; /* tfields */
   
  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PHtype, PHform, PHunit, "HISTORY", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  pch[0] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, 1, pch, &status );
  /* Processing program and command */
  pch[0] = "WBCOR";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, 1, pch, &status );
  /* Polarisation identifier */
  if( npols < 4 ) {
    str[0] = '\0';
    k = (*c_c).prod_group[first_normal_group].first_prod;
    m = 0;
    for( j=0; j<npols; j++ ) {
      pol = (*c_c).product[k].polarisation;
      if( pol == 1 ) strcat( str, "XX" );
      else if( pol == 2 ) {
	/* An XY product will be written out as two pols, real and imag */
	strcat( str, "CRCI" );
	m++;
      }
      else if( pol == 3 ) {
	/* A YX product will be written out as two pols, real and imag */
	strcat( str, "CRCI" );
	m++;
      }
      else if( pol == 4 ) strcat( str, "YY" );
      else strcat( str, "??" );
      k++;
    }
  }
  else {
    strcpy( str, "XXYYXYYX" );
  }
  pch[0] = str;
  fits_write_col( cfitsptr, TSTRING, 3, 1, 1, 1, pch, &status );

  /* Nr of pols  - i.e. actually written out */
  sj = npols + m;
  fits_write_col( cfitsptr, TSHORT, 4, 1, 1, 1, &sj, &status );

  /* Nr of bins per product (0 for SEARCH mode) */
  sj = (*c_c).band[0].num_bins;
  fits_write_col( cfitsptr, TSHORT, 5, 1, 1, 1, &sj, &status );

  /* Nr of bins per period */
  fits_write_col( cfitsptr, TSHORT, 6, 1, 1, 1, &sj, &status );

  /* Bin time */
  dx =  (*c_c).pulsar_period / sj;
  fits_write_col( cfitsptr, TDOUBLE, 7, 1, 1, 1, &dx, &status );

  /* Centre freq. */
  dx = header.band[0].frequency;  
  fits_write_col( cfitsptr, TDOUBLE, 8, 1, 1, 1, &dx, &status );

  /* Number of channels */
  chan_inc = header.band[0].channel_increment;
  if( chan_inc <= 0 ) chan_inc = 1;
  n = ( ( header.band[0].last_channel - 
		   header.band[0].first_channel ) 
		 / chan_inc ) + 1;

  /* Don't include DC channel */  
  if( header.band[0].first_channel == 1 ) n--;
  
  sj = n;
  fits_write_col( cfitsptr, TSHORT, 9, 1, 1, 1, &sj, &status );

  /* Channel bandwidth */
  dy = header.band[0].bandwidth / (double) ( (*c_c).band[0].nfft / 2 );
  if( header.band[0].spectrum_inverted < 0 ) dy = -dy;

  /* Channel incr. width - signed */
  dx = (double) chan_inc * dy;
  fits_write_col( cfitsptr, TDOUBLE, 10, 1, 1, 1, &dx, &status );

  /* Create frequency array for later */
  /* Get freq. of first channel */
  if( ( k = header.band[0].first_channel ) == 1 ) k = 2;
  
  j = ( (*c_c).band[0].nfft / 4 ) + 1 - k;
  dz = header.band[0].frequency - ( j * dy );

  for(i=0; i<n; i++ ) {
    binned_freq[i] = (float) dz;
    dz += dx;
  }    


  sj = 0;
  /* Parallactic angle correction applied */
  fits_write_col( cfitsptr, TSHORT, 11, 1, 1, 1, &sj, &status );
  /* RM correction applied */
  fits_write_col( cfitsptr, TSHORT, 12, 1, 1, 1, &sj, &status );
  /* Data dedispersed */
  fits_write_col( cfitsptr, TSHORT, 13, 1, 1, 1, &sj, &status );
  /* Dedispersion method */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 14, 1, 1, 1, pch, &status );
  /* Scattered power correction method */
  pch[0] = supplhdr.scpwr;
  fits_write_col( cfitsptr, TSTRING, 15, 1, 1, 1, pch, &status );
  /* Calibration method */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 16, 1, 1, 1, pch, &status );
  /* Name of calibration file */
  pch[0] = "NONE";
  fits_write_col( cfitsptr, TSTRING, 17, 1, 1, 1, pch, &status );
  /* RFI excision method */
  pch[0] = supplhdr.rfiex;
  fits_write_col( cfitsptr, TSTRING, 18, 1, 1, 1, pch, &status );


  /* Add Original BANDPASS BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 3;  /* tfields */

  nchan_orig = ( (*c_c).band[0].nfft / 2 ) + 1;

  naxes[0] = nchan_orig;
  naxes[1] = nrcvr;

  sprintf( str, "%ldE", naxes[1] );

  ttype[0] = "DAT_OFFS";
  tform[0] = str;
  tunit[0] = "";

  ttype[1] = "DAT_SCL ";
  tform[1] = str;
  tunit[1] = "";

  sprintf( Istr, "%ldI", ( naxes[0] * naxes[1] ) );
  ttype[2] = "DATA    ";
  tform[2] = Istr;
  tunit[2] = "Jy      ";

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, tunit, "BANDPASS", &status);

  /* Add dimensions of column 3 = BANDPASS Data */  
  fits_write_tdim( cfitsptr, 3, 2, naxes, &status );

  /* Add keywords */
  fits_update_key( cfitsptr, TINT, "NCH_ORIG", &nchan_orig,
		     "Number of channels in original bandpass (I)", &status);
  fits_update_key( cfitsptr, TINT, "BP_NPOL ", &nrcvr,
		     "Number of polarizations in bandpass (I)", &status);

  /* Store hdu number */
  fits_get_hdu_num( cfitsptr, &bpass_hdu );


  /* Add Pulsar Ephemeris BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 56; /* tfields */

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PEtype, PEform, NULL, "PSREPHEM", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  pch[0] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, 1, pch, &status );
  /* Processing program and command */
  pch[0] = "WBCOR";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, 1, pch, &status );
  /* Ephemeris version */
  pch[0] = "PSRINFO:1.4";
  fits_write_col( cfitsptr, TSTRING, 3, 1, 1, 1, pch, &status );

  /* Open ephemeris file */
  /* Construct filename  */
  if( ( qch = getenv( "cor_pulsar" ) ) == NULL ) return(-11);

  strcpy( filename, qch );
  if( filename[ strlen(filename) - 1 ] != '/' )
    strcat( filename, "/" );
  strcat( filename, "online.eph" );
 
  if( ( fp = fopen( filename, "r" ) ) == NULL ) return(-12);

  while( fgets( gstr, GSTR_LEN, fp ) != NULL ) {

    if( ( qch = strtok( gstr, " " ) ) != NULL ) {

      /* Following gets a name change - From PSRJ to PSR_NAME */
      if( strcmp( qch, "PSRJ" ) == 0 ) i = 3;
      /* Following two get split into integer and fractional parts */
      else if( strcmp( qch, "F" ) == 0 ) i = 10;
      else if( strcmp( qch, "F0" ) == 0 ) i = 10; /* Possible alternative to just F */
      else if( strcmp( qch, "TZRMJD" ) == 0 ) i = 47;
      else {
	for( i=0; i<ncols; i++ ) {
	  if( strcmp( qch, PEtype[i] ) == 0 ) break;
	}
      }

      if( i < ncols ) {
	/* Get next parameter */
	if( ( rch = strtok( NULL, " " ) ) == NULL ) return(-13);

	if( i == 10 || i == 47 || ( qch = strchr( PEform[i], 'D' ) ) != NULL ) {
	  /* Change any D exponent to E */
	  if( ( sch = strrchr( rch, 'D' ) ) != NULL ) *sch = 'E';
	  tch = sch;
	
	  if( i == 10 || i == 47 ) {
	    /* Convert to integer + fractional part AND
	       if i == 10 convert from Hz to mHz i.e. multiply by 1000 */
	    /* Get exponent */
	    if( sch != NULL ) {
	      if( sscanf( ++sch, "%d", &j ) != 1 )  return(-91);
	    }
	    else j = 0;
	  
	    /* get position of decimal point */
	    if( ( sch = strrchr( rch, '.' ) ) == NULL ) {
	      /* Integer part only */
	      if( sscanf( rch, "%ld", &lk ) != 1 ) return(-92);
	      dx = 0.0;
	    }
	    else {
	      /* Decimal point present */
	      if( i == 10 ) j += 3;  /* multiply by 1000 - sec. to ms. */

	      if( j >= 0 ) {
		k = (int) ( sch - rch );
		if( k > 0 ) {
		  strncpy( astr, rch, k );
		  astr[k] = '\0';
		}
		else strcpy( astr, "0" );
	      
		if( j > 0 ) { /* multiply by 10**j, i.e. move decimal point */
		  strncat( astr, (sch+1), j );
		  *(sch += j) = '.';
		  *--sch = '0';
		}
		/* Now astr contains integer part, sch points to fractional part */
		if( sscanf( astr, "%ld", &lk ) != 1 ) return(-93);
		/* Don't want exponent - reduced to fraction */
		if( tch != NULL ) *tch = '\0';
		if( sscanf( sch, "%lf", &dx ) != 1 ) return(-94);
	      }
	      else {
		/* Fractional part only */
		lk = 0;
		if( sscanf( sch, "%lf", &dx ) != 1 ) return(-94);
		if( i == 10 ) dx *= 1000.0;
	      }
	    	    
	    }
	  
	    pv = &lk;
	    j = TLONG;

	  }
	  else {

	    if( sscanf( rch, "%lf", &dx ) != 1 ) return(-14);

	    j = TDOUBLE;
	    pv = &dx;

	  }	
	}
	else if( ( qch = strchr( PEform[i], 'A' ) ) != NULL ) {
	  j = TSTRING;
	  /* Strip off any trailing newline */
	  if( ( sch = strrchr( rch, '\n' ) ) != NULL ) *sch = '\0';
	  pch[0] = rch;
	  pv = pch;
	}
	else if( ( qch = strchr( PEform[i], 'I' ) ) != NULL ) {
	  j = TSHORT;
	  if( sscanf( rch, "%d", &k ) != 1 ) return(-15);
	  sj = k;
	  pv = &sj;
	}
	else if( ( qch = strchr( PEform[i], 'J' ) ) != NULL ) {
	  j = TINT;
	  if( sscanf( rch, "%d", &k ) != 1 ) return(-16);
	  pv = &k;
	}
	else return(-17);
            
	fits_write_col( cfitsptr, j, i+1, 1, 1, 1, pv, &status );

	/* Write fractional part */
	if( i == 10 || i == 47 ) {
	  j = TDOUBLE;
	  pv = &dx;
	  fits_write_col( cfitsptr, j, i+2, 1, 1, 1, pv, &status );
	  
	  printf( "\n In Ephemeris BINTABLE: %s = %ld %e", PEtype[i], lk, dx );
	}
      }
    }
  }
  fclose( fp );
  
  /* Add Digitiser Statistics BINTABLE */

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 1; /* tfields */

  wbsam_levs = 2;
  num_wbsams = nrcvr;

  naxes[0] = wbsam_levs;
  naxes[1] = num_wbsams;
  if( ( n = header.cycles_to_avg ) <= 0 ) n = 1;
  naxes[2] = n;

  sprintf( str, "%ldE", ( naxes[0] * naxes[1] * naxes[2] ) );
  ttype[0] = "DATA    ";
  tform[0] = str;

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   ttype, tform, NULL, "DIG_STAT", &status);

  /* Add dimensions of column 1 = Data */  
  fits_write_tdim( cfitsptr, 1, 3, naxes, &status );

  /* Add keywords */
  fits_update_key( cfitsptr, TSTRING, "DIG_MODE", "2-bit,3-level",
		     "Digitiser mode", &status);
  fits_update_key( cfitsptr, TINT, "NDIGR", &num_wbsams,
		     "Number of digitised channels (I)", &status);
  fits_update_key( cfitsptr, TINT, "NLEV", &wbsam_levs,
		     "Number of digitiser levels (I)", &status);
  fits_update_key( cfitsptr, TINT, "NCYCSUB", &n,
		     "Number of correlator cycles per subint (I)", &status);

  /* Store current hdu number */
  fits_get_hdu_num( cfitsptr, &dig_stats_hdu );


  
  /* Add Polyco History BINTABLE */

  /* Read in polyco file */
  /* Construct filename from .eph name  */

  qch = strstr( filename, ".eph" );
  *qch = '\0';
  strcat( filename, ".polyco" );
  if( ( fp = fopen( filename, "r" ) ) == NULL ) return(-18);

  k = 0;
  while( ( k < MAX_BLKS ) && 
	 ( ( n = fscanf( fp, "%s %s%lf%lf%lf%lf%lf%lf%lf %s%hd%hd%lf%16c", 
			 gstr, gstr, &dx, &rmjd[k], &dx, &dx, &lgfiterr[k], &rphase[k], &f0[k],
			 site[k], &nspan[k], &ncoeff[k], &rfreq[k], gstr ) ) != EOF ) ) {
    if( n != 14 ) return(-20);
    if( ncoeff[k] > MAX_COEFF ) return(-21);
    
    for( i=0; i<ncoeff[k]; i++ ) {
      if( fscanf( fp, "%s", gstr  ) != 1 ) return(-22);
      /* Translate exponent D to E */
      if( ( qch = strchr( gstr, (int) 'D' ) ) != NULL ) *qch = 'E';
      if( sscanf( gstr, "%lE", &coeff[k][i] ) != 1 ) return(-23);
    }
    for( i=ncoeff[k]; i<MAX_COEFF; i++ ) coeff[k][i] = 0.0;
    k++;
  }
  if( k >= MAX_BLKS ) return(-24);
  
  fclose( fp );

  printf("\nCFITS_SUBS:  Polyco - Site[0,1](hex) = %x %x", site[0][0], site[0][1] );
  

  nrows = 0;  /* naxis2 - Let CFITSIO sort this out */
  ncols = 13; /* tfields */
  

  fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		   PPtype, PPform, NULL, "POLYCO  ", &status);

  /* Processing date and time (YYYY-MM-DDThh:mm:ss UTC) */
  for( i=0; i<k; i++ ) pch[i] = date_time;
  fits_write_col( cfitsptr, TSTRING, 1, 1, 1, k, pch, &status );
  /* Polyco version */
  for( i=0; i<k; i++ ) pch[i] = "TEMPO:11.0";
  fits_write_col( cfitsptr, TSTRING, 2, 1, 1, k, pch, &status );
  /* Span of polyco in min */
  fits_write_col( cfitsptr, TSHORT, 3, 1, 1, k, nspan, &status );
  /* Nr of coefficients - per block */
  fits_write_col( cfitsptr, TSHORT, 4, 1, 1, k, ncoeff, &status );
  /* Nr of polyco blocks (of NCOEF coefficients) -reuse nspan array */
  for( i=0; i<k; i++ ) nspan[i] = k;
  fits_write_col( cfitsptr, TSHORT, 5, 1, 1, k, nspan, &status );
  /* TEMPO site code - 1 character */
  for( i=0; i<k; i++ ) pch[i] = &site[i][0];
  fits_write_col( cfitsptr, TSTRING, 6, 1, 1, k, pch, &status );
  /* Reference frequency for phase */
  fits_write_col( cfitsptr, TDOUBLE, 7, 1, 1, k, rfreq, &status );

  /* Predicted pulse phase at obs start - reuse rfreq  */
  for( i=0; i<k; i++ ) rfreq[i] = newcycle.WBpsr_timer_start_phase;
  fits_write_col( cfitsptr, TDOUBLE, 8, 1, 1, k, rfreq, &status );

  /* Reference MJD - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 9, 1, 1, k, rmjd, &status );
  /* Reference phase - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 10, 1, 1, k, rphase, &status );
  /* Reference F0 - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 11, 1, 1, k, f0, &status );
  /* Fit error - NPBLK doubles */
  fits_write_col( cfitsptr, TDOUBLE, 12, 1, 1, k, lgfiterr, &status );
  /* Polyco coefficients - NPBLK*NCOEF doubles */
  j = k * MAX_COEFF;
  fits_write_col( cfitsptr, TDOUBLE, 13, 1, 1, j, &coeff[0][0], &status );


  /* Store last header hdu number */
  fits_get_hdu_num( cfitsptr, &last_scanhdr_hdu );
  
  /* Restart SUBINT counter */
  subint_cnt = 0;
  
  return( status );

}
Exemple #25
0
int CDfits_write_subint( int num_cycles, int num_bins, int num_chans, int num_pols )
{
  int status;
  int j, k;
  int nscl, ndata;
  float x;
  double dx, dy, dz, ds, dc;
    
  int nrows, ncols, col;
  char *ttype[19], *tform[19], *tunit[19];
  long naxes[3];
  
  char Cstr16[16], Estr16[16], Istr16[16];

#define ASTR_LEN 32
  char astr[ ASTR_LEN ];

  
  /* BEGIN */

  nscl =  num_chans * num_pols;
  ndata = num_bins * nscl;

  status = 0;
  
  /* Increment SUBINT counter and if first SUBINT, write header */
  if( ++subint_cnt == 1 ) {

    /* Add START TIME to primary HDU */
    /* Move to primary HDU */
    fits_movabs_hdu( cfitsptr, 1, NULL, &status );

    if( bat_to_ut_str( astr, ASTR_LEN, newcycle.WBpsr_timer_start_bat ) < 0 ) {
      return( -9999 );
    }
    
    astr[10] = '\0';
    fits_update_key( cfitsptr, TSTRING, "STT_DATE", astr,
		     "Start UT date (YYYY-MM-DD)", &status);
    fits_update_key( cfitsptr, TSTRING, "STT_TIME", &astr[11],
		     "Start UT (hh:mm:ss)", &status);

    bat_to_mjd( &dx, newcycle.WBpsr_timer_start_bat );

    dz = modf( dx, &dy );   /* dz = fractional day,  dy = days */    

    j = (int) floor( ( dy + 0.1 ) );  /* Add 0.1d to make sure we get the correct one */
    fits_update_key( cfitsptr, TINT, "STT_IMJD", &j,
		     "Start MJD (UTC days) (J)", &status);
    
    dy = dz * 86400.0;   /* This should be an exact second - timer starts on 1pps */
    k = (int) floor( ( dy + 0.1 ) );   /* Add 0.1s to make sure we get the correct one */
    fits_update_key( cfitsptr, TINT, "STT_SMJD", &k,
		     "[s] Start time (sec past UTC 00h) (J)", &status);

    /* Add in offset = 1 - start phase - one bin !!!!!!!!!!! */
    /* 9 Jun 2004 - remove one bin offset - wrong !! */
    /* Was:
       dz = 1.0 - modf( newcycle.WBpsr_start_psr_phase, &dx ) - 1.0 / (double) num_bins; 
       dz *= (*c_c).pulsar_period;
       Now: the offset time is available directly */
    dz = newcycle.WBpsr_timer_start_offset_secs;
    
    /* Quantise to 128MHz clock cycles */
    dz *= 128.0E06;
    dx = floor( dz );
    dx /= 128.0E06;
    
    fits_update_key( cfitsptr, TDOUBLE, "STT_OFFS", &dx,
		     "[s] Start time offset (D)", &status);

    /* LST provided corresponds to integ. start time, i.e. oldcycle.bat */
    bat_to_ut_secs( &dy, oldcycle.bat );
    dy += dx;
    dx = scan_start_time_secs - dy;
    if( dx < -43200.0 ) dx += 86400.0;
    if( dx >  43200.0 ) dx -= 86400.0;
    dy = ( ( oldcycle.lst * 86400.0 ) / TwoPi ) + ( dx * 1.002737909350795 );
    if( dy < 0.0 ) dy += 86400.0;
    if( dy > 86400.0 ) dy -= 86400.0;
    fits_update_key( cfitsptr, TDOUBLE, "STT_LST ", &dy,
		     "[s] Start LST (D)", &status);

    /* Finished with primary HDU */

    /* Move to last created HDU in scan header */
    fits_movabs_hdu( cfitsptr, last_scanhdr_hdu, NULL, &status );
    

    /* Create SUBINT BINTABLE */

    nrows = 0; /* naxis2 - Let CFITSIO sort this out */
    ncols = 19; /* tfields */

    ttype[0] = "ISUBINT ";    /* Subint number. If NAXIS=-1, 0 indicates EOD. */
    tform[0] = "1J      ";
    tunit[0] = "";
    ttype[1] = "INDEXVAL";    /* Optionally used if INT_TYPE != TIME */
    tform[1] = "1D      ";
    tunit[1] = "";
    ttype[2] = "TSUBINT ";    /* [s] Length of subintegration */
    tform[2] = "1D      ";
    tunit[2] = "";
    ttype[3] = "OFFS_SUB";    /* [s] Offset from Start UTC of subint centre */
    tform[3] = "1D      ";
    tunit[3] = "";
    ttype[4] = "LST_SUB ";    /* [s] LST at subint centre */
    tform[4] = "1D      ";
    tunit[4] = "";
    ttype[5] = "RA_SUB  ";    /* [turns] RA (J2000) at subint centre */
    tform[5] = "1D      ";
    tunit[5] = "";
    ttype[6] = "DEC_SUB ";    /* [turns] Dec (J2000) at subint centre */
    tform[6] = "1D      ";
    tunit[6] = "";
    ttype[7] = "GLON_SUB";    /* [deg] Gal longitude at subint centre */
    tform[7] = "1D      ";
    tunit[7] = "";
    ttype[8] = "GLAT_SUB";    /* [deg] Gal latitude at subint centre */
    tform[8] = "1D      ";
    tunit[8] = "";
    ttype[9] = "FD_ANG  ";    /* [deg] Feed angle at subint centre */
    tform[9] = "1E      ";
    tunit[9] = "";
    ttype[10] = "POS_ANG ";    /* [deg] Position angle of feed at subint centre */
    tform[10] = "1E      ";
    tunit[10] = "";
    ttype[11] = "PAR_ANG ";    /* [deg] Parallactic angle at subint centre */
    tform[11] = "1E      ";
    tunit[11] = "";
    ttype[12] = "TEL_AZ  ";    /* [deg] Telescope azimuth at subint centre */
    tform[12] = "1E      ";
    tunit[12] = "";
    ttype[13] = "TEL_ZEN ";    /* [deg] Telescope zenith angle at subint centre */
    tform[13] = "1E      ";
    tunit[13] = "";

    sprintf( Cstr16, "%dE", num_chans );
    ttype[14] = "DAT_FREQ";
    tform[14] = Cstr16;
    tunit[14] = "";
    ttype[15] = "DAT_WTS ";
    tform[15] = Cstr16;
    tunit[15] = "";

    sprintf( Estr16, "%dE", nscl );
    ttype[16] = "DAT_OFFS";
    tform[16] = Estr16;
    tunit[16] = "";
    ttype[17] = "DAT_SCL ";
    tform[17] = Estr16;
    tunit[17] = "";

    sprintf( Istr16, "%dI", ndata );
    ttype[18] = "DATA    ";
    tform[18] = Istr16;
    tunit[18] = "Jy      ";


    fits_create_tbl( cfitsptr, BINARY_TBL, nrows, ncols, 
		     ttype, tform, tunit, "SUBINT  ", &status);

    /* Add dimensions of column 'ncols' = SUBINT Data */
    naxes[0] = num_bins;
    naxes[1] = num_chans;
    naxes[2] = num_pols;
  
    fits_write_tdim( cfitsptr, ncols, 3, naxes, &status );

    /* Add keywords */
    fits_update_key( cfitsptr, TSTRING, "INT_TYPE", "TIME",
		     "Time axis (TIME, BINPHSPERI, BINLNGASC, etc)", &status);

    fits_update_key( cfitsptr, TSTRING, "INT_UNIT", "SEC",
		     "Unit of time axis (SEC, PHS (0-1), DEG)", &status);

    fits_update_key( cfitsptr, TINT, "NCH_FILE", &num_chans,
		     "Number of channels/sub-bands in this file (I)", &status);
    j = 0;
    fits_update_key( cfitsptr, TINT, "NCH_STRT", &j,
		     "Start channel/sub-band number (0 to NCHAN-1) (I)", &status);
    
    /* Store subint hdu number */
    fits_get_hdu_num( cfitsptr, &subint_hdu );

  }
  
  /* Write SUBINT BINTABLE columns */

  /* Fill in columns of table */
  col = 1;
  
  /* Subint number. If NAXIS=-1, 0 indicates EOD. */
  fits_write_col( cfitsptr, TINT, col, subint_cnt, 1, 1, &subint_cnt, &status );
  col++;
  
  /* INDEXVAL - Optionally used if INT_TYPE != TIME */
  dx = 0.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [s] Length of subint */
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &sum_subint_len_secs, &status );
  col++;

  /* [s] Offset from Start UTC of subint centre */
  dx = sum_subint_mid_pt / sum_subint_len_secs;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [s] LST at subint centre */
  ds = sum_subint_lst_sin / sum_subint_len_secs;
  dc = sum_subint_lst_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 86400.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [turns] RA (J2000) at subint centre */
  ds = sum_subint_ra_sin / sum_subint_len_secs;
  dc = sum_subint_ra_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [turns] Dec (J2000) at subint centre */
  ds = sum_subint_dec_sin / sum_subint_len_secs;
  dc = sum_subint_dec_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) / TwoPi;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Gal longitude at subint centre */
  ds = sum_subint_Glon_sin / sum_subint_len_secs;
  dc = sum_subint_Glon_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 360.0;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Gal latitude at subint centre */
  ds = sum_subint_Glat_sin / sum_subint_len_secs;
  dc = sum_subint_Glat_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) * 360.0 / TwoPi;
  fits_write_col( cfitsptr, TDOUBLE, col, subint_cnt, 1, 1, &dx, &status );
  col++;

  /* [deg] Feed angle at subint centre */
  ds = sum_subint_fa_sin / sum_subint_len_secs;
  dc = sum_subint_fa_cos / sum_subint_len_secs;
  dx = atan2( ds, dc ) * 360.0 / TwoPi;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Parallactic angle at subint centre */
  ds = sum_subint_pa_sin / sum_subint_len_secs;
  dc = sum_subint_pa_cos / sum_subint_len_secs;
  dy = atan2( ds, dc ) * 360.0 / TwoPi;

  /* [deg] Position angle of feed at subint centre */
  dx = dx + dy;
  if( dx > 180.0 ) dx -= 360.0;
  if( dx < 180.0 ) dx += 360.0;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Parallactic angle at subint centre */
  x = (float) dy;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Telescope azimuth at subint centre */
  ds = sum_subint_az_sin / sum_subint_len_secs;
  dc = sum_subint_az_cos / sum_subint_len_secs;
  if( ( dx = ( atan2( ds, dc ) / TwoPi ) ) < 0.0 ) dx += 1.0;
  dx *= 360.0;
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;

  /* [deg] Telescope zenith angle at subint centre */
  ds = sum_subint_el_sin / sum_subint_len_secs;
  dc = sum_subint_el_cos / sum_subint_len_secs;
  dx = 90.0 - ( atan2( ds, dc ) * 360.0 / TwoPi );
  x = (float) dx;
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, 1, &x, &status );
  col++;


  /* Centre freq. for each channel - NCHAN floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, num_chans, binned_freq, &status );
  col++;

  /* Weights for each channel -  NCHAN floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, num_chans, binned_weight, &status );
  col++;

  /* Data offset for each channel - NCHAN*NPOL floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, nscl, binned_offset, &status );
  col++;

  /* Data scale factor for each channel - NCHAN*NPOL floats */
  fits_write_col( cfitsptr, TFLOAT, col, subint_cnt, 1, nscl, binned_scale, &status );
  col++;

  /* Subint data table - Dimensions of data table = (NBIN,NCHAN,NPOL) */
  fits_write_col( cfitsptr, TSHORT, col, subint_cnt, 1, ndata, binned_data, &status );
  col++;
  
  /* Finished SUBINT */

#define STEP_BACK
#ifdef STEP_BACK

  /* Move to digitiser statistics  */
  fits_movabs_hdu( cfitsptr, dig_stats_hdu, NULL, &status );

  if( subint_cnt == 1 ) {
    
    /* Now we know whether samplers are in fixed or auto mode - Add DIGLEV key */
    if( (*c_c).wb_ifsam.freq[0].ant[0].pol[0].sam_status & WBSAM_FIXED )
      strcpy( astr, "FIX" );
    else 
      strcpy( astr, "AUTO" );
    fits_update_key( cfitsptr, TSTRING, "DIGLEV", astr,
		     "Digitiser level-setting mode (AUTO, FIX)", &status);
  }
  
  /* Add data for this subint */
  fits_write_col( cfitsptr, TFLOAT, 1, subint_cnt, 1, num_wbsam_stats, wbsam_stats, &status );


  /* Move to bandpass  */
  fits_movabs_hdu( cfitsptr, bpass_hdu, NULL, &status );
  /* Overwrite row 1 with latest data  */

  /* Data offset for each receiver channel - NRCVR floats */
  fits_write_col( cfitsptr, TFLOAT, 1, 1, 1, nrcvr, bpass_offset, &status );

  /* Data scale factor for each receiver channel - NRCVR floats */
  fits_write_col( cfitsptr, TFLOAT, 2, 1, 1, nrcvr, bpass_scale, &status );

  /* Bandpass data table - Dimensions of data table = (NCHAN_orig,NRCVR) */
  ndata = nchan_orig * nrcvr;
  fits_write_col( cfitsptr, TSHORT, 3, 1, 1, ndata, bpass_data, &status );


  /* Move back to subint HDU for next subint */
  fits_movabs_hdu( cfitsptr, subint_hdu, NULL, &status );

#endif /* STEP_BACK */

  /* Now FLUSH any internal buffers to the file */
  fits_flush_file( cfitsptr, &status );


  return( status );
  
}
Exemple #26
0
int main(int argc, char *argv[])
{
  fitsfile *infptr = 0, *outfptr = 0;  /* FITS file pointers */
  int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
  int hdutype = 0, hdunum = 0, ii = 0;

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 4) {
    fprintf(stderr, "Usage:  %s infile expression outfile\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Copy selected rows from the input table to the output file\n");
    fprintf(stderr, "based on the input boolean expression.  The expression may \n");
    fprintf(stderr, "be a function of the values in other table columns or header \n");
    fprintf(stderr, "keyword values.  If the expression evaluates to 'true' then \n");
    fprintf(stderr, "that row is copied to the output file.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Example: \n");
    fprintf(stderr, "1. %s intab.fits+1 'counts > 0' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    copy rows that have a positive 'counts' column value\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "2. %s intab.fits+1 'gtifilter()' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    Select rows which have a Time column value that is\n");
    fprintf(stderr, "    within one of the Good Time Intervals (GTI) which are\n");
    fprintf(stderr, "    defined in a separate GTI extension in the same file.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "3. %s intab.fits+1 'regfilter(\"pow.reg\")' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    Select rows which have X,Y column coordinates located\n");
    fprintf(stderr, "    within the spatial region defined in the file named\n");
    fprintf(stderr, "    'pow.reg'.  This is an ASCII text file containing a\n");
    fprintf(stderr, "    list of one or more geometric regions such as circle,\n");
    fprintf(stderr, "    rectangle, annulus, etc.\n");
    return (0);
  }
  if (!fits_open_file(&infptr, argv[1], READONLY, &status)) {
    if (fits_get_hdu_type(infptr, &hdutype,&status) ||
        hdutype==IMAGE_HDU) {
      fprintf(stderr, "Error: input HDU is not a table\n");
    } else {

      fits_get_hdu_num(infptr, &hdunum);  /* save current HDU location */

      if (!fits_create_file(&outfptr, argv[3], &status)) {
        /* copy all the HDUs from the input file to the output file */
        for (ii = 1; !status; ii++) {
          if (!fits_movabs_hdu(infptr, ii, NULL, &status)) {
            fits_copy_hdu(infptr, outfptr, 0, &status);
          }
        }

        if (status == END_OF_FILE) {
          status = 0;  /* reset expected error */
        }

        /* move back to initial position in the file */
        fits_movabs_hdu(outfptr, hdunum, NULL, &status);

        /* argv[2] is the expression */
        /* input and output files are the same, so delete rows that */
        /* do not satisfy the expression */
        fits_select_rows(outfptr, outfptr, argv[2], &status);

        fits_close_file(outfptr, &status);  /* Done */
      }
    }
    fits_close_file(infptr, &status);
  }

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
Exemple #27
0
image_str *image_create_from_fits(char *filename)
{
    fitsfile *fits;
    char buf[FLEN_CARD];
    image_str *image = NULL;

    int status = 0;  /* Error code for CFITSIO library */
    int Ndims = 0;
    int bitpix = 0;
    long Npixels = 0;
    long firstpix[2] = {1, 1};
    long fits_dims[2] = {1, 1};

    if(!filename || !file_exists_and_normal(filename))
        return NULL;

    fits_open_file(&fits, filename, READONLY, &status);

    do {
        /* read dimensions */
        fits_get_img_dim(fits, &Ndims, &status);
        fits_get_img_size(fits, 2, fits_dims, &status);
        fits_get_img_type(fits, &bitpix, &status);

        if(Ndims < 2){
            int Nhdus = 0;
            int hdu = 0;
            int type = 0;

            fits_get_num_hdus(fits, &Nhdus, &status);
            fits_get_hdu_num(fits, &hdu);

            if(hdu < Nhdus){
                /* dprintf("Moving to HDU %d of %d\n", hdu + 1, Nhdus); */
                fits_movabs_hdu(fits, hdu + 1, &type, &status);
            } else {
                /* dprintf("Error: FITS images with less than 2 dimensions are not supported\n"); */
                /* fits_close_file(fits, &status); */
                /* return NULL; */
                break;
            }
        }
    } while(Ndims < 2);

    if(status || Ndims > 2){
        if(Ndims > 2)
            dprintf("Error: FITS images with more than 2 dimensions are not supported\n");
        fits_close_file(fits, &status);

        return image;
    }

    Npixels = fits_dims[0]*fits_dims[1];

    if(bitpix == DOUBLE_IMG || bitpix == FLOAT_IMG){
        double *data = (double *) malloc(Npixels * sizeof(double));

        fits_read_pix(fits, TDOUBLE, firstpix, Npixels, NULL, data, NULL, &status);
        image = image_create_with_data(fits_dims[0], fits_dims[1], (u_int16_t *)data);
        image->type = IMAGE_DOUBLE;
    } else {
        u_int16_t *data = (u_int16_t *) malloc(Npixels * sizeof(u_int16_t));

        fits_read_pix(fits, TUSHORT, firstpix, Npixels, NULL, data, NULL, &status);
        image = image_create_with_data(fits_dims[0], fits_dims[1], data);
    }

    /* Read all keywords we may need */
    image_keywords_from_fits(image, fits);
    /* Rewind the header */
    fits_read_record(fits, 0, buf, &status);

    image->coords = image_keyword_get_coords(image);
    if(image->coords.ra0 == 0 && image->coords.dec0 == 0){
        image->coords.ra0 = 15.0*image_keyword_get_sexagesimal(image, "RA");
        image->coords.dec0 = image_keyword_get_sexagesimal(image, "DEC");
    }
    image->time = time_str_from_date_time(image_keyword_get_string(image, "TIME"));

    fits_close_file(fits, &status);

    return image;
}
Exemple #28
0
int fits_read_wcstab(
  fitsfile   *fptr,
  int  nwtb,
  wtbarr *wtb,
  int  *status)

{
  int  anynul, colnum, hdunum, iwtb, m, naxis, nostat;
  long *naxes = 0, nelem;
  wtbarr *wtbp;


  if (*status) return *status;

  if (fptr == 0) {
    return (*status = NULL_INPUT_PTR);
  }

  if (nwtb == 0) return 0;

  /* Zero the array pointers. */
  wtbp = wtb;
  for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) {
    *wtbp->arrayp = 0x0;
  }

  /* Save HDU number so that we can move back to it later. */
  fits_get_hdu_num(fptr, &hdunum);

  wtbp = wtb;
  for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) {
    /* Move to the required binary table extension. */
    if (fits_movnam_hdu(fptr, BINARY_TBL, (char *)(wtbp->extnam),
        wtbp->extver, status)) {
      goto cleanup;
    }

    /* Locate the table column. */
    if (fits_get_colnum(fptr, CASEINSEN, (char *)(wtbp->ttype), &colnum,
        status)) {
      goto cleanup;
    }

    /* Get the array dimensions and check for consistency. */
    if (wtbp->ndim < 1) {
      *status = NEG_AXIS;
      goto cleanup;
    }

    if (!(naxes = calloc(wtbp->ndim, sizeof(long)))) {
      *status = MEMORY_ALLOCATION;
      goto cleanup;
    }

    if (fits_read_tdim(fptr, colnum, wtbp->ndim, &naxis, naxes, status)) {
      goto cleanup;
    }

    if (naxis != wtbp->ndim) {
      if (wtbp->kind == 'c' && wtbp->ndim == 2) {
        /* Allow TDIMn to be omitted for degenerate coordinate arrays. */
        naxis = 2;
        naxes[1] = naxes[0];
        naxes[0] = 1;
      } else {
        *status = BAD_TDIM;
        goto cleanup;
      }
    }

    if (wtbp->kind == 'c') {
      /* Coordinate array; calculate the array size. */
      nelem = naxes[0];
      for (m = 0; m < naxis-1; m++) {
        *(wtbp->dimlen + m) = naxes[m+1];
        nelem *= naxes[m+1];
      }
    } else {
      /* Index vector; check length. */
      if ((nelem = naxes[0]) != *(wtbp->dimlen)) {
        /* N.B. coordinate array precedes the index vectors. */
        *status = BAD_TDIM;
        goto cleanup;
      }
    }

    free(naxes);
    naxes = 0;

    /* Allocate memory for the array. */
    if (!(*wtbp->arrayp = calloc((size_t)nelem, sizeof(double)))) {
      *status = MEMORY_ALLOCATION;
      goto cleanup;
    }

    /* Read the array from the table. */
    if (fits_read_col_dbl(fptr, colnum, wtbp->row, 1L, nelem, 0.0,
        *wtbp->arrayp, &anynul, status)) {
      goto cleanup;
    }
  }

cleanup:
  /* Move back to the starting HDU. */
  nostat = 0;
  fits_movabs_hdu(fptr, hdunum, 0, &nostat);

  /* Release allocated memory. */
  if (naxes) free(naxes);
  if (*status) {
    wtbp = wtb;
    for (iwtb = 0; iwtb < nwtb; iwtb++, wtbp++) {
      if (*wtbp->arrayp) free(*wtbp->arrayp);
    }
  }

  return *status;
}
Exemple #29
0
/* process this command */
static int ProcessCmd(char *cmd, char **args, int node, int tty)
{
  int ip=0;
  char tbuf[SZ_LINE];
  Finfo finfo, tfinfo;
#if HAVE_CFITSIO
  int x0, x1, y0, y1, bin;
  int xcolnum, ycolnum, hdunum, hdutype;
  int status=0, status2=0;
  int dims[2];
  double cens[2];
  char *cols[2] = {"X", "Y"};
  char *ofile=NULL;
  char *omode=NULL;
  fitsfile *ifptr, *ofptr, *tfptr;
#endif

  switch(*cmd){
  case 'f':
    if( !strcmp(cmd, "fitsFile") ){
      if( args && word(args[0], tbuf, &ip) ){
	if( !(tfinfo=FinfoLookup(tbuf)) ){
	  fprintf(stderr, NOIMAGE, tbuf);
	  return 1;
	}
      } else if( !(tfinfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      if( tfinfo->fitsfile ){
	if( node ) fprintf(stdout, "fitsFile\r");
	fprintf(stdout, "%s %s\n", tfinfo->fname, tfinfo->fitsfile);
	fflush(stdout);
      }
      return 0;
    }
    break;
    break;
  case 'i':
    if( !strcmp(cmd, "image") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      if( node ) fprintf(stdout, "image\r");
      /* return the FITS file name, if possible */
      fprintf(stdout, "%s %s\n",
	      finfo->fname, finfo->fitsfile ? finfo->fitsfile : "?");
      fflush(stdout);
      return 0;
    } else if( !strcmp(cmd, "image_") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      /* no output! */
      return 0;
    } else if( !strcmp(cmd, "imsection") ){
#if HAVE_CFITSIO
      if( !(finfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      ifptr = openFITSFile(finfo->fitsfile, EXTLIST, &hdutype, &status);
      if( status ){
	fprintf(stderr, "ERROR: can't open FITS file '%s'\n", finfo->fitsfile);
	return 1;
      }
      if( !args || !parseSection(args[0], &x0, &x1, &y0, &y1, &bin) ){
	fprintf(stderr,
		"ERROR: can't parse section for '%s' [%s]\n",
		finfo->fitsfile, (args && args[1]) ? args[1] : "NONE");
	return 1;
      }
      if( args[1] ){
	omode = args[1];
      } else {
	omode = "native";
      }
      ofile = "stdout";
      // create image if ifile is an image or omode is not native
      if( (hdutype == IMAGE_HDU) || strcmp(omode, "native") ){
	fits_create_file(&ofptr, ofile, &status);
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't open output FITS file to section '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	switch(hdutype){
	case IMAGE_HDU:
	  if( bin != 1 ){
	    fprintf(stderr,
		    "ERROR: imsection of an image must use bin 1 for '%s'\n",
		    finfo->fitsfile);
	    return 1;
	  }
	  snprintf(tbuf, SZ_LINE-1, "%d:%d,%d:%d", x0, x1, y0, y1);
	  fits_copy_image_section(ifptr, ofptr, tbuf, &status);
	  break;
	default:
	  dims[0] = x1 - x0 + 1;
	  dims[1] = y1 - y0 + 1;
	  cens[0] = (x0 + x1) / 2;
	  cens[1] = (y0 + y1) / 2;
	  tfptr = filterTableToImage(ifptr, NULL, cols, dims, cens, bin,
				     &status);
	  if( status ){
	    fits_get_errstatus(status, tbuf);
	    fprintf(stderr,
		    "ERROR: can't create image from table for '%s' [%s]\n",
		    finfo->fitsfile, tbuf);
	    return 1;
	  }
	  fits_copy_image_section(tfptr, ofptr, "*,*", &status);
	  closeFITSFile(tfptr, &status2);
	  break;
	}
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't write section FITS file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  closeFITSFile(ofptr, &status);
	  return 1;
	}
	closeFITSFile(ofptr, &status);
      } else {
	// extract (native) table
	snprintf(tbuf, SZ_LINE-1,
		 "x >= %d && x <= %d && y >= %d && y <= %d",
		 x0, x1, y0, y1);
	// ffselect_table(&ifptr, ofile, tbuf, &status);
	// copied from cfileio.c/ffselect_table()
	/* create new empty file to hold copy of the image */
	if (ffinit(&ofptr, ofile, &status) > 0) {
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't init section file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	/* save current HDU number in input file */
	fits_get_hdu_num(ifptr, &hdunum);
	/* copy the primary array */
	fits_movabs_hdu(ifptr, 1, NULL, &status);
	if( fits_copy_hdu(ifptr, ofptr, 0, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy primary for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* back to current hdu */
	fits_movabs_hdu(ifptr, hdunum, NULL, &status);
	/* copy all the header keywords from the input to output file */
	if (fits_copy_header(ifptr, ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy header for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* set number of rows = 0 */
	/* warning: start of cfitsio black magic */
	fits_modify_key_lng(ofptr, "NAXIS2", 0, NULL, &status);
	(ofptr->Fptr)->numrows = 0;
	(ofptr->Fptr)->origrows = 0;
	/* force the header to be scanned */
	if (ffrdef(ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't rdef for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* warning: end of cfitsio black magic */
	/* select filtered rows and write to output file */
	if (fits_select_rows(ifptr, ofptr, tbuf, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't select rows for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* update params for this section */
	if( (fits_get_colnum(ofptr, CASEINSEN, "X", &xcolnum, &status) > 0) ||
	    (fits_get_colnum(ofptr, CASEINSEN, "Y", &ycolnum, &status) > 0) ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't find X,Y cols for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* we can ignore errors here */
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", xcolnum);
	fits_modify_key_lng(ofptr, tbuf, x1-x0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", ycolnum);
	fits_modify_key_lng(ofptr, tbuf, y1-y0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x1, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y1, 6, NULL, &status);
	/* close the output file */
	status = 0;
	fits_close_file(ofptr, &status);
      }
      closeFITSFile(ifptr, &status);
      return 0;
#else
      fprintf(stderr,
	      "ERROR: for section support, build js9helper with cfitsio\n");
      return 1;
#endif
    } else if( !strcmp(cmd, "info") ){
      if( tty ){
	if( !(finfo=FinfoGetCurrent()) ){
	  fprintf(stderr, NOFINFO, cmd);
	  return 1;
	}
	/* make sure we have a wcs */
	fprintf(stdout, "fname:\t%s\n", finfo->fname);
	fprintf(stdout, "fits:\t%s\n", finfo->fitsfile?finfo->fitsfile:"N/A");
	fflush(stdout);
      }
      return 0;
    }
    break;
  case 'l':
    /* list all images */
    if( !strcmp(cmd, "list") ){
      FinfoList(stdout);
      return 0;
    }
    break;
  case 's':
    if( !strcmp(cmd, "setDataPath") ){
      if( args && word(args[0], tbuf, &ip) ){
	setenv("JS9_DATAPATH", tbuf, 1);
	if( node ) fprintf(stdout, "setDataPath\r");
	fprintf(stdout, "%s\n", getenv("JS9_DATAPATH"));
	fflush(stdout);
      } else {
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      return 0;
    }
    break;
  case 'u':
    if( !strcmp(cmd, "unimage") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* close this image */
      FinfoFree(tbuf);
      return 0;
    }
    break;
  case '#':
  case '\0':
    return 0;
  default:
    break;
  }
  /* if we reached here, we did not recognize the command */
  fprintf(stderr, "ERROR: unknown command '%s'\n", cmd);
  /* return the news */
  return 2;
}