public software.sextractor

[/] [branches/] [multi/] [src/] [analyse.c] - Blame information for rev 285

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 233 bertin
/*
2
*                               analyse.c
3 2 bertin
*
4 233 bertin
* Do measurements on detections.
5 2 bertin
*
6 233 bertin
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 2 bertin
*
8 233 bertin
*       This file part of:      SExtractor
9 2 bertin
*
10 278 bertin
*       Copyright:              (C) 1993-2012 Emmanuel Bertin -- IAP/CNRS/UPMC
11 2 bertin
*
12 233 bertin
*       License:                GNU General Public License
13
*
14
*       SExtractor is free software: you can redistribute it and/or modify
15
*       it under the terms of the GNU General Public License as published by
16
*       the Free Software Foundation, either version 3 of the License, or
17
*       (at your option) any later version.
18
*       SExtractor is distributed in the hope that it will be useful,
19
*       but WITHOUT ANY WARRANTY; without even the implied warranty of
20
*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
*       GNU General Public License for more details.
22
*       You should have received a copy of the GNU General Public License
23
*       along with SExtractor. If not, see <http://www.gnu.org/licenses/>.
24
*
25 285 bertin
*       Last modified:          06/05/2012
26 233 bertin
*
27
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
28 2 bertin
 
29
#ifdef HAVE_CONFIG_H
30
#include        "config.h"
31
#endif
32
 
33
#include        <math.h>
34
#include        <stdio.h>
35
#include        <stdlib.h>
36
#include        <string.h>
37
 
38
#include        "define.h"
39
#include        "globals.h"
40
#include        "prefs.h"
41
#include        "fits/fitscat.h"
42 252 bertin
#include        "analyse.h"
43 2 bertin
#include        "back.h"
44 252 bertin
#include        "catout.h"
45 267 bertin
#include        "clean.h"
46 2 bertin
#include        "check.h"
47
#include        "assoc.h"
48
#include        "astrom.h"
49
#include        "plist.h"
50
#include        "flag.h"
51 274 bertin
#include        "graph.h"
52 2 bertin
#include        "growth.h"
53
#include        "image.h"
54 274 bertin
#include        "misc.h"
55 283 bertin
#include        "neurro.h"
56 2 bertin
#include        "photom.h"
57
#include        "psf.h"
58 173 bertin
#include        "profit.h"
59 2 bertin
#include        "retina.h"
60 6 bertin
#include        "som.h"
61 283 bertin
#include        "subimage.h"
62 210 bertin
#include        "weight.h"
63 2 bertin
#include        "winpos.h"
64
 
65 252 bertin
/****** analyse_iso *********************************************************
66 278 bertin
PROTO   void analyse_iso(fieldstruct **fields, fieldstruct **wfields,
67
                        int nfield, objliststruct *objlist, int n)
68
PURPOSE Do (isophotal) measurements on pixel lists.
69
INPUT   Pointer to an array of image field pointers,
70
        pointer to an array of weight-map field pointers,
71
        number of images,
72 252 bertin
        pointer to the objlist,
73
        object index in the objlist.
74
OUTPUT  -.
75
NOTES   Requires access to the global preferences.
76
AUTHOR  E. Bertin (IAP)
77 282 bertin
VERSION 07/03/2012
78 252 bertin
 ***/
79 278 bertin
void  analyse_iso(fieldstruct **fields, fieldstruct **wfields, int nfield,
80 252 bertin
                        objliststruct *objlist, int n)
81 2 bertin
  {
82 278 bertin
   fieldstruct          *field, *wfield;
83 2 bertin
   checkstruct          *check;
84 252 bertin
   objstruct            *obj;
85
   pliststruct          *pixel, *pixt;
86
   PIXTYPE              threshs[NISO],
87
                        pix, cdpix, tpix, peak,cdpeak, thresh,dthresh,minthresh;
88 2 bertin
   double               tv,sigtv, ngamma,
89
                        esum, emx2,emy2,emxy, err,gain,backnoise2,dbacknoise2,
90 231 bertin
                        xm,ym, x,y,var,var2, threshfac;
91 2 bertin
   float                *heap,*heapt,*heapj,*heapk, swap;
92 252 bertin
   int                  i,j,k,h, photoflag,area,errflag, cleanflag,
93
                        pospeakflag, minarea, gainflag;
94 2 bertin
 
95
 
96 267 bertin
  obj = objlist->obj+n;
97 252 bertin
  pixel = objlist->plist;
98 278 bertin
  field = fields[0];
99 2 bertin
/* Prepare computation of positional error */
100
  esum = emx2 = emy2 = emxy = 0.0;
101 272 bertin
  if ((errflag=FLAG(obj2.poserr_mx2)))
102 2 bertin
    {
103 278 bertin
    dbacknoise2 = field->backsig*field->backsig;
104 2 bertin
    xm = obj->mx;
105
    ym = obj->my;
106
    }
107
  else
108
    xm = ym = dbacknoise2 = 0.0;        /* to avoid gcc -Wall warnings */
109
 
110 272 bertin
  pospeakflag = FLAG(obj2.peakx);
111 173 bertin
  gain = field->gain;
112 2 bertin
  ngamma = field->ngamma;
113 282 bertin
  photoflag = (field->detector_type==DETECTOR_PHOTO);
114 2 bertin
  gainflag = PLISTEXIST(var) && prefs.weightgain_flag;
115
 
116
  h = minarea = prefs.ext_minarea;
117
 
118
/* Prepare selection of the heap selection for CLEANing */
119
  if ((cleanflag = prefs.clean_flag))
120
    {
121
    if (obj->fdnpix < minarea)
122
      {
123
      obj->mthresh = 0.0;
124
      cleanflag = 0;
125
      heapt = heap = NULL;              /* to avoid gcc -Wall warnings */
126
      }
127
    else
128
      {
129
      QMALLOC(heap, float, minarea);
130
      heapt = heap;
131
      }
132
    }
133
  else
134
    {
135
    obj->mthresh = 0.0;
136
    heapt = heap = NULL;                /* to avoid gcc -Wall warnings */
137
    }
138
 
139
 
140
/* Measure essential isophotal parameters in the measurement image... */
141 173 bertin
  tv = sigtv = 0.0;
142 2 bertin
  var = backnoise2 = field->backsig*field->backsig;
143
  peak = -BIG;
144
  cdpeak = -BIG;
145
  thresh = field->thresh;
146 231 bertin
  minthresh = (PLISTEXIST(var))? BIG : thresh;
147
  threshfac = field->backsig > 0.0 ? field->thresh / field->backsig : 1.0;
148 278 bertin
dthresh = field->dthresh;
149 2 bertin
  area = 0;
150
  for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
151
    {
152
    pix = PLIST(pixt,value);
153
    if (pix>peak)
154
      peak = pix;
155
 
156 278 bertin
    cdpix=PLISTPIX(pixt,cvalue);
157 2 bertin
    if (pospeakflag && cdpix>cdpeak)
158
      {
159
      cdpeak=cdpix;
160 281 bertin
      obj->dpeakx =  PLIST(pixt,x) + 1;
161
      obj->dpeaky =  PLIST(pixt,y) + 1;
162 2 bertin
      }
163
    if (PLISTEXIST(var))
164 231 bertin
      {
165 2 bertin
      var = PLISTPIX(pixt, var);
166 231 bertin
      thresh = threshfac*sqrt(var);
167
      if (thresh < minthresh)
168
        minthresh = thresh;
169
      }
170
 
171 2 bertin
    if (photoflag)
172
      {
173
      pix = exp(pix/ngamma);
174
      var2 = pix*pix*var;
175
      }
176
    else
177
      var2 = var;
178
 
179
    if (gainflag && pix>0.0 && gain>0.0)
180
      var2 += pix/gain*var/backnoise2;
181
 
182
    sigtv += var2;
183
    if (pix>thresh)
184
      area++;
185
    tv += pix;
186
    if (errflag)
187
      {
188
      err = dbacknoise2;
189
      if (gain>0.0 && cdpix>0.0)
190
        err += cdpix/gain;
191
      x = PLIST(pixt,x) - xm;
192
      y = PLIST(pixt,y) - ym;
193
      esum += err;
194
      emx2 += err*x*x;
195
      emy2 += err*y*y;
196
      emxy += err*x*y;
197
      }
198
 
199
/*-- Find the minareath pixel in decreasing intensity for CLEANing */
200
    if (cleanflag)
201
      {
202 278 bertin
      tpix = PLISTPIX(pixt, cvalue) - (PLISTEXIST(dthresh)?
203 2 bertin
                PLISTPIX(pixt, dthresh):dthresh);
204
      if (h>0)
205
        *(heapt++) = (float)tpix;
206
      else if (h)
207
        {
208
        if ((float)tpix>*heap)
209
          {
210
          *heap = (float)tpix;
211
          for (j=0; (k=(j+1)<<1)<=minarea; j=k)
212
            {
213
            heapk = heap+k;
214
            heapj = heap+j;
215
            if (k != minarea && *(heapk-1) > *heapk)
216
              {
217
              heapk++;
218
              k++;
219
              }
220
            if (*heapj <= *(--heapk))
221
              break;
222
            swap = *heapk;
223
            *heapk = *heapj;
224
            *heapj = swap;
225
            }
226
          }
227
        }
228
      else
229 233 bertin
        fqmedian(heap, minarea);
230 2 bertin
      h--;
231
      }
232
    }
233
 
234
/* Flagging from the flag-map */
235
  if (PLISTEXIST(flag))
236 282 bertin
    flag_get(obj, pixel);
237 2 bertin
 
238 210 bertin
/* Flag and count pixels with a low weight */
239
  if (PLISTEXIST(wflag))
240
    weight_count(obj, pixel);
241
 
242 2 bertin
  if (cleanflag)
243
    {
244
    obj->mthresh = *heap;
245
    free(heap);
246
    }
247
 
248
  if (errflag)
249
    {
250
     double     flux2;
251
 
252
    flux2 = obj->fdflux*obj->fdflux;
253
/*-- Estimation of the error ellipse moments: we re-use previous variables */
254
    emx2 /= flux2;      /* variance of xm */
255
    emy2 /= flux2;      /* variance of ym */
256
    emxy /= flux2;      /* covariance */
257
 
258
/*-- Handle fully correlated profiles (which cause a singularity...) */
259
    esum *= 0.08333/flux2;
260
    if (obj->singuflag && (emx2*emy2-emxy*emxy) < esum*esum)
261
      {
262
      emx2 += esum;
263
      emy2 += esum;
264
      }
265
 
266
    obj->poserr_mx2 = emx2;
267
    obj->poserr_my2 = emy2;
268
    obj->poserr_mxy = emxy;
269
    }
270
 
271
  if (photoflag)
272
    {
273
    tv = ngamma*(tv-obj->fdnpix*exp(obj->dbkg/ngamma));
274
    sigtv /= ngamma*ngamma;
275
    }
276
  else
277
    {
278
    tv -= obj->fdnpix*obj->dbkg;
279
    if (!gainflag && gain > 0.0 && tv>0.0)
280
      sigtv += tv/gain;
281
    }
282
 
283
  obj->npix = area;
284 281 bertin
  obj->dflux = tv;
285
  obj->dfluxerr = sigtv;
286
  obj->dpeak = peak;
287 231 bertin
  obj->thresh = minthresh - obj->dbkg;
288 281 bertin
  obj->dpeak -= obj->dbkg;
289 2 bertin
 
290
/* Initialize isophotal thresholds so as to sample optimally the full profile*/
291
 
292 272 bertin
  if (FLAG(obj2.iso[0]))
293 2 bertin
    {
294
     int        *iso;
295
     PIXTYPE    *thresht;
296
 
297
    memset(obj->iso, 0, NISO*sizeof(int));
298 282 bertin
    if (field->detector_type == DETECTOR_PHOTO)
299 2 bertin
      for (i=0; i<NISO; i++)
300 281 bertin
        threshs[i] = obj->thresh + (obj->dpeak-obj->thresh)*i/NISO;
301 2 bertin
    else
302
      {
303 281 bertin
      if (obj->dpeak>0.0 && obj->thresh>0.0)
304 2 bertin
        for (i=0; i<NISO; i++)
305 281 bertin
          threshs[i] = obj->thresh*pow(obj->dpeak/obj->thresh, (double)i/NISO);
306 2 bertin
      else
307
        for (i=0; i<NISO; i++)
308
          threshs[i] = 0.0;
309
      }
310
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
311
      for (i=NISO,iso=obj->iso,thresht=threshs;
312
                i-- && PLIST(pixt,value)>*(thresht++);)
313
        (*(iso++))++;
314
    }
315
 
316
/* Put objects in "segmentation check-image" */
317
 
318
  if ((check = prefs.check[CHECK_SEGMENTATION]))
319
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
320
      ((ULONG *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
321
                = (ULONG)obj->number;
322
 
323
  if ((check = prefs.check[CHECK_OBJECTS]))
324
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
325
      ((PIXTYPE *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
326
                = PLIST(pixt,value);
327
 
328
/* Compute the FWHM of the object */
329 272 bertin
  if (FLAG(obj2.fwhm))
330 2 bertin
    {
331
     PIXTYPE    thresh0;
332
 
333 281 bertin
    thresh0 = obj->dpeak/5.0;
334 2 bertin
    if (thresh0<obj->thresh)
335
      thresh0 = obj->thresh;
336
    if (thresh0>0.0)
337
      {
338
       double   mx,my, s,sx,sy,sxx,sxy, dx,dy,d2, lpix,pix, b, inverr2, sat,
339
                dbkg, d, bmax;
340
 
341
      mx = obj->mx;
342
      my = obj->my;
343
      dbkg = obj->dbkg;
344 173 bertin
      sat = (double)(field->satur_level - obj->bkg);
345 2 bertin
      s = sx = sy = sxx = sxy = 0.0;
346
      for (pixt=pixel+obj->firstpix;pixt>=pixel;pixt=pixel+PLIST(pixt,nextpix))
347
        {
348
        pix = PLIST(pixt,value)-dbkg;
349
        if (pix>thresh0 && pix<sat)
350
          {
351
          dx = PLIST(pixt,x) - mx;
352
          dy = PLIST(pixt,y) - my;
353
          lpix = log(pix);
354
          inverr2 = pix*pix;
355
          s += inverr2;
356
          d2 = dx*dx+dy*dy;
357
          sx += d2*inverr2;
358
          sxx += d2*d2*inverr2;
359
          sy += lpix*inverr2;
360
          sxy += lpix*d2*inverr2;
361
          }
362
        }
363
      d = s*sxx-sx*sx;
364
      if (fabs(d)>0.0)
365
        {
366
        b = -(s*sxy-sx*sy)/d;
367
        if (b<(bmax = 1/(13*obj->a*obj->b)))    /* to have FWHM # 6 sigma */
368
          b = bmax;
369
        obj->fwhm = (float)(1.6651/sqrt(b));
370
/*----- correction for undersampling effects (established from simulations) */
371
        if (obj->fwhm>0.0)
372
          obj->fwhm -= 1/(4*obj->fwhm);
373
        }
374
      else
375
        obj->fwhm = 0.0;
376
      }
377
    else
378
      obj->fwhm = 0.0;
379
    }
380
 
381
  return;
382
  }
383
 
384
 
385 267 bertin
/****** analyse_final *******************************************************
386 278 bertin
PROTO   void analyse_final(fieldstruct **fields, fieldstruct **wfields,
387
                        int nfield, objliststruct *objlist, int iobj)
388 267 bertin
PURPOSE Do the final analysis based on a list of detections and a detection
389
        index.
390 278 bertin
INPUT   Pointer to an array of image field pointers,
391
        pointer to an array of weight-map field pointers,
392
        number of images,
393 267 bertin
        objlist pointer,
394
        obj index.
395 253 bertin
OUTPUT  -.
396 267 bertin
NOTES   Global preferences are used.
397 253 bertin
AUTHOR  E. Bertin (IAP)
398 283 bertin
VERSION 29/03/2012
399 253 bertin
 ***/
400 278 bertin
void analyse_final(fieldstruct **fields, fieldstruct **wfields,
401
                        int nfield, objliststruct *objlist, int iobj)
402 253 bertin
  {
403 278 bertin
   fieldstruct          *field;
404 267 bertin
   obj2liststruct       *obj2list;
405
   objstruct            *obj;
406
   obj2struct           *obj2, *prevobj2, *firstobj2;
407 268 bertin
   int                  i, ymax, nextiobj, noverlap, iobj2;
408 253 bertin
 
409 267 bertin
  obj2list = thecat.obj2list;
410
 
411 278 bertin
/* field is the detection field */
412
  field = fields[0];
413 267 bertin
/* Find overlapping detections and link them */
414 268 bertin
  noverlap = analyse_overlapness(cleanobjlist, iobj);
415 267 bertin
/* Convert every linked detection to a linked obj2 */
416
  prevobj2 = NULL;
417
  for (i=noverlap; i--;)
418
    {
419
    obj = &objlist->obj[iobj];
420
/*-- Warn if there is a possibility for any aperture to be truncated */
421 278 bertin
    if ((ymax=obj->ycmax) > field->ymax)
422 267 bertin
      {
423
      sprintf(gstr, "Object at position %.0f,%.0f ", obj->mx+1, obj->my+1);
424
      QWARNING(gstr, "may have some apertures truncated:\n"
425
                "          You might want to increase MEMORY_BUFSIZE");
426
      }
427 278 bertin
    else if (ymax>field->yblank && prefs.blank_flag)
428 267 bertin
      {
429
      sprintf(gstr, "Object at position %.0f,%.0f ", obj->mx+1, obj->my+1);
430
      QWARNING(gstr, "may have some unBLANKed neighbours:\n"
431
                "          You might want to increase MEMORY_PIXSTACK");
432
      }
433 278 bertin
    obj2 = analyse_obj2obj2(fields, wfields, nfield, obj, obj2list);
434 267 bertin
    if (!obj2)
435
      error(EXIT_FAILURE, "*Error*: ", "obj2 stack full");
436
    obj2->nextobj2 = NULL;
437
    if (prevobj2)
438
      {
439
      prevobj2->nextobj2 = obj2;
440
      obj2->prevobj2 = prevobj2;
441
      }
442
    else
443
      {
444
      obj2->prevobj2 = NULL;
445
      firstobj2 = obj2;
446
      }
447
    prevobj2 = obj2;
448
    nextiobj = obj->next;
449 277 bertin
/*-- Take care of next obj that might be swapped by clean_sub! */
450 268 bertin
    if (nextiobj == objlist->nobj-1)
451
      nextiobj = iobj;
452 277 bertin
    clean_sub(iobj);
453 267 bertin
    iobj = nextiobj;
454
    }
455
 
456
/* Analyse the group of obj2s and write out catalogue */
457 278 bertin
  analyse_group(fields, wfields, nfield, firstobj2);
458 267 bertin
 
459
/* Free the group of obj2s */
460 268 bertin
  for (obj2=firstobj2; obj2; obj2=obj2->nextobj2)
461 283 bertin
    subimage_endall(obj2);
462 268 bertin
 
463 267 bertin
  for (obj2=firstobj2; obj2->nextobj2; obj2=obj2->nextobj2);
464
  obj2->nextobj2 = obj2list->freeobj2;
465
  obj2list->freeobj2->prevobj2 = obj2->nextobj2;
466
  obj2list->freeobj2 = firstobj2;
467
 
468
  return;
469
  }
470
 
471
 
472 282 bertin
/****** analyse_overlapness ***************************************************
473 268 bertin
PROTO   obj2struct analyse_overlapness(objliststruct *objlist, int iobj)
474 267 bertin
PURPOSE Link together overlapping detections.
475
INPUT   objliststruct pointer,
476 268 bertin
        obj index.
477 267 bertin
OUTPUT  -.
478
NOTES   -.
479
AUTHOR  E. Bertin (IAP)
480 268 bertin
VERSION 07/10/2011
481 267 bertin
 ***/
482 268 bertin
int analyse_overlapness(objliststruct *objlist, int iobj)
483 267 bertin
  {
484 268 bertin
   objstruct    *obj,*cobj,*fobj;
485 267 bertin
   int          i, blend, nblend,nobj;
486
 
487
  nblend = 1;
488 253 bertin
  nobj = objlist->nobj;
489 268 bertin
  obj = objlist->obj;
490
  fobj = &obj[iobj];
491
  fobj->prev = -1;
492 267 bertin
  blend = fobj->blend;
493
  cobj = fobj;
494
  for (i=0; i<nobj; i++, obj++)
495
    if (obj->blend == blend && obj!=fobj)
496
      {
497
      cobj->next = i;
498 268 bertin
      obj->prev = iobj;
499 267 bertin
      cobj = obj;
500 268 bertin
      iobj = i;
501 267 bertin
      nblend++;
502
      }
503 253 bertin
 
504 267 bertin
  cobj->next = -1;
505
 
506
  return nblend;
507 253 bertin
  }
508
 
509 267 bertin
 
510 253 bertin
/****** analyse_obj2obj2 ******************************************************
511 278 bertin
PROTO   obj2struct *analyse_obj2obj2(fieldstruct **fields,
512
                        fieldstruct **wfields, int nfield,
513
                        objstruct *obj, obj2liststruct *obj2list)
514 253 bertin
PURPOSE Move object data from obj to obj2 structure.
515 278 bertin
INPUT   Pointer to an array of image field pointers,
516
        pointer to an array of weight-map field pointers,
517
        number of images,
518 267 bertin
        obj pointer,
519 260 bertin
        obj2list pointer,
520 267 bertin
OUTPUT  New obj2 pointer.
521 253 bertin
NOTES   -.
522
AUTHOR  E. Bertin (IAP)
523 283 bertin
VERSION 29/03/2012
524 253 bertin
 ***/
525 278 bertin
obj2struct      *analyse_obj2obj2(fieldstruct **fields, fieldstruct **wfields,
526
                        int nfield, objstruct *obj, obj2liststruct *obj2list)
527 253 bertin
  {
528 283 bertin
   fieldstruct          *field;
529
   subimagestruct       *subimage;
530
   obj2struct           *obj2;
531
   float                sigbkg;
532
   int                  f, idx,idy;
533 260 bertin
 
534 267 bertin
  obj2 = obj2list->freeobj2;
535
  if (obj2->nextobj2)
536
    {
537
    obj2list->freeobj2 = obj2->nextobj2;
538
    obj2->nextobj2 = obj2->prevobj2 = NULL;
539
    }
540
  else
541
    return NULL;
542 253 bertin
 
543 278 bertin
/*-- Local backgrounds */
544 282 bertin
  for (f=0; f<nfield; f++)
545 278 bertin
    {
546 283 bertin
    field = fields[f];
547 281 bertin
    if (FLAG(obj2.bkg))
548 283 bertin
      obj2->bkg[f] = (float)back_interpolate(field, obj->mx, obj->my);
549 282 bertin
    obj2->dbkg[f] = 0.0;
550 278 bertin
    if (prefs.pback_type == LOCAL)
551
      {
552 283 bertin
      obj2->dbkg[f] = back_local(field, obj, &sigbkg);
553 281 bertin
      if (FLAG(obj2.bkg))
554 282 bertin
        obj2->bkg[f] += obj2->dbkg[f];
555 283 bertin
      obj2->sigbkg[f] = sigbkg<0.0? field->backsig : sigbkg;
556 278 bertin
      }
557
    else
558 283 bertin
      obj2->sigbkg[f] = field->backsig;
559 282 bertin
    if (FLAG(obj2.wflag))
560
      obj2->wflag[f] = obj->wflag;
561 278 bertin
    }
562 283 bertin
 
563 260 bertin
/* Copy main data */
564
  obj2->number = obj->number;
565
  obj2->fdnpix = obj->fdnpix;
566
  obj2->dnpix = obj->dnpix;
567
  obj2->npix = obj->npix;
568
  obj2->nzdwpix = obj->nzdwpix;
569
  obj2->nzwpix = obj->nzwpix;
570
  obj2->dflux = obj->dflux;
571 281 bertin
  obj2->dfluxerr = obj->dfluxerr;
572 260 bertin
  obj2->fdpeak = obj->fdpeak;
573 281 bertin
  obj2->peak = obj->dpeak;
574
  obj2->peakx = obj->dpeakx;
575
  obj2->peaky = obj->dpeaky;
576 260 bertin
  obj2->mx = obj->mx;
577
  obj2->my = obj->my;
578 267 bertin
/* Integer coordinates */
579 273 bertin
  obj2->ix=(int)(obj2->mx+0.49999);             /* Integer coordinates */
580 267 bertin
  obj2->iy=(int)(obj2->my+0.49999);
581 278 bertin
  obj2->posx[0] = obj2->mx+1.0;                  /* That's standard FITS */
582
  obj2->posy[0] = obj2->my+1.0;
583 260 bertin
  obj2->poserr_mx2 = obj->poserr_mx2;
584
  obj2->poserr_my2 = obj->poserr_my2;
585
  obj2->poserr_mxy = obj->poserr_mxy;
586
  obj2->xmin = obj->xmin;
587
  obj2->xmax = obj->xmax;
588
  obj2->ymin = obj->ymin;
589
  obj2->ymax = obj->ymax;
590 282 bertin
  obj2->flags = obj->flag;
591 260 bertin
  obj2->singuflag = obj->singuflag;
592 282 bertin
  if (FLAG(obj2.imaflags))
593
    {
594
    memcpy(obj2->imaflags, obj->imaflags, prefs.nfimage*sizeof(FLAGTYPE));
595
    memcpy(obj2->imanflags, obj->imanflags, prefs.nfimage*sizeof(int));
596
    }
597 260 bertin
  obj2->mx2 = obj->mx2;
598
  obj2->my2 = obj->my2;
599
  obj2->mxy = obj->mxy;
600
  obj2->a = obj->a;
601
  obj2->b = obj->b;
602
  obj2->theta = obj->theta;
603
  obj2->abcor = obj->abcor;
604
  obj2->cxx = obj->cxx;
605
  obj2->cyy = obj->cyy;
606
  obj2->cxy = obj->cxy;
607
  obj2->thresh = obj->thresh;
608
  obj2->dthresh = obj->dthresh;
609
  obj2->mthresh = obj->mthresh;
610 267 bertin
  memcpy(obj2->iso, obj->iso, NISO*sizeof(int));
611 260 bertin
  obj2->fwhm = obj->fwhm;
612
 
613 253 bertin
/* Copy image data around current object */
614 283 bertin
  subimage_getall(fields, wfields, nfield, obj2);
615 282 bertin
 
616 253 bertin
/* if BLANKing is on, paste back the object pixels in the image*/
617 282 bertin
  if (prefs.blank_flag && obj->blank)
618 253 bertin
    {
619 283 bertin
    subimage = obj2->subimage;
620 282 bertin
    deblankimage(obj->blank, obj->subw, obj->subh,
621 283 bertin
                subimage->image, subimage->imsize[0],subimage->imsize[1],
622 285 bertin
                obj->subx - subimage->immin[0], obj->suby - subimage->immin[1]);
623 282 bertin
    free(obj->blank);
624
    }
625
 
626
  return obj2;
627
  }
628
 
629
 
630
/****** analyse_group ********************************************************
631
PROTO   void analyse_group(fieldstruct **fields, fieldstruct **wfields,
632
                        int nfield, obj2struct *fobj2)
633
PURPOSE Perform measurements on a group of detections.
634
INPUT   Pointer to an array of image field pointers,
635
        pointer to an array of weight-map field pointers,
636
        number of images,
637
        obj2struct pointer.
638
OUTPUT  -.
639
NOTES   -.
640
AUTHOR  E. Bertin (IAP)
641 285 bertin
VERSION 06/05/2012
642 282 bertin
 ***/
643
void    analyse_group(fieldstruct **fields, fieldstruct **wfields,
644
                        int nfield, obj2struct *fobj2)
645
  {
646 285 bertin
   fieldstruct          *field, *wfield;
647
   subprofitstruct      *subprofit,*modsubprofit;
648
   subimagestruct       *subimage;
649
   obj2struct           *obj2, *modobj2;
650
   int                  i,s;
651 282 bertin
 
652
/* field is the detection field */
653
  field = fields[0];
654
  wfield = wfields? wfields[0]:NULL;
655
 
656
  if (prefs.prof_flag)
657
    {
658
/*-- Setup model fitting for this group */
659
    for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
660 253 bertin
      {
661 282 bertin
      photom_auto(fields, wfields, nfield, obj2);
662
      growth_aver(fields, wfields, nfield, obj2);
663 285 bertin
      obj2->profit = profit_init(obj2, prefs.prof_modelflags);
664 253 bertin
      }
665 282 bertin
    if (fobj2->nextobj2)
666
      {
667
/*---- Iterative multiple fit if several sources overlap */
668
      for (i=0; i<ANALYSE_NMULTITER; i++)
669
        {
670
        for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
671
          profit_fit(obj2->profit, obj2);
672
        for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
673
          {
674
          if (i)
675 285 bertin
            {
676
            subprofit = obj2->profit->subprofit;
677
            subimage = obj2->subimage;
678
            for (s=nfield; s--;)
679
              subprofit_copyobjpix(subprofit++, subimage++);
680
            }
681 282 bertin
          for (modobj2=fobj2; modobj2; modobj2=modobj2->nextobj2)
682
            if (modobj2 != obj2)
683 285 bertin
              {
684
              subprofit = obj2->profit->subprofit;
685
              modsubprofit = modobj2->profit->subprofit;
686
              for (s=nfield; s--;)
687
                subprofit_submodpix(subprofit++, modsubprofit++, 0.9);
688
              }
689 282 bertin
          }
690
        }
691
/*
692
      for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
693
        for (modobj2=fobj2; modobj2; modobj2=modobj2->nextobj2)
694
          if (modobj2 != obj2)
695
            addtobig(modobj2->profit->lmodpix,
696
                modobj2->profit->objnaxisn[0],modobj2->profit->objnaxisn[1],
697
                obj2->image, obj2->imsize[0], obj2->imsize[1],
698
                modobj2->profit->ix-obj2->ix, modobj2->profit->iy-obj2->iy,
699
                -1.0);
700
*/
701
      }
702
    else
703
/*---- One single source */
704
      profit_fit(fobj2->profit, fobj2);
705 253 bertin
    }
706
 
707 282 bertin
/* Full source analysis and catalogue output */
708
  for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
709
    if (analyse_full(fields, wfields, nfield, obj2) == RETURN_OK)
710
      {
711
/*---- Catalogue output */
712
      FPRINTF(OUTPUT, "%8d %6.1f %6.1f %5.1f %5.1f %12g "
713
                        "%c%c%c%c%c%c%c%c\n",
714
        obj2->number, obj2->mx+1.0, obj2->my+1.0,
715
        obj2->a, obj2->b,
716
        obj2->dflux,
717
        obj2->flags&OBJ_CROWDED?'C':'_',
718
        obj2->flags&OBJ_MERGED?'M':'_',
719
        obj2->flags&OBJ_SATUR?'S':'_',
720
        obj2->flags&OBJ_TRUNC?'T':'_',
721
        obj2->flags&OBJ_APERT_PB?'A':'_',
722
        obj2->flags&OBJ_ISO_PB?'I':'_',
723
        obj2->flags&OBJ_DOVERFLOW?'D':'_',
724
        obj2->flags&OBJ_OVERFLOW?'O':'_');
725
      catout_writeobj(obj2);
726
      }
727
 
728
/* Deallocate memory used for model-fitting */
729
  if (prefs.prof_flag)
730
    for (obj2=fobj2; obj2; obj2=obj2->nextobj2)
731
      profit_end(obj2->profit);
732
 
733
  return;
734 253 bertin
  }
735
 
736
 
737 252 bertin
/****** analyse_full *********************************************************
738 278 bertin
PROTO   int analyse_full(fieldstruct **fields, fieldstruct **wfields,
739
                        int nfield, obj2struct *obj2)
740 252 bertin
PURPOSE Final analysis of object data.
741 278 bertin
INPUT   Pointer to an array of image field pointers,
742
        pointer to an array of weight-map field pointers,
743
        number of images,
744 267 bertin
        obj2struct pointer.
745 272 bertin
OUTPUT  RETURN_OK if the object has been processed, RETURN_ERROR otherwise.
746 247 bertin
NOTES   -.
747
AUTHOR  E. Bertin (IAP)
748 285 bertin
VERSION 06/05/2012
749 247 bertin
 ***/
750 278 bertin
int     analyse_full(fieldstruct **fields, fieldstruct **wfields,
751
                        int nfield, obj2struct *obj2)
752 2 bertin
  {
753 278 bertin
fieldstruct *field, *dfield, *dwfield, *wfield;
754 208 bertin
   checkstruct          *check;
755
   double               rawpos[NAXIS],
756
                        analtime1;
757 248 bertin
   int                  i,j, ix,iy, idx,idy, selecflag, newnumber,nsub;
758 2 bertin
 
759 208 bertin
  if (FLAG(obj2.analtime))
760
    analtime1 = counter_seconds();
761 217 bertin
  else
762
    analtime1 = 0.0;            /* To avoid gcc -Wall warnings */
763 208 bertin
 
764 278 bertin
/* field is the detection field */
765
  field = fields[0];
766
 
767
dfield = dwfield = wfield = NULL;
768 238 bertin
   if (prefs.psf_flag)
769
     obj2->psf_flag = 0; /* Reset PSF building flag */
770
   if (prefs.dpsf_flag)
771
     obj2->dpsf_flag = 0;        /* Reset PSF building flag */
772 2 bertin
 
773 267 bertin
/*------------------------------ Association ------------------------------*/
774 2 bertin
  if (prefs.assoc_flag)
775 238 bertin
    {
776 278 bertin
    obj2->assoc_number = do_assoc(field, obj2->posx[0],obj2->posy[0],
777
                        obj2->assoc);
778 272 bertin
    if ((prefs.assocselec_type==ASSOCSELEC_MATCHED && !(obj2->assoc_number))
779
        ||
780
        (prefs.assocselec_type==ASSOCSELEC_NOMATCHED && (obj2->assoc_number)))
781 238 bertin
      {
782
/*---- Treatment of discarded detections */
783
/*---- update segmentation map  and exit */
784
      if ((check=prefs.check[CHECK_SEGMENTATION]))
785
        {
786
         ULONG  *pix;
787 267 bertin
         ULONG  oldsnumber = obj2->number;
788 238 bertin
         int    dx,dx0,dy,dpix;
789 2 bertin
 
790 267 bertin
        pix = (ULONG *)check->pix + check->width*obj2->ymin + obj2->xmin;
791
        dx0 = obj2->xmax-obj2->xmin+1;
792 238 bertin
        dpix = check->width-dx0;
793 267 bertin
        for (dy=obj2->ymax-obj2->ymin+1; dy--; pix += dpix)
794 238 bertin
          for (dx=dx0; dx--; pix++)
795
            if (*pix==oldsnumber)
796
              *pix = 0;
797
        }
798 272 bertin
      return RETURN_ERROR;
799 238 bertin
      }
800
    }
801
 
802 2 bertin
/*------------------------- Error ellipse parameters ------------------------*/
803 238 bertin
  if (FLAG(obj2.poserr_a))
804
    {
805
     double     pmx2,pmy2,temp,theta;
806 2 bertin
 
807 267 bertin
    if (fabs(temp=obj2->poserr_mx2-obj2->poserr_my2) > 0.0)
808
      theta = atan2(2.0 * obj2->poserr_mxy,temp) / 2.0;
809 238 bertin
    else
810
      theta = PI/4.0;
811 2 bertin
 
812 267 bertin
    temp = sqrt(0.25*temp*temp+obj2->poserr_mxy*obj2->poserr_mxy);
813
    pmy2 = pmx2 = 0.5*(obj2->poserr_mx2+obj2->poserr_my2);
814 238 bertin
    pmx2+=temp;
815
    pmy2-=temp;
816 2 bertin
 
817 238 bertin
    obj2->poserr_a = (float)sqrt(pmx2);
818
    obj2->poserr_b = (float)sqrt(pmy2);
819
    obj2->poserr_theta = theta*180.0/PI;
820
    }
821 2 bertin
 
822 238 bertin
  if (FLAG(obj2.poserr_cxx))
823
    {
824
     double     xm2,ym2, xym, temp;
825 2 bertin
 
826 267 bertin
    xm2 = obj2->poserr_mx2;
827
    ym2 = obj2->poserr_my2;
828
    xym = obj2->poserr_mxy;
829 238 bertin
    obj2->poserr_cxx = (float)(ym2/(temp=xm2*ym2-xym*xym));
830
    obj2->poserr_cyy = (float)(xm2/temp);
831
    obj2->poserr_cxy = (float)(-2*xym/temp);
832
    }
833 2 bertin
 
834 238 bertin
/* Aspect ratio */
835
  if (FLAG(obj2.elong))
836 267 bertin
    obj2->elong = obj2->a/obj2->b;
837 2 bertin
 
838 238 bertin
  if (FLAG(obj2.ellip))
839 267 bertin
    obj2->ellip = 1-obj2->b/obj2->a;
840 2 bertin
 
841 238 bertin
  if (FLAG(obj2.polar))
842 267 bertin
    obj2->polar = (obj2->a*obj2->a-obj2->b*obj2->b)
843
                / (obj2->a*obj2->a+obj2->b*obj2->b);
844 2 bertin
 
845 238 bertin
/* Express positions in FOCAL or WORLD coordinates */
846 278 bertin
  if (FLAG(obj2.posxf) || FLAG(obj2.posxw))
847
    astrom_pos(fields, nfield, obj2);
848 199 bertin
 
849 238 bertin
  obj2->pixscale2 = 0.0;        /* To avoid gcc -Wall warnings */
850
  if (FLAG(obj2.mx2w)
851 199 bertin
        || FLAG(obj2.win_mx2w)
852
        || FLAG(obj2.poserr_mx2w)
853
        || FLAG(obj2.winposerr_mx2w)
854 218 bertin
        || FLAG(obj2.poserrmx2w_psf)
855 199 bertin
        || FLAG(obj2.poserrmx2w_prof)
856
        || FLAG(obj2.prof_flagw)
857 247 bertin
        || ((!prefs.pixel_scale) && FLAG(obj2.area_flagw))
858
        || ((!prefs.pixel_scale) && FLAG(obj2.fwhmw_psf)))
859 238 bertin
    {
860 278 bertin
    rawpos[0] = obj2->posx[0];
861
    rawpos[1] = obj2->posy[0];
862 238 bertin
    obj2->pixscale2 = wcs_jacobian(field->wcs, rawpos, obj2->jacob);
863
    }
864 199 bertin
 
865 240 bertin
/* Express shape parameters in the FOCAL or WORLD frame */
866
  if (FLAG(obj2.mx2w))
867 267 bertin
    astrom_shapeparam(field, obj2);
868 240 bertin
/* Express position error parameters in the FOCAL or WORLD frame */
869
  if (FLAG(obj2.poserr_mx2w))
870 267 bertin
    astrom_errparam(field, obj2);
871 199 bertin
 
872 240 bertin
  if (FLAG(obj2.npixw))
873 267 bertin
    obj2->npixw = obj2->npix * (prefs.pixel_scale?
874 206 bertin
        field->pixscale/3600.0*field->pixscale/3600.0 : obj2->pixscale2);
875 240 bertin
  if (FLAG(obj2.fdnpixw))
876 267 bertin
    obj2->fdnpixw = obj2->fdnpix * (prefs.pixel_scale?
877 206 bertin
        field->pixscale/3600.0*field->pixscale/3600.0 : obj2->pixscale2);
878 199 bertin
 
879 240 bertin
  if (FLAG(obj2.fwhmw))
880 267 bertin
    obj2->fwhmw = obj2->fwhm * (prefs.pixel_scale?
881 206 bertin
        field->pixscale/3600.0 : sqrt(obj2->pixscale2));
882 199 bertin
 
883 2 bertin
/*------------------------------- Photometry -------------------------------*/
884
 
885 240 bertin
/* Convert the father of photom. error estimates from variance to RMS */
886 281 bertin
  obj2->flux_iso = obj2->dflux;
887
  obj2->fluxerr_iso = sqrt(obj2->dfluxerr);
888 2 bertin
 
889 240 bertin
  if (FLAG(obj2.flux_isocor))
890 267 bertin
    photom_isocor(field, obj2);
891 2 bertin
 
892 240 bertin
  if (FLAG(obj2.flux_aper))
893
    for (i=0; i<prefs.naper; i++)
894 267 bertin
      photom_aper(field, wfield, obj2, i);
895 2 bertin
 
896 285 bertin
  if ((prefs.auto_flag) && !prefs.prof_flag)
897 282 bertin
    photom_auto(fields, wfields, nfield, obj2);
898 268 bertin
 
899 240 bertin
  if (FLAG(obj2.flux_petro))
900 267 bertin
    photom_petro(field, dfield, wfield, dwfield, obj2);
901 2 bertin
 
902 267 bertin
/*------------------------------ Astrometry -------------------------------*/
903 248 bertin
/* Express positions in FOCAL or WORLD coordinates */
904
  if (FLAG(obj2.peakxf) || FLAG(obj2.peakxw))
905 267 bertin
    astrom_peakpos(field, obj2);
906 278 bertin
  if (obj2->peak+obj2->bkg[0] >= field->satur_level)
907 282 bertin
      obj2->flags |= OBJ_SATUR;
908
 
909 267 bertin
/* Estimate of shape */
910 278 bertin
  growth_aver(fields, wfields, nfield, obj2);
911 267 bertin
/* Get a good estimate of position and flux */
912 282 bertin
  if ((prefs.win_flag))
913
    win_pos(fields, wfields, nfield, obj2);
914 267 bertin
/* Express positions in FOCAL or WORLD coordinates */
915
  if (FLAG(obj2.winpos_xf) || FLAG(obj2.winpos_xw))
916 282 bertin
    astrom_winpos(fields, nfield, obj2);
917 267 bertin
/* Express shape parameters in the FOCAL or WORLD frame */
918
  if (FLAG(obj2.win_mx2w))
919 282 bertin
    astrom_winshapeparam(fields, nfield, obj2);
920 267 bertin
/* Express position error parameters in the FOCAL or WORLD frame */
921
  if (FLAG(obj2.winposerr_mx2w))
922 282 bertin
    astrom_winerrparam(fields, nfield, obj2);
923 2 bertin
 
924 248 bertin
/* Check-image CHECK_APERTURES option */
925
  if ((check = prefs.check[CHECK_APERTURES]))
926
    {
927
    if (FLAG(obj2.flux_aper))
928
      for (i=0; i<prefs.naper; i++)
929
        sexcircle(check->pix, check->width, check->height,
930 267 bertin
                obj2->mx, obj2->my, prefs.apert[i]/2.0, check->overlay);
931 2 bertin
 
932 248 bertin
    if (FLAG(obj2.flux_auto))
933 274 bertin
      sexellipse(check->pix, check->width, check->height,
934 282 bertin
                obj2->mx, obj2->my, obj2->a*obj2->auto_kronfactor,
935
                obj2->b*obj2->auto_kronfactor, obj2->theta,
936
                check->overlay, obj2->flags&OBJ_CROWDED);
937 2 bertin
 
938 248 bertin
    if (FLAG(obj2.flux_petro))
939 274 bertin
      sexellipse(check->pix, check->width, check->height,
940 267 bertin
                obj2->mx, obj2->my, obj2->a*obj2->petrofactor,
941
                obj2->b*obj2->petrofactor, obj2->theta,
942 282 bertin
                check->overlay, obj2->flags&OBJ_CROWDED);
943 248 bertin
    }
944 2 bertin
 
945 267 bertin
/*----------------------------- Model fitting -----------------------------*/
946
  if (prefs.prof_flag)
947 248 bertin
    {
948 267 bertin
/*-- Perform measurements on the fitted models */
949
    profit_measure(obj2->profit, obj2);
950
/*-- Express positions in FOCAL or WORLD coordinates */
951
    if (FLAG(obj2.xf_prof) || FLAG(obj2.xw_prof))
952
      astrom_profpos(field, obj2);
953
/*-- Express shape parameters in the FOCAL or WORLD frame */
954
    if (FLAG(obj2.prof_flagw))
955
      astrom_profshapeparam(field, obj2);
956
/*-- Express position error parameters in the FOCAL or WORLD frame */
957
    if (FLAG(obj2.poserrmx2w_prof))
958
      astrom_proferrparam(field, obj2);
959
/*-- PSF- and model-guided star/galaxy separation */
960
    if (FLAG(obj2.prof_class_star) || FLAG(obj2.prof_concentration))
961
      profit_spread(obj2->profit, field, wfield, obj2);
962 248 bertin
    }
963 2 bertin
 
964 267 bertin
/*------------------------------- PSF fitting ------------------------------
965
  nsub = 1;
966
  if (prefs.psffit_flag)
967
      {
968
      if (prefs.dpsffit_flag)
969
        double_psf_fit(ppsf, field, wfield, obj2, thepsf, dfield, dwfield);
970
      else
971
        psf_fit(thepsf, field, wfield, obj2);
972
      obj2->npsf = thepsfit->npsf;
973
      nsub = thepsfit->npsf;
974
      if (nsub<1)
975
        nsub = 1;
976
      }
977 2 bertin
 
978 267 bertin
    for (j=0; j<nsub; j++)
979
      {
980
      if (prefs.psffit_flag)
981
        {
982
        obj2->x_psf = thepsfit->x[j];
983
        obj2->y_psf = thepsfit->y[j];
984
        if (FLAG(obj2.xf_psf) || FLAG(obj2.xw_psf))
985
          astrom_psfpos(field, obj2);
986
*------ Express position error parameters in the FOCAL or WORLD frame *
987
        if (FLAG(obj2.poserrmx2w_psf))
988
          astrom_psferrparam(field, obj2);
989
        if (FLAG(obj2.flux_psf))
990
          obj2->flux_psf = thepsfit->flux[j]>0.0? thepsfit->flux[j]:0.0; *?*
991
        if (FLAG(obj2.mag_psf))
992
          obj2->mag_psf = thepsfit->flux[j]>0.0?
993
                prefs.mag_zeropoint -2.5*log10(thepsfit->flux[j]) : 99.0;
994
        if (FLAG(obj2.fluxerr_psf))
995
          obj2->fluxerr_psf= thepsfit->fluxerr[j];
996
        if (FLAG(obj2.magerr_psf))
997
          obj2->magerr_psf =
998
                (thepsfit->flux[j]>0.0 && thepsfit->fluxerr[j]>0.0) ? *?*
999
                        1.086*thepsfit->fluxerr[j]/thepsfit->flux[j] : 99.0;
1000
        }
1001
      }
1002
*/
1003 2 bertin
 
1004 267 bertin
/* Express everything in magnitude units */
1005
  photom_mags(field, obj2);
1006 2 bertin
 
1007 267 bertin
/*--------------------------------- "Vignets" ------------------------------*/
1008
  if (FLAG(obj2.vignet))
1009 275 bertin
    copyimage(field,obj2->vignet,prefs.vignet_size[0],prefs.vignet_size[1],
1010 267 bertin
        obj2->ix, obj2->iy);
1011 2 bertin
 
1012 267 bertin
  if (FLAG(obj2.vigshift))
1013 275 bertin
    copyimage_center(field, obj2->vigshift, prefs.vigshift_size[0],
1014
                prefs.vigshift_size[1], obj2->mx, obj2->my);
1015 2 bertin
 
1016
 
1017 267 bertin
/*------------------------------- Source index -----------------------------*/
1018 248 bertin
  newnumber = ++thecat.ntotal;
1019 267 bertin
/*-- update segmentation map */
1020 248 bertin
  if ((check=prefs.check[CHECK_SEGMENTATION]))
1021
    {
1022
     ULONG      *pix;
1023
     ULONG      newsnumber = newnumber,
1024 267 bertin
                oldsnumber = obj2->number;
1025 248 bertin
     int        dx,dx0,dy,dpix;
1026 2 bertin
 
1027 267 bertin
    pix = (ULONG *)check->pix + check->width*obj2->ymin + obj2->xmin;
1028
    dx0 = obj2->xmax-obj2->xmin+1;
1029 248 bertin
    dpix = check->width-dx0;
1030 267 bertin
    for (dy=obj2->ymax-obj2->ymin+1; dy--; pix += dpix)
1031 248 bertin
      for (dx=dx0; dx--; pix++)
1032
        if (*pix==oldsnumber)
1033
          *pix = newsnumber;
1034
    }
1035 267 bertin
  obj2->number = newnumber;
1036 2 bertin
 
1037 249 bertin
/* Edit min and max coordinates to follow the FITS conventions */
1038 267 bertin
  obj2->xmin += 1;
1039
  obj2->ymin += 1;
1040
  obj2->xmax += 1;
1041
  obj2->ymax += 1;
1042 2 bertin
 
1043 267 bertin
/* Processing time */
1044
  obj2->analtime = (float)(counter_seconds() - analtime1);
1045 2 bertin
 
1046 272 bertin
  return RETURN_OK;
1047 2 bertin
  }
1048
 
1049 258 bertin