source: Sophya/trunk/SigPredictor/sigcalctools.cc@ 1647

Last change on this file since 1647 was 1191, checked in by ansari, 25 years ago

cleaned up for maching LevelS upgrade ongoing

D.Y.

File size: 14.4 KB
RevLine 
[801]1 // Dominique YVON, CEA/DAPNIA/SPP 02/2000
2
3#include <math.h>
4#include <iostream>
5#include <iostream>
6#include <fstream>
7#ifdef __MWERKS__
[1148]8
[801]9 #include "unixmac.h"
10#endif
11#include "sigcalctools.h"
12#include "lightdipole.h"
13
14//_______________ ici toutes les frequences sont en Hz ___________________________
15
16static SigCalcTool* pSigToolcur;
17
18double SigCalGLFreqFunc1(double freq) {
19 double temp1=(pSigToolcur->pLSrc)->spectre(freq);
20 double temp2=(pSigToolcur->pLobe)->spectre(freq);
21 double temp3=(pSigToolcur->pFilter)->transmission(freq);
22
23 return temp1*temp2*temp3;
24}
25
26double SigCalGLFreqFunc2(double freq)
27{
28 // Integration function for GLInteg
29 double temp1=
30 (pSigToolcur->pLSrc)->powSpecDens((pSigToolcur->VPointe).Theta(),(pSigToolcur->VPointe).Phi(),freq);
31 double temp2=(pSigToolcur->pLobe)->weigth(pSigToolcur->VCur,pSigToolcur->VPointe,pSigToolcur->VY,freq);
32 double temp3=(pSigToolcur->pFilter)->transmission(freq);
33 return temp1*temp2*temp3;
34}
35
36SigCalcTool::SigCalcTool(AbsLightSource* pLightSrc, AbsLobeNoPolar* pLobeNoPolar,
[1148]37 SpectralResponse* pFilt):pLSrc(pLightSrc)
38{ pLobe=pLobeNoPolar;
39 pFilter=pFilt;
40
[801]41 SigCalcToolInit();
42}
43
44void SigCalcTool::SigCalcToolInit()
45{ emptySignal=false;
46// Compute frequency integration boundaries
47 cout<< "Initialisation Calctool"<<endl;
48 FreqMin=max(pLobe->minFreq(), pFilter->minFreq());
49 FreqMax=min(pLobe->maxFreq(), pFilter->maxFreq());
50 if(FreqMax<FreqMin) {
51 emptySignal=true;
52 cerr<< "Frequency max is lower than Frequency Min in SigCalcTool"<<endl;
53 cerr<< "check consistency of lobes and Filters"<<endl;
54 }
55// Computation Options
56 if(pLSrc->IsMappedPowerSrc())
57 { if(!pLobe->IsFreqSep())
58 { cerr<<" Sigcalctool error: using a LightMapPowerInband with a lobe non freq separable"<<endl;
59 cerr<<" Did you change lobe between constructing the map and running sigcalctool?"<<endl;
60 cerr<<" Program exited"<<endl;
61 exit(-1.);
62 }
63 Option=IsLightMapPowerInband;
64 pIntegrale= new GLInteg();
65 // Pour eviter un plantage dans ~SigCalcTool
66 }
67
68 else if(pLSrc->IsFreqSep()&&pLobe->IsFreqSep()) {
69 Option=AllSeparable;
70 pIntegrale= new GLInteg(SigCalGLFreqFunc1,FreqMin,FreqMax); //en Hz.
71 pSigToolcur=this;
72 pIntegrale->NStep(200); // Integration tres sŽrieuse
73 IntegSpectOverFreq=pIntegrale->Value();
74 }
75
76 else
77 { Option=NonSeparable;
78 pIntegrale= new GLInteg(SigCalGLFreqFunc2,FreqMin,FreqMax);
79 pIntegrale->NStep(10); // Pour aller plus vite. Serieux si le filtre est "compact"
80 }
81// Computation Resolution
82 RAngComp=pLSrc->LSrcResol(); // On integre sur la resolution de la carte
83 if(RAngComp==0.)
84 { RAngComp=pLobe->lobeResol();
85 if(RAngComp==0.)
86 { cerr<<" Bizarre un lobe de resolution nulle?"<<endl;
87 RAngComp= 5.e-4; // Radians
88 // On prend la resolution nominale de Planck
89 }
90 }
91 if(RAngComp<pLobe->lobeResol())
92 { cerr<<" SigCalcTool: LightSource resolution lower than expected lobe resolution"<<endl;
93 cerr<<" Not healthy: Ckeck consistency"<<endl;
94 }
95 cout<<"Resolution de calcul: "<<RAngComp<<" Radian"<<endl<<endl;
96}
97
98
[1148]99
[801]100double SigCalcTool::compPixel(UnitVector& VP, UnitVector& VdirectY){
101 double returnRes=0.;
102 VPointe=VP;
103 VY=VdirectY;
104 VX=VY^VP;
105 if(!emptySignal) returnRes=powerInteg(); // On integre sur la sphere
106 return returnRes;
107}
108
109
110double SigCalcTool::calcPowerDens() const{
111// Compute the power integrated on frequency dependance, (Lobe and LightSource)
112 pSigToolcur=(SigCalcTool*) this;
113 double returnRes;
114 double poidlobe;
115 double Puiss;
116 switch (Option)
117 {
118 case AllSeparable:
119 {
120 poidlobe=(pSigToolcur->pLobe)->weigthAmpl(VCur,VPointe,VY); // ss dimensions
121/*
122 if (poidlobe>.1)
123 { cout<<poidlobe<<endl;
124 }
125*/
126
127 Puiss=(pSigToolcur->pLSrc)->powerDensAmpli(VCur.Theta(),VCur.Phi());
128 // W m-2 st-1 Hz-1
129 returnRes=Puiss * poidlobe * IntegSpectOverFreq; // W / m2 / st
130 return returnRes;
131 }
132 case IsLightMapPowerInband:
133 {
134 // cout<<"VCur.Theta: "<<VCur.Theta()<<"VCur.Phi(): "<<VCur.Phi()<<endl;
135 poidlobe= (pSigToolcur->pLobe)->weigthAmpl(VCur,VPointe,VY);
136 Puiss= (pSigToolcur->pLSrc)->powerDensAmpli(VCur.Theta(),VCur.Phi());
137 returnRes=Puiss * poidlobe;
138 return returnRes;
139 }
140
141 default:
142 { // Cas NonSeparable
143 // Integration over at coordinates
144 returnRes=pIntegrale->Value();
145 return returnRes;
146 }
147
148 }
149}
150
151
152#define NBStepCircleMin (12)
153
154double SigCalcTool::powerInteg() {
155 // compute power on detector
156
157 double powerInteg=0.;
158 // Sum of the incominig power on detector.
159 UnitVector VPoin;
160 // VPointe Boresigth du telescope microonde
161 // VPoin direction priviliegiee du lobe, autour de laquelle on calcule
162 // VCur, vecteur courant du calcul.
163// double thetaCur, phiCur; // Coordinates of VCur
164 // Units is radian
165
166
167
168 //------Initialisation of Lobe integration------------------------------------------
169 double angShift=0.; // Angular distance from VPoin
170 double angShiftLimit; // On calcule jusqu'a angShiftLimit de VPoin
171
172 if(pLSrc->IsQPtSrc())
173 { double ang1=pLSrc->getAngSize()+pLobe->AngleMax();
174 VPoin=pLobe->VecShift(VPointe, VY);
175 if (ang1>=M_PI) { } //rien
176 else
177 { double cosinus=VPoin*pLSrc->GetVSrcCenter();
178 if (cosinus<cos(ang1)) return 0.;
179 //C'est le cas ou la source est trop loin de la direction pointŽe
180 }
181 // Maintenant on intgre
182 angShiftLimit=ang1;
183 }
184 else
185 {
186 VPoin=pLobe->VecShift(VPointe, VY);
187 angShiftLimit=pLobe->AngleMax();
188 }
189
190 // On va tourner autour de VPoin
191 // Compute unit vector perpendicular to Vpoin at same theta
192 UnitVector VPerp;
193 VPerp=VPoin.VperpPhi();
194
[1191]195 double dAngShift=AngResComp(0.);
[801]196 // AngleSteps are not necessarily constant.
197 double lastAngShiftMax;
198 // Needed to compute accurately solid angle values
199
200 VCur=VPoin;
201
202 powerInteg+=calcPowerDens()*diffSolidAng(0.,dAngShift/2.);
203 lastAngShiftMax= dAngShift/2.;
204
205 long NbPasOneCircle;
206 long CircleNumber=0; // no du cercle en cour:
207 // Gestion des dŽcalages pour un echantillonnage en quinconce
208 double solidAngStepCircle;
209 float stepAngCircle;
210
211 ///---------- Lobe integration-----------------------------------------
212 // generate vectors around VPoin at angular distance angShift.
213 // Compute power flux from foreground in this direction
214 // Weigth with weigth function and solid angle
215 dAngShift=AngResComp(lastAngShiftMax);
216
217 while((lastAngShiftMax+dAngShift)<angShiftLimit){
218 CircleNumber++;
219 angShift=lastAngShiftMax+dAngShift/2.;
220
221 VCur=VPoin.Rotate(VPerp,angShift);
222
223 // Compute number of step and associates on a circle
224 NbPasOneCircle=(long) (2*M_PI*sin(angShift)/sin(dAngShift));
225 if(NbPasOneCircle<NBStepCircleMin) NbPasOneCircle=NBStepCircleMin;
226 stepAngCircle=2*M_PI/NbPasOneCircle;
227 solidAngStepCircle= diffSolidAng(lastAngShiftMax,angShift+dAngShift/2.)/NbPasOneCircle;
228 // MRotAround=RotVec(VPoin,stepAngCircle);
229
230 //----------- integrate on a circle -------------------
231 if((CircleNumber%2)==0) VCur=VCur.Rotate(VPoin,stepAngCircle/2.);
232 // Pour un echantillonnage en quinconce
233
234 for(long i=0;i<NbPasOneCircle;i++)
235 {
236 //cout<< "rotation numb: "<< i<<endl;
237 powerInteg+=calcPowerDens()*solidAngStepCircle;
238 VCur=VCur.Rotate(VPoin,stepAngCircle);
239 } // end of circle
240
241 lastAngShiftMax+=dAngShift;
242 dAngShift=AngResComp(lastAngShiftMax);
243 }
244
245 // On s'occupe des effets de bord: un dernier tour!
246 // On change le code pour eviter les instabilites dues a dAngShift tres petit
247 CircleNumber++;
248 angShift=(angShiftLimit+lastAngShiftMax)/2.;
249
250 VCur=VPoin.Rotate(VPerp,angShift);
251 // Compute number of step and associates on a circle
252 NbPasOneCircle=(long) 2*M_PI*sin(angShift)/sin(AngResComp(angShift));
253 if(NbPasOneCircle<NBStepCircleMin) NbPasOneCircle=NBStepCircleMin;
254 stepAngCircle=2*M_PI/NbPasOneCircle;
255 solidAngStepCircle= diffSolidAng(lastAngShiftMax,angShiftLimit)/NbPasOneCircle;
256
257 //----------- integrate on last circle -------------------
258 for(long i=0;i<NbPasOneCircle;i++)
259 {
260 powerInteg+=calcPowerDens()*solidAngStepCircle;
261 VCur=VCur.Rotate(VPoin,stepAngCircle);
262 }
263 //end of last circle
264
265 //end of integration
266
267// cout<<"On a termine un point, OUFF"<< endl;
268 return powerInteg;
269}
270
271/*
272double SigCalcTool::CalcInBandPower(double theta, double phi)
273{
274 double returnRes=0.;
275 UnitVector VP(theta,phi);
276 UnitVector VYbidon=VP.VperpPhi();
277// Compute unit vector perpendicular to Vpoin at same theta
278 VCur=VP;
279 VPointe=VP;
280 VY=VYbidon;
281 VX=VY^VP;
282 if(!emptySignal) returnRes=calcPowerDens(); // On integre sur la frequence
283 return returnRes;
284}
285*/
286
287double SigCalcTool::AngResComp(double angle) const
288{
289 double AngRes;
290 if(pLSrc->IsQPtSrc()) AngRes=RAngComp;
291 else AngRes=RAngComp*pLobe->ResolutionCurve(angle);
292 return AngRes;
293}
294
295double SigCalcTool::CalcLobeSize(double frequency)
296{
297 // Compute lobe extension in steradians
298
299 if(frequency== -10.) frequency=(FreqMin+FreqMax)/2.;
300
301 double SizeInteg=0.;
302 // Sum of the incominig power on detector.
303 UnitVector VPoin;
304 // VPointe Boresigth du telescope microonde
305 // VPoin direction priviliegiee du lobe, autour de laquelle on calcule
306 // VCur, vecteur courant du calcul.
307
308 //------Initialisation of Lobe integration------------------------------------------
309 double angShift=0.; // Angular distance from VPoin
310 double angShiftLimit=pLobe->AngleMax(); // On calcule jusqu'a angShiftLimit de VPoin
311
312
313 // On va tourner autour de VPoin
314 // Compute unit vector perpendicular to Vpoin at same theta
315 UnitVector VPerp;
316 VPerp=VPoin.VperpPhi();
317
[1191]318 double dAngShift=AngResComp(0.);
[801]319 // AngleSteps are not necessarily constant.
320 double lastAngShiftMax;
321 // Needed to compute accurately solid angle values
322 UnitVector VCur;
323 VCur=VPoin;
324
325 SizeInteg+= pLobe->weigth(VCur,VPoin,VPerp,frequency)*diffSolidAng(0.,dAngShift/2.);
326 lastAngShiftMax= dAngShift/2.;
327
328 long NbPasOneCircle;
329 long CircleNumber=0; // no du cercle en cour:
330 // Gestion des dŽcalages pour un echantillonnage en quinconce
331 double solidAngStepCircle;
332 float stepAngCircle;
333
334 ///---------- Lobe integration-----------------------------------------
335 // generate vectors around VPoin at angular distance angShift.
336 // Compute power flux from foreground in this direction
337 // Weigth with weigth function and solid angle
338 dAngShift=AngResComp(lastAngShiftMax);
339
340 while((lastAngShiftMax+dAngShift)<angShiftLimit)
341 {
342 CircleNumber++;
343 angShift=lastAngShiftMax+dAngShift/2.;
344
345 VCur=VPoin.Rotate(VPerp,angShift);
346
347 // Compute number of step and associates on a circle
348 NbPasOneCircle=(long) (2*M_PI*sin(angShift)/sin(dAngShift));
349 if(NbPasOneCircle<NBStepCircleMin) NbPasOneCircle=NBStepCircleMin;
350 stepAngCircle=2*M_PI/NbPasOneCircle;
351 solidAngStepCircle= diffSolidAng(lastAngShiftMax,angShift+dAngShift/2.)/NbPasOneCircle;
352
353 //----------- integrate on a circle -------------------
354 if((CircleNumber%2)==0) VCur=VCur.Rotate(VPoin,stepAngCircle/2.);
355 // Pour un echantillonnage en quinconce
356
357 for(long i=0;i<NbPasOneCircle;i++)
358 {
359 SizeInteg+= pLobe->weigth(VCur,VPoin,VPerp,frequency)*diffSolidAng(0.,dAngShift/2.);
360 VCur=VCur.Rotate(VPoin,stepAngCircle);
361 } // end of circle
362
363 lastAngShiftMax+=dAngShift;
364 dAngShift=AngResComp(lastAngShiftMax);
365 }
366
367 // On s'occupe des effets de bord: un dernier tour!
368 // On change le code pour eviter les instabilites dues a dAngShift tres petit
369 CircleNumber++;
370 angShift=(angShiftLimit+lastAngShiftMax)/2.;
371
372 VCur=VPoin.Rotate(VPerp,angShift);
373 // Compute number of step and associates on a circle
374 NbPasOneCircle=(long) 2*M_PI*sin(angShift)/sin(AngResComp(angShift));
375 if(NbPasOneCircle<NBStepCircleMin) NbPasOneCircle=NBStepCircleMin;
376 stepAngCircle=2*M_PI/NbPasOneCircle;
377 solidAngStepCircle= diffSolidAng(lastAngShiftMax,angShiftLimit)/NbPasOneCircle;
378
379 //----------- integrate on last circle -------------------
380 for(long i=0;i<NbPasOneCircle;i++)
381 {
382 SizeInteg+= pLobe->weigth(VCur,VPoin,VPerp,frequency)*diffSolidAng(0.,dAngShift/2.);
383 VCur=VCur.Rotate(VPoin,stepAngCircle);
384 }
385 //end of last circle
386
387 //end of integration
388
389 return SizeInteg;
390}
391
392// should be included as a class member, would template member function
393// work on all compilers
394
395static AbsLobeNoPolar* AddInBandPowerpLobe;
396static AbsLightSource* AddInBandPowerpLSrc;
397static SpectralResponse* AddInBandPowerpFilter;
398static double AIBtheta;
399static double AIBphi;
400
401static double AddInBandPowerFreqFunc1(double freq)
402{ // Integration function for GLInteg
403 double temp1= AddInBandPowerpLSrc->powSpecDens(AIBtheta,AIBphi,freq);
404 double temp2= AddInBandPowerpLobe->spectre(freq);
405 double temp3= AddInBandPowerpFilter->transmission(freq);
406 return temp1*temp2*temp3;
407}
408
409template <class T> void addInInBandPowerMap(PixelMap<T>& Map, SigCalcTool& Tool)
410{ // No spatial integration on the lobe
411 // Valid if lobe is separable in frequency
412 // Test
413 AddInBandPowerpLobe=Tool.getpLobe();
414 AddInBandPowerpLSrc=Tool.getpLSrc();
415 AddInBandPowerpFilter=Tool.getpFilter();
416 if(!AddInBandPowerpLobe->IsFreqSep())
417 { cerr<<" Adding power to a map using a lobe non separable in frequency is inconsistent"<<endl;
418 cerr<<" No power added, addInBandPower skipped"<<endl;
419 return;
420 }
421
422 long PixelNumber= Map.NbPixels();
423 double out;
424 T temp;
425 if(Tool.getOption()==AllSeparable)
426 { // Fast !
427 double FreqIntFactor=Tool.getIntegSpectOverFreq();
428 for(long k=0; k<PixelNumber; k++)
429 { Map.PixThetaPhi(k,AIBtheta,AIBphi);
430 out= AddInBandPowerpLSrc->powerDensAmpli(AIBtheta,AIBphi)*FreqIntFactor;
431 // Lobe weigth do no enters here
432 temp= (T) out;
433 Map(k)+= temp;
434 // if((k%200)==0) cout<<"200 points calculŽs "<<"NbPoint Total= "<<k<<endl;
435 }
436
437 }
438 else
439 {
440 if(AddInBandPowerpLSrc->IsFreqSep())
441 { double FreqMax=Tool.getFreqMax();
442 double FreqMin=Tool.getFreqMin();
443 double out;
444 GLInteg Integrale(AddInBandPowerFreqFunc1,FreqMin,FreqMax);
445 Integrale.NStep(10); // Serieux!
446 for(long k=0; k<PixelNumber; k++)
447 {
448 Map.PixThetaPhi(k,AIBtheta,AIBphi);
449 // Lobe weigth do no enters here
450 out=Integrale.Value();
451 // Lobe weigth do no enters here
452 temp= (T) out;
453 Map(k)+= temp;
454 }
455 }
456 }
457 return;
458}
459
460template void addInInBandPowerMap(PixelMap<float>& Map, SigCalcTool& tool);
461template void addInInBandPowerMap(PixelMap<double>& Map, SigCalcTool& tool);
Note: See TracBrowser for help on using the repository browser.