apclust.c

00001 /* $Id: apclust.c,v 1.2 2010/09/09 12:09:57 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2010/09/09 12:09:57 $
00024  * $Revision: 1.2 $
00025  * $Name: vcam-1_3_0 $
00026  */
00027 
00028 #include <stdio.h>
00029 #include <cpl.h>
00030 
00031 #include "imcore.h"
00032 #include "util.h"
00033 
00034 static void minmax_xy(int, plstruct *, int *, int *, int *, int *);
00035 
00038 /*---------------------------------------------------------------------------*/
00069 /*---------------------------------------------------------------------------*/
00070 
00071 void apclust(ap_t *ap, int np, plstruct *plstr) {
00072 
00073     int i,i1,loop,ik;
00074     int is;    /* parent name for image in this slice */
00075     int ip;    /* parent name for image on last line */
00076     int ib;    /* data block name */
00077     int k,j,ix1,ix2,iy1,iy2,nwork,nx,ny,kk;
00078     float i2compare,icompare;
00079     short int *work;
00080  
00081     /* A couple of useful things */
00082 
00083     i2compare = ap->thresh;
00084     icompare = i2compare * ap->multiply;
00085 
00086     /* Get the min and max positions. Create a raster with the IDs of the
00087        pixels in the pixel list (algorithm prefers data to be in a raster) */
00088 
00089     minmax_xy(np,plstr,&ix1,&ix2,&iy1,&iy2);
00090     nx = ix2 - ix1 + 1;
00091     ny = iy2 - iy1 + 1;
00092     nwork = nx*ny;
00093     work = cpl_malloc(nwork*sizeof(*work));
00094     for (i = 0; i < nwork; i++)
00095         work[i] = -1;
00096     for (k = 0; k < np; k++) {
00097         i = plstr[k].x - 1;
00098         j = plstr[k].y - 1;
00099         kk = (j - iy1)*nx + i - ix1;
00100         work[kk] = k;
00101     }
00102 
00103     /* Now do the job */
00104             
00105     for (j = iy1; j <= iy2; j++) {
00106         for (i = ix1; i <= ix2; i++) {
00107             kk = (j - iy1)*nx + i - ix1;
00108             k = work[kk];
00109             if (k < 0) {
00110                 ap->lastline[i + 1] = 0;
00111             } else {
00112                 if (plstr[k].zsm > icompare) {
00113 
00114                     /* Pixel is above threshold, find which parent it belongs to. */
00115 
00116                     is = ap->lastline[i];       /* Parent last pixel this line */
00117                     ip = ap->lastline[i + 1];   /* Guess belongs to above line */
00118                     if (ip == 0) {
00119 
00120                         /* New parent, or, horizontal slice: */
00121 
00122                         if (is == 0) {
00123 
00124                             /* Ah - new parent. */
00125 
00126                             if (ap->ipstack > ap->maxpa*3/4) {
00127                                 for (ik = 0; ik < ap->maxpa*3/8; ik++)
00128                                     apfu(ap);
00129                             }
00130                             ip = ap->pstack[ap->ipstack++];
00131                             ap->parent[ip].first = ap->bstack[ap->ibstack];
00132                             ap->parent[ip].pnop = 0;
00133                             ap->parent[ip].pnbp = 0;
00134                             ap->parent[ip].growing = 0;
00135                             if (j == 0)
00136 
00137                                 /* It touches first line: */
00138 
00139                                 ap->parent[ip].touch = 1;
00140                             else
00141                                 ap->parent[ip].touch = 0;
00142 
00143                             /* For hunt thru list for terminates: */
00144 
00145                             if (ip > ap->maxip)
00146                                 ap->maxip = ip;
00147                         } else {
00148 
00149                             /* Slice with no vertical join: */
00150 
00151                             ip = is;
00152                         }
00153                     } else if ((ip > 0 && is > 0) && (ip != is)) {
00154 
00155                         /* merge: Join linked lists: */
00156 
00157                         ap->blink[ap->parent[ip].last] = ap->parent[is].first;
00158 
00159                         /* Copy `last block': */
00160 
00161                         ap->parent[ip].last = ap->parent[is].last;
00162                         ap->parent[ip].pnop += ap->parent[is].pnop;
00163                         ap->parent[ip].pnbp += ap->parent[is].pnbp;
00164 
00165                         /* Fix `lastline' correlator array: */
00166 
00167                         ib = ap->parent[is].first;
00168                         loop = 1;
00169                         while (loop) {
00170                             i1 = ap->plessey[ib].x;
00171                             if (ap->lastline[i1 + 1] == is)
00172                                 ap->lastline[i1 + 1] = ip;
00173                             if (ap->parent[is].last == ib)
00174                                 loop = 0;
00175                             else
00176                                 ib = ap->blink[ib];
00177                         }
00178 
00179                         /* Mark parent inactive: */
00180 
00181                         ap->parent[is].pnop = -1;
00182                         ap->parent[is].pnbp = -1;
00183 
00184                         /* return name to stack: */
00185 
00186                         ap->pstack[--ap->ipstack] = is;
00187                     }
00188 
00189                     /* Add in pixel to linked list: */
00190 
00191                     ib = ap->bstack[ap->ibstack++];
00192 
00193                     /* Patch forward link into last data block: */
00194 
00195                     if (ap->parent[ip].pnop > 0)
00196                         ap->blink[ap->parent[ip].last] = ib;
00197 
00198                     /* Remember last block in chain: */
00199 
00200                     ap->parent[ip].last = ib;
00201 
00202                     /* Store the data: */
00203 
00204                     ap->plessey[ib].x = i;
00205                     ap->plessey[ib].y = j;
00206                     ap->plessey[ib].z = plstr[k].z;
00207                     ap->plessey[ib].zsm = plstr[k].zsm;
00208 
00209                     /* increment active count: */
00210 
00211                     ap->parent[ip].pnop++;
00212 
00213                     /* remember which parent this pixel was for next line: */
00214 
00215                     ap->lastline[i + 1] = ip;
00216 
00217                 } else {
00218 
00219                     /* Pixel was below threshold, mark lastline: */
00220 
00221                     ap->lastline[i + 1] = 0;
00222                 }
00223             }
00224         }
00225     }
00226 
00227     /* Check for images touching left & right edges:
00228        OR the touch flag with 2 for left, 4 for right: */
00229 
00230     if(ap->lastline[1] > 0 )
00231         ap->parent[ap->lastline[1]].touch |= 2;
00232     if(ap->lastline[ap->lsiz] > 0)
00233         ap->parent[ap->lastline[ap->lsiz]].touch |= 4;
00234     cpl_free(work);
00235 }
00236 
00237 /*---------------------------------------------------------------------------*/
00260 /*---------------------------------------------------------------------------*/
00261 
00262 static void minmax_xy(int np, plstruct *plstr, int *ix1, int *ix2, int *iy1,
00263                       int *iy2) {
00264     int i;
00265 
00266     /* Get the minmax of the positions of the pixels in a plstruct.  Take
00267        1 away from each position so that it runs from 0 rather than 1 */
00268 
00269     *ix1 = plstr[0].x - 1;
00270     *ix2 = plstr[0].x - 1;
00271     *iy1 = plstr[0].y - 1;
00272     *iy2 = plstr[0].y - 1; 
00273     for (i = 1; i < np; i++) {
00274         *ix1 = MIN(*ix1,plstr[i].x - 1);
00275         *ix2 = MAX(*ix2,plstr[i].x - 1);
00276         *iy1 = MIN(*iy1,plstr[i].y - 1);
00277         *iy2 = MAX(*iy2,plstr[i].y - 1);
00278     }
00279 }
00280 
00283 /*
00284 
00285 $Log: apclust.c,v $
00286 Revision 1.2  2010/09/09 12:09:57  jim
00287 Added docs
00288 
00289 Revision 1.1  2005/09/13 13:25:26  jim
00290 Initial entry after modifications to make cpl compliant
00291 
00292 
00293 */

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1