You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

175 lines
3.3 KiB

  1. /*
  2. * Atpdec
  3. * Copyright (c) 2003 by Thierry Leconte (F4DWV)
  4. *
  5. * $Id$
  6. *
  7. * This library is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Library General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. *
  21. */
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <sndfile.h>
  25. typedef struct {
  26. double slope;
  27. double offset;
  28. } rgparam;
  29. static void rgcomp(double *x, rgparam *rgpr)
  30. {
  31. /*const double y[9] = { 0.106,0.215,0.324,0.434,0.542,0.652,0.78,0.87 ,0.0}; */
  32. const double y[9] = { 0.11872,0.2408,0.36288,0.48608,0.60704,0.73024,0.8736,0.9744 , 0.0 };
  33. const double yavg=0.48819556;
  34. double xavg;
  35. double sxx,sxy;
  36. int i;
  37. for(i=0,xavg=0.0;i<9;i++)
  38. xavg+=x[i];
  39. xavg/=9;
  40. for(i=0,sxx=0.0;i<9;i++) {
  41. float t=x[i]-xavg;
  42. sxx+=t*t;
  43. }
  44. for(i=0,sxy=0.0;i<9;i++) {
  45. sxy+=(x[i]-xavg)*(y[i]-yavg);
  46. }
  47. rgpr->slope=sxy/sxx;
  48. rgpr->offset=yavg-rgpr->slope*xavg;
  49. }
  50. static double rgcal(float x,rgparam *rgpr)
  51. {
  52. return(rgpr->slope*x+rgpr->offset);
  53. }
  54. int Calibrate(float **prow,int nrow,int offset)
  55. {
  56. double tele[3000];
  57. double frm[9];
  58. rgparam regr[30];
  59. int n;
  60. int k,mk;
  61. int shift;
  62. int mshift,channel;
  63. float max;
  64. printf("Calibration ");
  65. fflush(stdout);
  66. /* build telemetry values lines */
  67. for(n=0;n<nrow;n++) {
  68. int i;
  69. tele[n]=0.0;
  70. for(i=3;i<43;i++)
  71. tele[n]+=prow[n][i+offset+909];
  72. tele[n]/=40;
  73. }
  74. if(nrow<128) {
  75. fprintf(stderr," impossible, not enought row\n");
  76. return (0);
  77. }
  78. /* find telemetry start */
  79. max=-1000.0;mshift=0;
  80. for(n=60;n<nrow-3;n++) {
  81. float df;
  82. df=(tele[n-4]+tele[n-3]+tele[n-2]+tele[n-1])-(tele[n]+tele[n+1]+tele[n+2]+tele[n+3]);
  83. if(df> max){ mshift=n; max=df; }
  84. }
  85. mshift-=64;
  86. shift=mshift%128;
  87. if(nrow<shift+8*9) {
  88. fprintf(stderr," impossible, not enought row\n");
  89. return (0);
  90. }
  91. /* compute regression params */
  92. for(n=shift,k=0;n<nrow-8*9;n+=128,k++) {
  93. int j;
  94. for(j=0;j<9;j++) {
  95. int i;
  96. frm[j]=0.0;
  97. for(i=1;i<7;i++)
  98. frm[j]+=tele[n+j*8+i];
  99. frm[j]/=6;
  100. }
  101. rgcomp(frm,&(regr[k]));
  102. if(n==mshift) {
  103. /* channel ID */
  104. int i;
  105. float cv,df;
  106. for(i=1,cv=0;i<7;i++)
  107. cv+=tele[n+15*8+i];
  108. cv/=6;
  109. for(i=0,max=10000.0,channel=-1;i<6;i++) {
  110. df=cv-frm[i]; df=df*df;
  111. if (df<max) { channel=i; max=df; }
  112. }
  113. }
  114. }
  115. mk=k;
  116. for(n=0;n<nrow;n++) {
  117. float *pixelv;
  118. int i,c;
  119. pixelv=prow[n];
  120. for(i=0;i<954;i++) {
  121. float pv;
  122. int k,kof;
  123. pv=pixelv[i+offset];
  124. k=(n-shift)/128;
  125. kof=(n-shift)%128;
  126. if(kof<64) {
  127. if(k<1)
  128. pv=rgcal(pv,&(regr[k]));
  129. else
  130. pv=rgcal(pv,&(regr[k]))*(64+kof)/128.0+
  131. rgcal(pv,&(regr[k-1]))*(64-kof)/128.0;
  132. } else {
  133. if((k+1)>=mk)
  134. pv=rgcal(pv,&(regr[k]));
  135. else
  136. pv=rgcal(pv,&(regr[k]))*(192-kof)/128.0+
  137. rgcal(pv,&(regr[k+1]))*(kof-64)/128.0;
  138. }
  139. if(pv>1.0) pv=1.0;
  140. if(pv<0.0) pv=0.0;
  141. pixelv[i+offset]=pv;
  142. }
  143. }
  144. printf("Done\n");
  145. return (channel);
  146. }