| 1 | #include "multicyl.h" | 
|---|
| 2 | #include "fftpserver.h" | 
|---|
| 3 | #include "vector3d.h" | 
|---|
| 4 | #include "matharr.h" | 
|---|
| 5 | #include "srandgen.h" | 
|---|
| 6 | #include "ctimer.h" | 
|---|
| 7 | #include "resusage.h" | 
|---|
| 8 | #include "datacards.h" | 
|---|
| 9 |  | 
|---|
| 10 | static double cLight=0.3;       // in 1E9 m/s | 
|---|
| 11 | static double tClock = 2.; // should come from param file !!!! | 
|---|
| 12 | //static double cLight=1; | 
|---|
| 13 | //static double tClock = 1.; | 
|---|
| 14 |  | 
|---|
| 15 |  | 
|---|
| 16 | //================================================= | 
|---|
| 17 |  | 
|---|
| 18 | MultiCylinders::MultiCylinders(int nr, int ns) | 
|---|
| 19 | { | 
|---|
| 20 | NR_ = nr; | 
|---|
| 21 | NS_ = ns; | 
|---|
| 22 |  | 
|---|
| 23 | SetPrintLevel(0); | 
|---|
| 24 |  | 
|---|
| 25 | SetBaseFreqDa(2., 0.25); | 
|---|
| 26 | SetNoiseSigma(0.); | 
|---|
| 27 | SetTimeJitter(0.); | 
|---|
| 28 | SetTimeOffsetSigma(0.); | 
|---|
| 29 | SetGains(1., 0., 0); | 
|---|
| 30 | adfg_ = false; src_ = NULL; | 
|---|
| 31 | SetSources(new BRSourceGen, true); | 
|---|
| 32 | } | 
|---|
| 33 |  | 
|---|
| 34 | //----------------------------------------------------------------------------- | 
|---|
| 35 | MultiCylinders::MultiCylinders(char* fileName) | 
|---|
| 36 | { | 
|---|
| 37 | adfg_ = false; src_ = NULL; | 
|---|
| 38 | SetSources(new BRSourceGen, true); | 
|---|
| 39 |  | 
|---|
| 40 | //      read telescope parameters and fill variable members | 
|---|
| 41 | DataCards dc; | 
|---|
| 42 | dc.ReadFile(fileName); | 
|---|
| 43 | //      in old versions frequences were in units of 1/T = 0.5 GHz | 
|---|
| 44 | //      and distances in units of cT =3E8 * 2E-9=0.60 m | 
|---|
| 45 | //  double fUnit=0.5;   // 0.5 GHz <=> T = 2 ns | 
|---|
| 46 | //  double dUnit=0.6;   // distance unit in m. | 
|---|
| 47 | //      now f and d in real units | 
|---|
| 48 | double fUnit=1.;      // 0.5 GHz <=> T = 2 ns | 
|---|
| 49 | double dUnit=1.;      // distance unit in m. | 
|---|
| 50 |  | 
|---|
| 51 | NR_=dc.IParam("nAntenna"); | 
|---|
| 52 | NS_=dc.IParam("nSample"); | 
|---|
| 53 | PrtLev_=dc.IParam("printLevel"); | 
|---|
| 54 | Da_=dc.DParam("dAntenna")/dUnit; | 
|---|
| 55 | freq0_=dc.DParam("freq0")/fUnit; | 
|---|
| 56 | timejitter_=dc.DParam("sigmaTimeJitt"); | 
|---|
| 57 | toffsig_=dc.DParam("sigmaClockJitt"); | 
|---|
| 58 | signoise_=dc.DParam("noiseSigma"); | 
|---|
| 59 | gain_=dc.DParam("meanGain"); | 
|---|
| 60 | siggain_=dc.DParam("sigmaGain"); | 
|---|
| 61 | ngainzero_=dc.IParam("nDeadAntenna"); | 
|---|
| 62 |  | 
|---|
| 63 | //  tClock=dc.DParam("tClock"); | 
|---|
| 64 | int nCyl=dc.IParam("nCyl"); | 
|---|
| 65 | for (int i=0; i<nCyl; i++){ | 
|---|
| 66 | double xCyl=dc.DParam("xCyl",i)/dUnit; | 
|---|
| 67 | double yCyl=dc.DParam("yCyl",i)/dUnit; | 
|---|
| 68 | AddCylinder(xCyl,yCyl); | 
|---|
| 69 | } | 
|---|
| 70 | //  maxangX=dc.DParam("angMaxX"); | 
|---|
| 71 | //  double cylDiam=dc.DParam("cylinderDiam")/dUnit; | 
|---|
| 72 | //// thetaMax = lambda_M/d = c/freq_min/d;  freq_min = freq0 + 1/2T | 
|---|
| 73 | //  maxangY=cLight/(freq0+1./2./tClock)/cylDiam; | 
|---|
| 74 | //  halfNY=dc.IParam("halfNY"); | 
|---|
| 75 | //  NX=dc.IParam("NX"); | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|
| 78 | //----------------------------------------------------------------------------- | 
|---|
| 79 | MultiCylinders::~MultiCylinders() | 
|---|
| 80 | { | 
|---|
| 81 | if (adfg_ && src_) delete src_; | 
|---|
| 82 | for(int k=0; k<(int)mCyl_.size(); k++) delete mCyl_[k]; | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | //----------------------------------------------------------------------------- | 
|---|
| 86 | MultiBeamCyl& MultiCylinders::GetCylinder(int k) | 
|---|
| 87 | { | 
|---|
| 88 | if ((k < 0) || (k >= (int)mCyl_.size())) { | 
|---|
| 89 | cout <<"******************************************* k="<<k<<endl; | 
|---|
| 90 | throw RangeCheckError("MultiCylinders::GetCylinder(k) k<0 OR k>=NCyl"); | 
|---|
| 91 | } | 
|---|
| 92 | return (*mCyl_[k]); | 
|---|
| 93 | } | 
|---|
| 94 |  | 
|---|
| 95 | //----------------------------------------------------------------------------- | 
|---|
| 96 | void MultiCylinders::SetSources(BRSourceGen* brs, bool ad) | 
|---|
| 97 | { | 
|---|
| 98 | if (brs == NULL) return; | 
|---|
| 99 | if (adfg_ && src_) delete src_; | 
|---|
| 100 | src_ = brs;  adfg_=ad; | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 |  | 
|---|
| 104 | //----------------------------------------------------------------------------- | 
|---|
| 105 | void MultiCylinders::ConfigureCylinders() | 
|---|
| 106 | { | 
|---|
| 107 | cout << " MultiCylinders::ConfigureCylinders() with NCyl= " << mCyl_.size() << endl; | 
|---|
| 108 | for(int k=0; k<(int)mCyl_.size(); k++) { | 
|---|
| 109 | mCyl_[k]->SetPrintLevel(PrtLev_); | 
|---|
| 110 | mCyl_[k]->SetBaseFreqDa(freq0_, Da_); | 
|---|
| 111 | mCyl_[k]->SetNoiseSigma(signoise_); | 
|---|
| 112 | mCyl_[k]->SetTimeJitter(timejitter_); | 
|---|
| 113 | mCyl_[k]->SetTimeOffsetSigma(toffsig_); | 
|---|
| 114 | mCyl_[k]->SetGains(gain_, siggain_, ngainzero_); | 
|---|
| 115 | mCyl_[k]->SetSources(src_, false); | 
|---|
| 116 | } | 
|---|
| 117 | } | 
|---|
| 118 |  | 
|---|
| 119 |  | 
|---|
| 120 | //----------------------------------------------------------------------------- | 
|---|
| 121 | void MultiCylinders::ReconstructCylinderPlaneS(bool fgzerocentre) | 
|---|
| 122 | { | 
|---|
| 123 | Timer tm("RecCylPlaneS"); | 
|---|
| 124 | ResourceUsage resu; | 
|---|
| 125 | cout << " MultiCylinders::ReconstructCylinderPlaneS()/Info - NCyl= " << mCyl_.size() | 
|---|
| 126 | << " MemSize=" << resu.getMemorySize() << " kb" << endl; | 
|---|
| 127 | ConfigureCylinders(); | 
|---|
| 128 |  | 
|---|
| 129 | char buff[128]; | 
|---|
| 130 | for(int k=0; k<(int)mCyl_.size(); k++) { | 
|---|
| 131 | cout << "---- Cyl[" << k << "] Calling MultiBeamCyl.ReconstructSourcePlane() ..." << endl; | 
|---|
| 132 | mCyl_[k]->ReconstructSourcePlane(fgzerocentre); | 
|---|
| 133 | sprintf(buff,"Cyl[%d].RecSrcPlane()",k); | 
|---|
| 134 | tm.Split(buff); | 
|---|
| 135 | } | 
|---|
| 136 | resu.Update(); | 
|---|
| 137 | cout << " MultiCylinders::ReconstructCylinderPlaneS()/Info - Done " | 
|---|
| 138 | << " MemSize=" << resu.getMemorySize() << " kb" << endl; | 
|---|
| 139 | } | 
|---|
| 140 |  | 
|---|
| 141 | //----------------------------------------------------------------------------- | 
|---|
| 142 | void MultiCylinders::ReconstructSourceBox(int halfny, double stepangy, | 
|---|
| 143 | int nx, double stepangx) | 
|---|
| 144 | { | 
|---|
| 145 | nx=256; | 
|---|
| 146 | ReconstructCylinderPlaneS(true); | 
|---|
| 147 | TMatrix< complex<r_4> > & mtx = GetCylinder(0).getRecSrcPlane(); | 
|---|
| 148 | // boite 3D X:angX, Y:angY , Z: freq | 
|---|
| 149 | //      if all cylinders at same x position NX is set to zero | 
|---|
| 150 | //      => x-size = mtx.NCols() = numbers of receptors per cylinders | 
|---|
| 151 | //              move that to readParam() ? | 
|---|
| 152 | sa_size_t sz[5] = {0,0,0,0,0}; | 
|---|
| 153 | sz[0] = nx; | 
|---|
| 154 | sz[1] = halfny*2+1; | 
|---|
| 155 | sz[2] = mtx.NRows(); | 
|---|
| 156 | TArray< complex<r_4> > & box = getRecSrcBox(); | 
|---|
| 157 | box.ReSize(3, sz);            //  values initialized to zero ? | 
|---|
| 158 | cout << " MultiCylinders::ReconstructSourceBox(" << halfny << "," << stepangy | 
|---|
| 159 | << "=" << Angle(stepangy).ToArcMin() << " ) srcbox:" << endl; | 
|---|
| 160 | Timer tm("RecSrcBox"); | 
|---|
| 161 | box.Show(cout); | 
|---|
| 162 |  | 
|---|
| 163 |  | 
|---|
| 164 | //  int pmod = mtx.NRows()/10; | 
|---|
| 165 |  | 
|---|
| 166 | double fstep = 1.0/(double)NS_/tClock;  // pas en frequence, | 
|---|
| 167 | // attention, on a vire la composante continu | 
|---|
| 168 | //  bool first=true; | 
|---|
| 169 | for(int kf=0; kf<mtx.NRows(); kf++) { // Loop over frequencies | 
|---|
| 170 | double frq = (double)(kf+1.)*fstep + freq0_;  // + 1 car f=0 a ete vire | 
|---|
| 171 | //            then up to frq =   (mtx.NRows() +1 ) * fstep            !!? | 
|---|
| 172 | //    cout<<"************"<<mCyl.size() | 
|---|
| 173 | for(int lc=0; lc<(int)mCyl_.size(); lc++) {  // Loop over cylinders | 
|---|
| 174 | MultiBeamCyl& cyl = GetCylinder(lc); | 
|---|
| 175 |  | 
|---|
| 176 | TMatrix< complex<r_4> > & recp = cyl.getRecSrcPlane(); | 
|---|
| 177 |  | 
|---|
| 178 | double facl_y = - 2*M_PI*frq*cyl.getCylinderYPos()/cLight;  // attention signe - | 
|---|
| 179 | double facl_x = - 2*M_PI*cyl.getCylinderXPos()/cyl.Da_; | 
|---|
| 180 | complex< r_4 > phasefactor; | 
|---|
| 181 | int jyy = 0; | 
|---|
| 182 |  | 
|---|
| 183 | for(int jy=-halfny; jy<=halfny; jy++) {  // Loop over Y angular steps | 
|---|
| 184 | for(int ix=0; ix<nx; ix++) {  // Loop over AngX directions | 
|---|
| 185 | double dphi = facl_y * sin( (double)jy*stepangy ) | 
|---|
| 186 | + facl_x*(double(ix)/double(nx)-1./2.); | 
|---|
| 187 | phasefactor = complex< r_4 > ((r_4) cos(dphi) , (r_4) sin(dphi)); | 
|---|
| 188 | // sur recp : index ligne -> frequence  ,    index colonne -> angX , | 
|---|
| 189 | int ixx=(int)(ix*(double)cyl.NR_/double(nx)); | 
|---|
| 190 | box(ix, jyy, kf) += recp(kf, ixx)*phasefactor; | 
|---|
| 191 | }  // | 
|---|
| 192 | jyy++; | 
|---|
| 193 | } // End of Loop over Y angles | 
|---|
| 194 | } // End of loop over cylinders | 
|---|
| 195 |  | 
|---|
| 196 | tm.Nop(); | 
|---|
| 197 | //    if ( (PrtLev_>0) && (kf%pmod == 0) ) | 
|---|
| 198 | if ( (PrtLev_>0) && (kf%(mtx.NRows()/10) == 0) ) | 
|---|
| 199 | cout << " OK box(angx,angy, freq=kf) done for kf=" << kf | 
|---|
| 200 | << " / Max_kf=" << mtx.NRows() << endl; | 
|---|
| 201 | } // End of loop over over frequencies | 
|---|
| 202 |  | 
|---|
| 203 | cout << " MultiCylinders::ReconstructSourceBox() done " << endl; | 
|---|
| 204 | } | 
|---|
| 205 |  | 
|---|
| 206 | //----------------------------------------------------------------------------- | 
|---|
| 207 | inline float myZmodule(complex<r_4>& z) | 
|---|
| 208 | { | 
|---|
| 209 | return (float)sqrt((double)(z.real()*z.real()+z.imag()*z.imag())); | 
|---|
| 210 | } | 
|---|
| 211 |  | 
|---|
| 212 | //----------------------------------------------------------------------------- | 
|---|
| 213 | TMatrix< r_4 >  MultiCylinders::getRecXYSlice(int kfmin, int kfmax) | 
|---|
| 214 | { | 
|---|
| 215 | TArray< complex<r_4> > & box = getRecSrcBox(); | 
|---|
| 216 | if ((kfmin < 0) || (kfmin >=  box.SizeZ()) || (kfmax < kfmin) || (kfmax >=  box.SizeZ()) ) | 
|---|
| 217 | throw RangeCheckError("MultiCylinders::getRecXYSlice(kfmin, kfmax)"); | 
|---|
| 218 | TMatrix< r_4> rmtx(box.SizeY(), box.SizeX()); | 
|---|
| 219 | for(int kf=kfmin; kf<=kfmax; kf++) { | 
|---|
| 220 | for(int jy=0; jy<box.SizeY(); jy++) | 
|---|
| 221 | for(int ix=0; ix<box.SizeX(); ix++) | 
|---|
| 222 | rmtx(jy, ix) += myZmodule(box(ix, jy, kf)); | 
|---|
| 223 | } | 
|---|
| 224 | return(rmtx); | 
|---|
| 225 | } | 
|---|
| 226 | //----------------------------------------------------------------------------- | 
|---|
| 227 | TMatrix< r_4 >  MultiCylinders::getRecYXSlice(int kfmin, int kfmax) | 
|---|
| 228 | { | 
|---|
| 229 | TArray< complex<r_4> > & box = getRecSrcBox(); | 
|---|
| 230 | if ((kfmin < 0) || (kfmin >=  box.SizeZ()) || (kfmax < kfmin) || (kfmax >=  box.SizeZ()) ) | 
|---|
| 231 | throw RangeCheckError("MultiCylinders::getRecXYSlice(kfmin, kfmax)"); | 
|---|
| 232 | TMatrix< r_4> rmtx(box.SizeX(), box.SizeY()); | 
|---|
| 233 | for(int kf=kfmin; kf<=kfmax; kf++) { | 
|---|
| 234 | for(int jy=0; jy<box.SizeY(); jy++) | 
|---|
| 235 | for(int ix=0; ix<box.SizeX(); ix++) | 
|---|
| 236 | rmtx(ix, jy) += myZmodule(box(ix, jy, kf)); | 
|---|
| 237 | } | 
|---|
| 238 | return(rmtx); | 
|---|
| 239 | } | 
|---|