public software.sextractor

[/] [trunk/] [src/] [analyse.c] - Blame information for rev 231

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

Line No. Rev Author Line
1 2 bertin
 /*
2
                                analyse.c
3
 
4
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5
*
6
*       Part of:        SExtractor
7
*
8
*       Author:         E.BERTIN (IAP)
9
*
10
*       Contents:       analyse(), endobject()...: measurements on detections.
11
*
12 231 bertin
*       Last modify:    28/09/2010
13 2 bertin
*
14
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15
*/
16
 
17
#ifdef HAVE_CONFIG_H
18
#include        "config.h"
19
#endif
20
 
21
#include        <math.h>
22
#include        <stdio.h>
23
#include        <stdlib.h>
24
#include        <string.h>
25
 
26
#include        "define.h"
27
#include        "globals.h"
28
#include        "prefs.h"
29
#include        "fits/fitscat.h"
30
#include        "back.h"
31
#include        "check.h"
32
#include        "assoc.h"
33
#include        "astrom.h"
34
#include        "plist.h"
35
#include        "flag.h"
36
#include        "growth.h"
37
#include        "image.h"
38
#include        "photom.h"
39
#include        "psf.h"
40 173 bertin
#include        "profit.h"
41 2 bertin
#include        "retina.h"
42 6 bertin
#include        "som.h"
43 210 bertin
#include        "weight.h"
44 2 bertin
#include        "winpos.h"
45
 
46
static obj2struct       *obj2 = &outobj2;
47 173 bertin
extern profitstruct     *theprofit;
48 2 bertin
 
49
/********************************* analyse ***********************************/
50
void  analyse(picstruct *field, picstruct *dfield, int objnb,
51
                objliststruct *objlist)
52
 
53
  {
54
   objstruct    *obj = objlist->obj+objnb;
55
 
56
/* Do photometry on the detection image if no other image available */
57
  obj->number = ++thecat.ndetect;
58
  obj->bkg = (float)back(field, (int)(obj->mx+0.5), (int)(obj->my+0.5));
59
  obj->dbkg = 0.0;
60
  if (prefs.pback_type == LOCAL)
61
    localback(field, obj);
62
  else
63
    obj->sigbkg = field->backsig;
64
 
65
  examineiso(field, dfield, obj, objlist->plist);
66
 
67
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
68
/* Put here your calls to custom functions related to isophotal measurements.
69
Ex:
70
 
71
compute_myparams(obj);
72
 
73
*/
74
 
75
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
76
 
77
 
78
  return;
79
  }
80
 
81
 
82
/***************************** examineiso ********************************/
83
/*
84
compute some isophotal parameters IN THE MEASUREMENT image.
85
*/
86
void  examineiso(picstruct *field, picstruct *dfield, objstruct *obj,
87
                pliststruct *pixel)
88
 
89
  {
90
   checkstruct          *check;
91
   pliststruct          *pixt;
92
   int                  i,j,k,h, photoflag,area,errflag, cleanflag,
93 173 bertin
                        pospeakflag, minarea, gainflag;
94 2 bertin
   double               tv,sigtv, ngamma,
95
                        esum, emx2,emy2,emxy, err,gain,backnoise2,dbacknoise2,
96 231 bertin
                        xm,ym, x,y,var,var2, threshfac;
97 2 bertin
   float                *heap,*heapt,*heapj,*heapk, swap;
98 231 bertin
   PIXTYPE              pix, cdpix, tpix, peak,cdpeak, thresh,dthresh,minthresh;
99 2 bertin
   static PIXTYPE       threshs[NISO];
100
 
101
 
102
  if (!dfield)
103
    dfield = field;
104
 
105
/* Prepare computation of positional error */
106
  esum = emx2 = emy2 = emxy = 0.0;
107
  if ((errflag=FLAG(obj.poserr_mx2)))
108
    {
109
    dbacknoise2 = dfield->backsig*dfield->backsig;
110
    xm = obj->mx;
111
    ym = obj->my;
112
    }
113
  else
114
    xm = ym = dbacknoise2 = 0.0;        /* to avoid gcc -Wall warnings */
115
 
116
  pospeakflag = FLAG(obj.peakx);
117 173 bertin
  gain = field->gain;
118 2 bertin
  ngamma = field->ngamma;
119
  photoflag = (prefs.detect_type==PHOTO);
120
  gainflag = PLISTEXIST(var) && prefs.weightgain_flag;
121
 
122
  h = minarea = prefs.ext_minarea;
123
 
124
/* Prepare selection of the heap selection for CLEANing */
125
  if ((cleanflag = prefs.clean_flag))
126
    {
127
    if (obj->fdnpix < minarea)
128
      {
129
      obj->mthresh = 0.0;
130
      cleanflag = 0;
131
      heapt = heap = NULL;              /* to avoid gcc -Wall warnings */
132
      }
133
    else
134
      {
135
      QMALLOC(heap, float, minarea);
136
      heapt = heap;
137
      }
138
    }
139
  else
140
    {
141
    obj->mthresh = 0.0;
142
    heapt = heap = NULL;                /* to avoid gcc -Wall warnings */
143
    }
144
 
145
 
146
/* Measure essential isophotal parameters in the measurement image... */
147 173 bertin
  tv = sigtv = 0.0;
148 2 bertin
  var = backnoise2 = field->backsig*field->backsig;
149
  peak = -BIG;
150
  cdpeak = -BIG;
151
  thresh = field->thresh;
152 231 bertin
  minthresh = (PLISTEXIST(var))? BIG : thresh;
153
  threshfac = field->backsig > 0.0 ? field->thresh / field->backsig : 1.0;
154 2 bertin
  dthresh = dfield->dthresh;
155
  area = 0;
156
  for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
157
    {
158
    pix = PLIST(pixt,value);
159
    if (pix>peak)
160
      peak = pix;
161
 
162
    cdpix=PLISTPIX(pixt,cdvalue);
163
    if (pospeakflag && cdpix>cdpeak)
164
      {
165
      cdpeak=cdpix;
166
      obj->peakx =  PLIST(pixt,x) + 1;
167
      obj->peaky =  PLIST(pixt,y) + 1;
168
      }
169
    if (PLISTEXIST(var))
170 231 bertin
      {
171 2 bertin
      var = PLISTPIX(pixt, var);
172 231 bertin
      thresh = threshfac*sqrt(var);
173
      if (thresh < minthresh)
174
        minthresh = thresh;
175
      }
176
 
177 2 bertin
    if (photoflag)
178
      {
179
      pix = exp(pix/ngamma);
180
      var2 = pix*pix*var;
181
      }
182
    else
183
      var2 = var;
184
 
185
    if (gainflag && pix>0.0 && gain>0.0)
186
      var2 += pix/gain*var/backnoise2;
187
 
188
    sigtv += var2;
189
    if (pix>thresh)
190
      area++;
191
    tv += pix;
192
    if (errflag)
193
      {
194
      err = dbacknoise2;
195
      if (gain>0.0 && cdpix>0.0)
196
        err += cdpix/gain;
197
      x = PLIST(pixt,x) - xm;
198
      y = PLIST(pixt,y) - ym;
199
      esum += err;
200
      emx2 += err*x*x;
201
      emy2 += err*y*y;
202
      emxy += err*x*y;
203
      }
204
 
205
/*-- Find the minareath pixel in decreasing intensity for CLEANing */
206
    if (cleanflag)
207
      {
208
      tpix = PLISTPIX(pixt, cdvalue) - (PLISTEXIST(dthresh)?
209
                PLISTPIX(pixt, dthresh):dthresh);
210
      if (h>0)
211
        *(heapt++) = (float)tpix;
212
      else if (h)
213
        {
214
        if ((float)tpix>*heap)
215
          {
216
          *heap = (float)tpix;
217
          for (j=0; (k=(j+1)<<1)<=minarea; j=k)
218
            {
219
            heapk = heap+k;
220
            heapj = heap+j;
221
            if (k != minarea && *(heapk-1) > *heapk)
222
              {
223
              heapk++;
224
              k++;
225
              }
226
            if (*heapj <= *(--heapk))
227
              break;
228
            swap = *heapk;
229
            *heapk = *heapj;
230
            *heapj = swap;
231
            }
232
          }
233
        }
234
      else
235
        hmedian(heap, minarea);
236
      h--;
237
      }
238
    }
239
 
240
/* Flagging from the flag-map */
241
  if (PLISTEXIST(flag))
242
    getflags(obj, pixel);
243
 
244 210 bertin
/* Flag and count pixels with a low weight */
245
  if (PLISTEXIST(wflag))
246
    weight_count(obj, pixel);
247
 
248 2 bertin
  if (cleanflag)
249
    {
250
    obj->mthresh = *heap;
251
    free(heap);
252
    }
253
 
254
  if (errflag)
255
    {
256
     double     flux2;
257
 
258
    flux2 = obj->fdflux*obj->fdflux;
259
/*-- Estimation of the error ellipse moments: we re-use previous variables */
260
    emx2 /= flux2;      /* variance of xm */
261
    emy2 /= flux2;      /* variance of ym */
262
    emxy /= flux2;      /* covariance */
263
 
264
/*-- Handle fully correlated profiles (which cause a singularity...) */
265
    esum *= 0.08333/flux2;
266
    if (obj->singuflag && (emx2*emy2-emxy*emxy) < esum*esum)
267
      {
268
      emx2 += esum;
269
      emy2 += esum;
270
      }
271
 
272
    obj->poserr_mx2 = emx2;
273
    obj->poserr_my2 = emy2;
274
    obj->poserr_mxy = emxy;
275
    }
276
 
277
  if (photoflag)
278
    {
279
    tv = ngamma*(tv-obj->fdnpix*exp(obj->dbkg/ngamma));
280
    sigtv /= ngamma*ngamma;
281
    }
282
  else
283
    {
284
    tv -= obj->fdnpix*obj->dbkg;
285
    if (!gainflag && gain > 0.0 && tv>0.0)
286
      sigtv += tv/gain;
287
    }
288
 
289
  obj->npix = area;
290
  obj->flux = tv;
291
  obj->fluxerr = sigtv;
292
  obj->peak = peak;
293 231 bertin
  obj->thresh = minthresh - obj->dbkg;
294 2 bertin
  obj->peak -= obj->dbkg;
295
 
296
/* Initialize isophotal thresholds so as to sample optimally the full profile*/
297
 
298
  if (FLAG(obj.iso[0]))
299
    {
300
     int        *iso;
301
     PIXTYPE    *thresht;
302
 
303
    memset(obj->iso, 0, NISO*sizeof(int));
304
    if (prefs.detect_type == PHOTO)
305
      for (i=0; i<NISO; i++)
306
        threshs[i] = obj->thresh + (obj->peak-obj->thresh)*i/NISO;
307
    else
308
      {
309
      if (obj->peak>0.0 && obj->thresh>0.0)
310
        for (i=0; i<NISO; i++)
311
          threshs[i] = obj->thresh*pow(obj->peak/obj->thresh, (double)i/NISO);
312
      else
313
        for (i=0; i<NISO; i++)
314
          threshs[i] = 0.0;
315
      }
316
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
317
      for (i=NISO,iso=obj->iso,thresht=threshs;
318
                i-- && PLIST(pixt,value)>*(thresht++);)
319
        (*(iso++))++;
320
    }
321
 
322
/* Put objects in "segmentation check-image" */
323
 
324
  if ((check = prefs.check[CHECK_SEGMENTATION]))
325
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
326
      ((ULONG *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
327
                = (ULONG)obj->number;
328
 
329
  if ((check = prefs.check[CHECK_OBJECTS]))
330
    for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
331
      ((PIXTYPE *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
332
                = PLIST(pixt,value);
333
 
334
/* Compute the FWHM of the object */
335
  if (FLAG(obj.fwhm))
336
    {
337
     PIXTYPE    thresh0;
338
 
339
    thresh0 = obj->peak/5.0;
340
    if (thresh0<obj->thresh)
341
      thresh0 = obj->thresh;
342
    if (thresh0>0.0)
343
      {
344
       double   mx,my, s,sx,sy,sxx,sxy, dx,dy,d2, lpix,pix, b, inverr2, sat,
345
                dbkg, d, bmax;
346
 
347
      mx = obj->mx;
348
      my = obj->my;
349
      dbkg = obj->dbkg;
350 173 bertin
      sat = (double)(field->satur_level - obj->bkg);
351 2 bertin
      s = sx = sy = sxx = sxy = 0.0;
352
      for (pixt=pixel+obj->firstpix;pixt>=pixel;pixt=pixel+PLIST(pixt,nextpix))
353
        {
354
        pix = PLIST(pixt,value)-dbkg;
355
        if (pix>thresh0 && pix<sat)
356
          {
357
          dx = PLIST(pixt,x) - mx;
358
          dy = PLIST(pixt,y) - my;
359
          lpix = log(pix);
360
          inverr2 = pix*pix;
361
          s += inverr2;
362
          d2 = dx*dx+dy*dy;
363
          sx += d2*inverr2;
364
          sxx += d2*d2*inverr2;
365
          sy += lpix*inverr2;
366
          sxy += lpix*d2*inverr2;
367
          }
368
        }
369
      d = s*sxx-sx*sx;
370
      if (fabs(d)>0.0)
371
        {
372
        b = -(s*sxy-sx*sy)/d;
373
        if (b<(bmax = 1/(13*obj->a*obj->b)))    /* to have FWHM # 6 sigma */
374
          b = bmax;
375
        obj->fwhm = (float)(1.6651/sqrt(b));
376
/*----- correction for undersampling effects (established from simulations) */
377
        if (obj->fwhm>0.0)
378
          obj->fwhm -= 1/(4*obj->fwhm);
379
        }
380
      else
381
        obj->fwhm = 0.0;
382
      }
383
    else
384
      obj->fwhm = 0.0;
385
    }
386
 
387
  return;
388
  }
389
 
390
 
391
/******************************* endobject **********************************/
392
/*
393
Final processing of object data, just before saving it to the catalog.
394
*/
395
void    endobject(picstruct *field, picstruct *dfield, picstruct *wfield,
396
                picstruct *dwfield, int n, objliststruct *objlist)
397
  {
398 208 bertin
   objstruct            *obj;
399
   checkstruct          *check;
400
   double               rawpos[NAXIS],
401
                        analtime1;
402
   int                  i,j, ix,iy,selecflag, newnumber,nsub;
403 2 bertin
 
404 221 bertin
   if (prefs.psf_flag || prefs.prof_flag)
405
     thepsf->build_flag = 0;     /* Reset PSF building flag */
406
   if (prefs.dpsf_flag)
407
     ppsf->build_flag = 0;       /* Reset PSF building flag */
408
 
409 208 bertin
  if (FLAG(obj2.analtime))
410
    analtime1 = counter_seconds();
411 217 bertin
  else
412
    analtime1 = 0.0;            /* To avoid gcc -Wall warnings */
413 208 bertin
 
414 2 bertin
  obj = &objlist->obj[n];
415
 
416
/* Current FITS extension */
417
  obj2->ext_number = thecat.currext;
418
 
419
/* Source position */
420
  obj2->sposx = (float)(obj2->posx = obj->mx+1.0); /* That's standard FITS */
421
  obj2->sposy = (float)(obj2->posy = obj->my+1.0);
422
 
423
/* Integer coordinates */
424
  ix=(int)(obj->mx+0.49999);
425
  iy=(int)(obj->my+0.49999);
426
 
427
/* Association */
428
  if (prefs.assoc_flag)
429
    obj2->assoc_number = do_assoc(field, obj2->sposx, obj2->sposy);
430
 
431
  if (prefs.assoc_flag && prefs.assocselec_type!=ASSOCSELEC_ALL)
432
    selecflag = (prefs.assocselec_type==ASSOCSELEC_MATCHED)?
433
                obj2->assoc_number:!obj2->assoc_number;
434
  else
435
    selecflag = 1;
436
 
437
  if (selecflag)
438
    {
439
/*-- Paste back to the image the object's pixels if BLANKing is on */
440
    if (prefs.blank_flag)
441
      {
442
      pasteimage(field, obj->blank, obj->subw, obj->subh,
443
                obj->subx, obj->suby);
444
      if (obj->dblank)
445
        pasteimage(dfield, obj->dblank, obj->subw, obj->subh,
446
                obj->subx, obj->suby);
447
      }
448
 
449
/*------------------------- Error ellipse parameters ------------------------*/
450
    if (FLAG(obj2.poserr_a))
451
      {
452
       double   pmx2,pmy2,temp,theta;
453
 
454
      if (fabs(temp=obj->poserr_mx2-obj->poserr_my2) > 0.0)
455
        theta = atan2(2.0 * obj->poserr_mxy,temp) / 2.0;
456
      else
457
        theta = PI/4.0;
458
 
459
      temp = sqrt(0.25*temp*temp+obj->poserr_mxy*obj->poserr_mxy);
460
      pmy2 = pmx2 = 0.5*(obj->poserr_mx2+obj->poserr_my2);
461
      pmx2+=temp;
462
      pmy2-=temp;
463
 
464
      obj2->poserr_a = (float)sqrt(pmx2);
465
      obj2->poserr_b = (float)sqrt(pmy2);
466
      obj2->poserr_theta = theta*180.0/PI;
467
      }
468
 
469
    if (FLAG(obj2.poserr_cxx))
470
      {
471
       double   xm2,ym2, xym, temp;
472
 
473
      xm2 = obj->poserr_mx2;
474
      ym2 = obj->poserr_my2;
475
      xym = obj->poserr_mxy;
476
      obj2->poserr_cxx = (float)(ym2/(temp=xm2*ym2-xym*xym));
477
      obj2->poserr_cyy = (float)(xm2/temp);
478
      obj2->poserr_cxy = (float)(-2*xym/temp);
479
      }
480
 
481
/* ---- Aspect ratio */
482
 
483
    if (FLAG(obj2.elong))
484
      obj2->elong = obj->a/obj->b;
485
 
486
    if (FLAG(obj2.ellip))
487
      obj2->ellip = 1-obj->b/obj->a;
488
 
489
    if (FLAG(obj2.polar))
490
      obj2->polar = (obj->a*obj->a - obj->b*obj->b)
491
                / (obj->a*obj->a + obj->b*obj->b);
492
 
493 199 bertin
/*-- Express positions in FOCAL or WORLD coordinates */
494
    if (FLAG(obj2.mxf) || FLAG(obj2.mxw))
495
      astrom_pos(field, obj);
496
 
497 206 bertin
    obj2->pixscale2 = 0.0;      /* To avoid gcc -Wall warnings */
498 199 bertin
    if (FLAG(obj2.mx2w)
499
        || FLAG(obj2.win_mx2w)
500
        || FLAG(obj2.poserr_mx2w)
501
        || FLAG(obj2.winposerr_mx2w)
502 218 bertin
        || FLAG(obj2.poserrmx2w_psf)
503 199 bertin
        || FLAG(obj2.poserrmx2w_prof)
504
        || FLAG(obj2.prof_flagw)
505 206 bertin
        || ((!prefs.pixel_scale) && FLAG(obj2.area_flagw)))
506 199 bertin
      {
507
      rawpos[0] = obj2->posx;
508
      rawpos[1] = obj2->posy;
509 206 bertin
      obj2->pixscale2 = wcs_jacobian(field->wcs, rawpos, obj2->jacob);
510 199 bertin
      }
511
 
512
/*-- Express shape parameters in the FOCAL or WORLD frame */
513
    if (FLAG(obj2.mx2w))
514
      astrom_shapeparam(field, obj);
515
/*-- Express position error parameters in the FOCAL or WORLD frame */
516
    if (FLAG(obj2.poserr_mx2w))
517
      astrom_errparam(field, obj);
518
 
519
    if (FLAG(obj2.npixw))
520
      obj2->npixw = obj->npix * (prefs.pixel_scale?
521 206 bertin
        field->pixscale/3600.0*field->pixscale/3600.0 : obj2->pixscale2);
522 199 bertin
    if (FLAG(obj2.fdnpixw))
523
      obj2->fdnpixw = obj->fdnpix * (prefs.pixel_scale?
524 206 bertin
        field->pixscale/3600.0*field->pixscale/3600.0 : obj2->pixscale2);
525 199 bertin
 
526
    if (FLAG(obj2.fwhmw))
527
      obj2->fwhmw = obj->fwhm * (prefs.pixel_scale?
528 206 bertin
        field->pixscale/3600.0 : sqrt(obj2->pixscale2));
529 199 bertin
 
530 2 bertin
/*------------------------------- Photometry -------------------------------*/
531
 
532
/*-- Convert the father of photom. error estimates from variance to RMS */
533
    obj2->flux_iso = obj->flux;
534
    obj2->fluxerr_iso = sqrt(obj->fluxerr);
535
 
536
    if (FLAG(obj2.flux_isocor))
537
      computeisocorflux(field, obj);
538
 
539
    if (FLAG(obj2.flux_aper))
540
      for (i=0; i<prefs.naper; i++)
541
        computeaperflux(field, wfield, obj, i);
542
 
543
    if (FLAG(obj2.flux_auto))
544
      computeautoflux(field, dfield, wfield, dwfield, obj);
545
 
546
    if (FLAG(obj2.flux_petro))
547
      computepetroflux(field, dfield, wfield, dwfield, obj);
548
 
549
/*-- Growth curve */
550
    if (prefs.growth_flag)
551
      makeavergrowth(field, wfield, obj);
552
 
553
/*--------------------------- Windowed barycenter --------------------------*/
554
    if (FLAG(obj2.winpos_x))
555 199 bertin
      {
556 2 bertin
      compute_winpos(field, wfield, obj);
557 199 bertin
/*---- Express positions in FOCAL or WORLD coordinates */
558
      if (FLAG(obj2.winpos_xf) || FLAG(obj2.winpos_xw))
559
        astrom_winpos(field, obj);
560
/*---- Express shape parameters in the FOCAL or WORLD frame */
561 206 bertin
      if (FLAG(obj2.win_mx2w))
562 199 bertin
        astrom_winshapeparam(field, obj);
563
/*---- Express position error parameters in the FOCAL or WORLD frame */
564 206 bertin
      if (FLAG(obj2.winposerr_mx2w))
565 199 bertin
        astrom_winerrparam(field, obj);
566
      }
567 2 bertin
 
568 199 bertin
/*---------------------------- Peak information ----------------------------*/
569 173 bertin
    if (obj->peak+obj->bkg >= field->satur_level)
570 2 bertin
      obj->flag |= OBJ_SATUR;
571 199 bertin
/*-- Express positions in FOCAL or WORLD coordinates */
572
    if (FLAG(obj2.peakxf) || FLAG(obj2.peakxw))
573
      astrom_peakpos(field, obj);
574 2 bertin
 
575
/*-- Check-image CHECK_APERTURES option */
576
 
577
    if ((check = prefs.check[CHECK_APERTURES]))
578
      {
579
      if (FLAG(obj2.flux_aper))
580
        for (i=0; i<prefs.naper; i++)
581
          sexcircle(check->pix, check->width, check->height,
582
                obj->mx, obj->my, prefs.apert[i]/2.0, check->overlay);
583
 
584
      if (FLAG(obj2.flux_auto))
585
        sexellips(check->pix, check->width, check->height,
586
        obj->mx, obj->my, obj->a*obj2->kronfactor,
587
        obj->b*obj2->kronfactor, obj->theta,
588
        check->overlay, obj->flag&OBJ_CROWDED);
589
 
590
      if (FLAG(obj2.flux_petro))
591
        sexellips(check->pix, check->width, check->height,
592
        obj->mx, obj->my, obj->a*obj2->petrofactor,
593
        obj->b*obj2->petrofactor, obj->theta,
594
        check->overlay, obj->flag&OBJ_CROWDED);
595
      }
596
 
597
/* ---- Star/Galaxy classification */
598
 
599
    if (FLAG(obj2.sprob))
600
      {
601
       double   fac2, input[10], output, fwhm;
602
 
603 221 bertin
      fwhm = (prefs.seeing_fwhm==0.0)? psf_fwhm(thepsf)*field->pixscale
604
                                : prefs.seeing_fwhm;
605 2 bertin
 
606
      fac2 = fwhm/field->pixscale;
607
      fac2 *= fac2;
608
      input[j=0] = log10(obj->iso[0]? obj->iso[0]/fac2: 0.01);
609
      input[++j] = field->thresh>0.0?
610
                  log10(obj->peak>0.0? obj->peak/field->thresh: 0.1)
611
                 :-1.0;
612
      for (i=1; i<NISO; i++)
613
        input[++j] = log10(obj->iso[i]? obj->iso[i]/fac2: 0.01);
614
      input[++j] = log10(fwhm);
615
      neurresp(input, &output);
616
      obj2->sprob = (float)output;
617
      }
618
 
619
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
620
/*-- Put here your calls to "BLIND" custom functions. Ex:
621
 
622
    compute_myotherparams(obj);
623
 
624
--*/
625
 
626
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
627
 
628
    newnumber = ++thecat.ntotal;
629
/*-- update segmentation map */
630
    if ((check=prefs.check[CHECK_SEGMENTATION]))
631
      {
632
       ULONG    *pix;
633
       ULONG    newsnumber = newnumber,
634
                oldsnumber = obj->number;
635
       int      dx,dx0,dy,dpix;
636
 
637
      pix = (ULONG *)check->pix + check->width*obj->ymin + obj->xmin;
638
      dx0 = obj->xmax-obj->xmin+1;
639
      dpix = check->width-dx0;
640
      for (dy=obj->ymax-obj->ymin+1; dy--; pix += dpix)
641
        for (dx=dx0; dx--; pix++)
642
          if (*pix==oldsnumber)
643
            *pix = newsnumber;
644
      }
645
    obj->number = newnumber;
646
 
647 6 bertin
/*-- SOM fitting */
648
    if (prefs.somfit_flag)
649
      {
650
       float    *input;
651
 
652
      input = thesom->input;
653
      copyimage(field,input,thesom->inputsize[0],thesom->inputsize[1],ix,iy);
654
 
655
      if (thesom->nextrainput)
656
        {
657
        input += thesom->ninput-thesom->nextrainput;
658
        *(input) = (obj->mx+1)/field->width;
659
        *(input+1) = (obj->my+1)/field->height;
660
        }
661
 
662
      som_phot(thesom, obj->bkg, field->backsig,
663 173 bertin
        (float)field->gain, obj->mx-ix, obj->my-iy,
664 6 bertin
        FLAG(obj2.vector_somfit)?outobj2.vector_somfit:NULL, -1.0);
665
      obj2->stderr_somfit = thesom->stderror;
666
      obj2->flux_somfit = thesom->amp;
667
      outobj2.fluxerr_somfit = thesom->sigamp;
668
      }
669
 
670 2 bertin
    if (FLAG(obj2.vignet))
671
      copyimage(field,outobj2.vignet,prefs.vignetsize[0],prefs.vignetsize[1],
672
        ix,iy);
673
 
674
    if (FLAG(obj2.vigshift))
675
      copyimage_center(field, outobj2.vigshift, prefs.vigshiftsize[0],
676
                prefs.vigshiftsize[1], obj->mx, obj->my);
677
 
678
/*------------------------------- PSF fitting ------------------------------*/
679
    nsub = 1;
680
    if (prefs.psf_flag)
681
      {
682 5 bertin
      if (prefs.dpsf_flag)
683
        double_psf_fit(ppsf, field, wfield, obj, thepsf, dfield, dwfield);
684
      else
685
        psf_fit(thepsf, field, wfield, obj);
686 2 bertin
      obj2->npsf = thepsfit->npsf;
687 218 bertin
      nsub = thepsfit->npsf;
688
      if (nsub<1)
689
        nsub = 1;
690 2 bertin
      }
691
 
692 173 bertin
/*----------------------------- Profile fitting -----------------------------*/
693 227 bertin
#ifdef USE_MODEL
694 173 bertin
    if (prefs.prof_flag)
695 199 bertin
      {
696 173 bertin
      profit_fit(theprofit, field, wfield, obj, obj2);
697 199 bertin
/*---- Express positions in FOCAL or WORLD coordinates */
698 206 bertin
      if (FLAG(obj2.xf_prof) || FLAG(obj2.xw_prof))
699 199 bertin
        astrom_profpos(field, obj);
700
/*---- Express shape parameters in the FOCAL or WORLD frame */
701 206 bertin
      if (FLAG(obj2.prof_flagw))
702 199 bertin
        astrom_profshapeparam(field, obj);
703
/*---- Express position error parameters in the FOCAL or WORLD frame */
704 206 bertin
      if (FLAG(obj2.poserrmx2w_prof))
705 199 bertin
        astrom_proferrparam(field, obj);
706
      }
707 227 bertin
#endif
708 173 bertin
/*--- Express everything in magnitude units */
709
    computemags(field, obj);
710
 
711 2 bertin
/*-------------------------------- Astrometry ------------------------------*/
712 199 bertin
 
713 2 bertin
/*-- Edit min and max coordinates to follow the FITS conventions */
714
    obj->xmin += 1;
715
    obj->ymin += 1;
716
    obj->xmax += 1;
717
    obj->ymax += 1;
718
 
719
/*-- Go through each newly identified component */
720
    for (j=0; j<nsub; j++)
721
      {
722 218 bertin
      if (prefs.psf_flag)
723 2 bertin
        {
724 218 bertin
        obj2->x_psf = thepsfit->x[j];
725
        obj2->y_psf = thepsfit->y[j];
726
        if (FLAG(obj2.xf_psf) || FLAG(obj2.xw_psf))
727
          astrom_psfpos(field, obj);
728
/*------ Express position error parameters in the FOCAL or WORLD frame */
729
        if (FLAG(obj2.poserrmx2w_psf))
730
          astrom_psferrparam(field, obj);
731 2 bertin
        if (FLAG(obj2.flux_psf))
732 218 bertin
          obj2->flux_psf = thepsfit->flux[j]>0.0? thepsfit->flux[j]:0.0; /*?*/
733 2 bertin
        if (FLAG(obj2.mag_psf))
734 218 bertin
          obj2->mag_psf = thepsfit->flux[j]>0.0?
735 2 bertin
                prefs.mag_zeropoint -2.5*log10(thepsfit->flux[j]) : 99.0;
736 5 bertin
        if (FLAG(obj2.fluxerr_psf))
737 218 bertin
          obj2->fluxerr_psf= thepsfit->fluxerr[j];
738
        if (FLAG(obj2.magerr_psf))
739
          obj2->magerr_psf =
740
                (thepsfit->flux[j]>0.0 && thepsfit->fluxerr[j]>0.0) ? /*?*/
741
                        1.086*thepsfit->fluxerr[j]/thepsfit->flux[j] : 99.0;
742 2 bertin
        if (j)
743
          obj->number = ++thecat.ntotal;
744
        }
745
 
746 208 bertin
      if (FLAG(obj2.analtime) && !j)
747
        obj2->analtime = (float)(counter_seconds() - analtime1);
748
 
749 2 bertin
      FPRINTF(OUTPUT, "%8d %6.1f %6.1f %5.1f %5.1f %12g "
750
                        "%c%c%c%c%c%c%c%c\n",
751
        obj->number, obj->mx+1.0, obj->my+1.0,
752
        obj->a, obj->b,
753
        obj->flux,
754
        obj->flag&OBJ_CROWDED?'C':'_',
755
        obj->flag&OBJ_MERGED?'M':'_',
756
        obj->flag&OBJ_SATUR?'S':'_',
757
        obj->flag&OBJ_TRUNC?'T':'_',
758
        obj->flag&OBJ_APERT_PB?'A':'_',
759
        obj->flag&OBJ_ISO_PB?'I':'_',
760
        obj->flag&OBJ_DOVERFLOW?'D':'_',
761
        obj->flag&OBJ_OVERFLOW?'O':'_');
762
      writecat(n, objlist);
763
      }
764
    }
765 173 bertin
  else
766
    {
767
/*-- Treatment of discarded detections */
768
/*-- update segmentation map */
769
    if ((check=prefs.check[CHECK_SEGMENTATION]))
770
      {
771
       ULONG    *pix;
772
       ULONG    oldsnumber = obj->number;
773
       int      dx,dx0,dy,dpix;
774 2 bertin
 
775 173 bertin
      pix = (ULONG *)check->pix + check->width*obj->ymin + obj->xmin;
776
      dx0 = obj->xmax-obj->xmin+1;
777
      dpix = check->width-dx0;
778
      for (dy=obj->ymax-obj->ymin+1; dy--; pix += dpix)
779
        for (dx=dx0; dx--; pix++)
780
          if (*pix==oldsnumber)
781
            *pix = 0;
782
      }
783
    }
784
 
785 2 bertin
/* Remove again from the image the object's pixels if BLANKing is on ... */
786
/*-- ... and free memory */
787
 
788
  if (prefs.blank_flag && obj->blank)
789
    {
790
    if (selecflag)
791
      {
792
      if (prefs.somfit_flag && (check=prefs.check[CHECK_MAPSOM]))
793
        blankcheck(check, obj->blank, obj->subw, obj->subh,
794
                obj->subx, obj->suby, (PIXTYPE)*(obj2->vector_somfit));
795
 
796
      }
797
    blankimage(field, obj->blank, obj->subw, obj->subh,
798
                obj->subx, obj->suby, -BIG);
799
    free(obj->blank);
800
    if (obj->dblank)
801
      {
802
      blankimage(dfield, obj->dblank, obj->subw, obj->subh,
803
                obj->subx, obj->suby, -BIG);
804
      free(obj->dblank);
805
      }
806
    }
807
 
808
  return;
809
  }
810