34 #include <vircam_utils.h>
35 #include <vircam_pfits.h>
47 #define PI 3.14159265358979323846
48 #define DEGRAD 57.2957795130823229
50 #define COREMAG(A,B,C) 2.5*log10((double)(max(C,A-B)))
51 #define MAX(A,B) (A > B ? A : B)
56 static float thresh,skylevel,skynoise,rcore,exptime;
61 static float sigell,fitell,elllim,sigellf,fitellf,sigpa,fitpa;
62 static float blim,flim,cmin,cmax;
63 static float fit1,fit2,fit3,fit4,fit5,fit6,fit7;
64 static float fit_final,sigma_final;
65 static float *lower1,*lower2,*lower3,*upper1,*upper2,*upper3,*uppere;
66 static float avsig1,avsig2,avsig3,wt1,wt2,wt3;
70 static int nstar,ngal,njunk,ncmp;
74 static float avsat,corlim,cormin,apcpkht,apcor,apcor1,apcor2,apcor3,apcor4;
75 static float apcor5,apcor6,apcor7;
79 static float *workspace = NULL;
80 static cpl_table *catcopy = NULL;
81 static float *areal[NAREAL];
82 static float *core_flux,*core1_flux,*core2_flux,*core3_flux,*core4_flux;
83 static float *core5_flux,*peak_height,*peak_mag,*ellipticity,*iso_flux;
84 static float *total_flux,*cls,*sig,*xpos,*ypos,*pa,*core6_flux,*skylev;
92 static const char *cols32[NCOL32] = {
"Core_flux",
"Core1_flux",
"Core2_flux",
93 "Core3_flux",
"Core4_flux",
"Peak_height",
94 "Ellipticity",
"Isophotal_flux",
95 "Total_flux",
"Core5_flux",
"X_coordinate",
96 "Y_coordinate",
"Position_angle",
99 static const char *cols80[NCOL80] = {
"Aper_flux_3",
"Aper_flux_1",
"Aper_flux_4",
100 "Aper_flux_5",
"Aper_flux_6",
"Peak_height",
101 "Ellipticity",
"Isophotal_flux",
102 "Isophotal_flux",
"Aper_flux_7",
103 "X_coordinate",
"Y_coordinate",
104 "Position_angle",
"Sky_level",
114 #define FRAMECUT 0.05
118 static void anhist(
float *,
int,
float *,
float *);
119 static void boundaries(
float *,
float *,
float *,
float,
float,
float,
float,
120 int,
float,
float,
float *,
float *,
float *,
float *);
121 static void boundpk(
float *,
float *,
float,
float,
float *,
float *,
123 static void classify_run(
void);
124 static void classstats(
float *,
float *,
int,
float,
float *,
float *);
125 static void classstats_ap0(
float *,
float *);
126 static void classstats_ap67(
float *,
float *,
float *,
float *);
127 static void classstats_el(
void);
128 static void classstats_pa(
void);
129 static void classstats_ellf(
float);
130 static void classstats_final(
void);
131 static void medstat(
float *,
int,
float *,
float *);
132 static void sort1(
float *,
int);
133 static void sort2(
float *,
float *,
int);
204 extern int classify(vir_tfits *catalogue, cpl_propertylist *plist,
205 float minsize,
int cattype) {
206 float fwhm,*work,moff;
207 float pkht,ell,core,ap,delap,area,junk,arg;
208 char *cols[MAX(NCOL32,NCOL80)],colname[32];
209 cpl_propertylist *extra;
211 const char *fctid =
"vircam_classify";
212 int i,n,iap,i1,i2,nxout,nyout;
217 thresh = cpl_propertylist_get_float(extra,
"ESO DRS THRESHOL");
218 skylevel = cpl_propertylist_get_float(extra,
"ESO QC MEAN_SKY");
219 skynoise = cpl_propertylist_get_float(extra,
"ESO QC SKY_NOISE");
220 rcore = cpl_propertylist_get_float(extra,
"ESO DRS RCORE");
221 fwhm = cpl_propertylist_get_float(extra,
"ESO DRS SEEING");
222 nxout = cpl_propertylist_get_int(extra,
"ESO DRS NXOUT");
223 nyout = cpl_propertylist_get_int(extra,
"ESO DRS NYOUT");
224 xmin = FRAMECUT*(float)nxout;
225 xmax = (1.0 - FRAMECUT)*(
float)nxout;
226 ymin = FRAMECUT*(float)nyout;
227 ymax = (1.0 - FRAMECUT)*(
float)nyout;
233 cpl_msg_warning(fctid,
"Unable to get expsoure time!");
240 ncols = cpl_table_get_ncol(cat);
243 for (i = 0; i < NCOL32; i++)
244 cols[i] = (
char *)cols32[i];
247 for (i = 0; i < NCOL80; i++)
248 cols[i] = (
char *)cols80[i];
251 for (i = 0; i < NCOL80; i++)
252 cols[i] = (
char *)cols80[i];
255 cpl_msg_error(fctid,
"Don't recognise catalogues with %" CPL_SIZE_FORMAT
" columns: cattype == %" CPL_SIZE_FORMAT,(cpl_size)ncols,(cpl_size)cattype);
262 catcopy = cpl_table_duplicate(cat);
263 nrows = cpl_table_get_nrow(cat);
264 core_flux = cpl_table_get_data_float(catcopy,cols[0]);
265 core1_flux = cpl_table_get_data_float(catcopy,cols[1]);
266 core2_flux = cpl_table_get_data_float(catcopy,cols[2]);
267 core3_flux = cpl_table_get_data_float(catcopy,cols[3]);
268 core4_flux = cpl_table_get_data_float(catcopy,cols[4]);
269 peak_height = cpl_table_get_data_float(catcopy,cols[5]);
270 ellipticity = cpl_table_get_data_float(catcopy,cols[6]);
271 iso_flux = cpl_table_get_data_float(catcopy,cols[7]);
272 total_flux = cpl_table_get_data_float(catcopy,cols[8]);
273 core5_flux = cpl_table_get_data_float(catcopy,cols[9]);
274 xpos = cpl_table_get_data_float(catcopy,cols[10]);
275 ypos = cpl_table_get_data_float(catcopy,cols[11]);
276 pa = cpl_table_get_data_float(catcopy,cols[12]);
277 skylev = cpl_table_get_data_float(catcopy,cols[13]);
278 if (cattype == 2 || cattype == 6)
279 core6_flux = cpl_table_get_data_float(catcopy,cols[14]);
282 cls = cpl_table_get_data_float(cat,
"Classification");
283 sig = cpl_table_get_data_float(cat,
"Statistic");
287 workspace = cpl_malloc(2*nrows*
sizeof(
float));
288 peak_mag = workspace;
289 work = workspace + nrows;
293 for (i = 0; i < nrows; i++) {
294 core_flux[i] = COREMAG(core_flux[i],0.0,1.0);
295 core1_flux[i] = COREMAG(core1_flux[i],0.0,1.0);
296 core2_flux[i] = COREMAG(core2_flux[i],0.0,1.0);
297 core3_flux[i] = COREMAG(core3_flux[i],0.0,1.0);
298 core4_flux[i] = COREMAG(core4_flux[i],0.0,1.0);
299 core5_flux[i] = COREMAG(core5_flux[i],0.0,1.0);
300 moff = 1.0/(1.0 - pow((thresh/MAX(peak_height[i],thresh)),0.6));
301 iso_flux[i] = COREMAG(moff*iso_flux[i],0.0,1.0);
302 peak_mag[i] = COREMAG(peak_height[i],skynoise,0.1);
304 if (core6_flux != NULL)
305 for (i = 0; i < nrows; i++)
306 core6_flux[i] = COREMAG(core6_flux[i],0.0,1.0);
308 for (i = 0; i < nrows; i++)
309 total_flux[i] = COREMAG(total_flux[i],0.0,1.0);
313 for (i = 0; i < NAREAL; i++) {
314 sprintf(colname,
"Areal_%d_profile",i+1);
315 areal[i] = cpl_table_get_data_float(catcopy,colname);
321 if (fwhm > max(5.0,rcore*sqrt(2.0)))
331 for (i = 0; i < nrows; i++) {
332 pkht = peak_height[i];
333 ell = ellipticity[i];
335 if (cls[i] == -1.0 && ell < elllim && core < corlim &&
336 pkht > 10.0*thresh) {
337 ap = log(0.5*pkht/thresh)/log(2.0) + 1.0;
339 delap = ap - (float)iap;
340 if (iap > 0 && iap < NAREAL && areal[1][i] > 0.0) {
341 i1 = (iap-1)*nrows + i;
343 area = areal[iap-1][i]*(1.0 - delap) + areal[iap][i]*delap;
344 work[n++] = 2.0*sqrt(area/PI);
349 medstat(work,n,&fwhm,&junk);
353 arg = 0.25*PI*fwhm*fwhm - 1;
354 fwhm = 2.0*sqrt(max(0.0,arg/PI));
361 freespace(workspace);
366 cpl_propertylist_update_float(extra,
"ESO QC IMAGE_SIZE",fwhm);
367 cpl_propertylist_set_comment(extra,
"ESO QC IMAGE_SIZE",
368 "[pixels] Average FWHM of stellar objects");
369 cpl_propertylist_update_float(extra,
"ESO QC ELLIPTICITY",fitell);
370 cpl_propertylist_set_comment(extra,
"ESO QC ELLIPTICITY",
371 "Average stellar ellipticity (1-b/a)");
372 cpl_propertylist_update_float(extra,
"ESO QC POSANG",fitpa);
373 cpl_propertylist_set_comment(extra,
"ESO QC POSANG",
374 "[degrees] Median position angle");
377 cpl_propertylist_update_float(extra,
"ESO QC APERTURE_CORR",apcor);
378 cpl_propertylist_set_comment(extra,
"ESO QC APERTURE_CORR",
379 "Stellar ap-corr 1x core flux");
382 cpl_propertylist_update_float(extra,
"ESO QC APERTURE_CORR",apcor3);
383 cpl_propertylist_set_comment(extra,
"ESO QC APERTURE_CORR",
384 "Stellar ap-corr 1x core flux");
387 cpl_propertylist_update_float(extra,
"ESO QC APERTURE_CORR",apcor3);
388 cpl_propertylist_set_comment(extra,
"ESO QC APERTURE_CORR",
389 "Stellar ap-corr 1x core flux");
392 cpl_propertylist_update_int(extra,
"ESO QC NOISE_OBJ",njunk);
393 cpl_propertylist_set_comment(extra,
"ESO QC NOISE_OBJ",
394 "Number of noise objects");
395 cpl_propertylist_update_float(extra,
"ESO QC SATURATION",avsat);
399 cpl_propertylist_update_bool(extra,
"ESO DRS CLASSIFD",1);
400 cpl_propertylist_set_comment(extra,
"ESO DRS CLASSIFD",
401 "Catalogue has been classified");
407 cpl_propertylist_update_float(extra,
"APCORPK",apcpkht);
408 cpl_propertylist_set_comment(extra,
"APCORPK",
"Stellar aperture correction - peak height");
409 cpl_propertylist_update_float(extra,
"APCOR1",apcor1);
410 cpl_propertylist_set_comment(extra,
"APCOR1",
"Stellar aperture correction - 1/2x core flux");
411 cpl_propertylist_update_float(extra,
"APCOR",apcor);
412 cpl_propertylist_set_comment(extra,
"APCOR",
"Stellar aperture correction - 1x core flux");
413 cpl_propertylist_update_float(extra,
"APCOR2",apcor2);
414 cpl_propertylist_set_comment(extra,
"APCOR2",
"Stellar aperture correction - sqrt(2)x core flux");
415 cpl_propertylist_update_float(extra,
"APCOR3",apcor3);
416 cpl_propertylist_set_comment(extra,
"APCOR3",
"Stellar aperture correction - 2x core flux");
417 cpl_propertylist_update_float(extra,
"APCOR4",apcor4);
418 cpl_propertylist_set_comment(extra,
"APCOR4",
"Stellar aperture correction - 2*sqrt(2)x core flux");
419 cpl_propertylist_update_float(extra,
"APCOR5",apcor5);
420 cpl_propertylist_set_comment(extra,
"APCOR5",
"Stellar aperture correction - 4x core flux");
423 cpl_propertylist_update_float(extra,
"APCORPK",apcpkht);
424 cpl_propertylist_set_comment(extra,
"APCORPK",
"Stellar aperture correction - peak height");
425 cpl_propertylist_update_float(extra,
"APCOR1",apcor1);
426 cpl_propertylist_set_comment(extra,
"APCOR1",
"Stellar aperture correction - 1/2x core flux");
427 cpl_propertylist_update_float(extra,
"APCOR2",apcor2);
428 cpl_propertylist_set_comment(extra,
"APCOR2",
"Stellar aperture correction - core/sqrt(2) flux");
429 cpl_propertylist_update_float(extra,
"APCOR3",apcor3);
430 cpl_propertylist_set_comment(extra,
"APCOR3",
"Stellar aperture correction - 1x core flux");
431 cpl_propertylist_update_float(extra,
"APCOR4",apcor4);
432 cpl_propertylist_set_comment(extra,
"APCOR4",
"Stellar aperture correction - sqrt(2)x core flux");
433 cpl_propertylist_update_float(extra,
"APCOR5",apcor5);
434 cpl_propertylist_set_comment(extra,
"APCOR5",
"Stellar aperture correction - 2x core flux");
435 cpl_propertylist_update_float(extra,
"APCOR6",apcor6);
436 cpl_propertylist_set_comment(extra,
"APCOR6",
"Stellar aperture correction - 2*sqrt(2)x core flux");
437 cpl_propertylist_update_float(extra,
"APCOR7",apcor7);
438 cpl_propertylist_set_comment(extra,
"APCOR7",
"Stellar aperture correction - 4x core flux");
441 cpl_propertylist_update_float(extra,
"APCORPK",apcpkht);
442 cpl_propertylist_set_comment(extra,
"APCORPK",
"Stellar aperture correction - peak height");
443 cpl_propertylist_update_float(extra,
"APCOR1",apcor1);
444 cpl_propertylist_set_comment(extra,
"APCOR1",
"Stellar aperture correction - 1/2x core flux");
445 cpl_propertylist_update_float(extra,
"APCOR2",apcor2);
446 cpl_propertylist_set_comment(extra,
"APCOR2",
"Stellar aperture correction - core/sqrt(2) flux");
447 cpl_propertylist_update_float(extra,
"APCOR3",apcor3);
448 cpl_propertylist_set_comment(extra,
"APCOR3",
"Stellar aperture correction - 1x core flux");
449 cpl_propertylist_update_float(extra,
"APCOR4",apcor4);
450 cpl_propertylist_set_comment(extra,
"APCOR4",
"Stellar aperture correction - sqrt(2)x core flux");
451 cpl_propertylist_update_float(extra,
"APCOR5",apcor5);
452 cpl_propertylist_set_comment(extra,
"APCOR5",
"Stellar aperture correction - 2x core flux");
453 cpl_propertylist_update_float(extra,
"APCOR6",apcor6);
454 cpl_propertylist_set_comment(extra,
"APCOR6",
"Stellar aperture correction - 2*sqrt(2)x core flux");
455 cpl_propertylist_update_float(extra,
"APCOR7",apcor7);
456 cpl_propertylist_set_comment(extra,
"APCOR7",
"Stellar aperture correction - 4x core flux");
462 cpl_propertylist_update_string(extra,
"SYMBOL1",
"{Ellipticity Position_angle Areal_1_profile Classification} {el");
463 cpl_propertylist_update_string(extra,
"SYMBOL2",
"lipse blue (1.0-$Ellipticity) $Position_angle+90 {} $Classific");
464 cpl_propertylist_update_string(extra,
"SYMBOL3",
"ation==1} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)} : {");
465 cpl_propertylist_update_string(extra,
"SYMBOL4",
"Ellipticity Position_angle Areal_1_profile Classification} {el");
466 cpl_propertylist_update_string(extra,
"SYMBOL5",
"lipse red (1.0-$Ellipticity) $Position_angle+90 {} $Classific");
467 cpl_propertylist_update_string(extra,
"SYMBOL6",
"ation==-1} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)} :");
468 cpl_propertylist_update_string(extra,
"SYMBOL7",
"{Ellipticity Position_angle Areal_1_profile Classification} {el");
469 cpl_propertylist_update_string(extra,
"SYMBOL8",
"lipse green (1.0-$Ellipticity) $Position_angle+90 {} $Classifi");
470 cpl_propertylist_update_string(extra,
"SYMBOL9",
"cation==0} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)}");
505 static void anhist(
float *data,
int n,
float *medval,
float *sigma) {
506 int i,*histo,ilev,imax,ismax;
507 float *sval,hmax,smax,hlim,ratio;
511 histo = cpl_calloc(MAXHIST,
sizeof(
int));
512 sval = cpl_calloc(MAXHIST,
sizeof(
float));
516 for (i = 0; i < n; i++) {
517 ilev = vircam_nint(data[i]/STEP);
518 if (ilev >= -10 && ilev <= 100) {
528 for (i = 0; i < MAXHIST; i++) {
529 if (histo[i] > hmax) {
530 hmax = (float)histo[i];
539 *medval = data[(n+1)/2-1];
540 *sigma = 1.48*0.5*(data[(3*n+3)/4-1] - data[(n+3)/4-1]);
553 for (i = 1; i < MAXHIST-1; i++) {
554 sval[i] = (histo[i-1] + histo[i] + histo[i+1])/3.0;
555 if (sval[i] > smax) {
562 hmax = (float)histo[imax];
567 for (i = imax-1; i > 0; i--) {
568 if (sval[i] >= sval[i+1] && sval[i] >= sval[i-1]) {
569 if (sval[i] > 0.5*smax)
575 hmax = (float)histo[imax];
580 *medval = min((
float)(imax-10)*STEP,data[(n+1)/2-1]);
581 hlim = vircam_nint(0.5*hmax);
583 while (histo[imax-i] > hlim && imax-i > 1)
585 ratio = hmax/max(1.0,(
float)histo[imax-i]);
586 *sigma = (float)i*STEP/(sqrt(2.0)*max(1.0,log(ratio)));
587 *sigma = max(*sigma,0.5*STEP);
636 static void boundaries(
float *core1,
float *core2,
float *core3,
float medval1,
637 float sigma1,
float medval2,
float sigma2,
int small,
638 float area1,
float area2,
float *wt,
float *avsig,
639 float *lower,
float *upper) {
641 float c1,c2,dc,*work,xnoise,xmag,xflux,ratio,asign,junk;
645 work = cpl_malloc(nrows*
sizeof(
float));
651 asign = ((small == 1) ? -1.0 : 1.0);
656 for (i = 0; i < nrows; i++) {
660 dc = asign*(c2 - c1);
661 if (dc > medval1 - 3.0*sigma1 && c1 < blim - 3.0)
662 work[n++] = dc - medval1;
666 if (dc > medval2 - 3.0*sigma2 && c1 < blim - 3.0)
667 work[n++] = dc - medval2;
673 medstat(work,n,avsig,&junk);
679 *wt = min(5.0,max(1.0,*avsig/sigma1));
680 xnoise = sqrt(area1)*skynoise;
682 *wt = min(2.5,max(1.0,*avsig/sigma2));
683 xnoise = sqrt(area2)*skynoise;
688 for (i = 0; i < NSAMPLE; i++) {
689 xmag = 5.0 + (float)(i+1)*0.1;
690 xflux = pow(10.0,(
double)(0.4*xmag));
691 ratio = COREMAG(1.0+xnoise/xflux,0.0,0.0);
693 lower[i] = medval1 - 3.0*sqrt(sigma1*sigma1 + ratio*ratio);
694 upper[i] = medval1 + 3.0*sqrt(sigma1*sigma1 + 0.5*ratio*ratio);
696 lower[i] = medval2 - 3.0*sqrt(sigma2*sigma2 + ratio*ratio);
697 upper[i] = medval2 + 3.0*sqrt(sigma2*sigma2 + 0.5*ratio*ratio);
700 upper[0] = ((poor == 0) ? medval1 : medval2);
737 static void boundpk(
float *core,
float *pkht,
float medval,
float sigma,
738 float *wt,
float *avsig,
float *lower,
float *upper) {
740 float c,p,*work,xnoise,xmag,pmag,xflux,pflux,ratio,junk;
744 work = cpl_malloc(nrows*
sizeof(
float));
749 for (i = 0; i < nrows; i++) {
752 if (c - p > medval - 3.0*sigma && c < blim - 3.0)
753 work[n++] = c - p - medval;
758 medstat(work,n,avsig,&junk);
760 *wt = min(5.0,max(1.0,*avsig/sigma));
764 xnoise = sqrt(PI*rcore*rcore)*skynoise;
765 for (i = 0; i < NSAMPLE; i++) {
766 xmag = 5.0 + (float)(i+1)*0.1;
767 pmag = xmag - medval;
768 xflux = pow(10.0,(
double)(0.4*xmag));
769 pflux = pow(10.0,(
double)(0.4*pmag));
770 ratio = 2.5*log10((
double)(1.0+max(xnoise/xflux,skynoise/pflux)));
771 lower[i] = medval - 3.0*sqrt(sigma*sigma + ratio*ratio);
772 upper[i] = medval + 3.0*sqrt(sigma*sigma + 0.5*ratio*ratio);
798 static void classify_run() {
799 float fluxlim,ell,pk,pkht,core,sig1,sig2,sig3,denom,w1,w2,w3;
800 float core_small,core_large,core_midd,statistic,statcut,sigtot;
801 float fit0,sigma0,xnoise,xmag,ratio,xflux,ratell,ratscl,ellbound;
802 float *lower,*upper,sigma1,sigma2,sigma3,sigma4,sigma5,sigma6,sigma7;
803 float *work,avsatnew,junk;
810 fluxlim = 2.5*log10((
double)(5.0*sqrt(PI*rcore*rcore)*skynoise));
811 flim = min(flim,max(6.0,fluxlim+3.0));
812 corlim = min(blim,max(12.5,fluxlim+5.0));
813 cormin = min(blim,max(12.5,fluxlim+5.0));
819 for (i = 0; i < nrows; i++) {
820 xflux = core_flux[i];
821 cmin = min(cmin,xflux);
822 cmax = max(cmax,xflux);
824 cmin = max(fluxlim-0.5,cmin);
826 cmax = min(cmax,20.0);
835 classstats(core_flux,core1_flux,1,0.2,&fit1,&sigma1);
839 classstats(core_flux,core3_flux,0,0.1,&fit2,&sigma2);
843 classstats(core_flux,core2_flux,0,0.0,&fit4,&sigma4);
847 classstats(core_flux,core4_flux,0,0.1,&fit5,&sigma5);
851 classstats(core_flux,peak_mag,1,0.2,&fit3,&sigma3);
855 classstats_ellf(fluxlim);
863 lower1 = cpl_malloc(NSAMPLE*
sizeof(
float));
864 lower2 = cpl_malloc(NSAMPLE*
sizeof(
float));
865 lower3 = cpl_malloc(NSAMPLE*
sizeof(
float));
866 upper1 = cpl_malloc(NSAMPLE*
sizeof(
float));
867 upper2 = cpl_malloc(NSAMPLE*
sizeof(
float));
868 upper3 = cpl_malloc(NSAMPLE*
sizeof(
float));
874 boundaries(core_flux,core1_flux,core2_flux,fit1,sigma1,fit4,sigma4,
875 1,PI*rcore*rcore,2.0*PI*rcore*rcore,&wt1,&avsig1,lower1,
880 boundaries(core_flux,core3_flux,core4_flux,fit2,sigma2,fit5,sigma5,
881 0,4.0*PI*rcore*rcore,8.0*PI*rcore*rcore,&wt2,&avsig2,lower2,
886 boundpk(core_flux,peak_mag,fit3,sigma3,&wt3,&avsig3,lower3,upper3);
895 lower = cpl_malloc(NSAMPLE*
sizeof(
float));
896 upper = cpl_malloc(NSAMPLE*
sizeof(
float));
897 uppere = cpl_malloc(NSAMPLE*
sizeof(
float));
898 xnoise = sqrt(PI*rcore*rcore)*skynoise;
899 ratell = xnoise/pow(10.0,0.4*(fluxlim+1.5));
900 ratell = COREMAG(1.0+ratell,0.0,0.0);
901 ratscl = (pow((fitellf + 2.0*sigellf - fitell),2.0) - 4.0*sigell*sigell)/(4.0*ratell*ratell);
902 ratscl = max(0.25,min(10.0,ratscl));
903 for (i = 0; i < NSAMPLE; i++) {
904 xmag = 5.0 + 0.1*(float)(i+1);
905 xflux = pow(10.0,0.4*xmag);
906 ratio = 2.5*log10(1.0+xnoise/xflux);
907 lower[i] = fit_final - 5.0*sqrt(sigma_final*sigma_final + ratio*ratio);
908 upper[i] = fit_final + sqrt(9.0*sigma_final*sigma_final + 0.0*ratio*ratio);
909 uppere[i] = fitell + 2.0*sqrt(sigell*sigell + ratscl*ratio*ratio);
910 uppere[i] = min(0.5,uppere[i]);
912 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
913 fluxlim = 2.5*log10((
double)(2.5*sqrt(PI*rcore*rcore)*skynoise));
921 for (i = 0; i < nrows; i++) {
922 ell = ellipticity[i];
923 pk = peak_height[i] + skylevel;
926 iarg = vircam_nint(10.0*(core - 5.0));
927 iarg = max(1,min(NSAMPLE,iarg)) - 1;
929 sig1 = max(0.01,(fit1 - lower1[iarg])/3.0);
930 sig2 = max(0.01,(fit2 - lower2[iarg])/3.0);
932 sig1 = max(0.01,(fit4 - lower1[iarg])/3.0);
933 sig2 = max(0.01,(fit5 - lower2[iarg])/3.0);
935 sig3 = max(0.01,(fit3 - lower3[iarg])/3.0);
936 denom = (wt1/sig1 + wt2/sig2 + wt3/sig3);
937 w1 = (wt1/sig1)/denom;
938 w2 = (wt2/sig2)/denom;
939 w3 = (wt3/sig3)/denom;
941 core_small = core1_flux[i];
942 core_large = core3_flux[i];
943 statistic = (core - core_small - fit1)*w1 +
944 (max(-3.0*sig2,core_large - core - fit2))*w2 +
945 (core - pkht - fit3)*w3;
947 core_midd = core2_flux[i];
948 core_large = core4_flux[i];
949 statistic = (core_midd - core - fit4)*w1 +
950 (max(-3.0*sig2,core_large - core - fit5))*w2 +
951 (core - pkht - fit3)*w3;
954 statcut = upper[iarg] + 3.0*sigma_final*(exp(max(0.0,core-corlim+1.0)) - 1.0);
955 if (statistic >= statcut)
957 else if (statistic <= lower[iarg])
962 sigtot = (fit_final - lower[iarg])/5.0;
963 sig[i] = (statistic - fit_final)/sigtot;
968 if (core - pkht - fit3 < -4.0*sig3)
973 ellbound = max(elllim,uppere[iarg]);
974 if (ell > ellbound && cls[i] == -1.0 && core < flim && sig[i] > -2.0)
979 if (core > corlim && statistic >= lower[iarg])
984 if (ell > 0.9 && core < corlim)
996 else if (cls[i] == 1.0)
998 else if (cls[i] == -2.0)
1007 classstats_ap67(core5_flux,core3_flux,&fit6,&sigma6);
1008 classstats_ap67(core_flux,core6_flux,&fit7,&sigma7);
1011 classstats_ap0(&fit0,&sigma0);
1013 fit0 = max(fit6,fit0);
1015 fit0 = max(fit5,fit0);
1016 apcpkht = fit0 + fit3;
1019 apcor1 = fit0 + fit1;
1021 apcor2 = fit0 - fit4;
1022 apcor3 = fit0 - fit2;
1023 apcor4 = fit0 - fit5;
1027 apcor1 = fit0 + fit1;
1028 apcor2 = fit0 + fit7;
1030 apcor4 = fit0 - fit4;
1031 apcor5 = fit0 - fit2;
1032 apcor6 = fit0 - fit5;
1033 apcor7 = fit0 - fit6;
1040 work = cpl_malloc(nrows*
sizeof(
float));
1041 for (i = 0; i < nrows; i++) {
1042 ell = ellipticity[i];
1043 core = core_flux[i];
1044 pkht = max(thresh,peak_height[i]) + skylev[i];
1045 if (((ell < elllim && core > flim && cls[i] == -1 && sig[i] >= 5.0 &&
1046 areal[0][i] >= pixlim) || pkht >= 0.9*avsat) && xpos[i] >= xmin &&
1047 xpos[i] <= xmax && ypos[i] >= ymin && ypos[i] <= ymax) {
1052 medstat(work,ii,&avsatnew,&junk);
1053 avsatnew = max(10000.0+skylevel,avsatnew);
1055 avsatnew = 10000.0 + skylevel;
1104 static void classstats(
float *core1,
float *core2,
int small,
float cutlev,
1105 float *medval,
float *sigma) {
1108 float *work,*dc,sigmaold,amult;
1114 amult = (small == 1 ? -1.0 : 1.0);
1118 work = cpl_malloc(nrows*
sizeof(
float));
1119 dc = cpl_malloc(nrows*
sizeof(
float));
1123 for (i = 0; i < nrows; i++)
1124 dc[i] = amult*(core2[i] - core1[i]);
1128 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1134 for (i = 0; i < nrows; i++) {
1138 if (ellipticity[i] < elllim && core1[i] < blim && core1[i] > flim &&
1139 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
1140 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
1141 ypos[i] <= ymax && areal[0][i] >= pixlim) {
1142 if (iloop > 0 || (iloop == 0 && dc[i] >= cutlev))
1152 anhist(work,n,medval,sigma);
1154 medstat(work,n,medval,sigma);
1155 *sigma = min(sigmaold,*sigma);
1164 *sigma = max(*sigma,0.01);
1190 static void classstats_el(
void) {
1201 work = cpl_malloc(nrows*
sizeof(
float));
1205 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1207 for (i = 0; i < nrows; i++) {
1208 if (ellipticity[i] < 0.5 && core_flux[i] < blim &&
1209 core_flux[i] > flim &&
1210 fabs(ellipticity[i] - fitell) < 2.0*sigell &&
1211 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
1212 ypos[i] <= ymax && areal[0][i] >= pixlim)
1213 work[n++] = ellipticity[i];
1216 medstat(work,n,&fitell,&sigell);
1222 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
1246 static void classstats_pa() {
1257 work = cpl_malloc(nrows*
sizeof(
float));
1261 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1263 for (i = 0; i < nrows; i++) {
1264 if (core_flux[i] < blim && core_flux[i] > flim &&
1265 fabs(pa[i] - fitpa) < 2.0*sigpa &&
1266 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
1267 ypos[i] <= ymax && areal[0][i] >= pixlim)
1271 medstat(work,n,&fitpa,&sigpa);
1303 static void classstats_ellf(
float fluxlim) {
1314 work = cpl_malloc(nrows*
sizeof(
float));
1318 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1320 for (i = 0; i < nrows; i++) {
1321 if (ellipticity[i] < 0.75 && core_flux[i] > fluxlim+1.0 &&
1322 core_flux[i] < fluxlim+2.0 &&
1323 fabs(ellipticity[i] - fitellf) < 2.0*sigellf)
1324 work[n++] = ellipticity[i];
1327 medstat(work,n,&fitellf,&sigellf);
1361 static void classstats_ap0(
float *medval,
float *sigma) {
1364 float *work,*dc,c2,sigmanew;
1370 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
1374 work = cpl_malloc(nrows*
sizeof(
float));
1375 dc = cpl_malloc(nrows*
sizeof(
float));
1379 for (i = 0; i < nrows; i++) {
1380 c2 = max(0.0,max(iso_flux[i],core5_flux[i]));
1381 dc[i] = c2 - core_flux[i];
1386 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1391 for (i = 0; i < nrows; i++) {
1395 if (ellipticity[i] < elllim && core_flux[i] < blim &&
1396 core_flux[i] > flim &&
1397 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
1398 cls[i] == -1.0 && sig[i] < 5.0 &&
1399 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
1400 ypos[i] <= ymax && areal[0][i] >= pixlim)
1401 if (iloop > 0 || (iloop == 0 && dc[i] >= 0.0)) {
1411 anhist(work,n,medval,sigma);
1412 *sigma = 1.48*(*medval - work[(int)(0.25*(
float)(n+3))-1]);
1413 *sigma = max(0.025,*sigma);
1415 medstat(work,n,medval,&sigmanew);
1416 *sigma = min(*sigma,sigmanew);
1417 *sigma = max(0.01,*sigma);
1426 *sigma = max(*sigma,0.01);
1435 static void classstats_ap67(
float *mag1,
float *mag2,
float *medval,
1439 float *work,*dc,sigmanew;
1445 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
1449 work = cpl_malloc(nrows*
sizeof(
float));
1450 dc = cpl_malloc(nrows*
sizeof(
float));
1454 for (i = 0; i < nrows; i++)
1455 dc[i] = mag1[i] - mag2[i];
1459 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1464 for (i = 0; i < nrows; i++) {
1468 if (ellipticity[i] < elllim && core_flux[i] < blim &&
1469 core_flux[i] > flim &&
1470 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
1471 cls[i] == -1.0 && sig[i] < 5.0 &&
1472 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
1473 ypos[i] <= ymax && areal[0][i] >= pixlim) {
1474 if (iloop > 0 || (iloop == 0 && dc[i] >= 0.0)) {
1485 anhist(work,n,medval,sigma);
1486 *sigma = 1.48*(*medval - work[(int)(0.25*(
float)(n+3))-1]);
1487 *sigma = max(0.025,*sigma);
1489 medstat(work,n,medval,&sigmanew);
1490 *sigma = min(*sigma,sigmanew);
1491 *sigma = max(0.01,*sigma);
1500 *sigma = max(*sigma,0.01);
1528 static void classstats_final(
void) {
1529 int n,i,iloop,iarg,ii,iend,ncls,kk,k;
1530 float *work,ell,core,sig1,sig2,sig3,denom,w1,w2,w3,core_small;
1531 float core_large,*statistic,core_midd,pkht,xcor,cfit,csig;
1532 float *work1,junk,corlim1,corval1,corlim2,corval2,sigmaold;
1536 sigma_final = 1.0e6;
1542 work = cpl_malloc(nrows*
sizeof(
float));
1543 work1 = cpl_malloc(nrows*
sizeof(
float));
1544 statistic = cpl_malloc(nrows*
sizeof(
float));
1548 for (i = 0; i < nrows; i++) {
1549 ell = ellipticity[i];
1551 core = core_flux[i];
1552 iarg = vircam_nint(10.0*(core - 5.0));
1553 iarg = max(1,min(NSAMPLE,iarg)) - 1;
1555 sig1 = max(0.01,(fit1 - lower1[iarg])/3.0);
1556 sig2 = max(0.01,(fit2 - lower2[iarg])/3.0);
1558 sig1 = max(0.01,(fit4 - lower1[iarg])/3.0);
1559 sig2 = max(0.01,(fit5 - lower2[iarg])/3.0);
1561 sig3 = max(0.01,(fit3 - lower3[iarg])/3.0);
1562 denom = (wt1/sig1 + wt2/sig2 + wt3/sig3);
1563 w1 = (wt1/sig1)/denom;
1564 w2 = (wt2/sig2)/denom;
1565 w3 = (wt3/sig3)/denom;
1567 core_small = core1_flux[i];
1568 core_large = core3_flux[i];
1569 statistic[i] = (core - core_small - fit1)*w1 +
1570 (core_large - core - fit2)*w2 + (core - pkht - fit3)*w3;
1572 core_midd = core2_flux[i];
1573 core_large = core4_flux[i];
1574 statistic[i] = (core_midd - core - fit4)*w1 +
1575 (core_large - core - fit5)*w2 + (core - pkht - fit3)*w3;
1582 for (iloop = 0; iloop < MAXLOOP; iloop++) {
1583 sigmaold = sigma_final;
1585 for (i = 0; i < nrows ; i++) {
1587 ell = ellipticity[i];
1588 core = core_flux[i];
1589 if (ell < elllim && core < blim && core > flim &&
1590 fabs((
double)(statistic[i] - fit_final)) < 3.0*sigma_final &&
1591 areal[0][i] >= pixlim)
1592 work[n++] = statistic[i];
1597 if (core > corlim && iloop == MAXLOOP-2) {
1598 cls[ncls] = statistic[i];
1607 if (iloop == 0 && n > 10) {
1608 anhist(work,n,&fit_final,&sigma_final);
1610 medstat(work,n,&fit_final,&sigma_final);
1612 sigma_final = max(0.01,min(sigmaold,sigma_final));
1621 sort2(sig,cls,ncls);
1630 while (iend == 0 && i < ncls-1) {
1632 if (sig[i] > xcor+0.25 && ii >= 3) {
1633 medstat(work,ii,&cfit,&csig);
1634 for (iloop = 0; iloop < 3; iloop++) {
1636 for (k = 0; k < ii; k++) {
1637 if (work[k] <= cfit + 3.0*csig)
1638 work1[kk++] = work[k];
1640 medstat(work1,kk,&cfit,&junk);
1642 if (cfit <= fit_final + 3.0*sigma_final) {
1651 work[ii++] = cls[i];
1658 corlim = corlim2 - 0.5*(corval2 - fit_final - 3.0*sigma_final)/(corval2 - corval1);
1661 corlim = max(cormin,corlim);
1663 for (i = 0; i < nrows; i++) {
1664 core = core_flux[i];
1666 work[kk++] = peak_height[i] + skylevel;
1669 medstat(work,kk,&avsat,&junk);
1670 avsat = max(10000.0+skylevel,avsat);
1672 avsat = 10000.0 + skylevel;
1679 freespace(statistic);
1709 static void medstat(
float *array,
int n,
float *medval,
float *sigval) {
1725 *medval = array[lev1-1];
1726 *sigval = 1.48*0.5*(array[lev2-1] - array[lev3-1]);
1750 static void sort1(
float *a,
int n) {
1751 int iii,ii,i,ifin,j;
1757 iii = min(n,(3*iii)/4 - 1);
1762 for (ii = 0; ii < ifin; ii++) {
1771 if (i < 0 || a[i] <= b)
1804 static void sort2(
float *a1,
float *a2,
int n) {
1805 int iii,ii,i,ifin,j;
1811 iii = min(n,(3*iii)/4 - 1);
1816 for (ii = 0; ii < ifin; ii++) {
1819 if (a1[i] > a1[j]) {
1827 if (i < 0 || a1[i] <= b1)
cpl_table * vircam_tfits_get_table(vir_tfits *p)
cpl_propertylist * vircam_tfits_get_ehu(vir_tfits *p)
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
int classify(vir_tfits *catalogue, cpl_propertylist *plist, float minsize, int cattype)
Do star/galaxy classification.