| 1 | #include "mbeamcyl.h" | 
|---|
| 2 | #include "fftpserver.h" | 
|---|
| 3 | #include "vector3d.h" | 
|---|
| 4 | #include "matharr.h" | 
|---|
| 5 | #include "srandgen.h" | 
|---|
| 6 |  | 
|---|
| 7 | //================================================= | 
|---|
| 8 |  | 
|---|
| 9 | MultiBeamCyl::MultiBeamCyl(int nr, int ns, double posy) | 
|---|
| 10 | : texact(ns) , tjitt(ns) , toffset(nr) , | 
|---|
| 11 | signal(ns), sigjitt(ns) , gain(nr) | 
|---|
| 12 | { | 
|---|
| 13 | NR = nr; | 
|---|
| 14 | NS = ns; | 
|---|
| 15 | posY = posy; | 
|---|
| 16 |  | 
|---|
| 17 | SetPrintLevel(0); | 
|---|
| 18 |  | 
|---|
| 19 | SetBaseFreqDa(2., 0.25); | 
|---|
| 20 | SetNoiseSigma(0.); | 
|---|
| 21 | SetTimeJitter(0.); | 
|---|
| 22 | SetTimeOffsetSigma(0.); | 
|---|
| 23 | SetGains(1., 0., 0); | 
|---|
| 24 | adfg = false; src = NULL; | 
|---|
| 25 | SetSources(new BRSourceGen, true); | 
|---|
| 26 | } | 
|---|
| 27 |  | 
|---|
| 28 | MultiBeamCyl::~MultiBeamCyl() | 
|---|
| 29 | { | 
|---|
| 30 | if (adfg && src) delete src; | 
|---|
| 31 | } | 
|---|
| 32 |  | 
|---|
| 33 | void MultiBeamCyl::SetSources(BRSourceGen* brs, bool ad) | 
|---|
| 34 | { | 
|---|
| 35 | if (brs == NULL) return; | 
|---|
| 36 | if (adfg && src) delete src; | 
|---|
| 37 | src = brs;  adfg=ad; | 
|---|
| 38 | if (PrtLev > 1) | 
|---|
| 39 | cout << " MultiBeamCyl::SetSources(brs=" << brs <<" ,bool) NbSrc=" | 
|---|
| 40 | << src->NbSources() << endl; | 
|---|
| 41 |  | 
|---|
| 42 | } | 
|---|
| 43 |  | 
|---|
| 44 | void MultiBeamCyl::SetGains(double g, double sigg, int nzerogain) | 
|---|
| 45 | { | 
|---|
| 46 | if (sigg < 1.e-6)  gain = g; | 
|---|
| 47 | else gain = RandomSequence(RandomSequence::Gaussian, g, sigg); | 
|---|
| 48 | int k; | 
|---|
| 49 | for (k=0; k<NR; k++) if (gain(k) < 0) gain(k) = 0.; | 
|---|
| 50 | for(k=0; k<nzerogain; k++) { | 
|---|
| 51 | int zg = random()%NR; | 
|---|
| 52 | if ((zg >=0) && (zg < NR))  gain(zg) = 0.; | 
|---|
| 53 | } | 
|---|
| 54 | if (PrtLev > 1) | 
|---|
| 55 | cout << " MultiBeamCyl::SetGains(g=" << g <<" ,sigg=" << sigg | 
|---|
| 56 | << " ,nzg=" << nzerogain << " )" << endl; | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 | void MultiBeamCyl::ComputeTimeVectors() | 
|---|
| 60 | { | 
|---|
| 61 | texact = RegularSequence(0., 1.); | 
|---|
| 62 | toffset = RandomSequence(RandomSequence::Gaussian, 0., toffsig); | 
|---|
| 63 | NewTJitVector(); | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | void MultiBeamCyl::NewTJitVector(int num) | 
|---|
| 67 | { | 
|---|
| 68 | if (timejitter > 1.e-19) { | 
|---|
| 69 | tjitt = RandomSequence(RandomSequence::Gaussian, 0., timejitter); | 
|---|
| 70 | tjitt += texact; | 
|---|
| 71 | } | 
|---|
| 72 | else tjitt = texact; | 
|---|
| 73 | if (num >= 0) tjitt += toffset(num); | 
|---|
| 74 |  | 
|---|
| 75 | } | 
|---|
| 76 |  | 
|---|
| 77 | int MultiBeamCyl::ComputeSignalVector(int num, bool fgsignojit) | 
|---|
| 78 | { | 
|---|
| 79 | int nok = 0; | 
|---|
| 80 | signal = 0.; | 
|---|
| 81 | sigjitt = 0.; | 
|---|
| 82 | for(int is=0; is<src->freq.Size(); is++) { | 
|---|
| 83 | double fr = src->freq(is); | 
|---|
| 84 | if ((fr < 0.) || (fr > 0.5)) continue; | 
|---|
| 85 | nok++; | 
|---|
| 86 | // Pour le dephasage entre recepteurs, on doit utiliser la frequence vraie, | 
|---|
| 87 | // pas celle apres shift (freq-reduite) | 
|---|
| 88 | // lambda = c T = c/freq avec c = 1, dephasage = 2*pi*num*Da*sin(ang)/lambda | 
|---|
| 89 | double dephasage = num*Da*sin(src->angX(is)) + posY*sin(src->angY(is)) ; | 
|---|
| 90 | dephasage *= (2*M_PI*(fr+freq0)); | 
|---|
| 91 | // On ajoute alors la phase propre de chaque source | 
|---|
| 92 | dephasage += src->phase(is); | 
|---|
| 93 | double amprep = src->amp(is)*AngResponse(src->angX(is), src->angY(is)); | 
|---|
| 94 | for(int k=0; k<NS; k++) { | 
|---|
| 95 | sigjitt(k) += amprep*sin(2.*M_PI*fr*tjitt(k)+dephasage); | 
|---|
| 96 | if (fgsignojit) | 
|---|
| 97 | signal(k) += amprep*sin(2.*M_PI*fr*texact(k)+dephasage); | 
|---|
| 98 | } | 
|---|
| 99 | } | 
|---|
| 100 | // Application du gain du detecteur | 
|---|
| 101 | r_4 ga = gain(num); | 
|---|
| 102 | if (fabs(ga-1.) > 1.e-9) { | 
|---|
| 103 | signal *= ga; | 
|---|
| 104 | sigjitt *= ga; | 
|---|
| 105 | } | 
|---|
| 106 | // Ajout de bruit (ampli ...) | 
|---|
| 107 | if (signoise > 1.e-18) { | 
|---|
| 108 | for(int k=0; k<NS; k++) { | 
|---|
| 109 | sigjitt(k) += GauRnd(0., signoise); | 
|---|
| 110 | if (fgsignojit) signal(k) += GauRnd(0., signoise); | 
|---|
| 111 | } | 
|---|
| 112 | } | 
|---|
| 113 |  | 
|---|
| 114 | FFTPackServer ffts; | 
|---|
| 115 |  | 
|---|
| 116 | ffts.FFTForward(sigjitt, f_sigjit); | 
|---|
| 117 | if (fgsignojit) ffts.FFTForward(signal, f_sig); | 
|---|
| 118 |  | 
|---|
| 119 | return nok; | 
|---|
| 120 | } | 
|---|
| 121 |  | 
|---|
| 122 |  | 
|---|
| 123 | /*  --- a supprimer ? | 
|---|
| 124 | inline float myZmodule(complex<r_4>& z) | 
|---|
| 125 | { | 
|---|
| 126 | return (float)sqrt((double)(z.real()*z.real()+z.imag()*z.imag())); | 
|---|
| 127 | } | 
|---|
| 128 | ----- */ | 
|---|
| 129 |  | 
|---|
| 130 | void MultiBeamCyl::ReconstructSourcePlane(bool fgzerocentre) | 
|---|
| 131 | { | 
|---|
| 132 | ComputeTimeVectors(); | 
|---|
| 133 | int noksrc = ComputeSignalVector(0, false); | 
|---|
| 134 | vector<TVector< complex<r_4> > >  vvfc; | 
|---|
| 135 | cout << "MultiBeamCyl::ReconstructSourcePlane() NR=" << NR | 
|---|
| 136 | << " PosY=" << posY << " NFreq=" << f_sigjit.Size()-1 << " NOkSrc=" << noksrc << endl; | 
|---|
| 137 | if (PrtLev > 0) { | 
|---|
| 138 | cout << " ... posY= " << posY << " MeanGain=" << Mean(gain) << " MeanAmpSrc=" | 
|---|
| 139 | << Mean(src->amp) << endl; | 
|---|
| 140 | cout << " ...SigNoise=" << signoise << " TimeJitter=" << timejitter | 
|---|
| 141 | << " TOffSig=" << toffsig << " Da=" << Da << " Freq0=" << freq0 << endl; | 
|---|
| 142 | } | 
|---|
| 143 | // On ne s'occupe pas de la composante continue | 
|---|
| 144 | for(int jf=1; jf<f_sigjit.Size(); jf++) { | 
|---|
| 145 | TVector<complex<r_4> > cf(NR); | 
|---|
| 146 | vvfc.push_back(cf); | 
|---|
| 147 | } | 
|---|
| 148 | cout << "ReconstructSourcePlane()/Info: computing s(t) for each receptor ..." << endl; | 
|---|
| 149 | int pmod = NR/10; | 
|---|
| 150 | for(int ir=0; ir<NR; ir++) { | 
|---|
| 151 | if (timejitter > 1.e-19) NewTJitVector(ir); | 
|---|
| 152 | noksrc = ComputeSignalVector(ir, false); | 
|---|
| 153 | for(int jf=1; jf<f_sigjit.Size(); jf++) | 
|---|
| 154 | vvfc[jf-1](ir) = f_sigjit(jf); | 
|---|
| 155 | if ( (PrtLev>0) && (ir%pmod == 0) ) | 
|---|
| 156 | cout << " OK s(t) for ir=" << ir << " / NR=" << NR << " NOkSrc=" << noksrc << endl; | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 | cout << "ReconstructSourcePlane()/Info: computing s(ang) for each freq by FFT" << endl; | 
|---|
| 160 | cmplx_srcplane.SetSize(f_sigjit.Size()-1, NR); | 
|---|
| 161 | // rec_srcplane.SetSize(f_sigjit.Size()-1, NR); | 
|---|
| 162 | FFTPackServer ffts; | 
|---|
| 163 | TVector<complex<r_4> > fcf; | 
|---|
| 164 | pmod = vvfc.size()/10; | 
|---|
| 165 | for(int jf=0; jf<vvfc.size(); jf++) { | 
|---|
| 166 | ffts.FFTForward(vvfc[jf], fcf); | 
|---|
| 167 | if (fcf.Size() != NR) { | 
|---|
| 168 | cout << "ReconstructSourcePlane()/BUG jf=" << jf << " fcf.Size() != NR " | 
|---|
| 169 | << fcf.Size() << " != " << NR << endl; | 
|---|
| 170 | continue; | 
|---|
| 171 | } | 
|---|
| 172 | if (fgzerocentre) {  // On veut avoir la direction angle=0 au milieu de la matrice | 
|---|
| 173 | int milieu = (NR-1)/2; | 
|---|
| 174 | if (NR%2 == 0) milieu++; | 
|---|
| 175 | int decal = NR - milieu - 1; | 
|---|
| 176 | for (int ir=0; ir<=milieu; ir++) | 
|---|
| 177 | cmplx_srcplane(jf, ir+decal) = fcf(ir); | 
|---|
| 178 | //        rec_srcplane(jf, ir+decal) = myZmodule(fcf(ir)); | 
|---|
| 179 |  | 
|---|
| 180 | for (int ir=milieu+1; ir<NR; ir++) | 
|---|
| 181 | cmplx_srcplane(jf, decal-(NR-ir)) = fcf(ir); | 
|---|
| 182 | //        rec_srcplane(jf, decal-(NR-ir)) = myZmodule(fcf(ir)); | 
|---|
| 183 |  | 
|---|
| 184 | } | 
|---|
| 185 | else for (int ir=0; ir<NR; ir++) | 
|---|
| 186 | cmplx_srcplane(jf, ir) = fcf(ir); | 
|---|
| 187 | //      rec_srcplane(jf, ir) = myZmodule(fcf(ir)); | 
|---|
| 188 |  | 
|---|
| 189 | if ( (PrtLev > 0) && (jf%pmod == 0)) | 
|---|
| 190 | cout << " OK rec_srcplane(jf, ir) for jf=" << jf << endl; | 
|---|
| 191 | } | 
|---|
| 192 |  | 
|---|
| 193 |  | 
|---|
| 194 | cout << "ReconstructSourcePlane()/Info: rec_srcplane computed OK" << endl; | 
|---|
| 195 | } | 
|---|
| 196 |  | 
|---|
| 197 |  | 
|---|