00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <strings.h>
00032
00033 #include <cpl.h>
00034 #include <vircam_utils.h>
00035 #include <vircam_pfits.h>
00036 #include "classify.h"
00037
00038 #define MAXHIST 111
00039 #define STEP 0.05
00040 #define NSAMPLE 150
00041 #define MAXLOOP 5
00042 #define BLIMDEF 15.0;
00043 #define FLIMDEF 11.0;
00044 #define CMINDEF 7.5
00045 #define CMAXDEF 15.0
00046 #define NAREAL 8
00047 #define PI 3.14159265358979323846
00048 #define DEGRAD 57.2957795130823229
00049
00050 #define COREMAG(A,B,C) 2.5*log10((double)(max(C,A-B)))
00051 #define MAX(A,B) (A > B ? A : B)
00052
00053
00054
00055 static long nrows;
00056 static float thresh,skylevel,skynoise,rcore,exptime;
00057
00058
00059
00060 static int poor;
00061 static float sigell,fitell,elllim,sigellf,fitellf,sigpa,fitpa;
00062 static float blim,flim,cmin,cmax;
00063 static float fit1,fit2,fit3,fit4,fit5,fit6,fit7;
00064 static float fit_final,sigma_final;
00065 static float *lower1,*lower2,*lower3,*upper1,*upper2,*upper3,*uppere;
00066 static float avsig1,avsig2,avsig3,wt1,wt2,wt3;
00067
00068
00069
00070 static int nstar,ngal,njunk,ncmp;
00071
00072
00073
00074 static float avsat,corlim,cormin,apcpkht,apcor,apcor1,apcor2,apcor3,apcor4;
00075 static float apcor5,apcor6,apcor7;
00076
00077
00078
00079 static float *workspace = NULL;
00080 static cpl_table *catcopy = NULL;
00081 static float *areal[NAREAL];
00082 static float *core_flux,*core1_flux,*core2_flux,*core3_flux,*core4_flux;
00083 static float *core5_flux,*peak_height,*peak_mag,*ellipticity,*iso_flux;
00084 static float *total_flux,*cls,*sig,*xpos,*ypos,*pa,*core6_flux,*skylev;
00085
00086
00087
00088
00089 #define NCOL32 14
00090 #define NCOL80 15
00091
00092 static const char *cols32[NCOL32] = {"Core_flux","Core1_flux","Core2_flux",
00093 "Core3_flux","Core4_flux","Peak_height",
00094 "Ellipticity","Isophotal_flux",
00095 "Total_flux","Core5_flux","X_coordinate",
00096 "Y_coordinate","Position_angle",
00097 "Skylev"};
00098
00099 static const char *cols80[NCOL80] = {"Aper_flux_3","Aper_flux_1","Aper_flux_4",
00100 "Aper_flux_5","Aper_flux_6","Peak_height",
00101 "Ellipticity","Isophotal_flux",
00102 "Isophotal_flux","Aper_flux_7",
00103 "X_coordinate","Y_coordinate",
00104 "Position_angle","Sky_level",
00105 "Aper_flux_2"};
00106
00107 static int ncols;
00108 static float xmin;
00109 static float xmax;
00110 static float ymin;
00111 static float ymax;
00112 static float pixlim;
00113
00114 #define FRAMECUT 0.05
00115
00116
00117
00118 static void anhist(float *, int, float *, float *);
00119 static void boundaries(float *, float *, float *, float, float, float, float,
00120 int, float, float, float *, float *, float *, float *);
00121 static void boundpk(float *, float *, float, float, float *, float *,
00122 float *, float *);
00123 static void classify_run(void);
00124 static void classstats(float *, float *, int, float, float *, float *);
00125 static void classstats_ap0(float *, float *);
00126 static void classstats_ap67(float *, float *, float *, float *);
00127 static void classstats_el(void);
00128 static void classstats_pa(void);
00129 static void classstats_ellf(float);
00130 static void classstats_final(void);
00131 static void medstat(float *, int, float *, float *);
00132 static void sort1(float *, int);
00133 static void sort2(float *, float *, int);
00134
00137
00202
00203
00204 extern int classify(vir_tfits *catalogue, cpl_propertylist *plist,
00205 float minsize, int cattype) {
00206 float fwhm,*work,moff;
00207 float pkht,ell,core,ap,delap,area,junk,arg;
00208 char *cols[MAX(NCOL32,NCOL80)],colname[32];
00209 cpl_propertylist *extra;
00210 cpl_table *cat;
00211 const char *fctid = "vircam_classify";
00212 int i,n,iap,i1,i2,nxout,nyout;
00213
00214
00215
00216 extra = vircam_tfits_get_ehu(catalogue);
00217 thresh = cpl_propertylist_get_float(extra,"ESO DRS THRESHOL");
00218 skylevel = cpl_propertylist_get_float(extra,"ESO QC MEAN_SKY");
00219 skynoise = cpl_propertylist_get_float(extra,"ESO QC SKY_NOISE");
00220 rcore = cpl_propertylist_get_float(extra,"ESO DRS RCORE");
00221 fwhm = cpl_propertylist_get_float(extra,"ESO DRS SEEING");
00222 nxout = cpl_propertylist_get_int(extra,"ESO DRS NXOUT");
00223 nyout = cpl_propertylist_get_int(extra,"ESO DRS NYOUT");
00224 xmin = FRAMECUT*(float)nxout;
00225 xmax = (1.0 - FRAMECUT)*(float)nxout;
00226 ymin = FRAMECUT*(float)nyout;
00227 ymax = (1.0 - FRAMECUT)*(float)nyout;
00228 pixlim = minsize;
00229
00230
00231
00232 if (vircam_pfits_get_exptime(plist,&exptime) != VIR_OK) {
00233 cpl_msg_warning(fctid,"Unable to get expsoure time!");
00234 exptime = 10.0;
00235 }
00236
00237
00238
00239 cat = vircam_tfits_get_table(catalogue);
00240 ncols = cpl_table_get_ncol(cat);
00241 switch (cattype) {
00242 case 1:
00243 for (i = 0; i < NCOL32; i++)
00244 cols[i] = (char *)cols32[i];
00245 break;
00246 case 2:
00247 for (i = 0; i < NCOL80; i++)
00248 cols[i] = (char *)cols80[i];
00249 break;
00250 default:
00251 cpl_msg_error(fctid,"Don't recognise catalogues with %" CPL_SIZE_FORMAT " columns: cattype == %" CPL_SIZE_FORMAT,(cpl_size)ncols,(cpl_size)cattype);
00252 return(VIR_FATAL);
00253 }
00254
00255
00256
00257
00258 catcopy = cpl_table_duplicate(cat);
00259 nrows = cpl_table_get_nrow(cat);
00260 core_flux = cpl_table_get_data_float(catcopy,cols[0]);
00261 core1_flux = cpl_table_get_data_float(catcopy,cols[1]);
00262 core2_flux = cpl_table_get_data_float(catcopy,cols[2]);
00263 core3_flux = cpl_table_get_data_float(catcopy,cols[3]);
00264 core4_flux = cpl_table_get_data_float(catcopy,cols[4]);
00265 peak_height = cpl_table_get_data_float(catcopy,cols[5]);
00266 ellipticity = cpl_table_get_data_float(catcopy,cols[6]);
00267 iso_flux = cpl_table_get_data_float(catcopy,cols[7]);
00268 total_flux = cpl_table_get_data_float(catcopy,cols[8]);
00269 core5_flux = cpl_table_get_data_float(catcopy,cols[9]);
00270 xpos = cpl_table_get_data_float(catcopy,cols[10]);
00271 ypos = cpl_table_get_data_float(catcopy,cols[11]);
00272 pa = cpl_table_get_data_float(catcopy,cols[12]);
00273 skylev = cpl_table_get_data_float(catcopy,cols[13]);
00274 if (cattype == 2)
00275 core6_flux = cpl_table_get_data_float(catcopy,cols[14]);
00276 else
00277 core6_flux = NULL;
00278 cls = cpl_table_get_data_float(cat,"Classification");
00279 sig = cpl_table_get_data_float(cat,"Statistic");
00280
00281
00282
00283 workspace = cpl_malloc(2*nrows*sizeof(float));
00284 peak_mag = workspace;
00285 work = workspace + nrows;
00286
00287
00288
00289 for (i = 0; i < nrows; i++) {
00290 core_flux[i] = COREMAG(core_flux[i],0.0,1.0);
00291 core1_flux[i] = COREMAG(core1_flux[i],0.0,1.0);
00292 core2_flux[i] = COREMAG(core2_flux[i],0.0,1.0);
00293 core3_flux[i] = COREMAG(core3_flux[i],0.0,1.0);
00294 core4_flux[i] = COREMAG(core4_flux[i],0.0,1.0);
00295 core5_flux[i] = COREMAG(core5_flux[i],0.0,1.0);
00296 moff = 1.0/(1.0 - pow((thresh/MAX(peak_height[i],thresh)),0.6));
00297 iso_flux[i] = COREMAG(moff*iso_flux[i],0.0,1.0);
00298 peak_mag[i] = COREMAG(peak_height[i],skynoise,0.1);
00299 }
00300 if (core6_flux != NULL)
00301 for (i = 0; i < nrows; i++)
00302 core6_flux[i] = COREMAG(core6_flux[i],0.0,1.0);
00303 if (ncols == 32)
00304 for (i = 0; i < nrows; i++)
00305 total_flux[i] = COREMAG(total_flux[i],0.0,1.0);
00306
00307
00308
00309 for (i = 0; i < NAREAL; i++) {
00310 sprintf(colname,"Areal_%d_profile",i+1);
00311 areal[i] = cpl_table_get_data_float(catcopy,colname);
00312 }
00313
00314
00315
00316 poor = 0;
00317 if (fwhm > max(5.0,rcore*sqrt(2.0)))
00318 poor = 1;
00319
00320
00321
00322 classify_run();
00323
00324
00325
00326 n = 0;
00327 for (i = 0; i < nrows; i++) {
00328 pkht = peak_height[i];
00329 ell = ellipticity[i];
00330 core = core_flux[i];
00331 if (cls[i] == -1.0 && ell < elllim && core < corlim &&
00332 pkht > 10.0*thresh) {
00333 ap = log(0.5*pkht/thresh)/log(2.0) + 1.0;
00334 iap = (int)ap;
00335 delap = ap - (float)iap;
00336 if (iap > 0 && iap < NAREAL && areal[1][i] > 0.0) {
00337 i1 = (iap-1)*nrows + i;
00338 i2 = iap*nrows + i;
00339 area = areal[iap-1][i]*(1.0 - delap) + areal[iap][i]*delap;
00340 work[n++] = 2.0*sqrt(area/PI);
00341 }
00342 }
00343 }
00344 if (n > 2) {
00345 medstat(work,n,&fwhm,&junk);
00346
00347
00348
00349 arg = 0.25*PI*fwhm*fwhm - 1;
00350 fwhm = 2.0*sqrt(max(0.0,arg/PI));
00351
00352 } else
00353 fwhm = -1.0;
00354
00355
00356
00357 freespace(workspace);
00358 freetable(catcopy);
00359
00360
00361
00362 cpl_propertylist_update_float(extra,"ESO QC IMAGE_SIZE",fwhm);
00363 cpl_propertylist_set_comment(extra,"ESO QC IMAGE_SIZE",
00364 "[pixels] Average FWHM of stellar objects");
00365 cpl_propertylist_update_float(extra,"ESO QC ELLIPTICITY",fitell);
00366 cpl_propertylist_set_comment(extra,"ESO QC ELLIPTICITY",
00367 "Average stellar ellipticity (1-b/a)");
00368 cpl_propertylist_update_float(extra,"ESO QC POSANG",fitpa);
00369 cpl_propertylist_set_comment(extra,"ESO QC POSANG",
00370 "[degrees] Median position angle");
00371 switch (cattype) {
00372 case 1:
00373 cpl_propertylist_update_float(extra,"ESO QC APERTURE_CORR",apcor);
00374 cpl_propertylist_set_comment(extra,"ESO QC APERTURE_CORR",
00375 "Stellar ap-corr 1x core flux");
00376 break;
00377 case 2:
00378 cpl_propertylist_update_float(extra,"ESO QC APERTURE_CORR",apcor3);
00379 cpl_propertylist_set_comment(extra,"ESO QC APERTURE_CORR",
00380 "Stellar ap-corr 1x core flux");
00381 break;
00382 }
00383 cpl_propertylist_update_int(extra,"ESO QC NOISE_OBJ",njunk);
00384 cpl_propertylist_set_comment(extra,"ESO QC NOISE_OBJ",
00385 "Number of noise objects");
00386 cpl_propertylist_update_float(extra,"ESO QC SATURATION",avsat);
00387
00388
00389
00390 cpl_propertylist_update_bool(extra,"ESO DRS CLASSIFD",1);
00391 cpl_propertylist_set_comment(extra,"ESO DRS CLASSIFD",
00392 "Catalogue has been classified");
00393
00394
00395
00396 switch (cattype) {
00397 case 1:
00398 cpl_propertylist_update_float(extra,"APCORPK",apcpkht);
00399 cpl_propertylist_set_comment(extra,"APCORPK","Stellar aperture correction - peak height");
00400 cpl_propertylist_update_float(extra,"APCOR1",apcor1);
00401 cpl_propertylist_set_comment(extra,"APCOR1","Stellar aperture correction - 1/2x core flux");
00402 cpl_propertylist_update_float(extra,"APCOR",apcor);
00403 cpl_propertylist_set_comment(extra,"APCOR","Stellar aperture correction - 1x core flux");
00404 cpl_propertylist_update_float(extra,"APCOR2",apcor2);
00405 cpl_propertylist_set_comment(extra,"APCOR2","Stellar aperture correction - sqrt(2)x core flux");
00406 cpl_propertylist_update_float(extra,"APCOR3",apcor3);
00407 cpl_propertylist_set_comment(extra,"APCOR3","Stellar aperture correction - 2x core flux");
00408 cpl_propertylist_update_float(extra,"APCOR4",apcor4);
00409 cpl_propertylist_set_comment(extra,"APCOR4","Stellar aperture correction - 2*sqrt(2)x core flux");
00410 cpl_propertylist_update_float(extra,"APCOR5",apcor5);
00411 cpl_propertylist_set_comment(extra,"APCOR5","Stellar aperture correction - 4x core flux");
00412 break;
00413 case 2:
00414 cpl_propertylist_update_float(extra,"APCORPK",apcpkht);
00415 cpl_propertylist_set_comment(extra,"APCORPK","Stellar aperture correction - peak height");
00416 cpl_propertylist_update_float(extra,"APCOR1",apcor1);
00417 cpl_propertylist_set_comment(extra,"APCOR1","Stellar aperture correction - 1/2x core flux");
00418 cpl_propertylist_update_float(extra,"APCOR2",apcor2);
00419 cpl_propertylist_set_comment(extra,"APCOR2","Stellar aperture correction - core/sqrt(2) flux");
00420 cpl_propertylist_update_float(extra,"APCOR3",apcor3);
00421 cpl_propertylist_set_comment(extra,"APCOR3","Stellar aperture correction - 1x core flux");
00422 cpl_propertylist_update_float(extra,"APCOR4",apcor4);
00423 cpl_propertylist_set_comment(extra,"APCOR4","Stellar aperture correction - sqrt(2)x core flux");
00424 cpl_propertylist_update_float(extra,"APCOR5",apcor5);
00425 cpl_propertylist_set_comment(extra,"APCOR5","Stellar aperture correction - 2x core flux");
00426 cpl_propertylist_update_float(extra,"APCOR6",apcor6);
00427 cpl_propertylist_set_comment(extra,"APCOR6","Stellar aperture correction - 2*sqrt(2)x core flux");
00428 cpl_propertylist_update_float(extra,"APCOR7",apcor7);
00429 cpl_propertylist_set_comment(extra,"APCOR7","Stellar aperture correction - 4x core flux");
00430
00431 break;
00432 }
00433
00434
00435
00436 cpl_propertylist_update_string(extra,"SYMBOL1","{Ellipticity Position_angle Areal_1_profile Classification} {el");
00437 cpl_propertylist_update_string(extra,"SYMBOL2","lipse blue (1.0-$Ellipticity) $Position_angle+90 {} $Classific");
00438 cpl_propertylist_update_string(extra,"SYMBOL3","ation==1} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)} : {");
00439 cpl_propertylist_update_string(extra,"SYMBOL4","Ellipticity Position_angle Areal_1_profile Classification} {el");
00440 cpl_propertylist_update_string(extra,"SYMBOL5","lipse red (1.0-$Ellipticity) $Position_angle+90 {} $Classific");
00441 cpl_propertylist_update_string(extra,"SYMBOL6","ation==-1} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)} :");
00442 cpl_propertylist_update_string(extra,"SYMBOL7","{Ellipticity Position_angle Areal_1_profile Classification} {el");
00443 cpl_propertylist_update_string(extra,"SYMBOL8","lipse green (1.0-$Ellipticity) $Position_angle+90 {} $Classifi");
00444 cpl_propertylist_update_string(extra,"SYMBOL9","cation==0} {sqrt($Areal_1_profile*(1.0-$Ellipticity)/3.142)}");
00445
00446
00447
00448 return(VIR_OK);
00449 }
00450
00451
00477
00478
00479 static void anhist(float *data, int n, float *medval, float *sigma) {
00480 int i,*histo,ilev,imax,ismax;
00481 float *sval,hmax,smax,hlim,ratio;
00482
00483
00484
00485 histo = cpl_calloc(MAXHIST,sizeof(int));
00486 sval = cpl_calloc(MAXHIST,sizeof(float));
00487
00488
00489
00490 for (i = 0; i < n; i++) {
00491 ilev = vircam_nint(data[i]/STEP);
00492 if (ilev >= -10 && ilev <= 100) {
00493 ilev += 10;
00494 histo[ilev] += 1;
00495 }
00496 }
00497
00498
00499
00500 hmax = 0.0;
00501 imax = 0;
00502 for (i = 0; i < MAXHIST; i++) {
00503 if (histo[i] > hmax) {
00504 hmax = (float)histo[i];
00505 imax = i;
00506 }
00507 }
00508
00509
00510
00511 if (hmax == 0.0) {
00512 if (n >= 10) {
00513 *medval = data[(n+1)/2-1];
00514 *sigma = 1.48*0.5*(data[(3*n+3)/4-1] - data[(n+3)/4-1]);
00515 } else {
00516 *medval = 0.0;
00517 *sigma = 1.0;
00518 }
00519 return;
00520 }
00521
00522
00523
00524
00525 smax = 0.0;
00526 ismax = 0;
00527 for (i = 1; i < MAXHIST-1; i++) {
00528 sval[i] = (histo[i-1] + histo[i] + histo[i+1])/3.0;
00529 if (sval[i] > smax) {
00530 smax = sval[i];
00531 ismax = i;
00532 }
00533 }
00534 if (ismax < imax) {
00535 imax = ismax;
00536 hmax = (float)histo[imax];
00537 }
00538
00539
00540
00541 for (i = imax-1; i > 0; i--) {
00542 if (sval[i] >= sval[i+1] && sval[i] >= sval[i-1]) {
00543 if (sval[i] > 0.5*smax)
00544 ismax = i;
00545 }
00546 }
00547 if (ismax < imax) {
00548 imax = ismax;
00549 hmax = (float)histo[imax];
00550 }
00551
00552
00553
00554 *medval = min((float)(imax-10)*STEP,data[(n+1)/2-1]);
00555 hlim = vircam_nint(0.5*hmax);
00556 i = 1;
00557 while (histo[imax-i] > hlim && imax-i > 1)
00558 i++;
00559 ratio = hmax/max(1.0,(float)histo[imax-i]);
00560 *sigma = (float)i*STEP/(sqrt(2.0)*max(1.0,log(ratio)));
00561 *sigma = max(*sigma,0.5*STEP);
00562
00563
00564
00565 freespace(histo);
00566 freespace(sval);
00567 }
00568
00569
00608
00609
00610 static void boundaries(float *core1, float *core2, float *core3, float medval1,
00611 float sigma1, float medval2, float sigma2, int small,
00612 float area1, float area2, float *wt, float *avsig,
00613 float *lower, float *upper) {
00614 int i,n;
00615 float c1,c2,dc,*work,xnoise,xmag,xflux,ratio,asign,junk;
00616
00617
00618
00619 work = cpl_malloc(nrows*sizeof(float));
00620
00621
00622
00623 lower[0] = cmin;
00624 lower[1] = cmax;
00625 asign = ((small == 1) ? -1.0 : 1.0);
00626
00627
00628
00629 n = 0;
00630 for (i = 0; i < nrows; i++) {
00631 c1 = core1[i];
00632 if (! poor) {
00633 c2 = core2[i];
00634 dc = asign*(c2 - c1);
00635 if (dc > medval1 - 3.0*sigma1 && c1 < blim - 3.0)
00636 work[n++] = dc - medval1;
00637 } else {
00638 c2 = core3[i];
00639 dc = c2 - c1;
00640 if (dc > medval2 - 3.0*sigma2 && c1 < blim - 3.0)
00641 work[n++] = dc - medval2;
00642 }
00643 }
00644
00645
00646
00647 medstat(work,n,avsig,&junk);
00648 freespace(work);
00649
00650
00651
00652 if (! poor) {
00653 *wt = min(5.0,max(1.0,*avsig/sigma1));
00654 xnoise = sqrt(area1)*skynoise;
00655 } else {
00656 *wt = min(2.5,max(1.0,*avsig/sigma2));
00657 xnoise = sqrt(area2)*skynoise;
00658 }
00659
00660
00661
00662 for (i = 0; i < NSAMPLE; i++) {
00663 xmag = 5.0 + (float)(i+1)*0.1;
00664 xflux = pow(10.0,(double)(0.4*xmag));
00665 ratio = COREMAG(1.0+xnoise/xflux,0.0,0.0);
00666 if (! poor) {
00667 lower[i] = medval1 - 3.0*sqrt(sigma1*sigma1 + ratio*ratio);
00668 upper[i] = medval1 + 3.0*sqrt(sigma1*sigma1 + 0.5*ratio*ratio);
00669 } else {
00670 lower[i] = medval2 - 3.0*sqrt(sigma2*sigma2 + ratio*ratio);
00671 upper[i] = medval2 + 3.0*sqrt(sigma2*sigma2 + 0.5*ratio*ratio);
00672 }
00673 }
00674 upper[0] = ((poor == 0) ? medval1 : medval2);
00675 upper[1] = upper[0];
00676 }
00677
00678
00709
00710
00711 static void boundpk(float *core, float *pkht, float medval, float sigma,
00712 float *wt, float *avsig, float *lower, float *upper) {
00713 int i,n;
00714 float c,p,*work,xnoise,xmag,pmag,xflux,pflux,ratio,junk;
00715
00716
00717
00718 work = cpl_malloc(nrows*sizeof(float));
00719
00720
00721
00722 n = 0;
00723 for (i = 0; i < nrows; i++) {
00724 c = core[i];
00725 p = pkht[i];
00726 if (c - p > medval - 3.0*sigma && c < blim - 3.0)
00727 work[n++] = c - p - medval;
00728 }
00729
00730
00731
00732 medstat(work,n,avsig,&junk);
00733 freespace(work);
00734 *wt = min(5.0,max(1.0,*avsig/sigma));
00735
00736
00737
00738 xnoise = sqrt(PI*rcore*rcore)*skynoise;
00739 for (i = 0; i < NSAMPLE; i++) {
00740 xmag = 5.0 + (float)(i+1)*0.1;
00741 pmag = xmag - medval;
00742 xflux = pow(10.0,(double)(0.4*xmag));
00743 pflux = pow(10.0,(double)(0.4*pmag));
00744 ratio = 2.5*log10((double)(1.0+max(xnoise/xflux,skynoise/pflux)));
00745 lower[i] = medval - 3.0*sqrt(sigma*sigma + ratio*ratio);
00746 upper[i] = medval + 3.0*sqrt(sigma*sigma + 0.5*ratio*ratio);
00747 }
00748 upper[0] = medval;
00749 upper[1] = upper[0];
00750 }
00751
00752
00770
00771
00772 static void classify_run() {
00773 float fluxlim,ell,pk,pkht,core,sig1,sig2,sig3,denom,w1,w2,w3;
00774 float core_small,core_large,core_midd,statistic,statcut,sigtot;
00775 float fit0,sigma0,xnoise,xmag,ratio,xflux,ratell,ratscl,ellbound;
00776 float *lower,*upper,sigma1,sigma2,sigma3,sigma4,sigma5,sigma6,sigma7;
00777 float *work,avsatnew,junk;
00778 int i,iarg,ii;
00779
00780
00781
00782 blim = BLIMDEF;
00783 flim = FLIMDEF;
00784 fluxlim = 2.5*log10((double)(5.0*sqrt(PI*rcore*rcore)*skynoise));
00785 flim = min(flim,max(6.0,fluxlim+3.0));
00786 corlim = min(blim,max(12.5,fluxlim+5.0));
00787 cormin = min(blim,max(12.5,fluxlim+5.0));
00788
00789
00790
00791 cmin = CMINDEF;
00792 cmax = CMAXDEF;
00793 for (i = 0; i < nrows; i++) {
00794 xflux = core_flux[i];
00795 cmin = min(cmin,xflux);
00796 cmax = max(cmax,xflux);
00797 }
00798 cmin = max(fluxlim-0.5,cmin);
00799 cmax += 0.1;
00800 cmax = min(cmax,20.0);
00801
00802
00803
00804 classstats_el();
00805
00806
00807
00808
00809 classstats(core_flux,core1_flux,1,0.2,&fit1,&sigma1);
00810
00811
00812
00813 classstats(core_flux,core3_flux,0,0.1,&fit2,&sigma2);
00814
00815
00816
00817 classstats(core_flux,core2_flux,0,0.0,&fit4,&sigma4);
00818
00819
00820
00821 classstats(core_flux,core4_flux,0,0.1,&fit5,&sigma5);
00822
00823
00824
00825 classstats(core_flux,peak_mag,1,0.2,&fit3,&sigma3);
00826
00827
00828
00829 classstats_ellf(fluxlim);
00830
00831
00832
00833 classstats_pa();
00834
00835
00836
00837 lower1 = cpl_malloc(NSAMPLE*sizeof(float));
00838 lower2 = cpl_malloc(NSAMPLE*sizeof(float));
00839 lower3 = cpl_malloc(NSAMPLE*sizeof(float));
00840 upper1 = cpl_malloc(NSAMPLE*sizeof(float));
00841 upper2 = cpl_malloc(NSAMPLE*sizeof(float));
00842 upper3 = cpl_malloc(NSAMPLE*sizeof(float));
00843
00844
00845
00846
00847
00848 boundaries(core_flux,core1_flux,core2_flux,fit1,sigma1,fit4,sigma4,
00849 1,PI*rcore*rcore,2.0*PI*rcore*rcore,&wt1,&avsig1,lower1,
00850 upper1);
00851
00852
00853
00854 boundaries(core_flux,core3_flux,core4_flux,fit2,sigma2,fit5,sigma5,
00855 0,4.0*PI*rcore*rcore,8.0*PI*rcore*rcore,&wt2,&avsig2,lower2,
00856 upper2);
00857
00858
00859
00860 boundpk(core_flux,peak_mag,fit3,sigma3,&wt3,&avsig3,lower3,upper3);
00861
00862
00863
00864
00865 classstats_final();
00866
00867
00868
00869 lower = cpl_malloc(NSAMPLE*sizeof(float));
00870 upper = cpl_malloc(NSAMPLE*sizeof(float));
00871 uppere = cpl_malloc(NSAMPLE*sizeof(float));
00872 xnoise = sqrt(PI*rcore*rcore)*skynoise;
00873 ratell = xnoise/pow(10.0,0.4*(fluxlim+1.5));
00874 ratell = COREMAG(1.0+ratell,0.0,0.0);
00875 ratscl = (pow((fitellf + 2.0*sigellf - fitell),2.0) - 4.0*sigell*sigell)/(4.0*ratell*ratell);
00876 ratscl = max(0.25,min(10.0,ratscl));
00877 for (i = 0; i < NSAMPLE; i++) {
00878 xmag = 5.0 + 0.1*(float)(i+1);
00879 xflux = pow(10.0,0.4*xmag);
00880 ratio = 2.5*log10(1.0+xnoise/xflux);
00881 lower[i] = fit_final - 5.0*sqrt(sigma_final*sigma_final + ratio*ratio);
00882 upper[i] = fit_final + sqrt(9.0*sigma_final*sigma_final + 0.0*ratio*ratio);
00883 uppere[i] = fitell + 2.0*sqrt(sigell*sigell + ratscl*ratio*ratio);
00884 uppere[i] = min(0.5,uppere[i]);
00885 }
00886 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
00887 fluxlim = 2.5*log10((double)(2.5*sqrt(PI*rcore*rcore)*skynoise));
00888
00889
00890
00891 nstar = 0;
00892 ngal = 0;
00893 njunk = 0;
00894 ncmp = 0;
00895 for (i = 0; i < nrows; i++) {
00896 ell = ellipticity[i];
00897 pk = peak_height[i] + skylevel;
00898 pkht = peak_mag[i];
00899 core = core_flux[i];
00900 iarg = vircam_nint(10.0*(core - 5.0));
00901 iarg = max(1,min(NSAMPLE,iarg)) - 1;
00902 if (! poor) {
00903 sig1 = max(0.01,(fit1 - lower1[iarg])/3.0);
00904 sig2 = max(0.01,(fit2 - lower2[iarg])/3.0);
00905 } else {
00906 sig1 = max(0.01,(fit4 - lower1[iarg])/3.0);
00907 sig2 = max(0.01,(fit5 - lower2[iarg])/3.0);
00908 }
00909 sig3 = max(0.01,(fit3 - lower3[iarg])/3.0);
00910 denom = (wt1/sig1 + wt2/sig2 + wt3/sig3);
00911 w1 = (wt1/sig1)/denom;
00912 w2 = (wt2/sig2)/denom;
00913 w3 = (wt3/sig3)/denom;
00914 if (! poor) {
00915 core_small = core1_flux[i];
00916 core_large = core3_flux[i];
00917 statistic = (core - core_small - fit1)*w1 +
00918 (max(-3.0*sig2,core_large - core - fit2))*w2 +
00919 (core - pkht - fit3)*w3;
00920 } else {
00921 core_midd = core2_flux[i];
00922 core_large = core4_flux[i];
00923 statistic = (core_midd - core - fit4)*w1 +
00924 (max(-3.0*sig2,core_large - core - fit5))*w2 +
00925 (core - pkht - fit3)*w3;
00926 }
00927 cls[i] = -1.0;
00928 statcut = upper[iarg] + 3.0*sigma_final*(exp(max(0.0,core-corlim+1.0)) - 1.0);
00929 if (statistic >= statcut)
00930 cls[i] = 1.0;
00931 else if (statistic <= lower[iarg])
00932 cls[i] = 0.0;
00933
00934
00935
00936 sigtot = (fit_final - lower[iarg])/5.0;
00937 sig[i] = (statistic - fit_final)/sigtot;
00938
00939
00940
00941
00942 if (core - pkht - fit3 < -4.0*sig3)
00943 cls[i] = 0.0;
00944
00945
00946
00947 ellbound = max(elllim,uppere[iarg]);
00948 if (ell > ellbound && cls[i] == -1.0 && core < flim && sig[i] > -2.0)
00949 cls[i] = -2.0;
00950
00951
00952
00953 if (core > corlim && statistic >= lower[iarg])
00954 cls[i] = -1.0;
00955
00956
00957
00958 if (ell > 0.9 && core < corlim)
00959 cls[i] = 0.0;
00960
00961
00962
00963 if (core < fluxlim)
00964 cls[i] = 0.0;
00965
00966
00967
00968 if (cls[i] == -1.0)
00969 nstar++;
00970 else if (cls[i] == 1.0)
00971 ngal++;
00972 else if (cls[i] == -2.0)
00973 ncmp++;
00974 else
00975 njunk++;
00976 }
00977
00978
00979
00980 if (ncols == 80) {
00981 classstats_ap67(core5_flux,core3_flux,&fit6,&sigma6);
00982 classstats_ap67(core_flux,core6_flux,&fit7,&sigma7);
00983 fit6 += fit2;
00984 }
00985 classstats_ap0(&fit0,&sigma0);
00986 if (ncols == 80)
00987 fit0 = max(fit6,fit0);
00988 else
00989 fit0 = max(fit5,fit0);
00990 apcpkht = fit0 + fit3;
00991 switch (ncols) {
00992 case 32:
00993 apcor1 = fit0 + fit1;
00994 apcor = fit0;
00995 apcor2 = fit0 - fit4;
00996 apcor3 = fit0 - fit2;
00997 apcor4 = fit0 - fit5;
00998 apcor5 = 0.0;
00999 break;
01000 case 80:
01001 apcor1 = fit0 + fit1;
01002 apcor2 = fit0 + fit7;
01003 apcor3 = fit0;
01004 apcor4 = fit0 - fit4;
01005 apcor5 = fit0 - fit2;
01006 apcor6 = fit0 - fit5;
01007 apcor7 = fit0 - fit6;
01008 break;
01009 }
01010
01011
01012
01013 ii = 0;
01014 work = cpl_malloc(nrows*sizeof(float));
01015 for (i = 0; i < nrows; i++) {
01016 ell = ellipticity[i];
01017 core = core_flux[i];
01018 pkht = max(thresh,peak_height[i]) + skylev[i];
01019 if (((ell < elllim && core > flim && cls[i] == -1 && sig[i] >= 5.0 &&
01020 areal[0][i] >= pixlim) || pkht >= 0.9*avsat) && xpos[i] >= xmin &&
01021 xpos[i] <= xmax && ypos[i] >= ymin && ypos[i] <= ymax) {
01022 work[ii++] = pkht;
01023 }
01024 }
01025 if (ii > 0) {
01026 medstat(work,ii,&avsatnew,&junk);
01027 avsatnew = max(10000.0+skylevel,avsatnew);
01028 } else {
01029 avsatnew = 10000.0 + skylevel;
01030 }
01031 avsat = avsatnew;
01032 freespace(work);
01033
01034
01035
01036 freespace(lower1);
01037 freespace(lower2);
01038 freespace(lower3);
01039 freespace(upper1);
01040 freespace(upper2);
01041 freespace(upper3);
01042 freespace(lower);
01043 freespace(upper);
01044 freespace(uppere);
01045
01046 }
01047
01048
01076
01077
01078 static void classstats(float *core1, float *core2, int small, float cutlev,
01079 float *medval, float *sigma) {
01080
01081 int i,iloop,n;
01082 float *work,*dc,sigmaold,amult;
01083
01084
01085
01086 *medval = 0.0;
01087 *sigma = 1.0e6;
01088 amult = (small == 1 ? -1.0 : 1.0);
01089
01090
01091
01092 work = cpl_malloc(nrows*sizeof(float));
01093 dc = cpl_malloc(nrows*sizeof(float));
01094
01095
01096
01097 for (i = 0; i < nrows; i++)
01098 dc[i] = amult*(core2[i] - core1[i]);
01099
01100
01101
01102 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01103 sigmaold = *sigma;
01104 n = 0;
01105
01106
01107
01108 for (i = 0; i < nrows; i++) {
01109
01110
01111
01112 if (ellipticity[i] < elllim && core1[i] < blim && core1[i] > flim &&
01113 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
01114 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01115 ypos[i] <= ymax && areal[0][i] >= pixlim) {
01116 if (iloop > 0 || (iloop == 0 && dc[i] >= cutlev))
01117 work[n++] = dc[i];
01118 }
01119 }
01120
01121
01122
01123 if (n > 0) {
01124 sort1(work,n);
01125 if (iloop == 0) {
01126 anhist(work,n,medval,sigma);
01127 } else {
01128 medstat(work,n,medval,sigma);
01129 *sigma = min(sigmaold,*sigma);
01130 }
01131 } else {
01132 *medval = 0.0;
01133 *sigma = 0.01;
01134 }
01135
01136
01137
01138 *sigma = max(*sigma,0.01);
01139 }
01140
01141
01142
01143 free(work);
01144 free(dc);
01145 }
01146
01147
01162
01163
01164 static void classstats_el(void) {
01165 int iloop,n,i;
01166 float *work;
01167
01168
01169
01170 sigell = 1.0e6;
01171 fitell = 0.0;
01172
01173
01174
01175 work = cpl_malloc(nrows*sizeof(float));
01176
01177
01178
01179 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01180 n = 0;
01181 for (i = 0; i < nrows; i++) {
01182 if (ellipticity[i] < 0.5 && core_flux[i] < blim &&
01183 core_flux[i] > flim &&
01184 fabs(ellipticity[i] - fitell) < 2.0*sigell &&
01185 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01186 ypos[i] <= ymax && areal[0][i] >= pixlim)
01187 work[n++] = ellipticity[i];
01188 }
01189 if (n > 2)
01190 medstat(work,n,&fitell,&sigell);
01191 else {
01192 fitell = 0.25;
01193 sigell = 0.05;
01194 }
01195 }
01196 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
01197
01198
01199
01200 freespace(work);
01201 }
01202
01203
01218
01219
01220 static void classstats_pa() {
01221 int iloop,n,i;
01222 float *work;
01223
01224
01225
01226 sigpa = 1.0e6;
01227 fitpa = 0.0;
01228
01229
01230
01231 work = cpl_malloc(nrows*sizeof(float));
01232
01233
01234
01235 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01236 n = 0;
01237 for (i = 0; i < nrows; i++) {
01238 if (core_flux[i] < blim && core_flux[i] > flim &&
01239 fabs(pa[i] - fitpa) < 2.0*sigpa &&
01240 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01241 ypos[i] <= ymax && areal[0][i] >= pixlim)
01242 work[n++] = pa[i];
01243 }
01244 if (n > 2)
01245 medstat(work,n,&fitpa,&sigpa);
01246 else {
01247 fitpa = 0.0;
01248 sigpa = 0.05;
01249 }
01250 }
01251
01252
01253
01254 freespace(work);
01255 }
01256
01257
01275
01276
01277 static void classstats_ellf(float fluxlim) {
01278 int iloop,n,i;
01279 float *work;
01280
01281
01282
01283 sigellf = 1.0e6;
01284 fitellf = 0.0;
01285
01286
01287
01288 work = cpl_malloc(nrows*sizeof(float));
01289
01290
01291
01292 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01293 n = 0;
01294 for (i = 0; i < nrows; i++) {
01295 if (ellipticity[i] < 0.75 && core_flux[i] > fluxlim+1.0 &&
01296 core_flux[i] < fluxlim+2.0 &&
01297 fabs(ellipticity[i] - fitellf) < 2.0*sigellf)
01298 work[n++] = ellipticity[i];
01299 }
01300 if (n > 2)
01301 medstat(work,n,&fitellf,&sigellf);
01302 else {
01303 fitellf = 0.25;
01304 sigellf = 0.05;
01305 }
01306 }
01307
01308
01309
01310 freespace(work);
01311 }
01312
01313
01333
01334
01335 static void classstats_ap0(float *medval, float *sigma) {
01336
01337 int i,iloop,n;
01338 float *work,*dc,c2,sigmanew;
01339
01340
01341
01342 *medval = 0.0;
01343 *sigma = 1.0e6;
01344 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
01345
01346
01347
01348 work = cpl_malloc(nrows*sizeof(float));
01349 dc = cpl_malloc(nrows*sizeof(float));
01350
01351
01352
01353 for (i = 0; i < nrows; i++) {
01354 c2 = max(0.0,max(iso_flux[i],core5_flux[i]));
01355 dc[i] = c2 - core_flux[i];
01356 }
01357
01358
01359
01360 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01361 n = 0;
01362
01363
01364
01365 for (i = 0; i < nrows; i++) {
01366
01367
01368
01369 if (ellipticity[i] < elllim && core_flux[i] < blim &&
01370 core_flux[i] > flim &&
01371 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
01372 cls[i] == -1.0 && sig[i] < 5.0 &&
01373 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01374 ypos[i] <= ymax && areal[0][i] >= pixlim)
01375 if (iloop > 0 || (iloop == 0 && dc[i] >= 0.0)) {
01376 work[n++] = dc[i];
01377 }
01378 }
01379
01380
01381
01382 if (n > 0) {
01383 sort1(work,n);
01384 if (iloop == 0) {
01385 anhist(work,n,medval,sigma);
01386 *sigma = 1.48*(*medval - work[(int)(0.25*(float)(n+3))-1]);
01387 *sigma = max(0.025,*sigma);
01388 } else {
01389 medstat(work,n,medval,&sigmanew);
01390 *sigma = min(*sigma,sigmanew);
01391 *sigma = max(0.01,*sigma);
01392 }
01393 } else {
01394 *medval = 0.0;
01395 *sigma = 0.01;
01396 }
01397
01398
01399
01400 *sigma = max(*sigma,0.01);
01401 }
01402
01403
01404
01405 freespace(work);
01406 freespace(dc);
01407 }
01408
01409 static void classstats_ap67(float *mag1, float *mag2, float *medval,
01410 float *sigma) {
01411
01412 int i,iloop,n;
01413 float *work,*dc,sigmanew;
01414
01415
01416
01417 *medval = 0.0;
01418 *sigma = 1.0e6;
01419 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
01420
01421
01422
01423 work = cpl_malloc(nrows*sizeof(float));
01424 dc = cpl_malloc(nrows*sizeof(float));
01425
01426
01427
01428 for (i = 0; i < nrows; i++)
01429 dc[i] = mag1[i] - mag2[i];
01430
01431
01432
01433 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01434 n = 0;
01435
01436
01437
01438 for (i = 0; i < nrows; i++) {
01439
01440
01441
01442 if (ellipticity[i] < elllim && core_flux[i] < blim &&
01443 core_flux[i] > flim &&
01444 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
01445 cls[i] == -1.0 && sig[i] < 5.0 &&
01446 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01447 ypos[i] <= ymax && areal[0][i] >= pixlim) {
01448 if (iloop > 0 || (iloop == 0 && dc[i] >= 0.0)) {
01449 work[n++] = dc[i];
01450 }
01451 }
01452 }
01453
01454
01455
01456 if (n > 0) {
01457 sort1(work,n);
01458 if (iloop == 0) {
01459 anhist(work,n,medval,sigma);
01460 *sigma = 1.48*(*medval - work[(int)(0.25*(float)(n+3))-1]);
01461 *sigma = max(0.025,*sigma);
01462 } else {
01463 medstat(work,n,medval,&sigmanew);
01464 *sigma = min(*sigma,sigmanew);
01465 *sigma = max(0.01,*sigma);
01466 }
01467 } else {
01468 *medval = 0.0;
01469 *sigma = 0.01;
01470 }
01471
01472
01473
01474 *sigma = max(*sigma,0.01);
01475 }
01476
01477
01478
01479 free(work);
01480 free(dc);
01481 }
01482
01483
01500
01501
01502 static void classstats_final(void) {
01503 int n,i,iloop,iarg,ii,iend,ncls,kk,k;
01504 float *work,ell,core,sig1,sig2,sig3,denom,w1,w2,w3,core_small;
01505 float core_large,*statistic,core_midd,pkht,xcor,cfit,csig;
01506 float *work1,junk,corlim1,corval1,corlim2,corval2,sigmaold;
01507
01508
01509
01510 sigma_final = 1.0e6;
01511 fit_final = 0.0;
01512 ncls = 0;
01513
01514
01515
01516 work = cpl_malloc(nrows*sizeof(float));
01517 work1 = cpl_malloc(nrows*sizeof(float));
01518 statistic = cpl_malloc(nrows*sizeof(float));
01519
01520
01521
01522 for (i = 0; i < nrows; i++) {
01523 ell = ellipticity[i];
01524 pkht = peak_mag[i];
01525 core = core_flux[i];
01526 iarg = vircam_nint(10.0*(core - 5.0));
01527 iarg = max(1,min(NSAMPLE,iarg)) - 1;
01528 if (! poor) {
01529 sig1 = max(0.01,(fit1 - lower1[iarg])/3.0);
01530 sig2 = max(0.01,(fit2 - lower2[iarg])/3.0);
01531 } else {
01532 sig1 = max(0.01,(fit4 - lower1[iarg])/3.0);
01533 sig2 = max(0.01,(fit5 - lower2[iarg])/3.0);
01534 }
01535 sig3 = max(0.01,(fit3 - lower3[iarg])/3.0);
01536 denom = (wt1/sig1 + wt2/sig2 + wt3/sig3);
01537 w1 = (wt1/sig1)/denom;
01538 w2 = (wt2/sig2)/denom;
01539 w3 = (wt3/sig3)/denom;
01540 if (! poor) {
01541 core_small = core1_flux[i];
01542 core_large = core3_flux[i];
01543 statistic[i] = (core - core_small - fit1)*w1 +
01544 (core_large - core - fit2)*w2 + (core - pkht - fit3)*w3;
01545 } else {
01546 core_midd = core2_flux[i];
01547 core_large = core4_flux[i];
01548 statistic[i] = (core_midd - core - fit4)*w1 +
01549 (core_large - core - fit5)*w2 + (core - pkht - fit3)*w3;
01550 }
01551 }
01552
01553
01554
01555
01556 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01557 sigmaold = sigma_final;
01558 n = 0;
01559 for (i = 0; i < nrows ; i++) {
01560
01561 ell = ellipticity[i];
01562 core = core_flux[i];
01563 if (ell < elllim && core < blim && core > flim &&
01564 fabs((double)(statistic[i] - fit_final)) < 3.0*sigma_final &&
01565 areal[0][i] >= pixlim)
01566 work[n++] = statistic[i];
01567
01568
01569
01570
01571 if (core > corlim && iloop == MAXLOOP-2) {
01572 cls[ncls] = statistic[i];
01573 sig[ncls++] = core;
01574 }
01575 }
01576
01577
01578
01579 if (n > 2) {
01580 sort1(work,n);
01581 if (iloop == 0 && n > 10) {
01582 anhist(work,n,&fit_final,&sigma_final);
01583 } else {
01584 medstat(work,n,&fit_final,&sigma_final);
01585 }
01586 sigma_final = max(0.01,min(sigmaold,sigma_final));
01587 } else {
01588 fit_final = 0.0;
01589 sigma_final = 0.01;
01590 }
01591 }
01592
01593
01594
01595 sort2(sig,cls,ncls);
01596 ii = 0;
01597 xcor = 12.5;
01598 iend = 0;
01599 i = -1;
01600 corlim1 = 0.0;
01601 corlim2 = 0.0;
01602 corval1 = 0.0;
01603 corval2 = 0.0;
01604 while (iend == 0 && i < ncls-1) {
01605 i++;
01606 if (sig[i] > xcor+0.25 && ii >= 3) {
01607 medstat(work,ii,&cfit,&csig);
01608 for (iloop = 0; iloop < 3; iloop++) {
01609 kk = 0;
01610 for (k = 0; k < ii; k++) {
01611 if (work[k] <= cfit + 3.0*csig)
01612 work1[kk++] = work[k];
01613 }
01614 medstat(work1,kk,&cfit,&junk);
01615 }
01616 if (cfit <= fit_final + 3.0*sigma_final) {
01617 corlim1 = xcor;
01618 corval1 = cfit;
01619 } else {
01620 corlim2 = xcor;
01621 corval2 = cfit;
01622 iend = 1;
01623 }
01624 } else {
01625 work[ii++] = cls[i];
01626 }
01627 }
01628
01629
01630
01631 if (iend == 1)
01632 corlim = corlim2 - 0.5*(corval2 - fit_final - 3.0*sigma_final)/(corval2 - corval1);
01633 else
01634 corlim = corlim1;
01635 corlim = max(cormin,corlim);
01636 kk = 0;
01637 for (i = 0; i < nrows; i++) {
01638 core = core_flux[i];
01639 if (core >= corlim)
01640 work[kk++] = peak_height[i] + skylevel;
01641 }
01642 if (kk > 0) {
01643 medstat(work,kk,&avsat,&junk);
01644 avsat = max(10000.0+skylevel,avsat);
01645 } else {
01646 avsat = 10000.0 + skylevel;
01647 }
01648
01649
01650
01651 freespace(work);
01652 freespace(work1);
01653 freespace(statistic);
01654 }
01655
01656
01681
01682
01683 static void medstat(float *array, int n, float *medval, float *sigval) {
01684 int lev1,lev2,lev3;
01685
01686
01687
01688
01689
01690 if (n == 0) {
01691 *medval = 0.0;
01692 *sigval = 0.0;
01693 return;
01694 }
01695 sort1(array,n);
01696 lev1 = (n + 1)/2;
01697 lev2 = (3*n + 3)/4;
01698 lev3 = (n + 3)/4;
01699 *medval = array[lev1-1];
01700 *sigval = 1.48*0.5*(array[lev2-1] - array[lev3-1]);
01701 }
01702
01703
01722
01723
01724 static void sort1(float *a, int n) {
01725 int iii,ii,i,ifin,j;
01726 float b;
01727
01728 iii = 4;
01729 while (iii < n)
01730 iii *= 2;
01731 iii = min(n,(3*iii)/4 - 1);
01732
01733 while (iii > 1) {
01734 iii /= 2;
01735 ifin = n - iii;
01736 for (ii = 0; ii < ifin; ii++) {
01737 i = ii;
01738 j = i + iii;
01739 if (a[i] > a[j]) {
01740 b = a[j];
01741 while (1) {
01742 a[j] = a[i];
01743 j = i;
01744 i = i - iii;
01745 if (i < 0 || a[i] <= b)
01746 break;
01747 }
01748 a[j] = b;
01749 }
01750 }
01751 }
01752 }
01753
01754
01776
01777
01778 static void sort2(float *a1, float *a2, int n) {
01779 int iii,ii,i,ifin,j;
01780 float b1,b2;
01781
01782 iii = 4;
01783 while (iii < n)
01784 iii *= 2;
01785 iii = min(n,(3*iii)/4 - 1);
01786
01787 while (iii > 1) {
01788 iii /= 2;
01789 ifin = n - iii;
01790 for (ii = 0; ii < ifin; ii++) {
01791 i = ii;
01792 j = i + iii;
01793 if (a1[i] > a1[j]) {
01794 b1 = a1[j];
01795 b2 = a2[j];
01796 while (1) {
01797 a1[j] = a1[i];
01798 a2[j] = a2[i];
01799 j = i;
01800 i = i - iii;
01801 if (i < 0 || a1[i] <= b1)
01802 break;
01803 }
01804 a1[j] = b1;
01805 a2[j] = b2;
01806 }
01807 }
01808 }
01809 }
01810
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877