/* Alexey Vikhlinin <alexey % head-cfa.harvard.edu> 15 Mar 2000 */
/* badpixfilter.c */

/* x.10.6: emandel changed #defines (HAVE_READPAR / NOREADPAR) */
/* Must be compiled with the CFITSIO library and header files */
/* If ReadPar library is not available, compile with -DNOREADPAR */
/* Usage:
 (with ReadPar)
  badpixfilter evtfile=dirty_evt.fits o=clean_evt.fits badpixfiler=badpix.dat

 (without ReadPar)
  badpixfilter dirty_evt.fits clean_evt.fits badpix.dat
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fitsio.h>
#include <math.h>
#ifdef HAVE_READPAR
#include <readpar.h>
#endif

char GOODPIX[1024][1024][10];

int main (int argc, char *argv[]) {
  extern iter_evt ();   /* EXTERNAL WORK FUNCTION IS PASSED TO THE ITERATOR */
  fitsfile *ifptr, *ofptr;
  iteratorCol cols[100]; /* STRUCTURE USED BY THE ITERATOR FUNCTION */
  int ncols;
  long rows_per_loop, offset;
  char evtfile[200],outfile[200],badpixfile[200];
  FILE *badpix;
  char buff[1000];
  int tfields[1000];
  char ttype[1000][80], tform[1000][80], tunit[1000][80];
  char extname[80], comment[80];
  long pcount,nrows;
  unsigned char databuf[16384];
  int iccd,i,j;
  short chipx,chipy,ccdid,N;
  int chipxmin,chipxmax,chipymin,chipymax;
  int chipxcol, chipycol, ccdidcol;
  int status, match, exact, anynul, hdutype;
  long naxes[100]; int nfound;
  long nread, nreadthistime;
  long irow, nout;

#ifdef HAVE_READPAR
  Ini_ReadPar(argc,argv);
  
  get_command_line_par ("evtfile",evtfile);
  get_command_line_par ("o",outfile);
  get_command_line_par ("badpixfilter",badpixfile);
  if (!defined(evtfile)) {
    fprintf (stderr,"evtfile=?\n");
    exit(1);
  }
  if (!defined(outfile)) {
    fprintf (stderr,"o=?\n");
    exit(1);
  }
  if (!defined(badpixfile)) {
    fprintf (stderr,"badpixfilter=?\n");
    exit(1);
  }
#else
  if (argc!=4) {
    fprintf (stderr,"Usage: %s dirty_evt.fits clean_evt.fits badpix.dat\n",argv[0]);
    exit(1);
  }
  strcpy(evtfile,argv[1]);
  strcpy(outfile,argv[2]);
  strcpy(badpixfile,argv[3]);
#endif


  badpix = fopen(badpixfile,"r");
  if (badpix==NULL) {
    perror(badpixfile);
    exit(1);
  }

  for (iccd=0;iccd<10;iccd++)
    for (i=0;i<1024;i++)
      for (j=0;j<1024;j++)
	GOODPIX[i][j][iccd]=1;
  
  while (fgets(buff,1000,badpix)!=NULL) {
    if (sscanf(buff,"%d %d %d %d %d",
	       &iccd,&chipxmin,&chipxmax,&chipymin,&chipymax)==5) {
      if (iccd>=0&&iccd<10) {
	if (chipxmin<0) chipxmin=0; if (chipxmin>1023) chipxmin=1023; 
	if (chipxmax<0) chipxmax=0; if (chipxmax>1023) chipxmax=1023; 
	if (chipymin<0) chipymin=0; if (chipymin>1023) chipymin=1023; 
	if (chipymax<0) chipymax=0; if (chipymax>1023) chipymax=1023; 
	for (i=chipxmin;i<=chipxmax;i++)
	  for (j=chipymin;j<=chipymax;j++)
	    GOODPIX[i][j][iccd]=0;
      }
    }
  }
  fclose(badpix);

  status = 0; 
  
  if (fits_open_file(&ifptr, evtfile, READONLY, &status)) /* open file */
    exit_fitsio(status);

  if (fits_create_file(&ofptr, outfile, &status)) /* create new FITS file */
    exit_fitsio(status);
  
  strcpy(extname,"junk");
  fits_compare_str (extname,"events", CASEINSEN, &match, &exact);
  while (!match) {
    /* copy the extension to output file */
    if (
	fits_copy_hdu (ifptr,ofptr,0,&status)
	)
      exit_fitsio(status);
    
    /* move to the next extension */
    if (
	fits_movrel_hdu (ifptr,1,&hdutype,&status)
	) {
      fprintf (stderr,"ERROR: EVENTS extension not found in the input file!\n");
      exit_fitsio(status);
    }
    
    if (hdutype==BINARY_TBL) {
      fits_read_key (ifptr,TSTRING,"EXTNAME",extname,comment,&status);
      fits_get_num_rows (ifptr,&nrows,&status);
      if (status)
	exit_fitsio(status);
    }
    fits_compare_str (extname,"events", CASEINSEN, &match, &exact);
  }
  
  /* we can be here only if we are in the events extension */
  if (fits_get_rowsize(ifptr,&nread,&status)) 
    exit_fitsio(status);
  if (fits_read_keys_lng(ifptr, "NAXIS", 1, 2, naxes, &nfound, &status) )
    exit_fitsio(status);

  fits_get_colnum(ifptr,CASEINSEN,"CHIPX",&chipxcol,&status);
  fits_get_colnum(ifptr,CASEINSEN,"CHIPY",&chipycol,&status);
  fits_get_colnum(ifptr,CASEINSEN,"CCD_ID",&ccdidcol,&status);
  if (status) 
    exit_fitsio(status);

  /* Copy header */
  if (fits_copy_header(ifptr,ofptr,&status))
    exit_fitsio(status);
  

  nout = 0;
  irow = 0;

  while (irow<nrows) {
    nreadthistime = nread;
    if (nrows-irow<nreadthistime) nreadthistime = nrows-irow;
    for (i=0;i<nreadthistime;i++) {
      irow ++;
      if (fits_read_tblbytes(ifptr,irow,1,naxes[0],databuf,&status))
	exit_fitsio(status);

      N = 0;
      fits_read_col (ifptr,TSHORT,ccdidcol,irow,1,1,&N,&ccdid,&anynul,&status);
      fits_read_col (ifptr,TSHORT,chipxcol,irow,1,1,&N,&chipx,&anynul,&status);
      fits_read_col (ifptr,TSHORT,chipycol,irow,1,1,&N,&chipy,&anynul,&status);
      if (status)
	exit_fitsio(status);
      
      if (GOODPIX[chipx][chipy][ccdid]) {
	nout ++;
	if (fits_write_tblbytes(ofptr,nout,1,naxes[0],databuf,&status))
	  exit_fitsio(status);
      }
    }
  }
  if ( fits_update_key(ofptr, TLONG, "NAXIS2", &nout, 0, &status) )
    exit_fitsio(status);
  if ( fits_write_chksum (ofptr,&status) )
    exit_fitsio(status);
  
  /* Copy the rest */
  while ( ! fits_movrel_hdu (ifptr,1,&hdutype,&status) ) {
    if (
	fits_copy_hdu (ifptr,ofptr,0,&status)
	)
      exit_fitsio(status); 
  }
  status = 0;
  fits_close_file (ifptr,&status);
  status = 0;
  fits_close_file (ofptr,&status);

  exit(0);
}

int exit_fitsio (int status)
{
  fits_report_error(stderr, status);
  exit(1);
}










