VIRCAM Pipeline  1.3.3
apclust.c
1 /* $Id: apclust.c,v 1.2 2010-09-09 12:09:57 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jim $
23  * $Date: 2010-09-09 12:09:57 $
24  * $Revision: 1.2 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #include <stdio.h>
29 #include <cpl.h>
30 
31 #include "imcore.h"
32 #include "util.h"
33 
34 static void minmax_xy(int, plstruct *, int *, int *, int *, int *);
35 
38 /*---------------------------------------------------------------------------*/
69 /*---------------------------------------------------------------------------*/
70 
71 void apclust(ap_t *ap, int np, plstruct *plstr) {
72 
73  int i,i1,loop,ik;
74  int is; /* parent name for image in this slice */
75  int ip; /* parent name for image on last line */
76  int ib; /* data block name */
77  int k,j,ix1,ix2,iy1,iy2,nwork,nx,ny,kk;
78  float i2compare,icompare;
79  short int *work;
80 
81  /* A couple of useful things */
82 
83  i2compare = ap->thresh;
84  icompare = i2compare * ap->multiply;
85 
86  /* Get the min and max positions. Create a raster with the IDs of the
87  pixels in the pixel list (algorithm prefers data to be in a raster) */
88 
89  minmax_xy(np,plstr,&ix1,&ix2,&iy1,&iy2);
90  nx = ix2 - ix1 + 1;
91  ny = iy2 - iy1 + 1;
92  nwork = nx*ny;
93  work = cpl_malloc(nwork*sizeof(*work));
94  for (i = 0; i < nwork; i++)
95  work[i] = -1;
96  for (k = 0; k < np; k++) {
97  i = plstr[k].x - 1;
98  j = plstr[k].y - 1;
99  kk = (j - iy1)*nx + i - ix1;
100  work[kk] = k;
101  }
102 
103  /* Now do the job */
104 
105  for (j = iy1; j <= iy2; j++) {
106  for (i = ix1; i <= ix2; i++) {
107  kk = (j - iy1)*nx + i - ix1;
108  k = work[kk];
109  if (k < 0) {
110  ap->lastline[i + 1] = 0;
111  } else {
112  if (plstr[k].zsm > icompare) {
113 
114  /* Pixel is above threshold, find which parent it belongs to. */
115 
116  is = ap->lastline[i]; /* Parent last pixel this line */
117  ip = ap->lastline[i + 1]; /* Guess belongs to above line */
118  if (ip == 0) {
119 
120  /* New parent, or, horizontal slice: */
121 
122  if (is == 0) {
123 
124  /* Ah - new parent. */
125 
126  if (ap->ipstack > ap->maxpa*3/4) {
127  for (ik = 0; ik < ap->maxpa*3/8; ik++)
128  apfu(ap);
129  }
130  ip = ap->pstack[ap->ipstack++];
131  ap->parent[ip].first = ap->bstack[ap->ibstack];
132  ap->parent[ip].pnop = 0;
133  ap->parent[ip].pnbp = 0;
134  ap->parent[ip].growing = 0;
135  if (j == 0)
136 
137  /* It touches first line: */
138 
139  ap->parent[ip].touch = 1;
140  else
141  ap->parent[ip].touch = 0;
142 
143  /* For hunt thru list for terminates: */
144 
145  if (ip > ap->maxip)
146  ap->maxip = ip;
147  } else {
148 
149  /* Slice with no vertical join: */
150 
151  ip = is;
152  }
153  } else if ((ip > 0 && is > 0) && (ip != is)) {
154 
155  /* merge: Join linked lists: */
156 
157  ap->blink[ap->parent[ip].last] = ap->parent[is].first;
158 
159  /* Copy `last block': */
160 
161  ap->parent[ip].last = ap->parent[is].last;
162  ap->parent[ip].pnop += ap->parent[is].pnop;
163  ap->parent[ip].pnbp += ap->parent[is].pnbp;
164 
165  /* Fix `lastline' correlator array: */
166 
167  ib = ap->parent[is].first;
168  loop = 1;
169  while (loop) {
170  i1 = ap->plessey[ib].x;
171  if (ap->lastline[i1 + 1] == is)
172  ap->lastline[i1 + 1] = ip;
173  if (ap->parent[is].last == ib)
174  loop = 0;
175  else
176  ib = ap->blink[ib];
177  }
178 
179  /* Mark parent inactive: */
180 
181  ap->parent[is].pnop = -1;
182  ap->parent[is].pnbp = -1;
183 
184  /* return name to stack: */
185 
186  ap->pstack[--ap->ipstack] = is;
187  }
188 
189  /* Add in pixel to linked list: */
190 
191  ib = ap->bstack[ap->ibstack++];
192 
193  /* Patch forward link into last data block: */
194 
195  if (ap->parent[ip].pnop > 0)
196  ap->blink[ap->parent[ip].last] = ib;
197 
198  /* Remember last block in chain: */
199 
200  ap->parent[ip].last = ib;
201 
202  /* Store the data: */
203 
204  ap->plessey[ib].x = i;
205  ap->plessey[ib].y = j;
206  ap->plessey[ib].z = plstr[k].z;
207  ap->plessey[ib].zsm = plstr[k].zsm;
208 
209  /* increment active count: */
210 
211  ap->parent[ip].pnop++;
212 
213  /* remember which parent this pixel was for next line: */
214 
215  ap->lastline[i + 1] = ip;
216 
217  } else {
218 
219  /* Pixel was below threshold, mark lastline: */
220 
221  ap->lastline[i + 1] = 0;
222  }
223  }
224  }
225  }
226 
227  /* Check for images touching left & right edges:
228  OR the touch flag with 2 for left, 4 for right: */
229 
230  if(ap->lastline[1] > 0 )
231  ap->parent[ap->lastline[1]].touch |= 2;
232  if(ap->lastline[ap->lsiz] > 0)
233  ap->parent[ap->lastline[ap->lsiz]].touch |= 4;
234  cpl_free(work);
235 }
236 
237 /*---------------------------------------------------------------------------*/
260 /*---------------------------------------------------------------------------*/
261 
262 static void minmax_xy(int np, plstruct *plstr, int *ix1, int *ix2, int *iy1,
263  int *iy2) {
264  int i;
265 
266  /* Get the minmax of the positions of the pixels in a plstruct. Take
267  1 away from each position so that it runs from 0 rather than 1 */
268 
269  *ix1 = plstr[0].x - 1;
270  *ix2 = plstr[0].x - 1;
271  *iy1 = plstr[0].y - 1;
272  *iy2 = plstr[0].y - 1;
273  for (i = 1; i < np; i++) {
274  *ix1 = MIN(*ix1,plstr[i].x - 1);
275  *ix2 = MAX(*ix2,plstr[i].x - 1);
276  *iy1 = MIN(*iy1,plstr[i].y - 1);
277  *iy2 = MAX(*iy2,plstr[i].y - 1);
278  }
279 }
280 
283 /*
284 
285 $Log: not supported by cvs2svn $
286 Revision 1.1 2005/09/13 13:25:26 jim
287 Initial entry after modifications to make cpl compliant
288 
289 
290 */