source: Sophya/trunk/FrEROS/AnaLC/filtccd.cc@ 3807

Last change on this file since 3807 was 3308, checked in by ansari, 18 years ago

Creation du module AnaLC (lecture suivi EROS avec SOPHYA) dans la base
SOPHYA - cmv+reza 22/08/2007

  • Property svn:executable set to *
File size: 39.0 KB
Line 
1#include "machdefs.h"
2#include <stdlib.h>
3#include <stdio.h>
4#include <math.h>
5
6#include "nbtri.h"
7#include "nbmath.h"
8#include "matxop.h"
9#include "filtccd.h"
10
11static int DEB_FitPan = 0;
12static int DEB_BaseLine = 0;
13static int DEB_Bosse = 0;
14static int DEB_BossePaG = 0;
15static int DEB_SigmaInt = 0;
16static int DEB_FiltMed = 0;
17static int DEB_FiltInt = 0;
18
19static int Bosse_probnb = 0;
20
21/*=========================================================================*/
22void SetDebFilt(int razer)
23{
24char *c;
25DEB_FitPan = DEB_BaseLine = DEB_Bosse = DEB_BossePaG
26 = DEB_SigmaInt = DEB_FiltMed = DEB_FiltInt = 0;
27if( razer < 0 ) return;
28if( (c = getenv("DEB_FitPan")) ) DEB_FitPan = atoi(c); else DEB_FitPan = 0;
29if( (c = getenv("DEB_BaseLine")) ) DEB_BaseLine = atoi(c); else DEB_BaseLine = 0;
30if( (c = getenv("DEB_Bosse")) ) DEB_Bosse = atoi(c); else DEB_Bosse = 0;
31if( (c = getenv("DEB_BossePaG")) ) DEB_BossePaG = atoi(c); else DEB_BossePaG = 0;
32if( (c = getenv("DEB_SigmaInt")) ) DEB_SigmaInt = atoi(c); else DEB_SigmaInt = 0;
33if( (c = getenv("DEB_FiltMed")) ) DEB_FiltMed = atoi(c); else DEB_FiltMed = 0;
34if( (c = getenv("DEB_FiltInt")) ) DEB_FiltInt = atoi(c); else DEB_FiltInt = 0;
35}
36
37/*=========================================================================*/
38double LPacZin(double t,double *Par,double *DgDpar)
39/* Christophe 11/02/94
40fonction de paczinski en -magnitude 2.5*log10(Paczin) au temps t
41pour U0,T0,Tau,magfond et derivees de la fonction par rapport
42aux parametres [0]=U0,[1]=T0,[2]=Tau,[3]=magfond
43*/
44{
45double Paczin,u2,su2u24,tt0tau,dadu2;
46
47tt0tau = (t-Par[1])/Par[2];
48u2 = Par[0]*Par[0] + tt0tau*tt0tau;
49su2u24 = sqrt(u2*(u2+4.));
50dadu2 = -4./su2u24/su2u24/su2u24;
51
52Paczin = (u2+2.)/su2u24;
53DgDpar[0] = DftoDm/Paczin *dadu2* 2.*Par[0];
54DgDpar[1] = DftoDm/Paczin *dadu2*(-2.*tt0tau/Par[2]);
55DgDpar[2] = DftoDm/Paczin *dadu2*(-2.*tt0tau*tt0tau/Par[2]);
56DgDpar[3] = 1.;
57
58Paczin = 2.5*log10(Paczin) + Par[3];
59return (Paczin);
60}
61
62/*=========================================================================*/
63double MPacZin(double t,double *Par,double *DgDpar)
64/* rcecile 13/06/94
65fonction de paczinski a l'envers en -magnitude 2.5*log10(Paczin) au temps t
66pour U0,T0,Tau,magfond et derivees de la fonction par rapport
67aux parametres [0]=U0,[1]=T0,[2]=Tau,[3]=magfond
68*/
69{
70double Paczin,u2,su2u24,tt0tau,dadu2;
71
72tt0tau = (t-Par[1])/Par[2];
73u2 = Par[0]*Par[0] + tt0tau*tt0tau;
74su2u24 = sqrt(u2*(u2+4.));
75dadu2 = -4./su2u24/su2u24/su2u24;
76
77Paczin = (u2+2.)/su2u24;
78DgDpar[0] = DftoDm/Paczin *dadu2* 2.*Par[0];
79DgDpar[1] = DftoDm/Paczin *dadu2*(-2.*tt0tau/Par[2]);
80DgDpar[2] = DftoDm/Paczin *dadu2*(-2.*tt0tau*tt0tau/Par[2]);
81DgDpar[3] = 1.;
82
83Paczin = -2.5*log10(Paczin) + Par[3];
84return (Paczin);
85}
86
87/*=========================================================================*/
88double LPacZin2(double t,double *Par,double *DgDpar)
89/* Christophe 11/02/94
90fonction de paczinski en -magnitude 2.5*log10(Paczin) au temps t
91pour 1/U0,T0,1/Tau,magfond et derivees de la fonction par rapport
92aux parametres [0]=1/U0,[1]=T0,[2]=1/Tau,[3]=magfond
93*/
94{
95double Paczin,U2,U02,tt0,tt0tau,tt0tau2,dPdU2,U24p1,sU24p1,den;
96
97tt0 = t-Par[1];
98tt0tau = tt0*Par[2];
99tt0tau2 = tt0tau*tt0tau;
100U02 = Par[0]*Par[0];
101U2 = U02/(1.+U02*tt0tau2);
102U24p1 = 1.+4*U2; sU24p1 = sqrt(U24p1);
103den = 1.+U02*tt0tau2; den *= den;
104dPdU2 = 4.*U2/(U24p1*sU24p1);
105
106Paczin = (1.+2.*U2)/sU24p1;
107DgDpar[0] = DftoDm/Paczin *dPdU2* 2.*Par[0]/den;
108DgDpar[1] = DftoDm/Paczin *dPdU2* 2.*U02*U02*Par[2]*tt0tau/den;
109DgDpar[2] = -DftoDm/Paczin *dPdU2* 2.*U02*U02*tt0*tt0tau/den;
110DgDpar[3] = 1.;
111
112Paczin = 2.5*log10(Paczin) + Par[3];
113return (Paczin);
114}
115
116/*=========================================================================*/
117double MPacZin2(double t,double *Par,double *DgDpar)
118/* rcecile 13/06/94
119fonction de paczinski a l'envers en -magnitude 2.5*log10(Paczin) au temps t
120pour 1/U0,T0,1/Tau,magfond et derivees de la fonction par rapport
121aux parametres [0]=1/U0,[1]=T0,[2]=1/Tau,[3]=magfond
122*/
123{
124double Paczin,U2,U02,tt0,tt0tau,tt0tau2,dPdU2,U24p1,sU24p1,den;
125
126tt0 = t-Par[1];
127tt0tau = tt0*Par[2];
128tt0tau2 = tt0tau*tt0tau;
129U02 = Par[0]*Par[0];
130U2 = U02/(1.+U02*tt0tau2);
131U24p1 = 1.+4*U2; sU24p1 = sqrt(U24p1);
132den = 1.+U02*tt0tau2; den *= den;
133dPdU2 = 4.*U2/(U24p1*sU24p1);
134
135Paczin = (1.+2.*U2)/sU24p1;
136DgDpar[0] = DftoDm/Paczin *dPdU2* 2.*Par[0]/den;
137DgDpar[1] = DftoDm/Paczin *dPdU2* 2.*U02*U02*Par[2]*tt0tau/den;
138DgDpar[2] = -DftoDm/Paczin *dPdU2* 2.*U02*U02*tt0*tt0tau/den;
139DgDpar[3] = 1.;
140
141Paczin = -2.5*log10(Paczin) + Par[3];
142return (Paczin);
143}
144
145/*=========================================================================*/
146double LErrExt(double m,double *Par,double *DgDpar)
147/* fonction des erreurs externes -- Cecile 23/02/94 */
148{
149double errext;
150errext =exp(Par[1]*m) ;
151if ( errext < 1.e-200 ) errext = 0.;
152DgDpar[0] = errext;
153errext *= Par[0];
154DgDpar[1] = m*errext;
155DgDpar[2] = 1.;
156errext += Par[2];
157return (errext);
158}
159
160/*=========================================================================*/
161void SetBosse_probnb(int iset)
162{
163if( iset<=0 ) Bosse_probnb=0; else Bosse_probnb=1;
164}
165
166/*=========================================================================*/
167int_4 Bosse(float *mag,float *err,int_4 ndata
168 ,float mean,int_4 nptmin,float scut,int_4 nptscut
169 ,float *chi2,int_4 *npoint,float *Pchi2
170 ,int_4 *ideb,int_4 *ifin,int_4 *classB,int_4 NbossMX)
171/* Christophe 10/11/93 La Silla
172**** Recherche de Bosses ****
173ENTREE:
174 mag: magnitude
175 err: erreur sur la magnitude
176 ndata: nombre de donnees
177 mean: moyenne de reference pour calculer les bosses
178 nptmin: nombre minimum de points pour valider une bosse
179 scut, nptscut: definition des conditions d'arret de la bosse:
180 Soit un point de signe oppose a plus de abs(scut*sigma)
181 Soit nptscut points a moins de abs(scut*sigma)
182 si scut<=0. la seule interruption est sur le changement de signe
183SORTIE:
184 chi2: Xi2 des bosses
185 npoint: nombre de points dans la bosse
186 Pchi2: probabilite de Xi2 des bosses
187 ideb: indice du debut de la bosse
188 ifin: indice de fin de la bosse (idem)
189 classB: tableau des indices de rangement par probabilite de Xi2 croissant
190 NbossMX: nombre maximum de bosses permis
191 Bosse: nombre de bosse trouvees
192*/
193{
194int_4 deb=DEB_Bosse;
195int_4 ipo,ifirst,j,k,npt,i1,i2,sgn,sgnsave,nbosse,np_scut,cont_bosse,pass;
196double v,av,ev,c2,sc2,pc2;
197
198ipo = sgnsave = npt = i1 = i2 = ifirst = np_scut = 0;
199nbosse = -1;
200c2 = sc2= pc2 = 0.;
201nptmin = ( nptmin <= 0 ) ? 1 : nptmin ;
202nptscut = ( nptscut <= 0 ) ? 1 : nptscut ;
203scut = ( scut <= 0. ) ? 0. : scut ;
204
205while ( ipo < ndata ) {
206 ev = err[ipo];
207 v = 0.;
208 if ( ev > 0. ) v = ( mag[ipo] - mean ) / ev;
209 av = fabs(v);
210 sgn = ( v > 0. ) ? 1 : -1 ;
211 if ( deb >= 4 ) printf("ipo=%5d sgn=%2d v=%f ev=%f\n",ipo,sgn,v,ev);
212 /* conditions d'increment de la fluctuation*/
213 cont_bosse = 1;
214 if ( sgn != sgnsave && av > scut ) cont_bosse = 0;
215 if ( cont_bosse && ev > 0. ) {
216 npt++;
217 c2 += v*v;
218 pc2 += nberfc(av/Rac2) + Log2;
219 i2 = ipo;
220 if( av < scut ) { np_scut++;} else { np_scut=0;}
221 }
222 /* conditions d'arret de la fluctuation */
223 if ( ( cont_bosse == 0 && ev>0. ) ||
224 ( np_scut>=nptscut && ev>0. ) ||
225 ( ipo == ndata-1 ) ) {
226 /* y a t il assez de points ? */
227 if ( npt >= nptmin ) {
228 nbosse++;
229 /* on prend prob(xi2,npt)/2**(npt-1) */
230 if(Bosse_probnb)
231 pc2 = (double) probnb( (float) c2,npt,&pass) + (npt-1)*Log2;
232 if ( nbosse >= NbossMX ) {
233 printf("Bosse: Trop de bosses (%d), changez dimension tableaux",nbosse);
234 exit(-1);
235 } else if ( nbosse == 0 ) {
236 classB[0] = 0;
237 } else if ( nbosse > 0 ) {
238 for ( j=0;j<nbosse;j++)
239 if ( pc2 > fabs( (double) Pchi2[classB[j]] ) ) break;
240 for ( k=nbosse-1;k>=j;k--) classB[k+1] = classB[k];
241 classB[j] = nbosse;
242 }
243 Pchi2[nbosse] = sgnsave*pc2;
244 sc2 += sgnsave*c2;
245 chi2[nbosse] = sgnsave*c2;
246 npoint[nbosse] = npt;
247 ideb[nbosse] = i1;
248 ifin[nbosse] = i2;
249 if(deb>=3) printf("Find bosse %5d, npt=%5d lim=%5d %5d classB=%5d pc2=%.2f\n"
250 ,nbosse,npoint[nbosse],ideb[nbosse],ifin[nbosse]
251 ,classB[nbosse],Pchi2[nbosse]);
252 }
253 i1 = ipo;
254 npt = 1;
255 sgnsave = ( v > 0. ) ? 1 : -1;
256 c2 = v*v;
257 pc2 = nberfc(av/Rac2) + Log2;
258 }
259 ipo++;
260}
261
262nbosse++;
263if(deb) printf("Bosse: nombre de bosses trouvees=%d, somme des Pchi2=%f\n"
264 ,nbosse,sc2);
265if ( nbosse > 0 && deb ) {
266 k=3;
267 if ( deb >= 2 ) k=nbosse;
268 for (ipo=0;ipo<k;ipo++) {
269 j = classB[ipo];
270 printf("Find bosse %4d, npt=%5d lim=%5d %5d pc2=%.2f\n"
271 ,j,npoint[j],ideb[j],ifin[j],Pchi2[j]);
272 }
273}
274return(nbosse);
275}
276
277/*=========================================================================*/
278int BosseN(float *mag,float *err,int_4 ndata
279 ,float mean,float smin,int_4 nptsmin,float scut,int_4 nptscut
280 ,float *chi2,int_4 *npoint,float *Pchi2
281 ,int_4 *ideb,int_4 *ifin,int_4 *classB,int_4 NbossMX)
282/* Christophe 27/12/95 Saclay
283**** Recherche de Bosses sur courbe de lumiere ****
284ENTREE:
285 mag: tableau des magnitudes
286 err: tableau des erreurs sur la magnitude (<=0 point non considere)
287 ndata: nombre de donnees dans les tableaux (mag,err)
288 mean: ligne de base par rapport a laquelle les bosses sont determinees
289 smin, nptsmin: condition de validation d une bosse:
290 nombre minimum de points au dessus (dessous)
291 de smin*err (-smin*err) pour valider une bosse
292 scut : condition de demarrage d une bosse:
293 1 point > scut (ou < -scut)
294 scut, nptscut: definition des conditions d'arret de la bosse:
295 nptscut points a moins de scut**err si bosse positive
296 nptscut points a plus de -scut**err si bosse negative
297 Conseil: scut = 1.
298 NbossMX: nombre maximum permis de bosses
299SORTIE:
300 chi2: tableau des Xi2 des bosses
301 npoint: tableau des nombres de points dans les bosses (du meme signe que la bosse)
302 Pchi2: tableau des probabilites de Xi2 des bosses
303 ideb: tableau des indices de debut des bosses
304 ifin: tableau des indices de fin des bosses (idem)
305 classB: tableau des indices de rangement par probabilite de Xi2 croissant
306 ex: pchi2 de la 3ieme bosse = Pchi2[classB[2]]
307 return: Bosse: nombre de bosses trouvees
308REMARQUE:
309 npoints != ifin-ideb+1 car
310 1-/ il y a des points a erreur <=0
311 2-/ les points de signes opposes
312 au signe de la bosse ne sont pas comptabilises
313 c'est le nombre de points de meme signe que la bosse dans la bosse
314 le nombre total de points dans la bossse est ifin-ideb+1
315*/
316{
317int deb=DEB_Bosse; /* 0,1,2,3 */
318int j,k,ipo,npt=0,npt_cut=0,npt_c2_cut=0,i1=-1,i2=-1,sgn,sgnsave,nbosse,npt_valid,pass;
319double v,av,ev,c2,pc2,c2_cut,pc2_cut;
320char s;
321
322if(smin<0.) smin = 1.;
323if(nptsmin<=0) nptsmin = 1;
324if(scut<0.) scut = 1.;
325if(nptscut<=0) nptscut = 1;
326
327if(deb>=1) printf("***** BosseN ndata=%d smin=%d, %f scut=%d, %f\n"
328 ,ndata,nptsmin,smin,nptscut,scut);
329
330if( ndata <= 1 ) return(-1);
331
332nbosse = -1;
333ipo = sgnsave = 0;
334
335for (;;) {
336 /* caracteristiques du point ipo */
337 ev = err[ipo];
338 if ( ev > 0. ) v = ( mag[ipo] - mean ) / ev; else v = 0.;
339 if ( v > 0. ) { av = v; sgn = 1; } else { av = -v; sgn = -1; }
340 if (deb>=3)
341 printf(" ipo=%5d sgn=%2d v=%f ev=%f c2=%f\n",ipo,sgn,v,ev,v*v);
342 if ( ev>0. && sgnsave==0 && av>=scut ) {
343 /* essai d'une nouvelle bosse (sgnsave==0), on demarre si > scut */
344 i1 = i2 = ipo;
345 sgnsave = sgn;
346 c2 = v*v;
347 pc2 = nberfc(av/Rac2) + Log2;
348 npt = 1;
349 if( av >= smin ) npt_valid = 1; else npt_valid = 0;
350 c2_cut = pc2_cut = 0.;
351 npt_cut = npt_c2_cut = 0;
352 if(deb>=3)
353 printf("* Dep bosse [%d] i1=%d n,c2,pc2= %d, %.3f, %.3f\n"
354 ,sgnsave,i1,npt,c2,pc2);
355 } else if( sgnsave!=0 &&
356 ( (ev>0. && sgnsave*v<scut) || ipo==ndata-1 ) ) {
357 /* c'est une possibilite de fin de bosse */
358 /* c a d soit un point normal en position de coupure */
359 /* soit le dernier point des tableaux */
360 if ( ev>0. && sgnsave*v<scut ) {
361 /* point normal ou dernier point dans des conditions d arret de bosse */
362 s = '-';
363 npt_cut++;
364 if( sgn == sgnsave ) {
365 npt_c2_cut++;
366 c2_cut += v*v;
367 pc2_cut += nberfc(av/Rac2) + Log2;
368 }
369 } else if ( ev>0. && sgnsave*v>=scut ) {
370 /* c-a-d le dernier point (ipo==ndata-1) */
371 /* avec une amplitude (grande) continuant la bosse */
372 /* --> dans ce cas la bosse doit inclure ce point */
373 /* et eventuellement les precedents de cette coupure */
374 s = '+';
375 npt += 1 + npt_c2_cut;
376 c2 += v*v + c2_cut;
377 pc2 += nberfc(av/Rac2) + Log2 + pc2_cut;
378 if( av >= smin ) npt_valid++;
379 i2 = ipo;
380 } else {
381 /* cas ipo==ndata-1 et ev<=0. : point ignore */
382 s = '0';
383 }
384 if(deb>=3)
385 printf("- Fin%c ncut=%d n,c2,pc2= %d, %.3f, %.3f cut= %d, %.3f, %.3f\n"
386 ,s,npt_cut,npt,c2,pc2,npt_c2_cut,c2_cut,pc2_cut);
387 if ( npt_cut>=nptscut || ipo==ndata-1 ) {
388 /* c'est une fin de bosse */
389 if ( npt_valid >= nptsmin ) {
390 /* validation de la bosse */
391 nbosse++;
392 /* on prend prob(xi2,npt)/2**(npt-1) */
393 if(Bosse_probnb)
394 pc2 = (double) probnb((float) c2,npt,&pass) + (npt-1)*Log2;
395 if ( nbosse >= NbossMX ) {
396 printf("Bosse: Trop de bosses (%d), changez dimension tableaux",nbosse);
397 return(-NbossMX);
398 } else if ( nbosse == 0 ) {
399 classB[0] = 0;
400 } else if ( nbosse > 0 ) {
401 for ( j=0;j<nbosse;j++)
402 if ( pc2 > fabs( (double) Pchi2[classB[j]] ) ) break;
403 for ( k=nbosse-1;k>=j;k--) classB[k+1] = classB[k];
404 classB[j] = nbosse;
405 }
406 Pchi2[nbosse] = sgnsave*pc2;
407 chi2[nbosse] = sgnsave*c2;
408 npoint[nbosse] = npt;
409 ideb[nbosse] = i1;
410 ifin[nbosse] = i2;
411 if(deb>=3)
412 printf("* Bosse %d, lim=%d %d classB=%d n,c2,pc2=%d %.3f %.3f\n"
413 ,nbosse,ideb[nbosse],ifin[nbosse],classB[nbosse]
414 ,npoint[nbosse],chi2[nbosse],Pchi2[nbosse]);
415 } else {
416 if(deb>=3) printf("* Bosse rejetee npt=%d /%d\n",npt,nptsmin);
417 }
418 sgnsave = 0;
419 ipo = i2;
420 }
421 } else if ( ev>0. && sgnsave!=0 ) {
422 /* c'est un point normal dans la bosse */
423 npt += 1 + npt_c2_cut;
424 c2 += v*v + c2_cut;
425 pc2 += nberfc(av/Rac2) + Log2 + pc2_cut;
426 if( av >= smin ) npt_valid++;
427 i2 = ipo;
428 if(deb>=3)
429 printf("- add point i2=%d n,c2,pc2= %d, %.3f, %.3f cut= %d, %.3f, %.3f\n"
430 ,i2,npt,c2,pc2,npt_c2_cut,c2_cut,pc2_cut);
431 npt_cut = npt_c2_cut = 0;
432 c2_cut = pc2_cut = 0.;
433 } else {
434 /* point a erreur negative ou points a moins de scut sans bosse demarree */
435 if(deb>=3)
436 printf("- pas de bosse demarree (%d) ou erreur negative (%f)\n"
437 ,sgnsave,ev);
438 }
439 ipo++;
440 if(ipo >= ndata ) break;
441}
442nbosse++;
443
444if(deb>=1) {
445 printf("Bosse: nombre de bosses trouvees=%d\n",nbosse);
446 if ( nbosse>0 ) {
447 printf("********************************************************\n");
448 k=3;
449 if ( deb>=2 ) k=nbosse;
450 for (ipo=0;ipo<k;ipo++) {
451 j = classB[ipo];
452 printf("* bosse %4d, lim=%5d %5d n,c2,pc2=%d %.3f %.3f\n"
453 ,j,ideb[j],ifin[j],npoint[j],chi2[j],Pchi2[j]);
454 }
455 printf("********************************************************\n");
456 }
457}
458
459return(nbosse);
460}
461
462/*=========================================================================*/
463int_4 BossePaG(float *temps,float *mag,float *err,int_4 ndata,float mean
464 ,int_4 I1,int_4 I2,float *U0,float *T0,float *Tau)
465/* Christophe 11/11/93 La Silla
466**** Recherche des parametres U0,T0,Tau d'une bosse ****
467 bosse + ou - en magnitude ou en flux
468ENTREE:
469 temps: temps
470 mag: magnitude
471 err: erreur sur la magnitude
472 ndata: nombre de donnees (si >0 mag=magnitudes, si <0 mag=flux)
473 mean: valeur de la ligne de base
474 I1: indice de depart de la bosse
475 I2: indice de fin de la bosse
476 U0: si >0 la bosse est positive, si <0 la bosse est negative
477SORTIE:
478 U0: estimation du parametre d'impact U0
479 T0: estimation du temps de minimum d'approche T0
480 Tau: estimation de la largeur Tau
481 BossePaG: retourne 0 si calcul ok, <0 sinon
482Methode:
483 Les parametres T0 et Tau sont estimes a partir de la
484 distribution en temps des points dans la bosse,
485 U0 par l'estimation de la hauteur de la gaussienne de sigma
486 calcule pour la valeur de Tau et de l'aire de la bosse.
487*/
488{
489int_4 deb=DEB_BossePaG;
490int_4 i,flu=0,bossp=1;
491float tprev,magprev;
492double v,m,s,norm,sint,hgauss,a,aa,u12,hmax;
493int ifirst;
494
495if( ndata<0 ) { flu=1; ndata *= -1;}
496if( *U0<0 ) bossp = -1;
497*U0 = *T0 = *Tau = 0.;
498if ( I2 <= I1 ) {printf("BossePaG: I1 <= I2 %d %d\n",I1,I2); return(-1);}
499if ( mean <= 0. && flu ) return(-11);
500if(deb) printf("BossePaG: de I1=%d a I2=%d n=%d mean=%g flu=%d\n"
501 ,I1,I2,ndata,mean,flu);
502
503/* Calcul de T0 et Tau */
504hmax= -1.e30;
505tprev = temps[I1]; magprev = mean; /* $CHECK$ EA pas cool l'init de magprev */
506/* magprev peut etre une amplitude, mais pas mean !! */
507/* $CHECK$ EA si on tue le point I1, sint delire. Je rajoute ifirst */
508m = s = norm = sint = 0.;
509ifirst = 1;
510for (i=I1;i<=I2;i++) {
511 if ( err[i] <= 0. ) continue;
512 if(flu && bossp<0 && mag[i]<=0.) continue;
513 if(flu && bossp>=0) a = mag[i]/mean-1.;
514 else if(flu && bossp<0) a = 1.-mean/mag[i];
515 else a = mag[i]-mean;
516 aa = bossp*a;
517 if( aa<=0 ) continue;
518 if( aa > hmax ) hmax=aa;
519 v = temps[i];
520 m += v*aa;
521 s += v*v*aa;
522 norm += aa;
523 if ( !ifirst )
524 sint += (temps[i]-tprev)*(a+magprev)/2.;
525 else
526 ifirst = 0;
527 tprev = temps[i];
528 magprev = a;
529}
530if(norm <= 0. ) return(-2);
531sint = fabs(sint);
532m = m/norm;
533s = s/norm - m*m;
534if(s <= 0.) return(-3);
535s = sqrt(s);
536hgauss = sint / S2Pi / s;
537if (deb>=2) printf("m=%f s=%f int=%f hgauss=%f hmax=%f\n",m,s,sint,hgauss,hmax);
538
539/* T0 = moyenne */
540*T0 = m;
541
542/* U0 = hauteur de la gaussienne de sigma s */
543if(flu) a = hgauss+1.; else a = pow(10.,0.4*hgauss);
544if(a<=1. || a>= sqrt(GRAND2)) return(-4);
545*U0 = 2.*(a/sqrt(a*a-1.)-1.);
546if(deb>=2) printf("A0=%f u0^2=%f",a,*U0);
547
548/* Tau = en considerant que 2.36*s est la largeur
549 a mi-hauteur (magnitude) de la courbe de pazcinski */
550if(flu) a = hgauss/2.+1.; else a = pow(10.,0.2*hgauss);
551if(a<1.) return(-5);
552u12 = 2*(a/sqrt(a*a-1.)-1.);
553if (deb>=2) printf(" a1/2=%f u1/2^2=%f\n",a,u12);
554v = 2.36*s/2.;
555if ( u12 <= *U0 ) return(-6);
556v = v*v/(u12-*U0);
557*Tau = sqrt(v);
558*U0 = sqrt(*U0);
559if (deb) printf("BossePaG: U0=%f, T0=%f, Tau=%f\n",*U0,*T0,*Tau);
560
561return(0);
562}
563
564/*=========================================================================*/
565float SigmaInt(float *temps,float *mag,float *err,int_4 *ndata,float nsigma)
566/* Christophe 12/11/93 La Silla
567**** Calcul du sigma interne d'une courbe de lumiere ****
568ENTREE:
569 temps: temps
570 mag: magnitude
571 err: erreur sur la magnitude
572 ndata: nombre de donnees
573 nsigma: nombre de sigmas pour la coupure de la 2sd passe
574 si <=0 une seule passe
575SORTIE:
576 SigmaInt: retourne le sigma Interne ou <0 si il y a eu un probleme
577- Methode: On calcul le sigma avec la dispersion d'un point Y(t) et de la
578 prediction lineaire a partir de ses 2 voisins Y0(t) et Y1(t):
579 M = Y - Ypred = Y - (Y1 +(Y2-Y1)/(t2-t1)*(t-t1))
580 le calcul de propagation des erreurs donne:
581 SM = 2*(R^2-R+1)*SY avec SY=SY1=SY2 et R=(t-t1)/(t2-t1) (<1.)
582 donc pour avoir SY on calcul le sigma de la quantite:
583 M et on divise le resultat par sqrt( <2*(R^2-R+1)> )
584 ce qui dans le cas ou les points sont equidistants
585 donne comme R=1/2: SM/sqrt(3/2)
586*/
587{
588int_4 deb=DEB_SigmaInt;
589int_4 pass,passmx,i,n=0;
590float sigma;
591double m,s,fpred,R,sR;
592
593passmx = ( nsigma > 0. ) ? 2 : 1 ;
594if ( *ndata < 3 ) return(-1.);
595sigma = GRAND;
596if( nsigma <= 0. ) nsigma = 1.;
597for (pass=1;pass<=passmx;pass++) {
598 n=0;
599 m = s = sR = 0.;
600 for (i=1;i<*ndata-1;i++) {
601 if ( err[i] > 0. && err[i-1] > 0. && err[i+1] > 0. ) {
602 R = ( temps[i] - temps[i-1] ) / ( temps[i+1]- temps[i-1] );
603 fpred = mag[i] - ( mag[i-1] + (mag[i+1]- mag[i-1] )*R );
604 if ( fabs(fpred) < nsigma*sigma ) {
605 m += fpred;
606 s += fpred*fpred;
607 sR += 2.*(R*R-R+1.);
608 n++;
609 } } }
610 if ( n <= 0 ) return(-2.);
611 m = m/n;
612 sR = sR/n;
613 sigma = sqrt(s/n) / sqrt(sR);
614 if ( deb ) printf("SigmaInt: pass=%d sigma=%f m=%f sR=%f npoints=%d\n"
615 ,pass,sigma,m,sR,n);
616}
617*ndata = n;
618return(sigma);
619}
620
621/*=========================================================================*/
622int_4 FiltMed(float *mag,float *err
623 ,float *magflt, float* errflt, int_4 ndata)
624/* Christophe 13/11/93 La Silla
625**** Filtre Statistique Median a 3 points ****
626ENTREE:
627 mag: magnitude
628 err: erreur sur la magnitude
629 ndata: nombre de donnees
630SORTIE:
631 magflt: magnitude filtree
632 errflt: erreur sur la magnitude filtree
633 FiltMed: retourne 0 si ok, <0 sinon.
634*/
635{
636int deb=DEB_FiltMed;
637int j,k0,k1,k2,imin=-1,imax=-1;
638
639if ( ndata<3 ) {
640 for (k0=0;k0<ndata;k0++)
641 { magflt[k0] = mag[k0]; errflt[k0] = err[k0];}
642 return(-1);
643}
644
645/* filtre median sur tous les points sauf le premier et le dernier */
646for (k0=1;k0<ndata-1;k0++) {
647 magflt[k0] = mag[k0]; errflt[k0] = err[k0];
648 if ( err[k0] <= 0. ) continue;
649 /*recherche du 1er point inferieur utilisable */
650 k1 = k0-1; while ( err[k1] <= 0. && k1 > 0 ) k1--;
651 /* recherche du 1er point superieur utilisable */
652 k2 = k0+1; while ( err[k2] <= 0. && k2 < ndata-1 ) k2++;
653 if ( err[k1]<=0. || err[k2]<=0. ) continue;
654 if ((mag[k1]-mag[k0])*(mag[k2]-mag[k0])<0.) j=k0;
655 else if((mag[k0]-mag[k1])*(mag[k2]-mag[k1])<0.) j=k1;
656 else if((mag[k1]-mag[k2])*(mag[k0]-mag[k2])<0.) j=k2;
657 else {
658 if (mag[k0]==mag[k1]) {if(err[k0]<=err[k1]) j=k0; else j=k1;}
659 else if(mag[k1]==mag[k2]) {if(err[k1]<=err[k2]) j=k1; else j=k2;}
660 else {if(err[k2]< err[k0]) j=k2; else j=k0;}
661 }
662 magflt[k0] = mag[j]; errflt[k0] = err[j];
663 if( imin == -1 ) imin = k0; imax = k0;
664}
665
666/* cas du premier point */
667k0 = 0; magflt[k0] = mag[k0]; errflt[k0] = err[k0];
668if( err[k0]>0. && imin>=0 )
669 { magflt[k0] = magflt[imin]; errflt[k0] = errflt[imin];}
670
671/* cas du dernier point */
672k0 = ndata-1; magflt[k0] = mag[k0]; errflt[k0] = err[k0];
673if( err[k0]>0. && imax>=0 )
674 { magflt[k0] = magflt[imax]; errflt[k0] = errflt[imax];}
675
676/* debug? */
677if (deb>=1) {
678 printf("FiltMed:");
679 for(k0=0;k0<ndata+10;k0+=10) {
680 for(j=k0; j<k0+10 && j<ndata; j++)
681 { if(k0==j) printf("\nF "); printf(" %10.3f",mag[j]);}
682 for(j=k0; j<k0+10 && j<ndata; j++)
683 { if(k0==j) printf("\nE "); printf(" %10.3f",err[j]);}
684 for(j=k0; j<k0+10 && j<ndata; j++)
685 { if(k0==j) printf("\nFf"); printf(" %10.3f",magflt[j]);}
686 for(j=k0; j<k0+10 && j<ndata; j++)
687 { if(k0==j) printf("\nEf"); printf(" %10.3f",errflt[j]);}
688 }
689 printf("\n");
690}
691
692return(0);
693}
694
695/*=========================================================================*/
696int_4 FiltInt(float *temps,float *mag,float *err,int_4 ndata,int_4 I1,int_4 I2
697 ,float lbosse,int_4 npomin,int_4 *ideb,int_4 *ifin)
698/* Christophe 15/11/93 La Silla
699**** Calcul de l'intervalle pour le fit ****
700ENTREE:
701 temps: temps
702 mag: magnitude
703 err: erreur sur la magnitude
704 ndata: nombre de donnees
705 I1: 1er indice de la bosse
706 I2: dernier indice de la bosse
707 lbosse: largeur (en unite de largeur de bosse)
708 a rajouter de part et d'autre de la bosse
709 npomin: nombre de points minimum avant/apres la bosse
710SORTIE:
711 ideb: indice du debut de l'intervalle
712 ifin: indice de fin de l'intervalle
713 FiltInt: retourne nombre de points dans l'intervalle et hors bosse,
714 <0 si probleme.
715*/
716{
717int_4 deb=DEB_FiltInt;
718int_4 i,n,ntot;
719float t1,t2;
720double dt;
721
722if ( I2 <= I1 ) {printf("FiltInt: I2 <= I1 %d %d\n",I1,I2); return(-1);}
723
724ntot = 0;
725t1 = temps[I1];
726t2 = temps[I2];
727lbosse = (lbosse<=0.) ? 1. : lbosse ;
728dt = (t2-t1)*lbosse;
729if(deb>1) printf("FiltInt: limites bosse %f %f (%f)\n",t1,t2,dt);
730t1 -= dt;
731t2 += dt;
732if(deb>1) printf("FiltInt: limites intervalle de fit %f %f\n",t1,t2);
733
734/* calcul de la borne inferieure de fit */
735n=0;
736for (i=I1;i>=0;i--) {
737 if(err[i] > 0. ) {
738 n++;
739 if( temps[i] < t1 && n > npomin ) break;
740} }
741ntot += n;
742*ideb= ( i<0 ) ? 0 : i;
743
744/* calcul de la borne superieure de fit */
745n=0;
746for (i=I2;i<ndata;i++) {
747 if(err[i] > 0. ) {
748 n++;
749 if( temps[i] > t2 && n > npomin ) break;
750} }
751ntot += n;
752*ifin= ( i>= ndata ) ? ndata-1 : i;
753
754if(deb) printf("FiltInt: limites intervalle de fit %d %d\n",*ideb,*ifin);
755
756return(ntot);
757}
758
759/*======================================================================================*/
760double chi2_exterieur(float *mag,float *err,int_4 ndata,float mean
761 ,int_4 I1,int_4 I2,int_4 *npt)
762/* Cecile
763calcul du Chi2 par degre de liberte a l'exterieur de la bosse delimitee par i1 et I2
764ENTREE :
765 mag : magnitude
766 err : erreur sur la magnitude
767 ndata : nombre de donnees
768 mean : moyenne des mesures
769 I1, I2 : limites de la bosse
770SORTIE:
771 chi2_exterieur : valeur du Chi2 reduit a l'exterieur de la bosse
772*/
773{
774int_4 i;
775double chi2,d;
776
777if ( I2 <= I1 ) {printf("chi2_ext. : I2 <= I1 %d %d\n",I1,I2); return(-1.);}
778
779*npt=0;
780chi2=0.;
781
782if(I1>0) {
783 for(i=0;i<I1;i++) {
784 if( err[i] > 0.) {
785 d = (mag[i] - mean) / err[i];
786 chi2+= d*d;
787 (*npt)++;
788} } }
789
790if(I2<ndata) {
791 for(i=I2+1;i<ndata;i++) {
792 if( err[i] > 0.) {
793 d = (mag[i] - mean) / err[i];
794 chi2+= d*d;
795 (*npt)++;
796} } }
797
798return(chi2);
799}
800
801/*===================================================================*/
802double Dt_PacZin(double u0,double tau,double A)
803/* pour calculer le DT ou la paczinsky a une ampli de A */
804{
805double x;
806if( A <= 1. ) return(-1.);
807x = 2.*( A / sqrt(A*A-1.) - 1. ) - u0*u0;
808if( x <= 0. ) return(-2.);
809x = tau * sqrt(x);
810return(x);
811}
812
813/*==================================================================*/
814int_4 Most_3D2D(float *Y,float *EY,int_4 *ndata,float Ymin,float Ymax
815 ,float *Res_2D,float *Res_3D)
816/*
817Pour calculer la valeur la + probable par estimation des parametres
818 d'une distribution parabolique / polynome de degre 3
819INPUT:
820 Y: tableau des valeurs
821 EY: tableau des erreurs (<=0 point non traite)
822 ndata: nombre de valeurs
823 Ymin,Ymax: limites des valeurs a considerees pour Y
824OUTPUT:
825 ndata: nombre de valeurs utilisees pour le calcul
826 Res_2D: resultat du fit parabolique
827 Res_3D: resultat du fit polynome d'ordre 3
828 rc: validation des resultats
829 =0 : probleme
830 =1 : fit parabolique ok
831 =2 : fit polynome_ordre_3 ok
832 =3 : fit parabolique + polynome_ordre_3 ok
833*/
834{
835int i,n,Flag,lp=0;
836double xmoy,x2moy,x3moy;
837double v1,v2,VN,det;
838double M3[3][3],M2[2][2],B[3],AX[4];
839
840if(lp) printf("Most_3D2D: ndata=%d Ymin=%g Ymax=%g\n",*ndata,Ymin,Ymax);
841
842*Res_3D = 0.;
843*Res_2D = 0.;
844Flag = 0;
845
846if( *ndata<=0 || Ymax <= Ymin ) goto END;
847
848/* on recentre tout entre 0 et 1 donc Ymin=0 YMax=1 */
849VN = Ymax-Ymin;
850n = 0;
851xmoy = x2moy = x3moy = 0.;
852
853for(i=0;i<*ndata;i++)
854 {
855 if( EY[i]>0. && Y[i]>Ymin && Y[i]<Ymax )
856 {
857 v1 = (Y[i]-Ymin)/VN;
858 xmoy += v1;
859 x2moy += v1*v1;
860 x3moy += v1*v1*v1;
861 n++;
862 }
863 }
864if(n<=0) goto END;
865xmoy /= n;
866x2moy /= n;
867x3moy /= n;
868if(lp) printf(" <x>=%g <x2>=%g <x3>=%g\n",xmoy,x2moy,x3moy);
869
870/* On remplit la matrice 2x2 pour le fit parabolique */
871M2[0][0] = 1./5. -1./9.;
872M2[0][1] = M2[1][0] = M2[1][1] = 1./12.; /* = 1./4. -1./6. = 1./3. -1./4. */
873B[0] = x2moy - 1./3.;
874B[1] = xmoy - 0.5;
875det = SolveDLinSyst(&(M2[0][0]), B, AX, 2);
876if(lp) printf("Solve_2D: det=%g sol=%g %g\n",det,AX[0],AX[1]);
877if ( det != 0. )
878 {
879 if ( AX[0] != 0. )
880 {
881 Flag += 1;
882 *Res_2D = -AX[1]/(2.*AX[0]);
883 if(lp) printf(" s1=%g\n",*Res_2D);
884 *Res_2D = Ymin + *Res_2D*VN;
885 }
886 }
887
888/* On remplit la matrice 3x3 pour le fit polynome d'ordre 3 */
889M3[0][0] = M3[2][2] = 1./5. -1./8.;
890/* 1./12. = 1./4. -1./6. = 1./3. -1./4. = 1./6. -1./12 */
891M3[0][1] = M3[1][2] = M3[0][2] = M3[1][0] = M3[2][1] = 1./12.;
892M3[1][1] = 1./5. -1./9.;
893M3[2][0] = 1./7. -1./16.;
894B[0] = xmoy - 0.5;
895B[1] = x2moy - 1./3.;
896B[2] = x3moy - 0.25;
897det = SolveDLinSyst(&(M3[0][0]), B, AX, 3);
898if(lp) printf("Solve_3D: det=%g sol=%g %g %g\n",det,AX[0],AX[1],AX[2]);
899if ( det != 0. )
900 {
901 /* on cherche les 2 racines de l'annulation de la derivee */
902 det = AX[1]*AX[1] - 3.*AX[0]*AX[2];
903 if(lp) printf(" det=%g\n",det);
904 if ( det >= 0. && AX[0] != 0. )
905 {
906 xmoy = (-AX[1] + sqrt(det))/(3.*AX[0]);
907 v1 = 6.*AX[0]*xmoy+2.*AX[1];
908 x2moy = (-AX[1] - sqrt(det))/(3.*AX[0]);
909 v2 = 6.*AX[0]*x2moy+2.*AX[1];
910 if(lp) printf(" s1=%g (%g) s2=%g (%g)\n",xmoy,v1,x2moy,v2);
911 Flag += 2;
912 *Res_3D = xmoy;
913 if(v2<0.) *Res_3D = x2moy;
914 *Res_3D = Ymin + *Res_3D*VN;
915 }
916 }
917
918
919END:
920if(lp) printf("Most_3D2D: *Res_2D=%g *Res_3D=%g Flag=%d\n"
921 ,*Res_2D,*Res_3D,Flag);
922return(Flag);
923}
924
925/*==================================================================*/
926double correlation(int_4 npts,double *x,double *y)
927{
928/* Cecile Numerical Recipies p. 503
929Calcule le coefficient de correlation de x et y sur npts points
930ENTREE :
931 npts nombre de points
932 x, y tableau des valeurs
933SORTIE:
934 correlation : coefficient de correlation
935 -2 si nb de points OK < 3
936 -3 si produit des (x[i]-ax)(y[i]-ay)<=0
937*/
938int_4 i,n;
939double ax,ay,xt,yt,sxx,syy,sxy;
940n=0; ay = ax= 0.;
941for(i=0;i<npts;i++) {ax += x[i]; ay += y[i]; n++;}
942if( n<3 ) {
943 printf("correlation: moins de 3 points pour le calcul de la correlation (%d)\n",n);
944 return(-2.);
945}
946ax /= n; ay /= n;
947xt = yt = syy = sxy = sxx = 0.;
948for(i=0;i<npts;i++) {
949 xt = x[i]-ax; yt = y[i]-ay;
950 sxx += xt*xt; syy += yt*yt; sxy += xt*yt;
951}
952return( ((sxx*syy>0.) ? sxy/sqrt(sxx*syy) : -3.) );
953}
954
955/*==================================================================*/
956double CorrelatioN(int_4 nptX,float *X,float *Y,int_4* IndXvY)
957/* cmv 17/4/99
958Calcule le coefficient de correlation de X[] et Y[] sur nptX points
959ENTREE :
960 nptX nombre de points dans le tableau X[]
961 X[], Y[] : tableau des valeurs a correler
962 IndXvY[] : tableau des indices de Y[] a correler a X[]
963SORTIE: coefficient de correlation
964 -2 si nb de points OK (>3)
965 -3 si somme des (X[i]-ax)^2 ou (Y[i]-ay)^2 <=0
966EXPLICATION:
967 X[1,nptX-1], Y[....], IndXvY[1,nptX-1]
968 - le point X[i] correspond au point Y[IndXvY[i]] si IndXvY[i]>=0
969 - le point X[i] n'est pas pris en compte si IndXvY[i]<0
970*/
971{
972int_4 i,n;
973double ax,ay,xt,yt,sxx,syy,sxy;
974n=0; ay=ax=0.;
975for(i=0;i<nptX;i++) if(IndXvY[i]>=0) {ax+=X[i]; ay+=Y[IndXvY[i]]; n++;}
976if(n<3)
977 {printf("CorrelatioN: %d<3 points pour le calcul\n",n); return(-2.);}
978ax /= n; ay /= n;
979xt = yt = syy = sxy = sxx = 0.;
980for(i=0;i<nptX;i++) if(IndXvY[i]>=0)
981 { xt = X[i]-ax; yt = Y[IndXvY[i]]-ay;
982 sxx += xt*xt; syy += yt*yt; sxy += xt*yt; }
983return( ((sxx*syy>0.) ? sxy/sqrt(sxx*syy) : -3.) );
984}
985
986/*=========================================================================*/
987int_4 MeanLine(float *mag,float *err,int_4 *ndata
988 ,int passmx,float nsigma,float *mean,float *sigma)
989/*
990Calcul de la moyenne et du sigma en plusieurs passes avec nettoyage
991ENTREE:
992 mag: magnitude
993 err: erreur sur la magnitude (Si NULL pas d'erreur)
994 ndata: nombre de donnees
995 nsigma: nombre de sigma dans lequel on calcule le mean
996 passmx: nombre de passes
997SORTIE:
998 ndata: nombre de data utilises pour calculer le most
999 mean: moyenne des donnees
1000 sigma: sigma des donnees
1001 MeanLine: 0 si calcul ok, <0 sinon
1002*/
1003{
1004int_4 pass,n,i;
1005double m,s2,scut,v;
1006if( passmx<=0 ) passmx = 1;
1007
1008*mean = *sigma = 0.;
1009for (pass=1;pass<=passmx;pass++) {
1010 m = s2 = 0.; n=0;
1011 if( pass>=2 ) scut=*sigma*nsigma; else scut=GRAND;
1012 for (i=0;i<*ndata;i++) {
1013 v = mag[i];
1014 if(err!=NULL) if( err[i] <= 0. ) continue;
1015 if( fabs(v-*mean) >= scut ) continue;
1016 n++;
1017 m += v;
1018 s2 += v * v;
1019 }
1020 if ( n>0 ) {
1021 m /= (double) n;
1022 v = s2/n - m*m;
1023 *mean = m;
1024 *sigma = (v>0) ? sqrt(v) : 0.;
1025 } else {
1026 *mean = *sigma = 0.;
1027 *ndata=n;
1028 return(-1);
1029 }
1030 /* printf("MeanLine: pass=%d mean=%f sigma=%f n=%d\n"
1031 ,pass,*mean,*sigma,n); */
1032}
1033return(0);
1034}
1035
1036/*=========================================================================*/
1037int_4 BaseLine(float *mag,float *err,int_4 *ndata,float nsigma
1038 ,float binini,float *mean,float *sigma,float *most)
1039/* Christophe 10/11/93 La Silla + modif 28/7/94 Saclay
1040**** calcul de la ligne de base d'une etoile par maxi d'histogramme ****
1041Methode: 1-/ moyenne, 2-/ moyenne tronquee,
1042 3-/ maximum d'histogramme,
1043 4-/ puis deuxieme passe sur histo plus lache
1044ENTREE:
1045 mag: magnitude
1046 err: erreur sur la magnitude
1047 ndata: nombre de donnees
1048 nsigma: nombre de sigma dans lequel on calcule le maximum
1049 si <=0, une seule passe pour la moyenne et dynamique histo = 5.
1050 binini: bin minimum de la methode d'histogramme
1051SORTIE:
1052 ndata: nombre de data utilises pour calculer le most
1053 mean: moyenne des donnees
1054 sigma: sigma des donnees
1055 most: maximum de probabilite
1056RETURN: nombre d entrees dans le bin du maximum, <0 si echec
1057*/
1058{
1059int_4 deb=DEB_BaseLine;
1060int_4 pass,passmx,i,ib0,ib1,n=0,ibin,nbin=0,tab0mx,nbinmx=100,tab0[101];
1061float mini,maxi,binw;
1062double m,s2,v,vv,scut;
1063double SX4,SX3,SX2,SX,S1,SYX2,SYX,SY;
1064double MX33[3][3],BB[3],AX[3],det;
1065
1066if(deb) printf("BaseLine: n=%d nsigma=%f binini=%f\n",*ndata,nsigma,binini);
1067
1068/*********** D'abord une moyenne et sigma ************/
1069*mean = *sigma = 0.;
1070passmx = ( nsigma <= 0. ) ? 1 : 2 ;
1071for (pass=1;pass<=passmx;pass++) {
1072 m = s2 = 0.; n=0;
1073 scut = GRAND;
1074 if( pass == 2 ) scut = nsigma* *sigma;
1075 for (i=0;i<*ndata;i++) {
1076 v = mag[i];
1077 if( err[i] <= 0. || fabs(v-*mean) >= scut ) continue;
1078 n++; m += v; s2 += v*v;
1079 }
1080 if ( n >= 2 ) {
1081 *mean = m / n;
1082 v = s2 / n - m/n * m/n;
1083 *sigma = ( v>0. ) ? sqrt(v) : 0.;
1084 } else {
1085 *mean = *sigma = 0.;
1086 *ndata=n;
1087 return(-1);
1088 }
1089 if(deb) printf("BaseLine: pass=%d mean=%f sigma=%f n=%d\n"
1090 ,pass,*mean,*sigma,n);
1091 if( *sigma == 0. ) return(-1);
1092}
1093
1094/***** Puis une methode de maximum d'histogramme *****/
1095if ( nsigma <= 0. ) nsigma = 5.;
1096mini = *mean - nsigma * *sigma;
1097maxi = *mean + nsigma * *sigma;
1098
1099for (pass=1;pass<=2;pass++) {
1100
1101 if( binini > 0. ) {
1102 if ( pass == 1 ) nbin = (maxi-mini)/(2.*binini) + 0.5; /* 1ere pass a 2*binini */
1103 if ( pass == 2 ) nbin = (maxi-mini)/binini + 0.5; /* 2sd pass a binini */
1104 if ( nbin >= nbinmx ) nbin = nbinmx;
1105 if ( nbin < 3 ) nbin = 3;
1106 } else nbin = nbinmx;
1107 binw = (maxi-mini)/nbin;
1108 if(deb) printf("mini=%f maxi=%f binw=%f nbin=%d\n",mini,maxi,binw,nbin);
1109
1110 /*fill histogramme tab0*/
1111 for (i=0;i<nbin;i++) tab0[i] = 0;
1112 for (i=0;i<*ndata;i++) {
1113 if( err[i] <= 0. ) continue;
1114 ibin = (mag[i]-mini)/binw;
1115 if( ibin >= 0 && ibin < nbin ) tab0[ibin] += 1;
1116 }
1117
1118 /*maximum de l'histogramme tab0*/
1119 ibin=0;
1120 tab0mx = 0;
1121 for (i=0;i<nbin;i++) if ( tab0[i] > tab0mx ) {tab0mx = tab0[i]; ibin=i;}
1122 ib0 = ibin-1; ib1 = ibin+1;
1123 if(ib0<0) { ib0 = 0; ib1++;}
1124 if(ib1>=nbin) { ib1 = nbin-1; ib0--;}
1125 if (deb>1) {
1126 printf("Maximum tab0=%d (%d [%d,%d])\n",tab0mx,ibin,ib0,ib1);
1127 if (deb>2) { printf("Tableau final tab0:\n");
1128 for (i=0;i<nbin;i++) printf(" %d=%d",i,tab0[i]);
1129 printf("\n"); }
1130 }
1131
1132 /* calcul de la valeur maximale par fit parabole +/- 1 bin autour du maximum */
1133 S1 = SY = SYX = SYX2 = SX4 = SX3 = SX2 = SX = 0.;
1134 for (i=ib0;i<=ib1;i++) {
1135 v = mini + (i+0.5)*binw;
1136 vv = v*v;
1137 m = tab0[i];
1138 s2=1.;
1139 S1 += s2;
1140 SX += s2*v;
1141 SY += s2*m;
1142 SYX += s2*v*m;
1143 SYX2 += s2*m*vv;
1144 SX2 += s2*vv;
1145 SX3 += s2*vv*v;
1146 SX4 += s2*vv*vv;
1147 }
1148 MX33[0][0] = S1;
1149 MX33[1][1] = SX2;
1150 MX33[2][2] = SX4;
1151 MX33[0][1] = MX33[1][0] = SX;
1152 MX33[0][2] = MX33[2][0] = SX2;
1153 MX33[1][2] = MX33[2][1] = SX3;
1154 BB[0] = SY;
1155 BB[1] = SYX;
1156 BB[2] = SYX2;
1157 det = SolveDLinSyst(&(MX33[0][0]), BB, AX, 3);
1158 if( det == 0. ) return(-2);
1159 if( AX[2] == 0. ) return(-2);
1160 *most = -AX[1]/(2.*AX[2]);
1161
1162 if(deb)
1163 printf("BaseLine: pass=%d most_probable=%f ibin=%d\n",pass,*most,ibin);
1164
1165 if( *most<=mini || *most >= maxi ) return(-3);
1166
1167 /*nouveaux parametres de l'histogramme tab0 */
1168 mini = *most-2.5*binw;
1169 maxi = *most+2.5*binw;
1170
1171}
1172
1173*ndata=n;
1174return(tab0mx);
1175}
1176
1177/*=========================================================================*/
1178int BaseLineS(float *y,float *ey,int ny,int nfiltre,float *mean,float *sigma)
1179/* D'apres Alain M. + modifs + code cmv 5/5/97
1180Determination de la ligne de base comme sequence de nfiltre points
1181 consecutifs de dispersion minimale:
1182 y : tableau des flux
1183 ey : tableau des erreurs sur les flux (pt non util. si <=0)
1184 ny : nombre de points
1185 nfiltre : nombre de points consecutifs pour calculer le sigma
1186 si <0 y est d'abord range par flux croissants
1187 mean : valeur du fond de ciel retourne
1188 sigma : valeur du sigma mini trouve
1189 rc : nombre d essais ( si <=0 echec)
1190*/
1191{
1192int rc=0, isort=0,i,j,npt,n;
1193double s,m;
1194float *ys=NULL;
1195
1196*mean = *sigma = -1.;
1197if( ny<=1 ) return(-1);
1198
1199if( nfiltre<0 ) {
1200 isort = 1;
1201 nfiltre *= -1;
1202 npt = 0;
1203 ys = (float *) malloc(ny*sizeof(float));
1204 if( ys==NULL ) return(-2);
1205 for(i=0;i<ny;i++) if(ey[i]>0.) ys[npt++] = y[i];
1206 qsort(ys,(size_t) npt,(size_t) sizeof(float),qSort_Float);
1207} else { npt=ny; ys = y;}
1208if( nfiltre>npt || nfiltre<=1 ) { if(isort) free(ys); return(-3);}
1209
1210for(i=0;i<npt-nfiltre+1;i++) {
1211 if( !isort && ey[i]<=0. ) continue;
1212 s = m = 0.; n = 0;
1213 for(j=i;j<npt;j++) {
1214 if( !isort && ey[j]<=0. ) continue;
1215 m += ys[j]; s += ys[j]*ys[j]; n++;
1216 if( n<nfiltre ) continue;
1217 rc++;
1218 m /= (double) n;
1219 s = s/n - m*m;
1220 s = ( s>0. ) ? sqrt(s) : 0.;
1221 if( s<*sigma || rc==1 ) { *sigma=s; *mean=m; }
1222 break;
1223 }
1224}
1225
1226if(isort) free(ys);
1227return(rc);
1228}
1229
1230/*=========================================================================*/
1231int BaseLineP(float *y,float *ey,int ny,int nfiltre,float *mean)
1232/* D'apres Alain M. + modifs + code cmv 5/5/97
1233Determination de la ligne de base comme endroit de pente minimale
1234 entre le point [i] et [i+nfiltre-1]. Ceci marche mieux avec
1235 le tableau trie mais la possibilite de ne pas trier est laissee:
1236 y : tableau des flux
1237 ey : tableau des erreurs sur les flux (pt non util. si <=0)
1238 ny : nombre de points
1239 nfiltre : nombre de points pour calculer la pente
1240 si <0 y est d'abord range par flux croissants
1241 mean : valeur du fond de ciel retourne
1242 rc : nombre d essais ( si <=0 echec)
1243*/
1244{
1245int rc=0, isort=0,i,j,npt,n;
1246float p=-1.,pmin=-1.,m;
1247float *ys=NULL;
1248
1249*mean = -1.;
1250if( ny<=1 ) return(-1);
1251
1252if( nfiltre<0 ) {
1253 isort = 1;
1254 nfiltre *= -1;
1255 npt = 0;
1256 ys = (float *) malloc(ny*sizeof(float));
1257 if( ys==NULL ) return(-2);
1258 for(i=0;i<ny;i++) if(ey[i]>0.) ys[npt++] = y[i];
1259 qsort(ys,(size_t) npt,(size_t) sizeof(float),qSort_Float);
1260} else { npt=ny; ys = y;}
1261if( nfiltre>npt || nfiltre<=1 ) { if(isort) free(ys); return(-3);}
1262
1263for(i=0;i<npt-nfiltre+1;i++) {
1264 if( !isort && ey[i]<=0. ) continue;
1265 m = 0.; n = 0;
1266 for(j=i;j<npt;j++) {
1267 if( !isort && ey[j]<=0. ) continue;
1268 m += ys[j]; n++;
1269 p = ys[j];
1270 if( n<nfiltre ) continue;
1271 rc++;
1272 p = fabs(ys[i]-p);
1273 if( p<pmin || rc==1 ) { pmin = p; *mean = m/n;}
1274 break;
1275 }
1276}
1277
1278if(isort) free(ys);
1279return(rc);
1280}
Note: See TracBrowser for help on using the repository browser.