#include #include #include #include #include #include #include "qfits.h" #include #include #define LIM 256 #define D2R M_PI/180.0 #define R2D 180.0/M_PI #define NMAX 4096 struct star { double ra,de; float pmra,pmde; float mag; }; struct image { int naxis1,naxis2,naxis3; float *z; float zmin,zmax; double ra0,de0; float x0,y0; float a[3],b[3]; double mjd; } img; struct catalog { int n; float x[NMAX],y[NMAX],mag[NMAX]; double ra[NMAX],de[NMAX],rx[NMAX],ry[NMAX]; int select[NMAX]; }; struct map { double lat,lng; float alt; int site_id; char observer[32]; } m; struct image read_fits(char *filename,int pnum); int fgetline(FILE *,char *,int); void forward(double ra0,double de0,double ra,double de,double *x,double *y); void reverse(double,double,double,double,double *,double *); void lfit2d(float *x,float *y,float *z,int n,float *a); struct catalog read_pixel_catalog(char *filename); double gmst(double mjd); double modulo(double x,double y); void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de); double sex2dec(char *s); // Read astrometric catalog struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float sy,float angle) { int i=0; FILE *file; char line[LIM]; struct catalog c; double rx,ry,x,y,ra,de; struct star s; double d,dx,dy; double mjd0=51544.5; file=fopen(filename,"rb"); if (file==NULL) { fprintf(stderr,"%s not found!\n",filename); exit(0); } while (!feof(file)) { fread(&s,sizeof(struct star),1,file); if (s.mag>mmin) continue; precess(mjd0,s.ra,s.de,img.mjd,&ra,&de); forward(img.ra0,img.de0,ra,de,&rx,&ry); x=img.x0+1.0/sx*(cos(angle*D2R)*rx+sin(angle*D2R)*ry); y=img.y0+1.0/sy*(-sin(angle*D2R)*rx+cos(angle*D2R)*ry); /* } else if (t.state==1) { dx=rx-t.a[0]; dy=ry-t.b[0]; d=t.a[1]*t.b[2]-t.a[2]*t.b[1]; x=(t.b[2]*dx-t.a[2]*dy)/d; y=(t.a[1]*dy-t.b[1]*dx)/d; } */ if (x>0.0 && x0.0 && ymmin) continue; precess(mjd0,s.ra,s.de,img.mjd,&ra,&de); forward(img.ra0,img.de0,ra,de,&rx,&ry); dx=rx-img.a[0]; dy=ry-img.b[0]; d=img.a[1]*img.b[2]-img.a[2]*img.b[1]; x=(img.b[2]*dx-img.a[2]*dy)/d+img.x0; y=(img.a[1]*dy-img.b[1]*dx)/d+img.y0; if (x>0.0 && x0.0 && yn;i++) cat->select[i]=0; for (i=0;in;i++) ast->select[i]=0; file=fopen("out.dat","w"); for (i=0,n=0;in;i++) { for (j=0,flag=0;jn;j++) { if (ast->select[j]!=0) continue; r=sqrt(pow(cat->x[i]-ast->x[j],2)+pow(cat->y[i]-ast->y[j],2)); if (flag==0 || rx[i]-img.x0,cat->y[i]-img.y0,ast->ra[jmin],ast->de[jmin]); cat->select[i]=n+1; ast->select[jmin]=n+1; n++; } } fclose(file); printf("%d stars matched\n",n); return n; } // Get observing site void get_site(int site_id) { int i=0; char line[LIM]; FILE *file; int id; double lat,lng; float alt; char abbrev[3],observer[64],filename[LIM],*env; env=getenv("ST_DATADIR"); sprintf(filename,"%s/data/sites.txt",env); file=fopen(filename,"r"); if (file==NULL) { printf("File with site information not found!\n"); return; } while (fgets(line,LIM,file)!=NULL) { // Skip if (strstr(line,"#")!=NULL) continue; // Strip newline line[strlen(line)-1]='\0'; // Read data sscanf(line,"%4d %2s %lf %lf %f", &id,abbrev,&lat,&lng,&alt); strcpy(observer,line+38); // Change to km alt/=1000.0; if (id==site_id) { m.lat=lat; m.lng=lng; m.alt=alt; m.site_id=id; strcpy(m.observer,observer); } } fclose(file); return; } int main(int argc,char *argv[]) { int i; float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; float x,y,r,rmin=1.0,rmax=10.0,mmin=5.0,mmax=10.0; struct catalog cat,ast; char c; int redraw=1,click=0,nselect=0,plotstars=1; char filename[128],sra[20],sde[20]; float h,q,s=0.0,mag=9; FILE *file; char *env,starfile[128]; // Environment variables env=getenv("ST_DATADIR"); sprintf(starfile,"%s/data/tycho2.dat",env); // Geographic position env=getenv("ST_COSPAR"); get_site(atoi(env)); // Read image img=read_fits(argv[1],0); sprintf(filename,"%s.cat",argv[1]); printf("Image read\n"); // Initial transformation if (argc==7) { s=atof(argv[2]); img.ra0=atof(argv[3]); img.de0=atof(argv[4]); q=atof(argv[5]); mag=atof(argv[6]); } else { file=fopen("position.txt","r"); if (file==NULL) { fprintf(stderr,"No position file found\n"); return 0; } fscanf(file,"%s %s",sra,sde); fclose(file); // Get parameters img.ra0=15.0*sex2dec(sra); img.de0=sex2dec(sde); // Hour angle h=gmst(img.mjd)+m.lng-img.ra0; q=atan2(sin(h*D2R),(tan(m.lat*D2R)*cos(img.de0*D2R)-sin(img.de0*D2R)*cos(h*D2R)))*R2D; printf("Hour angle: %.3f deg, parallactic angle: %.3f deg\n",h,q); } img.x0=0.5*(float) img.naxis1; img.y0=0.5*(float) img.naxis2; // Read catalogs cat=read_pixel_catalog(filename); if (s==0.0) ast=read_astrometric_catalog(starfile,mag,-36.15,33.22,-q); else ast=read_astrometric_catalog(starfile,mag,-s,s,-q); // Plot image cpgopen("/xs"); cpgwnad(0.0,img.naxis1,0.0,img.naxis2); cpgsfs(2); cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); // For ever loop for (;;) { if (redraw==1) { cpgimag(img.z,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,img.zmin,img.zmax,tr); cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0); // Plot catalogs if (plotstars==1) { cpgsci(3); for (i=0;i=3) { fit_transformation(cat,ast,nselect); ast=reread_astrometric_catalog(starfile,mag+1); redraw=1; } // Reread if (c=='r') { ast=reread_astrometric_catalog(starfile,mag+1); redraw=1; } // Select pixel catalog if (c=='a' && click==0) { i=select_nearest(cat,x,y); cat.select[i]=nselect+1; redraw=1; click=1; } // Select catalog if (c=='b' && click==1) { i=select_nearest(ast,x,y); ast.select[i]=nselect+1; redraw=1; click=0; nselect++; } // if (c=='p') { if (plotstars==1) plotstars=0; else if (plotstars==0) plotstars=1; redraw=1; } // Match catalogs if (c=='m') { nselect=match_catalogs(&cat,&ast,10.0); redraw=1; } } cpgend(); return 0; } // Read fits image struct image read_fits(char *filename,int pnum) { int i,j,k,l,m; qfitsloader ql; char key[FITS_LINESZ+1] ; struct image img; double s1,s2,avg,std; // Set plane ql.xtnum = 0; ql.pnum = pnum; // Set loadtype ql.ptype = PTYPE_FLOAT; // Set filename ql.filename=filename; // Image size img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); // Initialize load if (qfitsloader_init(&ql) != 0) printf("Error initializing data loading\n"); // Test load if (qfits_loadpix(&ql) != 0) printf("Error loading actual data\n"); // Allocate image memory img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2); // Fill z array for (i=0,l=0,m=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } // Linear 2D fit void lfit2d(float *x,float *y,float *z,int n,float *a) { int i; double chisq; gsl_matrix *X,*cov; gsl_vector *yy,*w,*c; X=gsl_matrix_alloc(n,3); yy=gsl_vector_alloc(n); w=gsl_vector_alloc(n); c=gsl_vector_alloc(3); cov=gsl_matrix_alloc(3,3); // Fill matrices for(i=0;i0) { if (strstr(line,"#")!=NULL) continue; sscanf(line,"%f %f %f",&c.x[i],&c.y[i],&c.mag[i]); c.select[i]=0; i++; } fclose(file); c.n=i; return c; } // Greenwich Mean Sidereal Time double gmst(double mjd) { double t,gmst; t=(mjd-51544.5)/36525.0; gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); return gmst; } // Return x modulo y [0,y) double modulo(double x,double y) { x=fmod(x,y); if (x<0.0) x+=y; return x; } // Precess a celestial position void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) { double t0,t; double zeta,z,theta; double a,b,c; // Angles in radians ra0*=D2R; de0*=D2R; // Time in centuries t0=(mjd0-51544.5)/36525.0; t=(mjd-mjd0)/36525.0; // Precession angles zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; zeta*=D2R/3600.0; z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; z*=D2R/3600.0; theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; theta*=D2R/3600.0; a=cos(de0)*sin(ra0+zeta); b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); *ra=(atan2(a,b)+z)*R2D; *de=asin(c)*R2D; if (*ra<360.0) *ra+=360.0; if (*ra>360.0) *ra-=360.0; return; } // Convert Sexagesimal into Decimal double sex2dec(char *s) { double x; float deg,min,sec; char t[LIM]; strcpy(t,s); deg=fabs(atof(strtok(t," :"))); min=fabs(atof(strtok(NULL," :"))); sec=fabs(atof(strtok(NULL," :"))); x=(double) deg+(double) min/60.+(double) sec/3600.; if (s[0]=='-') x= -x; return x; }