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 %d columns: cattype == %d",ncols,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 } else {
01388 medstat(work,n,medval,&sigmanew);
01389 *sigma = min(*sigma,sigmanew);
01390 }
01391 } else {
01392 *medval = 0.0;
01393 *sigma = 0.01;
01394 }
01395
01396
01397
01398 *sigma = max(*sigma,0.01);
01399 }
01400
01401
01402
01403 freespace(work);
01404 freespace(dc);
01405 }
01406
01407 static void classstats_ap67(float *mag1, float *mag2, float *medval,
01408 float *sigma) {
01409
01410 int i,iloop,n;
01411 float *work,*dc,sigmanew;
01412
01413
01414
01415 *medval = 0.0;
01416 *sigma = 1.0e6;
01417 elllim = min(0.5,max(0.2,fitell+2.0*sigell));
01418
01419
01420
01421 work = cpl_malloc(nrows*sizeof(float));
01422 dc = cpl_malloc(nrows*sizeof(float));
01423
01424
01425
01426 for (i = 0; i < nrows; i++)
01427 dc[i] = mag1[i] - mag2[i];
01428
01429
01430
01431 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01432 n = 0;
01433
01434
01435
01436 for (i = 0; i < nrows; i++) {
01437
01438
01439
01440 if (ellipticity[i] < elllim && core_flux[i] < blim &&
01441 core_flux[i] > flim &&
01442 fabs(dc[i] - *medval) < 3.0*(*sigma) &&
01443 cls[i] == -1.0 && sig[i] < 5.0 &&
01444 xpos[i] >= xmin && xpos[i] <= xmax && ypos[i] >= ymin &&
01445 ypos[i] <= ymax && areal[0][i] >= pixlim) {
01446 if (iloop > 0 || (iloop == 0 && dc[i] >= 0.0)) {
01447 work[n++] = dc[i];
01448 }
01449 }
01450 }
01451
01452
01453
01454 if (n > 0) {
01455 sort1(work,n);
01456 if (iloop == 0) {
01457 anhist(work,n,medval,sigma);
01458 *sigma = 1.48*(*medval - work[(int)(0.25*(float)(n+3))-1]);
01459 } else {
01460 medstat(work,n,medval,&sigmanew);
01461 *sigma = min(*sigma,sigmanew);
01462 }
01463 } else {
01464 *medval = 0.0;
01465 *sigma = 0.01;
01466 }
01467
01468
01469
01470 *sigma = max(*sigma,0.01);
01471 }
01472
01473
01474
01475 free(work);
01476 free(dc);
01477 }
01478
01479
01496
01497
01498 static void classstats_final(void) {
01499 int n,i,iloop,iarg,ii,iend,ncls,kk,k;
01500 float *work,ell,core,sig1,sig2,sig3,denom,w1,w2,w3,core_small;
01501 float core_large,*statistic,core_midd,pkht,xcor,cfit,csig;
01502 float *work1,junk,corlim1,corval1,corlim2,corval2,sigmaold;
01503
01504
01505
01506 sigma_final = 1.0e6;
01507 fit_final = 0.0;
01508 ncls = 0;
01509
01510
01511
01512 work = cpl_malloc(nrows*sizeof(float));
01513 work1 = cpl_malloc(nrows*sizeof(float));
01514 statistic = cpl_malloc(nrows*sizeof(float));
01515
01516
01517
01518 for (i = 0; i < nrows; i++) {
01519 ell = ellipticity[i];
01520 pkht = peak_mag[i];
01521 core = core_flux[i];
01522 iarg = vircam_nint(10.0*(core - 5.0));
01523 iarg = max(1,min(NSAMPLE,iarg)) - 1;
01524 if (! poor) {
01525 sig1 = max(0.01,(fit1 - lower1[iarg])/3.0);
01526 sig2 = max(0.01,(fit2 - lower2[iarg])/3.0);
01527 } else {
01528 sig1 = max(0.01,(fit4 - lower1[iarg])/3.0);
01529 sig2 = max(0.01,(fit5 - lower2[iarg])/3.0);
01530 }
01531 sig3 = max(0.01,(fit3 - lower3[iarg])/3.0);
01532 denom = (wt1/sig1 + wt2/sig2 + wt3/sig3);
01533 w1 = (wt1/sig1)/denom;
01534 w2 = (wt2/sig2)/denom;
01535 w3 = (wt3/sig3)/denom;
01536 if (! poor) {
01537 core_small = core1_flux[i];
01538 core_large = core3_flux[i];
01539 statistic[i] = (core - core_small - fit1)*w1 +
01540 (core_large - core - fit2)*w2 + (core - pkht - fit3)*w3;
01541 } else {
01542 core_midd = core2_flux[i];
01543 core_large = core4_flux[i];
01544 statistic[i] = (core_midd - core - fit4)*w1 +
01545 (core_large - core - fit5)*w2 + (core - pkht - fit3)*w3;
01546 }
01547 }
01548
01549
01550
01551
01552 for (iloop = 0; iloop < MAXLOOP; iloop++) {
01553 sigmaold = sigma_final;
01554 n = 0;
01555 for (i = 0; i < nrows ; i++) {
01556
01557 ell = ellipticity[i];
01558 core = core_flux[i];
01559 if (ell < elllim && core < blim && core > flim &&
01560 fabs((double)(statistic[i] - fit_final)) < 3.0*sigma_final &&
01561 areal[0][i] >= pixlim)
01562 work[n++] = statistic[i];
01563
01564
01565
01566
01567 if (core > corlim && iloop == MAXLOOP-2) {
01568 cls[ncls] = statistic[i];
01569 sig[ncls++] = core;
01570 }
01571 }
01572
01573
01574
01575 if (n > 2) {
01576 sort1(work,n);
01577 if (iloop == 0 && n > 10) {
01578 anhist(work,n,&fit_final,&sigma_final);
01579 } else {
01580 medstat(work,n,&fit_final,&sigma_final);
01581 }
01582 sigma_final = max(0.01,min(sigmaold,sigma_final));
01583 } else {
01584 fit_final = 0.0;
01585 sigma_final = 0.01;
01586 }
01587 }
01588
01589
01590
01591 sort2(sig,cls,ncls);
01592 ii = 0;
01593 xcor = 12.5;
01594 iend = 0;
01595 i = -1;
01596 corlim1 = 0.0;
01597 corlim2 = 0.0;
01598 corval1 = 0.0;
01599 corval2 = 0.0;
01600 while (iend == 0 && i < ncls-1) {
01601 i++;
01602 if (sig[i] > xcor+0.25 && ii >= 3) {
01603 medstat(work,ii,&cfit,&csig);
01604 for (iloop = 0; iloop < 3; iloop++) {
01605 kk = 0;
01606 for (k = 0; k < ii; k++) {
01607 if (work[k] <= cfit + 3.0*csig)
01608 work1[kk++] = work[k];
01609 }
01610 medstat(work1,kk,&cfit,&junk);
01611 }
01612 if (cfit <= fit_final + 3.0*sigma_final) {
01613 corlim1 = xcor;
01614 corval1 = cfit;
01615 } else {
01616 corlim2 = xcor;
01617 corval2 = cfit;
01618 iend = 1;
01619 }
01620 } else {
01621 work[ii++] = cls[i];
01622 }
01623 }
01624
01625
01626
01627 if (iend == 1)
01628 corlim = corlim2 - 0.5*(corval2 - fit_final - 3.0*sigma_final)/(corval2 - corval1);
01629 else
01630 corlim = corlim1;
01631 corlim = max(cormin,corlim);
01632 kk = 0;
01633 for (i = 0; i < nrows; i++) {
01634 core = core_flux[i];
01635 if (core >= corlim)
01636 work[kk++] = peak_height[i] + skylevel;
01637 }
01638 if (kk > 0) {
01639 medstat(work,kk,&avsat,&junk);
01640 avsat = max(10000.0+skylevel,avsat);
01641 } else {
01642 avsat = 10000.0 + skylevel;
01643 }
01644
01645
01646
01647 freespace(work);
01648 freespace(work1);
01649 freespace(statistic);
01650 }
01651
01652
01677
01678
01679 static void medstat(float *array, int n, float *medval, float *sigval) {
01680 int lev1,lev2,lev3;
01681
01682
01683
01684
01685
01686 if (n == 0) {
01687 *medval = 0.0;
01688 *sigval = 0.0;
01689 return;
01690 }
01691 sort1(array,n);
01692 lev1 = (n + 1)/2;
01693 lev2 = (3*n + 3)/4;
01694 lev3 = (n + 3)/4;
01695 *medval = array[lev1-1];
01696 *sigval = 1.48*0.5*(array[lev2-1] - array[lev3-1]);
01697 }
01698
01699
01718
01719
01720 static void sort1(float *a, int n) {
01721 int iii,ii,i,ifin,j;
01722 float b;
01723
01724 iii = 4;
01725 while (iii < n)
01726 iii *= 2;
01727 iii = min(n,(3*iii)/4 - 1);
01728
01729 while (iii > 1) {
01730 iii /= 2;
01731 ifin = n - iii;
01732 for (ii = 0; ii < ifin; ii++) {
01733 i = ii;
01734 j = i + iii;
01735 if (a[i] > a[j]) {
01736 b = a[j];
01737 while (1) {
01738 a[j] = a[i];
01739 j = i;
01740 i = i - iii;
01741 if (i < 0 || a[i] <= b)
01742 break;
01743 }
01744 a[j] = b;
01745 }
01746 }
01747 }
01748 }
01749
01750
01772
01773
01774 static void sort2(float *a1, float *a2, int n) {
01775 int iii,ii,i,ifin,j;
01776 float b1,b2;
01777
01778 iii = 4;
01779 while (iii < n)
01780 iii *= 2;
01781 iii = min(n,(3*iii)/4 - 1);
01782
01783 while (iii > 1) {
01784 iii /= 2;
01785 ifin = n - iii;
01786 for (ii = 0; ii < ifin; ii++) {
01787 i = ii;
01788 j = i + iii;
01789 if (a1[i] > a1[j]) {
01790 b1 = a1[j];
01791 b2 = a2[j];
01792 while (1) {
01793 a1[j] = a1[i];
01794 a2[j] = a2[i];
01795 j = i;
01796 i = i - iii;
01797 if (i < 0 || a1[i] <= b1)
01798 break;
01799 }
01800 a1[j] = b1;
01801 a2[j] = b2;
01802 }
01803 }
01804 }
01805 }
01806
01809
01810
01811
01812
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