Changeset 577 in Sophya for trunk/Poubelle/archTOI.old/starmatcher.cc
- Timestamp:
- Nov 16, 1999, 2:20:39 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Poubelle/archTOI.old/starmatcher.cc
r555 r577 8 8 #include "archparam.h" 9 9 #include "gondolageom.h" 10 #include "polfitclip.h" 11 12 #define STARDUMP 10 13 11 14 extern "C" { … … 14 17 #include "nrutil.h" 15 18 16 void lfit( float x[], float y[], float sig[], int ndat, floata[], int ia[],17 int ma, float **covar, float *chisq, void (*funcs)(float, float[], int));18 19 void polfunc( float x, floatafunc[], int ma);20 void sinfunc( float x, floatafunc[], int ma);21 } 22 23 void polfunc( float x, floatafunc[], int ma) {19 void lfit(double x[], double y[], double sig[], int ndat, double a[], int ia[], 20 int ma, double **covar, double *chisq, void (*funcs)(double, double [], int)); 21 22 void polfunc(double x, double afunc[], int ma); 23 void sinfunc(double x, double afunc[], int ma); 24 } 25 26 void polfunc(double x, double afunc[], int ma) { 24 27 afunc[1] = 1; 25 28 for (int i=2; i<=ma; i++) … … 27 30 } 28 31 29 void sinfunc( float x, floatafunc[], int /*ma*/) {32 void sinfunc(double x, double afunc[], int /*ma*/) { 30 33 afunc[1] = cos(x); 31 34 afunc[2] = sin(x); … … 34 37 35 38 36 float polval(float x, floata[], int ma);37 38 float polval(float x, floata[], int ma) {39 floatr = a[ma];39 double polval(double x, double a[], int ma); 40 41 double polval(double x, double a[], int ma) { 42 double r = a[ma]; 40 43 for (int i=ma-1; i>0; i--) { 41 44 r = r*x+a[i]; … … 186 189 static ofstream pendstream("pendul.dat"); 187 190 #endif 191 static ofstream logstream("starmatch.log"); 188 192 189 193 void StarMatcher::dataFeed(SSTEtoile const& x) { … … 295 299 296 300 // new set of matched stars... Clean, and get parameters... 297 // We don't want more than 20 seconds of data301 // We don't want more than 30 seconds of data 298 302 299 303 if (matchStars.empty()) return; … … 303 307 deque<matchStar>::iterator it; 304 308 for (it = matchStars.begin(); it!=matchStars.end(); it++) { 305 if ((snEnd - (*it).SN)*archParam.acq.perEch < 20) 309 if ((snEnd - (*it).SN)*archParam.acq.perEch < 30 || 310 (*it).seq > lastCleanSave) 306 311 break; 312 } 313 if (it != matchStars.begin()) { 314 it--; 307 315 } 308 316 if (it != matchStars.begin()) { … … 314 322 int nskip=0; 315 323 for (it = matchStars.begin(); it!=matchStars.end(); it++) { 316 if ((snEnd - (*it).SN)*archParam.acq.perEch < 7)324 if ((snEnd - (*it).SN)*archParam.acq.perEch < 5) 317 325 break; 318 326 nskip++; … … 334 342 if (burstLen >= 4) { 335 343 for (deque<matchStar>::iterator it2=lastIt; it2 != it1; it2++) { 344 //if ((*it2).ok) 345 // logstream << " kill " << (*it2).seq << " " << setprecision(11) << (*it2).SN << " burst" << '\n'; 336 346 (*it2).ok=false; 337 347 } … … 343 353 // we fit the data to a polynomial, with clipping... 344 354 345 float* sn = ::vector(1, matchStars.size());346 float* elv0 = ::vector(1, matchStars.size());347 float* azi = ::vector(1, matchStars.size());348 float* sig = ::vector(1, matchStars.size());349 float* ae = ::vector(1, 3);350 float* aa = ::vector(1, 3);355 //double* sn = ::vector(1, matchStars.size()); 356 double* elv0 = ::vector(1, matchStars.size()); 357 double* azi = ::vector(1, matchStars.size()); 358 double* sig = ::vector(1, matchStars.size()); 359 //double* ae = ::vector(1, 3); 360 double* aa = ::vector(1, 3); 351 361 int* ia = ivector(1, 3); 352 float** cov = matrix(1, 3, 1, 3);362 double** cov = matrix(1, 3, 1, 3); 353 363 int ndata; 354 364 355 long sn0 = matchStars.front().SN; 356 long snmin; 357 long snmax; 358 for (int i=0; i<4; i++) { 359 ndata = 0; 360 snmin = 99999999; 361 snmax = -99999999; 362 for (deque<matchStar>::iterator it1 = it ; it1!=matchStars.end(); it1++) { 363 matchStar s = (*it1); 364 if (!s.ok) continue; 365 double delv, daz; 366 if (i) { 367 delv = polval(s.SN-sn0, ae, 3)-(s.elvGSC - s.nDiode*1.41/45.); 368 daz = polval(s.SN-sn0, aa, 3)- s.azGSC; 369 if (daz>=180) daz -= 360; 370 if (daz<-180) daz += 360; 365 //long sn0 = matchStars.front().SN; 366 long sn0 = (*it).SN; 367 PolFitClip2 fitElvAz(matchStars.size(), 2); fitElvAz.setClip(0.1,0,2,3); 368 ndata = 0; 369 370 double oldAz = -1; 371 for (deque<matchStar>::iterator it1 = it ; it1!=matchStars.end(); it1++) { 372 matchStar s1 = (*it1); 373 if (!s1.ok) continue; 374 double az = s1.azGSC; 375 if (ndata > 0 && az - oldAz > 180) az -= 360; 376 if (ndata > 0 && az - oldAz < -180) az += 360; 377 fitElvAz.addData(s1.SN-sn0, s1.elvGSC - s1.nDiode*1.41/45., az); 378 oldAz = az; 379 ndata++; 380 } 381 382 double celv[3], caz[3]; 383 if (fitElvAz.doFit(celv,caz)) return; 384 //if (fitElvAz.doFit()) return; 385 386 //logstream << "*** Fit sig=" << fitElvAz.getSigmaY() << " " << fitElvAz.getSigmaZ() 387 // << " n =" << fitElvAz.getNData() << " " << fitElvAz.getNDataUsed() 388 // << " SN :" << fitElvAz.getXMin() + sn0 << " - " << fitElvAz.getXMax() + sn0 << '\n'; 389 //logstream << " sn0 = " << sn0 << "; snmin =" << fitElvAz.getXMin() + sn0 << "; snmax =" 390 // << fitElvAz.getXMax() + sn0 << '\n'; 391 //logstream << " fitelv[x_] := " << celv[2] << " x^2 + " << celv[1] << " x + " << celv[0] << '\n'; 392 //logstream << " fitaz[x_] := " << caz[2] << " x^2 + " << caz[1] << " x + " << caz[0] << '\n'; 393 394 //if (fitElvAz.getSigmaY() > 0.05 || fitElvAz.getSigmaZ() > 0.05) return; 395 if (fitElvAz.getNDataUsed() < 5 || 396 (double)fitElvAz.getNDataUsed()/fitElvAz.getNData() < .5) return; 397 398 double dcutElv = fitElvAz.getSigmaY()*3; 399 double dcutAz = fitElvAz.getSigmaZ()*3; 400 401 if (dcutElv < 0.05) dcutElv = 0.05; 402 if (dcutAz < 0.05) dcutAz = 0.05; 403 404 // don't kill borders of fit.... 405 //if (matchStars.end() - it > 6) 406 // for (deque<matchStar>::iterator it1 = it+3 ; it1!=matchStars.end()-3; it1++) { 407 for (deque<matchStar>::iterator it1 = it ; it1!=matchStars.end(); it1++) { 408 matchStar sss = (*it1); 409 if (!sss.ok) continue; 410 if (fabs(fitElvAz.valueY(sss.SN-sn0)-(sss.elvGSC - sss.nDiode*1.41/45.)) > dcutElv) { 411 (*it1).ok = false; 412 //logstream << " kill " << sss.seq << " " << setprecision(11) << sss.SN << " " 413 // << fitElvAz.valueY(sss.SN-sn0)-(sss.elvGSC - sss.nDiode*1.41/45.) << '\n'; 414 continue; 371 415 } 372 double dcutelv=0.2; 373 double dcutaz =0.4; 374 if (i>=2) { 375 dcutelv = 0.05; 376 dcutaz = 0.1; 416 double daz = fitElvAz.valueZ(sss.SN-sn0) - sss.azGSC; 417 if (daz>=180) daz -= 360; 418 if (daz<-180) daz += 360; 419 if (fabs(daz) > dcutAz) (*it1).ok = false; 420 if (!(*it1).ok) { 421 //logstream << " kill " << sss.seq << " " << setprecision(11) << sss.SN << " " 422 // << fitElvAz.valueY(sss.SN-sn0)-(sss.elvGSC - sss.nDiode*1.41/45.) << " " 423 // << daz << '\n'; 377 424 } 378 if (i>=3) { 379 dcutelv = 0.02; 380 dcutaz = 0.03; 381 } 382 if (i == 0 || ((fabs(delv)<dcutelv && fabs(daz)<dcutaz) && i<3)) { 383 ndata++; 384 sn [ndata] = s.SN-sn0; 385 elv0[ndata] = s.elvGSC - s.nDiode*1.41/45.; 386 azi [ndata] = s.azGSC; // $CHECK$ ou ajuster difference avec az galcross ? 387 if (ndata>1 && azi[ndata] - azi[ndata-1] > 180) azi[ndata] -= 360; 388 if (ndata>1 && azi[ndata] - azi[ndata-1] < -180) azi[ndata] += 360; 389 sig [ndata] = 0.01; 390 if (s.SN-sn0 > snmax) snmax = s.SN-sn0; 391 if (s.SN-sn0 < snmin) snmin = s.SN-sn0; 392 } 393 if ((fabs(delv)>=dcutelv || fabs(daz)>=dcutaz) && i==3) { 394 (*it1).ok = false; 395 } 396 } 397 if (i==3) break; 398 if (ndata<5) return; // on ne peut rien faire 399 ia[1] = ia[2] = ia[3] = 1; 400 float chi2; 401 try{ 402 lfit(sn, elv0, sig, ndata, ae, ia, 3, cov, &chi2, polfunc); 403 lfit(sn, azi, sig, ndata, aa, ia, 3, cov, &chi2, polfunc); 404 } catch(string s) { 405 return; 406 } 407 } 408 409 for (deque<matchStar>::iterator it1 = it ; it1!=matchStars.end(); it1++) { 425 } 426 427 bool gotNewStars = false; 428 for (deque<matchStar>::iterator it1 = matchStars.begin() ; it1!=it; it1++) { 410 429 if ((*it1).ok && (*it1).seq > lastCleanSave) { 430 gotNewStars = true; 411 431 lastCleanSave = (*it1).seq; 412 432 #ifdef STARDUMP … … 425 445 } 426 446 447 if (!gotNewStars) return; 448 427 449 // On a des etoiles nettoyees, on va trouver amplitude et phase du 428 450 // signal en elevation, ce qui va nous donner les deux angles d'Euler … … 430 452 431 453 // Il faut avoir une periode entiere ou pas loin, sinon on ne peut 432 // rien dire simplement.... 433 434 it = matchStars.end(); it--; 435 if ((((*it).SN) - (*matchStars.begin()).SN)*archParam.acq.perEch < 17) return; 436 437 long snmid = (((*it).SN) + (*matchStars.begin()).SN)/2; 454 // rien dire simplement.... -> we want to run on the last 18 seconds of 455 // data before the last fully cleaned star (it). 456 457 deque<matchStar>::iterator itstart; 458 459 for (itstart = matchStars.begin(); itstart != it; itstart++) { 460 if (((*it).SN - (*itstart).SN)*archParam.acq.perEch < 19) 461 break; 462 } 463 464 if (((*it).SN - (*itstart).SN)*archParam.acq.perEch < 15) return; 465 466 467 // it = matchStars.end(); it--; 468 // if (((*it).SN - matchStars.front().SN)*archParam.acq.perEch < 17) return; 469 470 // $CHECK$ utiliser plutot le SN moyen/median de tous les points effectivement utilises. 471 long snmid = ((*it).SN + (*itstart).SN)/2; 438 472 439 473 ndata=0; 440 441 for (deque<matchStar>::iterator it1 = matchStars.begin() ; it1!=matchStars.end(); it1++) { 442 if (!(*it1).ok) continue; 474 double snmean = 0; 475 476 logstream << "PendFit : " << setprecision(11) << (*itstart).SN << '-' << (*it).SN << " " 477 << setprecision(4) 478 << ((*it).SN - (*itstart).SN)*archParam.acq.perEch << " " ; 479 480 for (deque<matchStar>::iterator it1 = itstart ; it1!=it; it1++) { 481 matchStar st = *it1; 482 if (!st.ok) continue; 443 483 ndata++; 444 azi[ndata] = (*it1).azGSC * 3.1415926/180; 445 elv0[ndata] = (*it1).elvGSC - (*it1).nDiode*1.41/45.; 484 snmean += st.SN; 485 azi[ndata] = st.azGSC * 3.1415926/180; 486 elv0[ndata] = st.elvGSC - st.nDiode*1.41/45.; 446 487 sig[ndata] = 0.01; 447 488 } 448 ia[1] = ia[2] = 1; 449 ia[3] = 0; 450 aa[3] = GondolaGeom::elevSST0;// do not fit elv0 489 if (ndata) snmean /= ndata; 490 491 ia[1] = ia[2] = 1; 492 ia[3] = 0; 493 aa[3] = GondolaGeom::elevSST0;// do not fit elv0 451 494 452 495 if (ndata<5) return; 453 floatchi2;496 double chi2; 454 497 try { 455 498 lfit(azi, elv0, sig, ndata, aa, ia, 3, cov, &chi2, sinfunc); 456 } catch(string s ) {499 } catch(string st) { 457 500 return; 458 501 } 459 502 460 double c = aa[1]; 461 double s = aa[2]; 503 double cc = aa[1]; 504 double ss = aa[2]; 505 506 logstream << setprecision(11) << snmean << setprecision(4) 507 << " cs=" << cc << " " << ss << " chi2r=" << chi2/ndata 508 << " cov " << cov[1][1] << " " << cov[2][2] << '\n'; 462 509 463 510 // Get rid of bad fits. The cuts are rather ad hoc 464 511 465 512 //if (aa[3] < 39.64 || aa[3] > 39.68) return; 466 if (chi2/ndata > 4) return;513 if (chi2/ndata > 9) return; 467 514 if (cov[1][1] > 0.0001) return; 468 515 if (cov[2][2] > 0.0001) return; 469 516 470 double ampl = sqrt(c*c+s*s); 471 double phase = atan2(c,s)/(3.1415926/180); 472 473 #ifdef STARDUMP 474 pendstream << snmid << " " << ampl << " " << phase << " " << ndata << " " << chi2/ndata << 475 " " << cov[1][1] << " " << cov[2][2] << '\n'; 476 #endif 517 double ampl = sqrt(cc*cc+ss*ss); 518 double phase = atan2(cc,ss)/(3.1415926/180); 519 477 520 478 521 pendulInfo info; 479 info.SN = snmid; 480 info.azPendul = phase; 522 info.SN = snmean; 523 info.azPendul = 180-phase; 524 if (info.azPendul > 360) info.azPendul -= 360; 525 if (info.azPendul < 0) info.azPendul += 360; 481 526 info.angPendul = ampl; 482 527 pendulInfos[info.SN] = info; 483 528 529 #ifdef STARDUMP 530 pendstream << setprecision(11) << snmean << " " 531 << setprecision(4) << ampl << " " << info.azPendul << " " << ndata << " " << chi2/ndata << " " 532 << cov[1][1] << " " << cov[2][2] << '\n'; 533 #endif 484 534 /* 485 535 double snum = (matchStars.front().SN + matchStars.back().SN)/2-sn0; … … 497 547 // } 498 548 499 free_vector(sn, 1, matchStars.size());549 //free_vector(sn, 1, matchStars.size()); 500 550 free_vector(elv0, 1, matchStars.size()); 501 551 free_vector(azi, 1, matchStars.size()); 502 552 free_vector(sig, 1, matchStars.size()); 503 free_vector(ae, 1, 3);553 //free_vector(ae, 1, 3); 504 554 free_vector(aa, 1, 3); 505 555 free_ivector(ia, 1, matchStars.size()); 506 556 free_matrix(cov, 1, 3, 1, 3); 507 557 } 558 559 560 // $CHECK$ do a polynomial fit with several points... 561 int StarMatcher::getPendulInfo(double sampleNum, pendulInfo& info) { 562 563 PolFitClip2 fitPendul(30,2); 564 565 map<double, pendulInfo>::iterator i = pendulInfos.lower_bound(sampleNum); 566 if (i == pendulInfos.begin() && (*i).second.SN >= sampleNum) return -1; 567 if (i == pendulInfos.end() && (*i).second.SN <= sampleNum) return -1; 568 569 if ((*i).second.SN > sampleNum) i--; 570 571 int nn=0; 572 double aziprev=0, azicur=0, azi0=0; 573 for (map<double, pendulInfo>::iterator ii=i; ii != pendulInfos.begin(); ii--) { 574 nn++; 575 pendulInfo inf1 = (*ii).second; 576 aziprev = azicur; 577 azicur = inf1.azPendul; 578 if (nn==1) azi0 = azicur; 579 if (nn>1 && azicur - aziprev > 180) azicur -= 360; 580 if (nn>1 && azicur - aziprev < -180) azicur += 360; 581 fitPendul.addData(inf1.SN, inf1.angPendul, azicur); 582 if (nn>=5) break; 583 } 584 585 azicur = azi0; 586 if (i != pendulInfos.end()) i++; 587 for (map<double, pendulInfo>::iterator ii=i; ii != pendulInfos.end(); ii++) { 588 nn++; 589 pendulInfo inf1 = (*ii).second; 590 aziprev = azicur; 591 azicur = inf1.azPendul; 592 if (nn>1 && azicur - aziprev > 180) azicur -= 360; 593 if (nn>1 && azicur - aziprev < -180) azicur += 360; 594 fitPendul.addData(inf1.SN, inf1.angPendul, azicur); 595 if (nn>=10) break; 596 } 597 598 if (fitPendul.doFit()) return -1; 599 600 info.SN = sampleNum; 601 info.azPendul = fitPendul.valueZ(sampleNum); 602 if (info.azPendul > 360) info.azPendul -= 360; 603 if (info.azPendul < 0) info.azPendul += 360; 604 info.angPendul = fitPendul.valueY(sampleNum); 605 return 0; 606 } 607 608 #if 0 609 610 int StarMatcher::getPendulInfo(double sampleNum, pendulInfo& info) { 611 static double* sn = ::vector(1, 100); 612 static double* aziP = ::vector(1, 100); 613 static double* ampP = ::vector(1, 100); 614 static double* sig = ::vector(1, 100); 615 static double* aAzi = ::vector(1, 3); 616 static double* aAmp = ::vector(1, 3); 617 static int* ia = ::ivector(1,3); 618 static double** cov = ::matrix(1,3,1,3); 619 int ndata = 0; 620 map<double, pendulInfo>::iterator i = pendulInfos.lower_bound(sampleNum); 621 if (i == pendulInfos.begin() && (*i).second.SN >= sampleNum) return -1; 622 if (i == pendulInfos.end() && (*i).second.SN <= sampleNum) return -1; 623 624 if ((*i).second.SN > sampleNum) i--; 625 626 int nn=0; 627 for (map<double, pendulInfo>::iterator ii=i; ii != pendulInfos.begin(); ii--) { 628 nn++; 629 ndata++; 630 pendulInfo inf1 = (*ii).second; 631 sn[ndata] = inf1.SN; 632 ampP[ndata] = inf1.angPendul; 633 aziP[ndata] = inf1.azPendul; 634 int prev = ndata-1; 635 if (ndata>1 && aziP[ndata] - aziP[prev] > 180) aziP[ndata] -= 360; 636 if (ndata>1 && aziP[ndata] - aziP[prev] < -180) aziP[ndata] += 360; 637 sig[ndata] = 1; 638 if (nn>=50) break; 639 } 640 641 nn=0; 642 if (i != pendulInfos.end()) i++; 643 for (map<double, pendulInfo>::iterator ii=i; ii != pendulInfos.end(); ii++) { 644 nn++; 645 ndata++; 646 pendulInfo inf1 = (*ii).second; 647 sn[ndata] = inf1.SN; 648 ampP[ndata] = inf1.angPendul; 649 aziP[ndata] = inf1.azPendul; 650 int prev = ndata-1; 651 if (nn==1) prev=1; 652 if (ndata>1 && aziP[ndata] - aziP[prev] > 180) aziP[ndata] -= 360; 653 if (ndata>1 && aziP[ndata] - aziP[prev] < -180) aziP[ndata] += 360; 654 sig[ndata] = 1; 655 if (nn>=50) break; 656 } 657 658 if (ndata < 3) return -1; 659 660 ia[1] = ia[2] = ia[3] = 1; 661 double chi2; 662 try { 663 lfit(sn, aziP, sig, ndata, aAzi, ia, 3, cov, &chi2, polfunc); 664 lfit(sn, ampP, sig, ndata, aAmp, ia, 3, cov, &chi2, polfunc); 665 } catch(string st) { 666 return -1; 667 } 668 669 info.SN = sampleNum; 670 info.azPendul = polval(sampleNum, aAzi, 3); 671 if (info.azPendul > 360) info.azPendul -= 360; 672 if (info.azPendul < 0) info.azPendul += 360; 673 info.angPendul = polval(sampleNum, aAmp, 3); 674 return 0; 675 } 676 677 #endif 678 679 #if 0 508 680 509 681 int StarMatcher::getPendulInfo(double sampleNum, pendulInfo& info) { … … 527 699 } 528 700 701 #endif 702 529 703 530 704 double StarMatcher::getValue(long sampleNum, TOI const& toi) { … … 546 720 if ((*i).second.SN > sampleNum) i--; 547 721 722 // $CHECK$ if time spent here, can keep a GondolaGeom object for several 723 // samples... 548 724 GondolaGeom geom; 549 725 geom.setEarthPos((*i).second.lon,(*i).second.lat); 550 726 geom.setTSid((*i).second.ts); 551 727 geom.setPendulation(pendul.azPendul, pendul.angPendul); 728 729 int ns=0; 552 730 for (map<double, posInfo>::iterator it=i; it != posInfos.end(); it++) { 553 731 posInfo s = (*it).second; 554 732 double delsn = s.SN - sampleNum; 555 if (delsn * archParam.acq.perEch > 1) break; 733 ns++; 734 //if (delsn * archParam.acq.perEch > 1 && ns > 4) break; 735 if (delsn * archParam.acq.perEch > 5) break; 556 736 geom.addStar(delsn, s.azStar, s.elvStar, s.diodStar); 557 737 } 558 738 559 739 if (i != posInfos.begin()) i--; 740 ns = 0; 560 741 for (map<double, posInfo>::iterator it=i; it != posInfos.begin(); it--) { 561 742 posInfo s = (*it).second; 562 743 double delsn = s.SN - sampleNum; 563 if (-delsn * archParam.acq.perEch > 1) break; 744 ns++; 745 //if (-delsn * archParam.acq.perEch > 1 && ns > 4) break; 746 if (-delsn * archParam.acq.perEch > 5) break; 564 747 geom.addStar(delsn, s.azStar, s.elvStar, s.diodStar); 565 748 } 566 749 567 geom.solveStars();750 if (geom.solveStars()) return -99999; 568 751 569 752 if (toi.name == azimuthAxis) return geom.getAzimutAxis(); … … 608 791 if (i == pendulInfos.begin()) return true; 609 792 i--; 610 return (sampleNum 793 return (sampleNum+4000> (*i).second.SN); 611 794 } 612 795 … … 627 810 628 811 void StarMatcher::propagateLowBound(TOI const& toi, long sampleNum) { 812 // we want to keep some past information to interpolate... 813 // keep 1000 sampleNums (easier than a number of posinfos...) 814 815 sampleNum -= 4000; 816 629 817 map<double, posInfo>::iterator i = posInfos.begin(); 630 818 while (i != posInfos.end() && (*i).first < sampleNum) i++;
Note:
See TracChangeset
for help on using the changeset viewer.