This is a cached copy of http://cfa-www.harvard.edu/~jhora/mirac/xcor.tar.Z /*************************************************************************/ /* xcor.c - Determine offsets for image based on cross correlation */ /*************************************************************************/ /* Febuary 22, 1993 */ /* Joseph L Hora adapted from the CROSSR fortran program written */ /* by R. Tresch-Feinberg and J. Hora */ /* requires the files xfitsio.c and xfiocom.h to compile */ /*************************************************************************/ /* */ /* xcor */ /* */ /* */ /* This program reads in image files in FITS format (8, 16, 32, or -32 */ /* BITPIX) and calculates the cross correlation between two images. At */ /* least two images must be entered, the reference image (whose offsets */ /* are by definition zero) and the search or window image. A small */ /* window out of the search image is compared to part or all of the */ /* reference image. The offset result given by the program is the offset*/ /* in pixels necessary to align the search image with the reference */ /* image. The program is currently configured for a maximum image size */ /* of 256x256, but that can be easily changed using the definitions in */ /* the file "fiocom.h" for the paramters XPIX and YPIX. */ /* */ /* The program writes the output to the screen, and optionally to an */ /* output file. The following information is in the output file for each*/ /* image: the image name, X and Y coord. of the "center" structure, the */ /* X and Y offsets necessary to align the image with the reference image,*/ /* and the max, min, and average correlation values. */ /* */ /* */ /* The program can be compiled on a SUN workstation using the following */ /* command: */ /* */ /* cc xcor.c xfitsio.c -lm -o xcor */ /* */ /* The executable file "xcor" will be created. */ /* */ /* see message in program below for info on command line parameters */ /*************************************************************************/ /* */ /* MODIFICATION LOG */ /* */ /* 1/25/95 - JLH */ /* Changed the smoothing routines so that they use global arrays, */ /* and now only necessary part of window image is smoothed. */ /* */ /* 10/20/93 - JLH */ /* Changed program in xfitsio.c and xfiocom.h - the data files are */ /* read in as floating point, then scaled if necessary and converted */ /* to long integer. The scaling now also handles small numbers and */ /* large, so that rounding errors don't adversely affect the cross- */ /* correlation. */ /* */ /* 10/14/93 - JLH */ /* Corrected error in -q option: when specifying coordinates, it was */ /* getting them switched. */ /* */ /*************************************************************************/ #include #include #include #include #include "xfiocom.h" #define NULL 0 #define MAXES 6 #define TRUE 1 #define FALSE 0 static long refimg[XPIX][YPIX]; /* this is where final image is stored */ static long winimg[XPIX][YPIX]; /* mask file for a single image */ static long tmpimg[XPIX][YPIX]; /* mask file for a single image */ static float rdimg[XPIX][YPIX]; /* mask file for a single image */ static long dmax; /* max. good data value */ static float maxvalue; static int mwin,lwin; /* number of frames used in final image*/ static char speedy, xcorrelate, do_centroid; void save_final_image(); void do_xcorr(); void winsmooth(); void refsmooth(); int max(); int min(); main(argc, argv) /***********Main XCOR program start**********/ int argc; char *argv[]; { char fname[50]; float xtmp,ytmp,cmax,cmin,cavg,usemax; char fits_input,expand,discard_file, do_centroid, write_individual_files, outfileopen,interpolate,peak_coords,wsmooth,rsmooth,peakset; int ii, imin, imax, jmin, jmax, refpkx,refpky, nbuf, itmin, itmax, bitpix, jtmin, jtmax, tnum, rsmfac,wsmfac, xst,yst,ipk,jpk,xreg,yreg,xsim,ysim, hfsize, rxoff,ryoff,rxend,ryend,wxoff,wyoff,wxend,wyend,wxsiz,wysiz, rxsiz,rysiz, fmin,fmax; int numexclude; struct BUFFER searchead, windhead; char object[8]; char wname[60],excludefile[60], peakfile[60], fits_name[60],refname[60], winname[60],outfile[60],infile[60]; char lbuf[80]; int framenum, nump, st_arg; int n_rawimg; int i,j, k, l; char tstr[20]; FILE *fp1,*fp2; /* Initialize parameter values */ strcpy(peakfile,"NONE"); strcpy(fits_name,"NONE"); strcpy(infile,"NONE"); strcpy(outfile,"NONE"); imin=-1; imax=XPIX-1; jmin=0; fmin = fmax = -1; rsmfac=4; wsmfac=4; dmax=216000000; mwin=20; lwin=20; do_centroid=FALSE; xcorrelate=TRUE; jmax=YPIX-1; hfsize = 15; refpkx = refpky = -1; peakset = outfileopen=FALSE; st_arg = 1; do_centroid=FALSE; write_individual_files = FALSE; ipk = -999; fits_input = FALSE; wsmooth = FALSE; rsmooth = FALSE; peak_coords = FALSE; expand = FALSE; interpolate = FALSE; speedy = FALSE; printf("Cross correlation program ( xcor.c )\n\n"); /* If enough command line parameters have been entered, read them in */ if (argc >=3) { /* Fits filename of reference image is 1st argument */ sscanf(argv[1],"%s",refname); sscanf(argv[2],"%s",fname); if (strcspn(fname,"-")==0) { st_arg = 2; strcpy(fname,"NONE"); } else { st_arg = 3; strcpy(wname,fname); } if (argc>st_arg) { for (i= st_arg; i0)) { rxoff = max(refpkx-2*lwin-rsmfac,0); rxend = min(refpkx+2*lwin+rsmfac,XPIX+rxoff-1); ryoff = max(refpky-2*mwin-wsmfac,0); ryend = min(refpky+2*mwin+wsmfac,YPIX+ryoff-1); if (readfits(refname,&searchead,rdimg,&rxoff,&rxend,&ryoff,&ryend)!=0) { printf("Program terminating.\n"); exit(1); } refpkx -= rxoff; refpky -= ryoff; } else { rxoff = ryoff = 0; rxend = XPIX; ryend = YPIX; if (readfits(refname,&searchead,rdimg,&rxoff,&rxend,&ryoff,&ryend)!=0) { printf("Program terminating.\n"); exit(1); } } rxsiz = rxend - rxoff + 1; rysiz = ryend - ryoff + 1; bitpix = searchead.bitpix; if ((rxsiz100000)||(usemax<1000)) { printf("Now scaling reference image...\n"); for (i=0; itnum)&&(refimg[i][j]-1) /* The user has entered a range of files with the -r option */ { for (i=fmin; i<=fmax; i++) { strcpy(wname,fname); /* construct file names by adding extension to */ if (i==0) /* the root name entered on the command line */ strcat(wname,"00"); else if (i<10) strcat(wname,"00"); else if (i<100) strcat(wname,"0"); sprintf(tstr,"%i",i); strcat(wname,tstr); wxoff = 0; wxend = XPIX; wyoff = 0; wyend = YPIX; if(readfits(wname,&windhead,rdimg,&wxoff,&wxend,&wyoff,&wyend)!=0) { printf("Program terminating.\n"); exit(1); } wxsiz = wxend - wxoff + 1; wysiz = wyend - wyoff + 1; printf("File %s header read, parameters: %i %i %i\n",wname,wxsiz,wysiz, windhead.bitpix); if ((windhead.max>100000)||(windhead.max<100)) { printf("Now rescaling search image...\n"); for (ii=0; ii100000)||(windhead.max<100)) { printf("Now rescaling search image...\n"); for (i=0; i100000)||(windhead.max<100)) { printf("Now rescaling search image...\n"); for (i=0; i100000)||(windhead.max<100)) { printf("Now rescaling search image...\n"); for (i=0; i=imin) && (i<=imax) && (j>=jmin) && (j<=jmax)) && (winimg[i][j]maxpt)) { maxpt= winimg[i][j]; maxi = i; maxj = j; } } } ipk=maxi; jpk = maxj; } if (ipk!=-999) /* If peak was found, */ { /* Good peak found, now use offsets to add map to others */ if (do_centroid!=0) { xcentrd = ycentrd = dsum = 0; kmin = max(ipk-hfsize,0); kmax = min(ipk+hfsize,XPIX-1); lmin = max(jpk-hfsize,0); lmax = min(jpk+hfsize,YPIX-1); for (k=kmin; k<=kmax; k++) for (l=lmin; l<=lmax; l++) { xcentrd += k*winimg[k][l]; ycentrd += l*winimg[k][l]; dsum += winimg[k][l]; } if (dsum!=0) { ipk = (int)(xcentrd/dsum+0.5); if (ipk>=xsize) ipk = -1; jpk = (int)(ycentrd/dsum+0.5); if (jpk>=ysize) jpk = -1; } if ((ipk<0) || (jpk<0)) { ipk = -999; printf("xcor: Warning- no valid peak found \n"); } } } iwin = min(wxd-lwin,max(0,ipk - lwin/2)); jwin = min(wyd-mwin,max(0,jpk - mwin/2)); printf(" Peak used is (%i) at %i , %i\n",winimg[ipk][jpk],ipk+1,jpk+1); printf(" Window corner at %i %i\n",iwin+1,jwin+1); /* We have a peak position now, do xcorrelation if selected */ if (ipk!=-999) { /* Now do cross correlation */ if (wsmooth) winsmooth(wsmfac, xsize, ysize, iwin, jwin, lwin, mwin); if (xcorrelate) { for (j = 0; j< ysize-mwin; j++) for (i = 0; i < xsize - lwin; i++) { ww = 0.0; ss = 0.0; ws = 0.0; if ( (!speedy) || ((i>refpkx-lwin) && (irefpky-mwin) && (j0.01)) rmn = rdimg[i][j]; if (rdimg[i][j]>=rmx) { lstmax = rmx; rmx = rdimg[i][j]; *ireg = i-iwin; *jreg = j-jwin; } if (rdimg[i][j]>0.01) { sum += rdimg[i][j]; numpix++; } } if (lstmax == rmx) printf("xcor: Warning - no unique correlation max in image\n"); if (numpix>0) *cavg = sum/numpix; *cmax =rmx; *cmin = rmn; } } else { /* No good peak found in image */ printf("xcor: Warning - no good peak found in image\n"); } } /* End do_xcorr */ /*******************************************************************************/ /* Smooth - boxcar smooth an image with the chosen box width */ /*******************************************************************************/ void refsmooth(sfactor,xsize,ysize) int sfactor; /* smooth box size */ int xsize; /* x size of data image */ int ysize; /* y size of data image */ { double newpix,numpix; int i,j,k,l,sfd2; sfd2 = sfactor/2; for (j=0; j0) winimg[i][j] = (long)(newpix/numpix); else winimg[i][j] = 0; } for (i = 0; i< xsize-sfd2; i++) for (j = 0; j0) tmpimg[i][j] = (long)(newpix/numpix); else tmpimg[i][j] = 0; } for (i=sxst; i