/* @(#)tbjoin.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:11 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME tbjoin.c .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY table utilities .COMMENTS This module implements the following Midas commands: \begin{TeX} \begin{enumerate} \item {\tt JOIN/TABLE} table1 :X1,[:Y1] table2 :X2,[:Y2] \end{enumerate} \end{TeX} .VERSION 1.0 10-May-1992 Definition M.Peron ----------------------------------------------------------------------*/ #include #include #include #include #include #define PARLEN 80 #define STRINGLEN 256 #define COLS 2 int flc; struct tree { double xval; double yval; int row; struct tree *left; struct tree *right; }; struct tree *head; int lines,tid1,tid2,tod,ic1[256],ic2[256],oc1[256],oc2[256]; int ncol1,ncol2; int coltype1[256],coltype2[256]; char *osmmget(); tbl_join() { char *intable1,*intable2,*outtable,*incol1,*incol2; int npar,status; int dummy,i1,i2; int i,j,k,nbyt1,nbyt2; int icol1[COLS],icol2[COLS],flag[COLS]; int nrow1,nrow2,ncol,nrow,lerr; int type,type1,sel,null[256],snull,nbytes,bytes,alen,out,cop; int first,nc; float rerr; double dval[COLS],derr[COLS],dcomp,atof(); double rect[4]; double dvalue; char strsimple[256]; char form[1+TBL_FORLEN],unit[1+TBL_UNILEN],label[1+TBL_LABLEN]; char parm[6][PARLEN],cval[STRINGLEN]; typedef int (*FUNCTION)(); FUNCTION eread, ewrite; int TCERDC(), TCERDD(), TCERDI(), TCERDR(); int TCEWRC(), TCEWRD(), TCEWRI(), TCEWRR(); struct tree *s2dtree(); npar = tbl_argc(); intable1 = intable2 = outtable = incol1 = incol2 = (char *)0; lines = 0; derr[0] = derr[1] = 0.0e0; nbyt1 = nbyt2 = 0; lerr = 0; cop = 0; for (i=0; i 0) { status = TCESRC(tid2,icol2[0],cval,1,nbytes,first,&out); if ((status) || (out <=0)) continue; lines = lines+1; for (i=0; i nrow2) break; } } else for (i1=1; i1<=nrow1; i1++) { TCSGET(tid1,i1,&sel); if (!sel) continue; first = 1; out = 1; TCRRDD(tid1,i1,nc,icol1,dval,null); if (null[0]) continue; while (out > 0) { status = TCESRD(tid2,icol2[0],dval[0],derr[0],first,&out); if ((status) || (out <=0)) continue; lines = lines+1; for (i=0; i nrow2) break; } } break; case 2: head = (struct tree *) 0; for (i1=1; i1<=nrow2; i1++) { TCSGET(tid2,i1,&sel); if (!sel) continue; first = 1; out = 1; flc =0; TCRRDD(tid2,i1,nc,icol2,dval,null); if (null[0] || null[1]) continue; if (!head) head = s2dtree(head,head,dval[0],dval[1],i1); else s2dtree(head,head,dval[0],dval[1],i1); } for (i1=1; i1<=nrow1; i1++){ TCSGET(tid1,i1,&sel); if (!sel) continue; TCRRDD(tid1,i1,nc,icol1,dval,null); rect[0] = dval[0]-derr[0]; rect[1] = dval[0]+derr[0]; rect[2] = dval[1]-derr[1]; rect[3] = dval[1]+derr[1]; flc = 0; findtree(head,head,rect,i1); } } TCTCLO(tid1); TCTCLO(tid2); TCTCLO(tod); } struct tree *s2dtree(root,r,xval,yval,row) struct tree *root; struct tree *r; double xval,yval; int row; { if (!r) { r = (struct tree *)osmmget(sizeof(struct tree)); r->left = (struct tree *)0; r->right = (struct tree *)0; r->xval = xval; r->yval = yval; r->row = row; if (!root) return r; if (flc == 1) { if (yval < root->yval) root->left = r; else root->right = r; } else { if (xval < root->xval) root->left = r; else root->right = r; } return r; } if (flc == 0){ flc = 1; if (yval < r->yval) s2dtree(r,r->left,xval,yval,row); else if (yval >= r->yval) s2dtree(r,r->right,xval,yval,row); } else { flc = 0; if (xval < r->xval) s2dtree(r,r->left,xval,yval,row); else if (xval >= r->xval) s2dtree(r,r->right,xval,yval,row); } } int findtree(head,r,rect,row1) struct tree *head; struct tree *r; double rect[4]; int row1; { if (flc == 0) { if (r->yval < rect[2]) { flc = 1; if (r->right) findtree(head,r->right,rect,row1); } else if (r->yval > rect[3]) { flc = 1; if (r->left) findtree(head,r->left,rect,row1); } else { insiderect(r,rect,0,row1); flc = 1; if (r->left) findtree(head,r->left,rect,row1); flc = 1; if (r->right) findtree(head,r->right,rect,row1); } } else { if (r->xval < rect[0]) { flc = 0; if (r->right) findtree(head,r->right,rect,row1); } else if ( r->xval > rect[1]){ flc = 0; if (r->left) findtree(head,r->left,rect,row1); } else { insiderect(r,rect,1,row1); flc = 0; if (r->left) findtree(head,r->left,rect,row1); flc = 0; if (r->right) findtree(head,r->right,rect,row1); } } } int insiderect(r,rect,b,row1) struct tree *r; double rect[4]; int b,row1; { int i, null; double dvalue; char strsimple[256]; if (b==1) { if (r->yval >= rect[2] && r->yval <= rect[3]) { lines = lines+1; for (i=0; irow,ic2[i],strsimple,&null); if (!null) TCEWRC(tod,lines,oc2[i],strsimple); } else { TCERDD(tid2,r->row,ic2[i],&dvalue,&null); if (!null) TCEWRD(tod,lines,oc2[i],&dvalue); } } } } else { if (r->xval >=rect[0] && r->xval <= rect[1]) { lines = lines+1; for (i=0; irow,ic2[i],strsimple,&null); if (!null) TCEWRC(tod,lines,oc2[i],strsimple); } else { TCERDD(tid2,r->row,ic2[i],&dvalue,&null); if (!null) TCEWRD(tod,lines,oc2[i],&dvalue); } } } } }