source: Sophya/trunk/Cosmo/SimLSS/cmvhshsns.cc@ 3632

Last change on this file since 3632 was 3632, checked in by cmv, 16 years ago

add lobe N-S pour dipole avec regroupement analogique, cmv 25/05/2009

File size: 11.1 KB
Line 
1// lobes pour HSHS N-S
2// > cmvhshsns -n -d 0.105 -g 4,0.105,0. -i 2,0.41,0. -t 50,180,0 -f 1420 1410 1430
3#include "sopnamsp.h"
4#include "machdefs.h"
5#include <iostream>
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9#include <math.h>
10#include <unistd.h>
11
12#include "ntuple.h"
13#include "constcosmo.h"
14#include "geneutils.h"
15
16//----------------------------------------------------------------
17void usage(void);
18void usage(void)
19{
20cout<<"cmvhshsns [...] val1 val2 ..."<<endl
21 <<" -f : val1... sont des frequences en MHz"<<endl
22 <<" (defaut: longueurs d'onde en m"<<endl
23 <<" -n : hauteur des lobes normalises a 1"<<endl
24 <<" -d L : longueur totale dipole"<<endl
25 <<" L==0. alors approximation du dipole"<<endl
26 <<" -g N_g,D_g,Theta_g : regroupement de dipoles"<<endl
27 <<" N_g<=1 pas de regroupement"<<endl
28 <<" -i N_i,D_i,Theta_i : interferences entre regroupements de dipoles"<<endl
29 <<" N_i<=1 pas d'interference"<<endl
30 <<" -t Nang,Tmax,Tcent : nombre de pts entre 2 zeros consecutifs (def=25)"<<endl
31 <<" angle maxi (deg, def=180), angle central (deg, def=0)"<<endl
32 <<" -p : interprete Theta_{g,i} en picosecondes"<<endl
33 <<"..distances L,D: >0 en m , <0 en unites de longeur d'onde"<<endl
34 <<"..angles Theta: en deg"<<endl
35 <<" en secondes si option \"-p\""<<endl
36 <<endl;
37}
38
39double thetafromdt(double &theta,double dt,double lambda,double dconsec);
40double dtfromtheta(double theta,double lambda,double dconsec);
41
42//----------------------------------------------------------------
43int main(int narg,char *arg[])
44{
45 const double torad = M_PI/180.;
46
47 // --- longueur d'onde em m
48 vector<double> Lambda, Nu;
49 bool argfreq = false;
50 bool thetaps = false;
51 bool normone = false;
52
53 // --- dipole de longeur totale L (2 brins de L/2)
54 double L_d = -0.5; // >0 en m, <0 en unite de lambda
55
56 // --- groupes: regroupement des dipoles
57 // N est le nombre de dipoles regroupes
58 // D est la distance entre deux dipoles consecutifs
59 // Theta est le dephasage entre 2 dipoles consecutifs (dephasage electronique)
60 // i.e. c'est l'angle d'arrivee des rayons qui sont combines en phase
61 int N_g = 1; // nombre de dipoles regroupes
62 double D_g = -0.5; // >0 en m, <0 en unite de lambda
63 double Theta_g = 0.; // en deg
64
65 // --- interference des groupes
66 // N est le nombre de groupes sur la ligne focale
67 // D est la distance entre deux groupes consecutifs
68 // Theta est le dephasage entre 2 groupes consecutifs (dephasage electronique)
69 int N_i = 100; // nombre de groupes
70 double D_i = (N_g>1) ? N_g*D_g: -0.5; // >0 en m, <0 en en unite de lambda
71 double Theta_i = 0.; // en deg
72
73 // --- Tmax = angle maximum de scan a partir du zenith (degres)
74 double Tcent = 0., Tmax = 180.;
75
76 // --- Nang nombre de points entre deux zeros de la figure d'interfrence
77 int Nang = -1;
78
79 // Decodage des arguments
80 char c;
81 while((c = getopt(narg,arg,"hpnfd:g:i:t:")) != -1) {
82 switch (c) {
83 case 'f' :
84 argfreq = true;
85 break;
86 case 'p' :
87 thetaps = true;
88 break;
89 case 'n' :
90 normone = true;
91 break;
92 case 'd' :
93 sscanf(optarg,"%lf",&L_d);
94 break;
95 case 'i' :
96 sscanf(optarg,"%d,%lf,%lf",&N_i,&D_i,&Theta_i);
97 break;
98 case 'g' :
99 sscanf(optarg,"%d,%lf,%lf",&N_g,&D_g,&Theta_g);
100 break;
101 case 't' :
102 sscanf(optarg,"%d,%lf,%lf",&Nang,&Tmax,&Tcent);
103 break;
104 case 'h' :
105 default :
106 usage();
107 return -1;
108 break;
109 }
110 }
111
112 if(optind>=narg) {usage(); return -2;}
113 for(int i=optind;i<narg;i++) {
114 double v = atof(arg[i]);
115 if(v<=0.) continue;
116 if(argfreq) {
117 v *= 1.e6;
118 Nu.push_back(v);
119 Lambda.push_back(SpeedOfLight_Cst*1.e3/v);
120 } else {
121 Lambda.push_back(v);
122 Nu.push_back(SpeedOfLight_Cst*1.e3/v);
123 }
124 }
125 cout<<"Nombre de longueurs d'onde a traiter "<<Lambda.size()<<" (unites: m et Hz)"<<endl;
126 if(Lambda.size()==0) return -3;
127 for(unsigned short i=0;i<Lambda.size();i++)printf(" %.3f m , %.3f MHz\n",Lambda[i],Nu[i]/1.e6);
128
129 cout<<"Dipole : longueur totale L="<<L_d<<endl;
130 if(L_d==0.) return -4;
131
132 if(N_g<=0) N_g = 1;
133 cout<<"Regroupements N="<<N_g<<" D="<<D_g<<" Theta="<<Theta_g<<endl;
134 if(N_g>1 && D_g==0.) return -4;
135
136 if(N_i<=0) N_i = 1;
137 cout<<"Interferences N="<<N_i<<" D="<<D_i<<" Theta="<<Theta_i<<endl;
138 if(N_i>1 && D_i==0.) return -4;
139
140 if(Nang<=0) Nang = 25;
141 while(Tcent<-180.) Tcent += 360.;
142 while(Tcent>180.) Tcent -= 360.;
143 Tmax = fabs(Tmax); if(Tmax>180.) Tmax=180.;
144 cout<<"Display: Nang="<<Nang<<" Tmax="<<Tmax<<" Tcent="<<Tcent<<endl;
145
146 double norme_g=1., norme_i=1.;
147 if(normone) {norme_g=N_g*N_g; norme_i=N_i*N_i;}
148 cout<<"Normalisation: norme_g="<<norme_g<<" norme_i="<<norme_i<<endl;
149
150 char str[32];
151 POutPersist pos("cmvhshsns.ppf");
152
153 //------- Boucle sur les longeurs d'ondes
154 for(unsigned short il=0;il<Lambda.size();il++) {
155
156 //... mise en forme des parametres pour la longueur d'onde
157 double lambda = Lambda[il], nu = Nu[il];
158 cout<<"\n\n>>> Lambda = "<<lambda<<" m , nu = "<<nu/1.e6<<" MHz"<<endl;
159 double ld = (L_d<0.) ? -L_d*lambda : L_d;
160 cout<<"dipole: ld="<<ld<<" m"<<endl;
161 double dg = (D_g<0.) ? -D_g*lambda : D_g;
162 cout<<"groupe: ("<<N_g<<"), dg="<<dg<<" m -> "<<dg*N_g<<" m"<<endl;
163 double di = (D_i<0.) ? -D_i*lambda : D_i;
164 cout<<"interf: ("<<N_i<<"), di="<<di<<" m -> "<<di*N_i<<" m"<<endl;
165 double thg, thi, tg, ti;
166 if(thetaps) {
167 tg = Theta_g;
168 double rcg = thetafromdt(thg,tg,lambda,dg);
169 ti = Theta_i;
170 double rci = thetafromdt(thi,ti,lambda,di);
171 cout<<"dephasage electronique: groupe "<<tg<<" sec -> "<<thg/torad<<" deg pour rc="<<rcg<<endl
172 <<" interf "<<ti<<" sec -> "<<thi/torad<<" deg pour rc="<<rci<<endl;
173 if(rcg>1 || rci>1) {cout<<"!!!! Lambda NON-TRAITE"<<endl; continue;}
174 } else {
175 thg = Theta_g*torad; tg = dtfromtheta(thg,lambda,dg);
176 thi = Theta_i*torad; ti = dtfromtheta(thi,lambda,di);
177 cout<<"dephasage electronique: groupe "<<thg/torad<<" deg -> "<<tg<<" sec"<<endl
178 <<" interf "<<thi/torad<<" deg -> "<<ti<<" sec"<<endl;
179 }
180 double sthg = sin(thg);
181 double sthi = sin(thi);
182
183 //... distance approx entre 2 zeros
184 double dzero = M_PI/2.;
185 if(N_g>1) {
186 double z = lambda/(N_g*dg);
187 cout<<"groupe: distance entre 2 zeros: d(sin(t))="<<z<<" (approx "<<z/torad<<" deg)"<<endl;
188 if(z<dzero) dzero = z;
189 }
190 if(N_i>1) {
191 double z = lambda/(N_i*di);
192 cout<<"interf: distance entre 2 zeros: d(sin(t))="<<z<<" (approx "<<z/torad<<" deg)"<<endl;
193 if(z<dzero) dzero = z;
194 }
195 cout<<"distance approx entre 2 zeros "<<dzero<<" rad = "<<dzero/torad<<" deg"<<endl;
196
197 //... remplissage des angles
198 {
199 const int nnt=5; float xnt[nnt];
200 const char *namev[nnt] = {"t","ant","intfg","intfi","intf"};
201 NTuple nt(nnt,namev);
202
203 long npt = long(Tmax*torad/dzero*Nang +0.5);
204 double dt = Tmax*torad/npt;
205 cout<<"nombre de points dans la boucle "<<2*npt+1<<" , dt="<<dt/torad<<endl;
206 for(int i=-npt;i<=npt;i++) {
207 double t = Tcent*torad + i*dt;
208 double st = sin(t);
209 double ta = acos(st); // angle par rapport au fil de l'antenne
210 double deltag = M_PI*dg/lambda*(st-sthg);
211 double deltai = M_PI*di/lambda*(st-sthi);
212 double ant = (ld==0.) ? AntDipole(ld/lambda,ta): AntCentFed(ld/lambda,ta);
213 double intfg = (N_g==1) ? 1.: SinNXsX_Sqr(deltag,N_g)/norme_g;
214 double intfi = (N_i==1) ? 1.: SinNXsX_Sqr(deltai,N_i)/norme_i;
215 double intf = ant*intfg*intfi;
216
217 xnt[0] = t/torad;
218 xnt[1] = ant;
219 xnt[2] = intfg;
220 xnt[3] = intfi;
221 xnt[4] = intf;
222 nt.Fill(xnt);
223 }
224
225 //...ecriture ppf
226 sprintf(str,"nt_%d",il);
227 cout<<"writing "<<str<<" into ppf file"<<endl;
228 pos << PPFNameTag(str) << nt;
229 DVList dvl;
230 dvl("Lambda") = lambda; dvl("Nu") = nu;
231 dvl("Ld") = ld;
232 dvl("Ng") = N_g; dvl("Dg") = dg; dvl("Thg") = thg; dvl("Tg") = tg;
233 dvl("Ni") = N_i; dvl("Di") = di; dvl("Thi") = thi; dvl("Ti") = ti;
234 dvl("Tmax") = Tmax; dvl("Tcent") = Tcent;
235 sprintf(str,"dvl_%d",il);
236 pos << PPFNameTag(str) << dvl;
237 }
238
239 //... remplissage des zeros et des maximas principaux
240 {
241 const int nnt=2; double xnt[nnt];
242 const char *namev[nnt] = {"t","ztyp"};
243 if(N_g>1) {
244 NTuple nt(nnt,namev);
245 double no = (normone) ? 1.: norme_g;
246 for(int is=-1;is<=1;is+=2) {
247 int k0 = (is==1) ? 0: -1;
248 for(int k=k0;;k+=is) {
249 xnt[0] = k*lambda/(N_g*dg)+sthg;
250 xnt[1] = (k%N_g==0) ? no: 0.;
251 if(fabs(xnt[0])>1.) break;
252 xnt[0]=asin(xnt[0])/torad; nt.Fill(xnt);
253 }
254 }
255 sprintf(str,"ntzg_%d",il);
256 pos << PPFNameTag(str) << nt;
257 }
258 if(N_i>1) {
259 NTuple nt(nnt,namev);
260 double no = (normone) ? 1.: norme_i;
261 for(int is=-1;is<=1;is+=2) {
262 int k0 = (is==1) ? 0: -1;
263 for(int k=k0;;k+=is) {
264 xnt[0] = k*lambda/(N_i*di)+sthi;
265 xnt[1] = (k%N_i==0) ? no: 0.;
266 if(fabs(xnt[0])>1.) break;
267 xnt[0]=asin(xnt[0])/torad; nt.Fill(xnt);
268 }
269 }
270 sprintf(str,"ntzi_%d",il);
271 pos << PPFNameTag(str) << nt;
272 }
273 }
274
275 }
276
277 return 0;
278}
279
280//-----------------
281double thetafromdt(double &theta,double dt,double lambda,double dconsec)
282// Input:
283// dt : decalage en seconde
284// lambda : longueur d'onde en m
285// dconsec : distance entre 2 dipoles consecutifs en m
286// Output et Return code "rc":
287// on cherche theta tel que: "C*dt = dconsec*sin(theta)"
288// ...si on peut trouver theta on renvoie
289// theta (en rad) angle equivalent
290// rc = 1
291// ...si on ne peut pas trouver theta on renvoie
292// theta (en rad) angle equivalent
293// rc > 1
294// pour la premiere solution de "C*dt = rc*dconsec*sin(theta)"
295// ...mauvais parametre on renvoie
296// rc=0
297{
298 if(dconsec<=0. || lambda<=0.) return 0.;
299
300 // conversion de dt en longueur
301 dt *= SpeedOfLight_Cst*1.e3;
302
303 // translation dans une longueur d'onde
304 dt = (dt/lambda - trunc(dt/lambda))*lambda;
305
306 // calcul de sin(theta)
307 double st = dt/dconsec;
308
309 // calcul du nombre de dconsec pour avoir la premiere solution
310 double rc = ceil(fabs(st));
311 if(rc==0) rc=1;
312
313 // equivalent en angle possible
314 theta = asin(st/rc);
315 return rc;
316 }
317
318double dtfromtheta(double theta,double lambda,double dconsec)
319// Input:
320// theta : angle en rad
321// lambda : longueur d'onde en m
322// dconsec : distance entre 2 dipoles consecutifs en m
323// Return: dt = dconsec/C * sin(theta) remis dans la periode
324{
325 double dt = dconsec*sin(theta);
326
327 // translation dans une longueur d'onde
328 dt = (dt/lambda - trunc(dt/lambda))*lambda;
329
330 return dt/(SpeedOfLight_Cst*1.e3);
331}
332
333/******************************
334openppf cmvhshsns.ppf
335
336set l 0
337
338set t t
339set t sin(t*M_PI/180.)
340
341set cut 1
342set cut -90<t&&t<90
343
344n/plot $nt.$t%_nl
345
346n/plot nt_$l.ant%$t $cut ! "nsta cpts green"
347n/plot nt_$l.intfg%$t $cut ! "nsta cpts same red"
348n/plot nt_$l.intfi%$t $cut ! "nsta cpts same blue"
349n/plot nt_$l.intf%$t $cut ! "nsta cpts same black"
350
351n/plot ntzg_$l.ztyp%$t $cut ! "nsta same marker=circle,9 red"
352n/plot ntzi_$l.ztyp%$t $cut ! "nsta same marker=star,9 blue"
353
354
355# compare frequences
356n/plot nt_0.intf%$t $cut ! "nsta cpts black"
357n/plot nt_1.intf%$t $cut ! "nsta cpts same blue"
358n/plot nt_2.intf%$t $cut ! "nsta cpts same red"
359n/plot nt_3.intf%$t $cut ! "nsta cpts same orange"
360
361 */
Note: See TracBrowser for help on using the repository browser.