Beispiel #1
0
void 
writefits(int im, inputPars *par, molData *m, image *img){
  double bscale,bzero,epoch,lonpole,equinox,restfreq;
  double cdelt1,crpix1,crval1,cdelt2,crpix2,crval2;
  double cdelt3,crpix3,crval3,ru3;
  int velref;
  float *row;
  int px,py,ichan;
  fitsfile *fptr;
  int status = 0;
  int naxis=3, bitpix=-32;
  long naxes[3];
  long int fpixels[3],lpixels[3];
  char negfile[100]="! ";

  row = malloc(sizeof(*row)*img[im].pxls);

  naxes[0]=img[im].pxls;
  naxes[1]=img[im].pxls;
  if(img[im].doline==1) naxes[2]=img[im].nchan;
  else if(img[im].doline==0 && par->polarization) naxes[2]=3;
  else naxes[2]=1;

  fits_create_file(&fptr, img[im].filename, &status);

  if(status!=0){
    if(!silent) warning("Overwriting existing fits file                   ");
    status=0;
    strcat(negfile,img[im].filename);
    fits_create_file(&fptr, negfile, &status);
  }

  /* Write FITS header */ 
  fits_create_img(fptr, bitpix, naxis, naxes, &status);
  epoch   =2.0e3;
  lonpole =1.8e2;
  equinox =2.0e3;
  restfreq=img[im].freq;
  velref  =257;
  cdelt1  =-1.8e2*img[im].imgres/PI;
  crpix1  =(double) img[im].pxls/2+0.5;
  crval1  =0.0e0;
  cdelt2  =1.8e2*img[im].imgres/PI;
  crpix2  =(double) img[im].pxls/2+0.5;
  crval2  =0.0e0;
  cdelt3  =img[im].velres;
  crpix3  =(double) (img[im].nchan-1)/2.+1;
  crval3  =0.0e0;
  bscale  =1.0e0;
  bzero   =0.0e0;

  fits_write_key(fptr, TSTRING, "OBJECT  ", &"LIMEMDL ",    "", &status);
  fits_write_key(fptr, TDOUBLE, "EPOCH   ", &epoch,         "", &status);
  fits_write_key(fptr, TDOUBLE, "LONPOLE ", &lonpole,       "", &status);
  fits_write_key(fptr, TDOUBLE, "EQUINOX ", &equinox,       "", &status);
  fits_write_key(fptr, TSTRING, "SPECSYS ", &"LSRK    ",    "", &status);
  fits_write_key(fptr, TDOUBLE, "RESTFREQ", &restfreq,      "", &status);
  fits_write_key(fptr, TINT,    "VELREF  ", &velref,        "", &status);
  fits_write_key(fptr, TSTRING, "CTYPE1  ", &"RA---SIN",    "", &status);
  fits_write_key(fptr, TDOUBLE, "CDELT1  ", &cdelt1,        "", &status);
  fits_write_key(fptr, TDOUBLE, "CRPIX1  ", &crpix1,        "", &status);
  fits_write_key(fptr, TDOUBLE, "CRVAL1  ", &crval1,        "", &status);
  fits_write_key(fptr, TSTRING, "CUNIT1  ", &"DEG     ",    "", &status);	
  fits_write_key(fptr, TSTRING, "CTYPE2  ", &"DEC--SIN",    "", &status);
  fits_write_key(fptr, TDOUBLE, "CDELT2  ", &cdelt2,        "", &status);
  fits_write_key(fptr, TDOUBLE, "CRPIX2  ", &crpix2,        "", &status);  	
  fits_write_key(fptr, TDOUBLE, "CRVAL2  ", &crval2,        "", &status);
  fits_write_key(fptr, TSTRING, "CUNIT2  ", &"DEG     ",    "", &status);
  fits_write_key(fptr, TSTRING, "CTYPE3  ", &"VELO-LSR",    "", &status);  
  fits_write_key(fptr, TDOUBLE, "CDELT3  ", &cdelt3,        "", &status);
  fits_write_key(fptr, TDOUBLE, "CRPIX3  ", &crpix3,        "", &status);
  fits_write_key(fptr, TDOUBLE, "CRVAL3  ", &crval3,        "", &status);
  fits_write_key(fptr, TSTRING, "CUNIT3  ", &"M/S     ",    "", &status);
  fits_write_key(fptr, TDOUBLE, "BSCALE  ", &bscale,        "", &status);
  fits_write_key(fptr, TDOUBLE, "BZERO   ", &bzero,         "", &status);
  if(img[im].unit==0) fits_write_key(fptr, TSTRING, "BUNIT", &"K       ", "", &status);
  if(img[im].unit==1) fits_write_key(fptr, TSTRING, "BUNIT", &"JY/PIXEL", "", &status);
  if(img[im].unit==2) fits_write_key(fptr, TSTRING, "BUNIT", &"WM2HZSR ", "", &status);
  if(img[im].unit==3) fits_write_key(fptr, TSTRING, "BUNIT", &"Lsun/PX ", "", &status);
  if(img[im].unit==3) fits_write_key(fptr, TSTRING, "BUNIT", &"        ", "", &status);

  /* Write FITS data */
  for(py=0;py<img[im].pxls;py++){
    for(ichan=0;ichan<img[im].nchan;ichan++){
      for(px=0;px<img[im].pxls;px++){
        if(img[im].unit==0) row[px]=(float) img[im].pixel[px+py*img[im].pxls].intense[ichan]*(CLIGHT/img[im].freq)*(CLIGHT/img[im].freq)/2./KBOLTZ*m[0].norm; 
        else if(img[im].unit==1) row[px]=(float) img[im].pixel[px+py*img[im].pxls].intense[ichan]*1e26*img[im].imgres*img[im].imgres*m[0].norm;
        else if(img[im].unit==2) row[px]=(float) img[im].pixel[px+py*img[im].pxls].intense[ichan]*m[0].norm;
        else if(img[im].unit==3) {
          ru3 = img[im].distance/1.975e13;
          row[px]=(float) img[im].pixel[px+py*img[im].pxls].intense[ichan]*4.*PI*ru3*ru3*img[im].freq*img[im].imgres*img[im].imgres*m[0].norm;
        }
        else if(img[im].unit==4) row[px]=(float) img[im].pixel[px+py*img[im].pxls].tau[ichan];
        else {
          if(!silent) bail_out("Image unit number invalid");
          exit(0);
        }
        if (fabs(row[px])<(float) eps) row[px]=(float)eps;
      }
      fpixels[0]=1;
      fpixels[1]=py+1;
      fpixels[2]=ichan+1;
      lpixels[0]=img[im].pxls;
      lpixels[1]=py+1;
      lpixels[2]=ichan+1;
      fits_write_subset(fptr, TFLOAT, fpixels, lpixels, row, &status);
    }
  }
  fits_close_file(fptr, &status);

  free(row);

  if(!silent) done(13);
}
Beispiel #2
0
std::string write_image_3D(std::string pathname_3D, float *array_2D_real, float *array_2D_imag, std::string name_3D, int naxis_2D, long *naxes_2D) {
  // this function writes a float array to a FITS image file
  TRACE_ENTER();
  // create new file
  fitsfile *fptr;
  int status = 0;
  fits_create_file(&fptr, pathname_3D.c_str(), &status);
  if (status != 0) {
    // cannot create the file
    // likely, the file already exists
    // try to open it, delete it and create it anew
    // try to open the file
    status = 0;
    fits_open_file(&fptr, pathname_3D.c_str(), READWRITE, &status);
    if (status != 0) {
      // cannot open the file, for some reason
      return FORMAT_STATUS(status);
    }
    // try to delete the file
    status = 0;
    fits_delete_file(fptr, &status);
    if (status != 0) {
      // cannot delete the file, for some reason
      return FORMAT_STATUS(status);
    }
    // try to create the file
    status = 0;
    fits_create_file(&fptr, pathname_3D.c_str(), &status);
    if (status != 0) {
      // cannot create the file, for some reason
      return FORMAT_STATUS(status);
    }
  }
  // create the primary array image
  int naxis_3D = naxis_2D+1;
  long *naxes_3D = new long [naxis_3D];
  for (int i = 0; i < naxis_2D; i++) {
    naxes_3D[i] = naxes_2D[i];
  }
  naxes_3D[naxis_3D-1] = 2;
  fits_create_img(fptr, FLOAT_IMG, naxis_3D, naxes_3D, &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  // write a keyword
  fits_update_key(fptr, TFLOAT, name_3D.c_str(), array_2D_real, name_3D.c_str(), &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  // write the array of floats to the image
  long *fpixel = new long [naxis_3D];
  fpixel[0] = 1;
  fpixel[1] = 1;
  fpixel[2] = 1;
  long *lpixel = new long [naxis_3D];
  lpixel[0] = naxes_2D[0];
  lpixel[1] = naxes_2D[1];
  lpixel[2] = 1;
  fits_write_subset(fptr, TFLOAT, fpixel, lpixel, (void*)array_2D_real, &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  // write a keyword
  fits_update_key(fptr, TFLOAT, name_3D.c_str(), array_2D_imag, name_3D.c_str(), &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  // write the array of floats to the image
  fpixel[0] = 1;
  fpixel[1] = 1;
  fpixel[2] = 2;
  lpixel[0] = naxes_2D[0];
  lpixel[1] = naxes_2D[1];
  lpixel[2] = 2;
  fits_write_subset(fptr, TFLOAT, fpixel, lpixel, (void*)array_2D_imag, &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  // close the file
  fits_close_file(fptr, &status);
  if (status != 0) {
    return FORMAT_STATUS(status);
  }
  return "WRITE_OK";
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    char opt, *framename, *listname, *outname, *e_outname, buffer[BUFSIZ];
    int n, row, col, cX, cY, npatch, npxi, npxt, nprof;
    int flag_autoname, flag_verbose, status, bitmask[YAR][XAR];
    long xsize, ysize, lowleft[DIM], upright[DIM], increment[DIM] = {1L, 1L}, framesize[DIM];
    float mask_val, cutoff, framefragment[YAR][XAR];
    struct star* patchstars;
    FILE *listfile;
    fitsfile *frame, *maskedframe;
    extern char *optarg;
    extern int opterr;


    framename = NULL;
    listname = NULL;
    outname = NULL;
    mask_val = DEFAULT_MASK;
    cutoff = DEFAULT_CUTOFF;
    flag_autoname = 1;
    flag_verbose = 0;

    opterr = 0;
    while ((opt=getopt(argc, argv, "f:l:o:m:c:v")) != -1) {
        switch (opt) {
            case 'f':
                framename = optarg;
                break;
            case 'l':
                listname = optarg;
                break;
            case 'o':
                flag_autoname = 0;
                outname = optarg;
                break;
            case 'm':
                mask_val = atof(optarg);
                break;
            case 'c':
                cutoff = atof(optarg);
                break;
            case 'v':
                flag_verbose = 1;
                break;
            default:
                usage(argv);
        }
    }

    /* check mandatory parameters: */
    if (framename == NULL || listname == NULL)
        usage(argv);

    if (cutoff < 0.0) {
        fprintf(stderr, " WARNING: invalid cut-off value (%.1f ADU), using default (%.1f ADU)\n",
            cutoff, DEFAULT_CUTOFF);
        cutoff = DEFAULT_CUTOFF;
    }

    /* read ID and coordinates from any single-lined Daophot output, detect and skip the header if necessary: */
    if ((listfile=fopen(listname, "r")) == NULL) {
        file_read_error(listname);
    } else {
        npatch = line_count(listfile);

        if (has_daophot_header(listfile) == 1) {
            npatch -= DAO_HEADER_SIZE;
            line_skip(listfile, DAO_HEADER_SIZE);
        }

        if (npatch <= 0) {
            fclose(listfile);
            fprintf(stderr, " couldn't read contents of '%s', exiting.\n\n", listname);
            exit(EXIT_FAILURE);
        }

        patchstars = calloc(npatch, sizeof(struct star));
        if (patchstars == NULL) {
            fclose(listfile);
            memory_error();
        }

        for (n=0; n < npatch; n++) {
            fgets(buffer, BUFSIZ, listfile);
            sscanf(buffer, "%d %lf %lf", &patchstars[n].num, &patchstars[n].X, &patchstars[n].Y);
        }

        fclose(listfile);
    }

    status = 0;

    fits_open_file(&frame, framename, READONLY, &status);
    if (status != 0) {
        free(patchstars);
        file_read_error(framename);
    }

    fits_get_img_size(frame, DIM, framesize, &status); fits_print_error(status);
    xsize = framesize[0];
    ysize = framesize[1];
    printf(" %s: %ld x %ld pixels\n", framename, xsize, ysize);
    printf(" %s: %d stars in the list\n", listname, npatch);
    printf(" mask value: %.1f ADU\n", mask_val);
    printf(" cut-off level: %.1f ADU\n", cutoff);

    if (flag_autoname == 1) {
        outname = expand_filename(framename, "-msk", 0, 0);
        if (outname == NULL) {
            free(patchstars);
            fits_close_file(frame, &status);
            memory_error();
        }
    }
    printf(" output file: %s\n", outname);

    /* force cfitsio to overwrite already existing file (prepend ! to the filename) */
    e_outname = prepend_bang(outname);
    if (e_outname == NULL) {
        free(patchstars);
        fits_close_file(frame, &status);
        memory_error();
    }

    /* create output (masked) frame: */
    fits_create_file(&maskedframe, e_outname, &status); fits_print_error(status);

    free(e_outname);
    if (flag_autoname == 1)  /* only necessary if outname was created automatically */
        free(outname);

    fits_copy_file(frame, maskedframe, 1, 1, 1, &status); fits_print_error(status);

    npxt = 0;
    nprof = 0;

    /* process the stars in the list: */
    for (n=0; n < npatch; n++)
    {
        if (flag_verbose == 1)
            printf("\n star #%d:\n", patchstars[n].num);

        /* cfitsio doesn't understand fractional pixels, round the coordinates to nearest integer: */
        cX = rint(patchstars[n].X);
        cY = rint(patchstars[n].Y);

        /* make sure center is in the picture, skip this star if it is not: */
        if (cX < 1 || cY < 1 || cX > xsize || cY > ysize) {
            printf(" star #%d is outside the frame (%d,%d), skipping.\n", patchstars[n].num, cX, cY);
            continue;
        }
       /*
        *  in fitsio pixel index runs from 1 to N, not from 0 to N-1.
        *  consider XAR=21 (reading 10 pixels right and left from center), XSIZE=2044.
        *  example 1: star with x=10. fitsio will reach and try to read pixel at x=0, ILLEGAL.
        *  example 2: star with x=2034. fitsio will reach and try to read pixel at x=2044, LEGAL.
        *  we have to use LESS OR EQUAL when checking lower and left boundary,
        *  for upper and right boundary only using GREATER is fine
        */
        else if (cX <= (XAR-1)/2 || cY <= (YAR-1)/2 || cX > xsize-(XAR-1)/2 || cY > ysize-(YAR-1)/2) {
            printf(" star #%d is too close to the edge or partially outside the frame (%d,%d), skipping.\n",
                patchstars[n].num, cX, cY);
            continue;
        }

        if (flag_verbose == 1)
            printf(" coordinates of star #%d center in current frame: (%d,%d)\n", patchstars[n].num, cX, cY);

        /* compute the coordinates of lower left and upper right pixel: */
        lowleft[0] = cX - (XAR-1)/2;
        lowleft[1] = cY - (YAR-1)/2;
        upright[0] = cX + (XAR-1)/2;
        upright[1] = cY + (YAR-1)/2;

        /* load frame fragment with the star into table: */
        fits_read_subset(frame, TFLOAT, lowleft, upright, increment, 0, framefragment, 0, &status); fits_print_error(status);

        /* initialise the bitmask with zeros: */
        for (row=0; row < YAR; row++)
            for (col=0; col < XAR; col++)
                bitmask[row][col] = 0;

        /* detect holes and write to bitmask: */
        for (row=YAR-1; row >= 0; row--)
            examine_row(framefragment, bitmask, row, cutoff);

        for (col=0; col < XAR; col++)
            examine_col(framefragment, bitmask, col, cutoff);

        npxi = apply_bitmask(framefragment, bitmask, mask_val);
        npxt += npxi;
        if (npxi > 0)
            ++nprof;

        if (flag_verbose == 1) {
            printf("\n");
            print_bitmask(bitmask);
            printf("\n star %d: %d pixels masked\n", patchstars[n].num, npxi);
        }

        /* write the modified frame subsection to output frame: */
        fits_write_subset(maskedframe, TFLOAT, lowleft, upright, framefragment, &status); fits_print_error(status);
    }

    printf(" %d pixels were masked in %d stars.\n", npxt, nprof);

    fits_close_file(frame, &status); fits_print_error(status);
    fits_close_file(maskedframe, &status); fits_print_error(status);

    free(patchstars);

    return 0;
}
Beispiel #4
0
void 
write4Dfits(int im, int unit_index, configInfo *par, imageInfo *img){
  /*
Users have complained that downstream packages (produced by lazy coders >:8) will not deal with FITS cubes having less that 4 axes. Thus all LIME output images are now sent to the present function.
  */
  const int numAxes=4;
  double bscale,bzero,epoch,lonpole,equinox,restfreq;
  int axesOrder[] = {0,1,2,3};
  char ctype[numAxes][9],cunit[numAxes][9];
  double crpix[numAxes],crval[numAxes];
  float cdelt[numAxes];
  double ru3,scale=1.0;
  int velref,unitI,i;
  float *row;
  int px,py,ichan;
  fitsfile *fptr;
  int status = 0;
  int naxis=numAxes, bitpix=-32;
  long naxes[numAxes];
  long int fpixels[numAxes],lpixels[numAxes];
  char negfile[100]="! ",message[STR_LEN_0];
  unsigned long ppi;

  unitI = img[im].imgunits[unit_index];
  row = malloc(sizeof(*row)*img[im].pxls);

  naxes[axesOrder[0]] = img[im].pxls;
  naxes[axesOrder[1]] = img[im].pxls;

  if(img[im].doline)
    naxes[axesOrder[2]] = img[im].nchan;
  else
    naxes[axesOrder[2]] = 1; /* In this case nchan can =3, the number of active Stokes parameters, if the dust is polarized. */

  if(!img[im].doline && par->polarization)
    naxes[axesOrder[3]]=4;
  else
    naxes[axesOrder[3]]=1;

  fits_create_file(&fptr, img[im].filename, &status);

  if(status!=0){
    if(!silent) warning("Overwriting existing fits file                   ");
    status=0;
    strcat(negfile,img[im].filename);
    fits_create_file(&fptr, negfile, &status);
  }

  /* Write FITS header */ 
  fits_create_img(fptr, bitpix, naxis, naxes, &status);
  epoch   =2.0e3;
  lonpole =1.8e2;
  equinox =2.0e3;
  restfreq=img[im].freq;
  velref  =257;

  sprintf(ctype[axesOrder[0]], "RA---SIN");
  cdelt[axesOrder[0]] = -1.8e2*(float)(img[im].imgres/M_PI);
  crpix[axesOrder[0]] = ((double)img[im].pxls)/2.0 + 0.5;
  crval[axesOrder[0]] = 0.0e0;
  sprintf(cunit[axesOrder[0]], "DEG    ");

  sprintf(ctype[axesOrder[1]], "DEC--SIN");
  cdelt[axesOrder[1]] = 1.8e2*(float)(img[im].imgres/M_PI);
  crpix[axesOrder[1]] = ((double)img[im].pxls)/2.0 + 0.5;
  crval[axesOrder[1]] = 0.0e0;
  sprintf(cunit[axesOrder[1]], "DEG    ");

  sprintf(ctype[axesOrder[2]], "VELO-LSR");
  if(img[im].doline)
    cdelt[axesOrder[2]] = (float)img[im].velres;
  else
    cdelt[axesOrder[2]] = 1.0;
  crpix[axesOrder[2]] = (double) (naxes[axesOrder[2]]-1)/2.+1;
  crval[axesOrder[2]] = 0.0e0;
  sprintf(cunit[axesOrder[2]], "M/S    ");

  sprintf(ctype[axesOrder[3]], "STOKES  ");
  cdelt[axesOrder[3]] = 1.0;
  crpix[axesOrder[3]] = (double) (naxes[axesOrder[3]]-1)/2.+1;
  crval[axesOrder[3]] = 1.0e0;
  sprintf(cunit[axesOrder[3]], "       ");

  bscale  =1.0e0;
  bzero   =0.0e0;

  fits_write_key(fptr, TSTRING, "OBJECT  ", &"LIMEMDL ",    "", &status);
  fits_write_key(fptr, TDOUBLE, "EPOCH   ", &epoch,         "", &status);
  fits_write_key(fptr, TDOUBLE, "LONPOLE ", &lonpole,       "", &status);
  fits_write_key(fptr, TDOUBLE, "EQUINOX ", &equinox,       "", &status);
  fits_write_key(fptr, TSTRING, "SPECSYS ", &"LSRK    ",    "", &status);
  fits_write_key(fptr, TDOUBLE, "RESTFREQ", &restfreq,      "", &status);
  fits_write_key(fptr, TINT,    "VELREF  ", &velref,        "", &status);

  for(i=0;i<numAxes;i++)
    writeWCS(fptr, i, axesOrder, cdelt, crpix, crval, ctype, cunit);

  fits_write_key(fptr, TDOUBLE, "BSCALE  ", &bscale,        "", &status);
  fits_write_key(fptr, TDOUBLE, "BZERO   ", &bzero,         "", &status);

  if(unitI==0) fits_write_key(fptr, TSTRING, "BUNIT", &"K       ", "", &status);
  if(unitI==1) fits_write_key(fptr, TSTRING, "BUNIT", &"JY/PIXEL", "", &status);
  if(unitI==2) fits_write_key(fptr, TSTRING, "BUNIT", &"WM2HZSR ", "", &status);
  if(unitI==3) fits_write_key(fptr, TSTRING, "BUNIT", &"Lsun/PX ", "", &status);
  if(unitI==4) fits_write_key(fptr, TSTRING, "BUNIT", &"        ", "", &status);

  if(     unitI==0)
    scale=0.5*(CLIGHT/img[im].freq)*(CLIGHT/img[im].freq)/KBOLTZ;
  else if(unitI==1)
    scale=1e26*img[im].imgres*img[im].imgres;
  else if(unitI==2)
    scale=1.0;
  else if(unitI==3) {
    ru3 = img[im].distance/1.975e13;
    scale=4.*M_PI*ru3*ru3*img[im].freq*img[im].imgres*img[im].imgres;
  }
  else if(unitI!=4) {
    if(!silent) bail_out("Image unit number invalid");
    exit(0);
  }

  /* Write FITS data */
  if(img[im].doline){
    for(ichan=0;ichan<img[im].nchan;ichan++){
      for(py=0;py<img[im].pxls;py++){
        for(px=0;px<img[im].pxls;px++){
          ppi = py*img[im].pxls + px;

          if(unitI>-1 && unitI<4)
            row[px]=(float) img[im].pixel[ppi].intense[ichan]*scale;
          else if(unitI==4)
            row[px]=(float) img[im].pixel[ppi].tau[ichan];
          else {
            if(!silent) bail_out("Image unit number invalid");
            exit(0);
          }
          if (fabs(row[px])<IMG_MIN_ALLOWED) row[px]=IMG_MIN_ALLOWED;
        }
        fpixels[axesOrder[0]] = 1;
        fpixels[axesOrder[1]] = py+1;
        fpixels[axesOrder[2]] = ichan+1;
        fpixels[axesOrder[3]] = 1;
        lpixels[axesOrder[0]] = img[im].pxls;
        lpixels[axesOrder[1]] = py+1;
        lpixels[axesOrder[2]] = ichan+1;
        lpixels[axesOrder[3]] = 1;
        fits_write_subset(fptr, TFLOAT, fpixels, lpixels, row, &status);
      }
    }
  }else{
    for(ichan=0;ichan<img[im].nchan;ichan++){
      for(py=0;py<img[im].pxls;py++){
        for(px=0;px<img[im].pxls;px++){
          ppi = py*img[im].pxls + px;

          if(unitI>-1 && unitI<4)
            row[px]=(float) img[im].pixel[ppi].intense[ichan]*scale;
          else if(unitI==4)
            row[px]=(float) img[im].pixel[ppi].tau[ichan];
          else {
            if(!silent) bail_out("Image unit number invalid");
            exit(0);
          }
          if (fabs(row[px])<IMG_MIN_ALLOWED) row[px]=IMG_MIN_ALLOWED;
        }
        fpixels[axesOrder[0]] = 1;
        fpixels[axesOrder[1]] = py+1;
        fpixels[axesOrder[3]] = ichan+1;
        fpixels[axesOrder[2]] = 1;
        lpixels[axesOrder[0]] = img[im].pxls;
        lpixels[axesOrder[1]] = py+1;
        lpixels[axesOrder[3]] = ichan+1;
        lpixels[axesOrder[2]] = 1;
        fits_write_subset(fptr, TFLOAT, fpixels, lpixels, row, &status);
      }
    }

    if(par->polarization){ /* ichan should have run from 0 to 2 in this case. Stokes I, Q and U but no V. Load zeros into the last pol channel: */
      if(img[im].nchan!=3){
        if(!silent){
          sprintf(message, "%d pol channels found but %d expected.", img[im].nchan, 3);
          bail_out(message);
        }
exit(1);
      }
      ichan = 3;
      for(px=0;px<img[im].pxls;px++)
        row[px] = IMG_MIN_ALLOWED;
      for(py=0;py<img[im].pxls;py++){
        fpixels[axesOrder[0]] = 1;
        fpixels[axesOrder[1]] = py+1;
        fpixels[axesOrder[3]] = ichan+1;
        fpixels[axesOrder[2]] = 1;
        lpixels[axesOrder[0]] = img[im].pxls;
        lpixels[axesOrder[1]] = py+1;
        lpixels[axesOrder[3]] = ichan+1;
        lpixels[axesOrder[2]] = 1;
        fits_write_subset(fptr, TFLOAT, fpixels, lpixels, row, &status);
      }
    }
  }

  fits_close_file(fptr, &status);

  free(row);
}