source: Sophya/trunk/SophyaLib/SkyMap/sphereecp.cc@ 2985

Last change on this file since 2985 was 2973, checked in by ansari, 19 years ago

1/ Nettoyage+commentaires/doxygen ds Vector3d, UnitVector, LongLat,
SphereCoordSys ...
2/ Ajout de la classe angle pour faciliter les conversions rad<>deg<>arcmin
dans le fichier vector3d.h .cc
3/ nettoyage/uniformisation methodes print pour pixelmap, ajout de la
methode PixelMap<T>::Show()
4/ Ajout methodes SphericalMap<T>::HasSymThetaSlice() et
GetSymThetaSliceIndex(int_4 idx) et leurs implementations pour
SphereHEALPix et SphereThetaPhi en vue de l'optimisation du calcul
transforme Ylm
5/ Ajout methode ResolToSizeIndex ds SphereThetaPhi , SphereHEALPix et
SphereECP

Reza , 20 Juin 2006

File size: 11.5 KB
RevLine 
[2615]1#include "sopnamsp.h"
[2610]2#include "sphereecp.h"
3#include <math.h>
4
[2808]5/*!
6 \class SOPHYA::SphereECP
7 \ingroup SkyMap
8 \brief Spherical maps in Equatorial Cylindrical Projection
9
10 Class implementing spherical maps, with a pixelisation
11 corresponding to the an Equatorial Cylindrical Projection.
12 Pixel size varie from equator to poles. The sphere is divided
13 into a number of slices along the parallels. Each slice is subdivided
14 into the same number of pixels.
15 This class provides the possibility to have partial coverage.
16 Can be used for the following types: <br>
17 <tt> int_4 , r_4 , r_8 , complex<r_4> , complex<r_8> </tt>
18*/
19
[2610]20namespace SOPHYA {
21
[2808]22//! Default constructor
[2610]23template <class T>
24SphereECP<T>::SphereECP()
25 : _pixels()
26{
27 _partial = false;
28 _theta1 = 0.;
29 _theta2 = M_PI;
30 _phi1 = 0.;
31 _phi2 = 2*M_PI;
32 _outofmapidx = -99;
[2621]33 _outofmapnphi = 0;
34 _outofmapntet = 0;
[2610]35 _outofmappix = 0;
36 _outofmapval = 0;
37 _dtheta = 0.;
38 _dphi = 0.;
39}
40
[2808]41/*!
42 \brief Constructor with the pixelisation parameter m
43
44 Complete coverage.
45 The sphere is divided into \b m slices in theta (0..pi). each slice is divided
46 into \b 2m pixels (along phi)
47*/
[2610]48template <class T>
49SphereECP<T>::SphereECP(int m)
50 : _pixels(2*m,m,0,0,0,true)
51{
52 _partial = false;
53 _theta1 = 0.;
54 _theta2 = M_PI;
55 _phi1 = 0.;
56 _phi2 = 2*M_PI;
57 _outofmapidx = -99;
[2621]58 _outofmapnphi = 0;
59 _outofmapntet = 0;
[2610]60 _outofmappix = 0;
61 _outofmapval = 0;
62 _dtheta = _dphi = M_PI/m;
63}
64
[2808]65/*!
66 Complete coverage.
67 \b ntet slices in theta (0..pi) and \b nphi pixels (along phi) for
68 each slice in theta
69*/
[2610]70template <class T>
71SphereECP<T>::SphereECP(int ntet, int nphi)
72 : _pixels(nphi,ntet,0,0,0,true)
73{
74 _partial = false;
75 _theta1 = 0.;
76 _theta2 = M_PI;
77 _phi1 = 0.;
78 _phi2 = 2*M_PI;
79 _outofmapidx = -99;
[2621]80 _outofmapnphi = 0;
81 _outofmapntet = 0;
[2610]82 _outofmappix = 0;
83 _outofmapval = 0;
84 _dtheta = M_PI/ntet;
85 _dphi = 2*M_PI/nphi;
86}
87
[2808]88/*!
89 Partial coverage :
90 \b ntet slices in theta , in the range (tet1 .. tet2) and \b nphi pixels (along phi) for
91 each slice in theta in the range (phi1 .. phi2)
92*/
[2610]93template <class T>
94SphereECP<T>::SphereECP(r_8 tet1, r_8 tet2, int ntet, r_8 phi1, r_8 phi2, int nphi)
95 : _pixels(nphi,ntet,0,0,0,true)
96{
97 if( (tet1 > M_PI) || (tet1 < 0.) || (tet2 > M_PI) || (tet2 < 0.) ||
98 (phi1 < 0.) || (phi1 > 2*M_PI) || (phi1 < 0.) || (phi1 > 2*M_PI) ||
99 (tet2 <= tet1) || (phi2 <= phi1) )
100 throw ParmError("SphereECP::SphereECP() Bad range for theta/phi limits");
101
102 _partial = true;
103 _theta1 = tet1;
104 _theta2 = tet2;
105 _phi1 = phi1;
106 _phi2 = phi2;
107 _outofmapidx = _pixels.Size()+659;
[2621]108 // Reza, 23 sep 2004
109 // pour des cartes partielles, et des pixels sur la sphere, mais
110 // en dehors de la couverture, on code le numero de tranche en theta,
111 // compte a partir de theta=0,phi=0 + _outofmapidx
112 // theta -> idx = _outofmapidx + theta/_dtheta*_outofmapnphi + _outofmapntet
113 _outofmapntet = 0;
[2610]114 _outofmappix = 0;
115 _outofmapval = 0;
116 _dtheta = (_theta2-_theta1)/ntet;
117 _dphi = (_phi2-_phi1)/nphi;
[2621]118
119 _outofmapntet = M_PI/_dtheta;
120 _outofmapnphi = 2*M_PI/_dphi;
[2610]121}
122
[2808]123//! Copy constructor - shares the pixel data if \b share=true
[2610]124template <class T>
125SphereECP<T>::SphereECP(const SphereECP<T>& a, bool share)
126 : _pixels(a._pixels, share)
127{
128 _partial = a._partial;
129 _theta1 = a._theta1;
130 _theta2 = a._theta2;
131 _phi1 = a._phi1;
132 _phi2 = a._phi2;
133 _outofmapidx = a._outofmapidx;
[2621]134 _outofmapnphi = a._outofmapnphi;
135 _outofmapntet = a._outofmapntet;
[2610]136 _outofmappix = a._outofmappix;
137 _outofmapval = a._outofmapval;
138 _dtheta = a._dtheta;
139 _dphi = a._dphi;
140}
141
[2808]142//! Copy constructor - shares the pixel data
[2610]143template <class T>
144SphereECP<T>::SphereECP(const SphereECP<T>& a)
145 : _pixels(a._pixels)
146{
147 _partial = a._partial;
148 _theta1 = a._theta1;
149 _theta2 = a._theta2;
150 _phi1 = a._phi1;
151 _phi2 = a._phi2;
152 _outofmapidx = a._outofmapidx;
[2621]153 _outofmapnphi = a._outofmapnphi;
154 _outofmapntet = a._outofmapntet;
[2610]155 _outofmappix = a._outofmappix;
156 _outofmapval = a._outofmapval;
157 _dtheta = a._dtheta;
158 _dphi = a._dphi;
159}
160
161template <class T>
162SphereECP<T>::~SphereECP()
163{
164}
165
166template <class T>
167string SphereECP<T>::TypeOfMap() const
168{
169 return string("TETAFI");
170}
171
172template <class T>
173void SphereECP<T>::SetTemp(bool temp) const
174{
175 _pixels.SetTemp(temp);
176}
177
178template <class T>
179int_4 SphereECP<T>::NbPixels() const
180{
181 return _pixels.Size();
182}
183
184template <class T>
185T& SphereECP<T>::PixVal(int_4 k)
186{
[2621]187 // On pourrait etre plus strict en demandant aussi k<_outofmapidx+_outofmapnphi*_outofmapntet (Reza 23/09/04)
188 if ((_partial) && (k>=_outofmapidx)) return _outofmappix;
[2610]189 if((k < 0) || (k >= _pixels.Size()) )
190 throw RangeCheckError("SphereECP::PIxVal() Pixel index out of range");
191 return _pixels.DataBlock()(k);
192}
193
194template <class T>
195T const& SphereECP<T>::PixVal(int_4 k) const
196{
[2621]197 // On pourrait etre plus strict en demandant aussi k<_outofmapidx+_outofmapnphi*_outofmapntet (Reza 23/09/04)
198 if ((_partial) && (k>=_outofmapidx)) return _outofmapval;
[2610]199 if((k < 0) || (k >= _pixels.Size()) )
200 throw RangeCheckError("SphereECP::PIxVal() Pixel index out of range");
201 // return _pixels.DataBlock()(k);
202 return _pixels.Data()[k];
203}
204
205template <class T>
206bool SphereECP<T>::ContainsSph(double theta, double phi) const
207{
208 if (_partial) {
209 if ( (theta >= _theta1) && (theta <= _theta2) &&
210 (phi >= _phi1) && (phi <= _phi2) ) return true;
211 else return false;
212 }
213 else return false;
214}
215
216template <class T>
217int_4 SphereECP<T>::PixIndexSph(double theta, double phi) const
218{
219 if((theta > M_PI) || (theta < 0.)) return(-1);
220 if((phi < 0.) || (phi > 2*M_PI)) return(-1);
221 if (_partial) {
222 if ( (theta < _theta1) || (theta > _theta2) ||
[2621]223 (phi < _phi1) || (phi > _phi2) ) return _outofmapidx+theta/_dtheta*_outofmapnphi+phi/_dphi;
[2610]224 }
225 int_4 it = (theta-_theta1)/_dtheta;
226 int_4 jp = (phi-_phi1)/_dphi;
227 return (it*_pixels.SizeX()+jp);
228}
229
230template <class T>
231void SphereECP<T>::PixThetaPhi(int_4 k, double& theta, double& phi) const
232{
[2621]233 if ((_partial) && (k>=_outofmapidx)) {
234 theta = (((k-_outofmapidx) / _outofmapnphi)+0.5)*_dtheta;
235 phi = (((k-_outofmapidx) % _outofmapnphi)+0.5)*_dphi;;
[2610]236 return;
237 }
238 if((k < 0) || (k >= _pixels.Size()) )
239 throw RangeCheckError("SphereECP::PixThetaPhi() Pixel index out of range");
240
241 int_4 it = k / _pixels.SizeX();
242 int_4 jp = k % _pixels.SizeX();
[2621]243 theta = _theta1+(it+0.5)*_dtheta;
244 phi = _phi1*(jp+0.5)*_dphi;
[2610]245 return;
246}
247
248template <class T>
249T SphereECP<T>::SetPixels(T v)
250{
251 _pixels = v;
252 return v;
253}
254
255template <class T>
256double SphereECP<T>::PixSolAngle(int_4 k) const
257{
[2621]258 if ((_partial) && (k>=_outofmapidx)) {
259 double theta = (((k-_outofmapidx) / _outofmapnphi)+0.5)*_dtheta;
260 return (_dtheta*_dphi*sin(theta));
261 }
262 if((k < 0) || (k >= _pixels.Size()) )
263 throw RangeCheckError("SphereECP::PixSolAngle(int_4 k) Pixel index out of range");
264
[2610]265 int_4 it = k / _pixels.SizeX();
266 double theta = _theta1+it*_dtheta;
267 return (_dtheta*_dphi*sin(theta));
268}
269
270template <class T>
271int_4 SphereECP<T>::SizeIndex() const
272{
273 return _pixels.SizeY();
274}
275
276template <class T>
277void SphereECP<T>::Resize(int_4 m)
278{
279 if ( (m <= 0) || ( m == _pixels.SizeY()) ) {
280 cout << " SphereECP<T>::Resize(int_4 " << m << ") m<0 ou m=NTheta - Ne fait rien " << endl;
281 return;
282 }
283 int mphi = m;
284 if (_pixels.Size() > 0) mphi = m*_pixels.SizeX()/_pixels.SizeY();
285 cout << " SphereECP<T>::Resize(" << m
286 << ") -> _pixels.Resize(" << mphi << "," << m << ")" << endl;
287 sa_size_t sz[5] = {0,0,0,0,0};
288 sz[0] = mphi; sz[1] = m;
289 _pixels.ReSize(2,sz);
290 _outofmapidx = _pixels.Size()+659;
291 _dtheta = (_theta2-_theta1)/m;
292 _dphi = (_phi2-_phi1)/mphi;
[2621]293
294 _outofmapntet = M_PI/_dtheta;
295 _outofmapnphi = 2*M_PI/_dphi;
[2610]296 return;
297}
298
299template <class T>
300uint_4 SphereECP<T>::NbThetaSlices() const
301{
302 return _pixels.SizeY();
303}
304
305template <class T>
[2968]306r_8 SphereECP<T>::ThetaOfSlice(int_4 index) const
307{
308 if( (index < 0) || (index >= _pixels.SizeY()) )
309 throw RangeCheckError("SphereECP::ThetaOfSlice() theta index out of range");
310 return (_theta1 + (index+0.5)*_dtheta);
311
312}
313
314template <class T>
[2610]315void SphereECP<T>::GetThetaSlice(int_4 index,r_8& theta,
316 TVector<r_8>& phi, TVector<T>& value) const
317{
318 if( (index < 0) || (index >= _pixels.SizeY()) )
[2968]319 throw RangeCheckError("SphereECP::GetThetaSlice() index out of range");
[2610]320
[2621]321 theta = _theta1 + (index+0.5)*_dtheta;
[2610]322 int_4 nphit = 2.*M_PI/_dphi;
323 phi.ReSize(nphit);
324 value.ReSize(nphit);
325 int_4 ioff = _phi1/_dphi;
326 int_4 i;
327 for(i=0; i<ioff; i++) {
[2621]328 phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
[2610]329 value(i) = _outofmapval;
330 }
331 for(i=ioff; i<ioff+_pixels.SizeX(); i++) {
[2621]332 phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
[2610]333 value(i) = _pixels(i-ioff,index,0);
334 }
335 for(i=ioff+_pixels.SizeX(); i<nphit; i++) {
[2621]336 phi(i) = _phi1 + (i-ioff+0.5)*_dphi;
[2610]337 value(i) = _outofmapval;
338 }
339 return;
340}
341
342template <class T>
343void SphereECP<T>::GetThetaSlice(int_4 index, r_8& theta, r_8& phi0,
344 TVector<int_4>& pixidx, TVector<T>& value) const
345{
346 if( (index < 0) || (index >= _pixels.SizeY()) )
[2968]347 throw RangeCheckError("SphereECP::GetThetaSlice() index out of range");
[2610]348
[2621]349 theta = _theta1 + (index+0.5)*_dtheta;
[2610]350 int_4 ioff = _phi1/_dphi;
[2621]351 phi0 = _phi1 - (ioff-0.5)*_dphi;
[2610]352
353 int_4 nphit = 2.*M_PI/_dphi;
354 pixidx.ReSize(nphit);
355 value.ReSize(nphit);
356
357 int_4 i;
358 for(i=0; i<ioff; i++) {
[2621]359 pixidx(i) = _outofmapidx+theta/_dtheta*_outofmapnphi+phi0/_dphi+i;
[2610]360 value(i) = _outofmapval;
361 }
362 for(i=ioff; i<ioff+_pixels.SizeX(); i++) {
363 pixidx(i) = index*_pixels.SizeX()+(i-ioff);
364 value(i) = _pixels(i-ioff,index,0);
365 }
366 for(i=ioff+_pixels.SizeX(); i<nphit; i++) {
[2621]367 pixidx(i) = _outofmapidx+theta/_dtheta*_outofmapnphi+phi0/_dphi+i;
[2610]368 value(i) = _outofmapval;
369 }
370 return;
371
372}
373
374template <class T>
[2973]375void SphereECP<T>::Show(ostream& os) const
[2610]376{
[2973]377 PixelMap<T>::Show(os);
[2610]378 if (_partial)
379 os << "SphereECP<T>::Print() - Partial ECP Map NPhi=" << _pixels.SizeX()
[2620]380 << " x NTheta= " << _pixels.SizeY() << " SolidAngle=" << PixSolAngle() << "\n"
[2610]381 << "ThetaLimits= " << _theta1 << " .. " << _theta2
382 << " PhiLimits= " << _phi1 << " .. " << _phi2 << endl;
383 else
384 os << "SphereECP<T>::Print() - Full ECP Map NPhi=" << _pixels.SizeX()
385 << " x NTheta= " << _pixels.SizeY() << " SolidAngle=" << PixSolAngle() << endl;
[2973]386}
387
388template <class T>
389void SphereECP<T>::Print(ostream& os) const
390{
391 Show(os);
[2610]392 os << _pixels;
393}
394
395template <class T>
396SphereECP<T>& SphereECP<T>::Set(const SphereECP<T>& a)
397{
398 _pixels.Set(a._pixels);
399 _partial = a._partial;
400 _theta1 = a._theta1;
401 _theta2 = a._theta2;
402 _phi1 = a._phi1;
403 _phi2 = a._phi2;
404 _outofmapidx = a._outofmapidx;
[2621]405 _outofmapnphi = a._outofmapnphi;
406 _outofmapntet = a._outofmapntet;
[2610]407 _outofmappix = a._outofmappix;
408 _outofmapval = a._outofmapval;
409 _dtheta = a._dtheta;
410 _dphi = a._dphi;
411 return *this ;
412}
413
414template <class T>
415SphereECP<T>& SphereECP<T>::SetCst(T x)
416{
417 _pixels.SetCst(x);
418 return *this ;
419}
420
421template <class T>
422SphereECP<T>& SphereECP<T>::AddCst(T x)
423{
424 _pixels += x;
425 return *this ;
426}
427
428template <class T>
429SphereECP<T>& SphereECP<T>::MulCst(T x)
430{
431 _pixels *= x;
432 return *this ;
433}
434
435
436
[2882]437}// Fin du namespace
[2610]438
439
440#ifdef __CXX_PRAGMA_TEMPLATES__
441#pragma define_template SphereECP<int_4>
442#pragma define_template SphereECP<r_4>
443#pragma define_template SphereECP<r_8>
444#pragma define_template SphereECP< complex<r_4> >
445#pragma define_template SphereECP< complex<r_8> >
446#endif
447#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[2869]448namespace SOPHYA {
[2610]449template class SphereECP<int_4>;
450template class SphereECP<r_4>;
451template class SphereECP<r_8>;
452template class SphereECP< complex<r_4> >;
453template class SphereECP< complex<r_8> >;
[2869]454}
[2610]455#endif
456
Note: See TracBrowser for help on using the repository browser.