Changeset 470 in Sophya


Ignore:
Timestamp:
Oct 15, 1999, 5:43:30 PM (26 years ago)
Author:
ansari
Message:

versions templatees, NdataBlocks etc. 15-OCT-99-GLM

Location:
trunk/SophyaLib/Samba
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/Samba/circle.cc

    r262 r470  
    120120}
    121121
    122 UnitVector Circle::ConvCircleSphere(double psi) const
     122UnitVector Circle::ConvToSphere(double psi) const
    123123{
    124124  psi=mod(psi,pi2);
     
    157157{
    158158  psi=mod(psi,pi2);
    159   return ConvCircleSphere(psi).EPhi();
     159  return ConvToSphere(psi).EPhi();
    160160}
    161161
     
    163163{
    164164  psi=mod(psi,pi2);
    165   return ConvCircleSphere(psi).ETheta();
     165  return ConvToSphere(psi).ETheta();
    166166}
    167167
  • trunk/SophyaLib/Samba/circle.h

    r262 r470  
    77#include "unitvector.h"
    88#include "utilgeom.h"
     9#include "geometry.h"
    910
    10 class Circle
     11class Circle : public Geometry
    1112{
    1213 
     
    2728  void SetApertureAngle(const Circle&);
    2829 
    29   // psi contient les 4 valeurs des angles d'intersection. -1 si les cercles ne se coupent pas
     30  // psi contient les 4 valeurs des angles d intersection. -1 si les cercles ne se coupent pas
    3031  // voir la numerotation dans le .cc
    3132  bool Intersection(const Circle&, double* psi) const;
    3233
    3334  // donne le UnitVector correspondant a une position donnee sur le cercle
    34   UnitVector ConvCircleSphere(double psi) const;
     35  UnitVector ConvToSphere(double psi) const;
    3536
    3637  // donne le UnitVector correspondant la tangente au cercle en une position donnee sur le cercle
     
    4041  UnitVector EPhi(double psi) const;
    4142
    42   // donne l'autre vecteur tangent (orthogonal a EPhi)
     43  // donne l autre vecteur tangent (orthogonal a EPhi)
    4344  UnitVector ETheta(double psi) const;
    4445
    45    // donne l'angle de separation dans [0,2Pi] en une position donnee sur le cercle et EPhi
     46   // donne l angle de separation dans [0,2Pi] en une position donnee sur le cercle et EPhi
    4647  double SepAngleTanEPhi02PI(double psi) const;
    4748
  • trunk/SophyaLib/Samba/exclude

    r228 r470  
     1lambuilder.cc
  • trunk/SophyaLib/Samba/localmap.cc

    r276 r470  
    11#include "localmap.h"
     2#include "nbmath.h"
     3#include <complex>
     4#include "piocmplx.h"
     5
     6#include <string.h>
    27#include <iostream.h>
    3 #include "nbmath.h"
     8
     9#ifdef __CXX_PRAGMA_TEMPLATES__
     10#pragma define_template LocalMap<double>
     11#pragma define_template LocalMap<float>
     12#pragma define_template LocalMap< complex<double> >
     13#pragma define_template LocalMap< complex<float> >
     14#pragma define_template FIO_LocalMap<double>
     15#pragma define_template FIO_LocalMap<float>
     16#pragma define_template FIO_LocalMap< complex<float> >
     17#pragma define_template FIO_LocalMap< complex<double> >
     18#endif
     19#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
     20template class LocalMap<double>;
     21template class LocalMap<float>;
     22template class LocalMap< complex<double> >;
     23template class LocalMap< complex<float> >;
     24template class FIO_LocalMap<double>;
     25template class FIO_LocalMap<float>;
     26template class FIO_LocalMap< complex<float> >;
     27template class FIO_LocalMap< complex<double> >;
     28#endif
     29
    430//*****************************************************************************
    531//++
     
    5278//--
    5379//++
    54 
    55 LocalMap::LocalMap()
    56 
    57 //--
    58 
    59 {InitNul();}
    60 
    61 //++
    62 
    63 LocalMap::LocalMap(int_4 nx, int_4 ny) : mSzX_(nx), mSzY_(ny)
    64 
     80template<class T>
     81LocalMap<T>::LocalMap()
     82//
     83// Constructeur par defaut
    6584//--
    6685{
    6786  InitNul();
    68   mNPix_=nx*ny;
    69   mPix_ = new r_8[mNPix_];
    70 }
    71 
    72 
    73 //++
    74 // Titre        Destructeur
    75 //--
    76 //++
    77 LocalMap::~LocalMap()
    78 
    79 //--
    80 {
    81   Clear();
    82 }
    83 
    84 
    85 
    86 void        LocalMap::WriteSelf(POutPersist& s) const
    87 {
    88   char strg[256];
    89   if (mInfo_) {sprintf(strg, "LocalMap: NPixX=%6d  NPixY=%9d HasInfo",  mSzX_, mSzY_);} else  {
    90     sprintf(strg, "LocalMap: NPixX=%6d  NPixY=%9d ",  mSzX_, mSzY_);
    91   }         
    92   s.PutLine(strg);
    93   if (mInfo_)  s << (*mInfo_);
    94   s.PutI4(mSzX_);
    95   s.PutI4(mSzY_);
    96   s.PutI4(mNPix_);
    97   s.PutI4(x0_);
    98   s.PutI4(y0_);
    99   s.PutI4(originFlag_);
    100   s.PutI4(SzFlag_);
    101   s.PutR4(cos_angle_);
    102   s.PutR4(sin_angle_);
    103   s.PutR8(theta0_);
    104   s.PutR8( phi0_);
    105   s.PutR8( tgAngleX_);
    106   s.PutR8(tgAngleY_);
    107   s.PutR8s(mPix_, mNPix_);
    108 }
    109 void        LocalMap::ReadSelf(PInPersist& s)
    110 {
    111   Clear();
    112   char strg[256];
    113   s.GetLine(strg, 255);
    114 // Pour savoir s'il y avait un DVList Info associe
    115   bool hadinfo = false;
    116   if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo = true;
    117   if (hadinfo) {    // Lecture eventuelle du DVList Info
    118     if (mInfo_ == NULL)  mInfo_ = new DVList;
    119     s >> (*mInfo_);
    120   }
    121   s.GetI4(mSzX_);
    122   s.GetI4(mSzY_);
    123   s.GetI4(mNPix_);
    124   s.GetI4(x0_);
    125   s.GetI4(y0_);
    126   s.GetI4(originFlag_);
    127   s.GetI4(SzFlag_);
    128   s.GetR4(cos_angle_);
    129   s.GetR4(sin_angle_);
    130   s.GetR8(theta0_);
    131   s.GetR8( phi0_);
    132   s.GetR8( tgAngleX_);
    133   s.GetR8(tgAngleY_);
    134   mPix_ = new r_8[mNPix_+1];
    135   s.GetR8s(mPix_, mNPix_);
     87}
     88
     89//++
     90template<class T>
     91LocalMap<T>::LocalMap(int_4 nx, int_4 ny) : nSzX_(nx), nSzY_(ny)
     92//
     93// Constructeur
     94//--
     95{
     96  InitNul();
     97  nPix_= nx*ny;
     98  pixels_.ReSize(nPix_);
     99  pixels_.Reset();
     100}
     101
     102//++
     103template<class T>
     104LocalMap<T>::LocalMap(const LocalMap<T>& lm)
     105//
     106// Constructeur de recopie
     107//--
     108{
     109  cout<<" LocalMap:: Appel du constructeur de recopie " << endl;
     110
     111  if(lm.mInfo_) mInfo_= new DVList(*lm.mInfo_);
     112  nSzX_= lm.nSzX_;
     113  nSzY_= lm.nSzY_;
     114  nPix_= lm.nPix_;
     115  originFlag_= lm.originFlag_;
     116  extensFlag_= lm.extensFlag_;
     117  x0_= lm.x0_;
     118  y0_= lm.y0_;
     119  theta0_= lm.theta0_;
     120  phi0_= lm.phi0_;
     121  angle_= lm.angle_;
     122  cos_angle_= lm.cos_angle_;
     123  sin_angle_= lm.sin_angle_;
     124  angleX_= lm.angleX_;
     125  angleY_= lm.angleY_;
     126  tgAngleX_= lm.tgAngleX_;
     127  tgAngleY_= lm.tgAngleY_;
     128  pixels_= lm.pixels_;
     129}
     130
     131//++
     132template<class T>
     133LocalMap<T>::~LocalMap()
     134//
     135// Destructeur
     136//--
     137{
     138  InitNul();
     139}
     140
     141//++
     142template<class T>
     143void LocalMap<T>::InitNul()
     144//
     145// Initialise à zéro certaines variables internes
     146//--
     147{
     148  originFlag_= false;
     149  extensFlag_= false;
     150  cos_angle_= 1.0;
     151  sin_angle_= 0.0;
     152  pixels_.Reset();
     153}
     154
     155//++
     156template<class T>
     157void LocalMap<T>::ReSize(int_4 nx, int_4 ny)
     158//
     159// Redimensionne l'espace de stokage des pixels
     160//--
     161{
     162  InitNul();
     163  nSzX_ = nx;
     164  nSzY_ = ny;
     165  nPix_= nx*ny;
     166  pixels_.ReSize(nPix_);
     167  pixels_.Reset();
    136168}
    137169
     
    142174
    143175//++
    144 int_4 LocalMap::NbPixels() const
    145 
     176template<class T>
     177int_4 LocalMap<T>::NbPixels() const
     178//
    146179//    Retourne le nombre de pixels du découpage
    147180//--
    148181{
    149   return(mNPix_);
    150 }
    151 
    152 //++
    153 r_8& LocalMap::PixVal(int_4 k)
    154 
     182  return(nPix_);
     183}
     184
     185//++
     186template<class T>
     187T& LocalMap<T>::PixVal(int_4 k)
     188//
    155189//    Retourne la valeur du contenu du pixel d'indice k
    156190//--
    157191{
    158   if ( (k<0) || (k >= mNPix_) ) {
    159     cout << " LocalMap::PIxVal : exceptions  a mettre en place" <<endl;
    160     //  THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
    161   THROW(rangeCheckErr);
    162 
    163     //throw "LocalMap::PIxVal Pixel index out of range";
    164   }
    165   //return (*(pixel_->Data()+k));
    166   return(mPix_[k]);
    167 }
    168 
    169 //++
    170 
    171 r_8 const& LocalMap::PixVal(int_4 k) const
    172 
     192  if((k < 0) || (k >= nPix_))
     193    {
     194      cout << " LocalMap::PIxVal : exceptions  a mettre en place" <<endl;
     195      //  THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
     196      THROW(rangeCheckErr);
     197      //throw "LocalMap::PIxVal Pixel index out of range";
     198    }
     199  return(pixels_(k));
     200}
     201
     202//++
     203
     204template<class T>
     205T const& LocalMap<T>::PixVal(int_4 k) const
     206//
    173207//    Retourne la valeur du contenu du pixel d'indice k
    174208//--
    175209{
    176   if ( (k<0) || (k >= mNPix_) ) {
    177     cout << " LocalMap::PIxVal : exceptions  a mettre en place" <<endl;
    178   //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
    179 
    180     throw "LocalMap::PIxVal Pixel index out of range";
    181   }
    182   //return *(pixel_->Data()+k);
    183   return(mPix_[k]);
    184 }
    185 
    186 //++
    187 int_4 LocalMap::PixIndexSph(float theta, float phi) const
    188 
     210  if((k < 0) || (k >= nPix_))
     211    {
     212      cout << " LocalMap::PIxVal : exceptions  a mettre en place" <<endl;
     213      //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
     214     
     215      throw "LocalMap::PIxVal Pixel index out of range";
     216    }
     217  return *(pixels_.Data()+k);
     218}
     219
     220//++
     221template<class T>
     222int_4 LocalMap<T>::PixIndexSph(float theta, float phi) const
     223//
    189224//    Retourne l'indice du pixel vers lequel pointe une direction définie par
    190225//    ses coordonnées sphériques
     
    192227{
    193228  int i,j;
    194   if (!(originFlag_==1) || !(SzFlag_==1) ) {
    195     cout << " LocalMap: correspondance carte-sphere non etablie" << endl;
    196     exit(0);
    197   }
    198   // theta et phi en coordonnees relatives (on se ramene a une situation
    199   // par rapport au plan de reference)
     229  if(!(originFlag_) || !(extensFlag_))
     230    {
     231      cout << " LocalMap: correspondance carte-sphere non etablie" << endl;
     232      exit(0);
     233    }
     234
     235  // theta et phi en coordonnees relatives (on se ramene a une situation par rapport au plan de reference)
    200236  float theta_aux=theta;
    201237  float phi_aux=phi;
    202238  UserToReference(theta_aux, phi_aux);
     239
    203240  // coordonnees dans le plan local en unites de pixels
    204241  float x,y;
    205   AngleProjToPix(theta_aux, phi_aux, x,y);
    206 
    207   float xmin=-x0_-0.5;
    208   float xmax=xmin+mSzX_;
    209   if( (x >  xmax) || (x < xmin ) ) return(-1);
    210   float xcurrent=xmin;
    211   for( i=0; i < mSzX_; i++ ) {
    212     xcurrent += 1.;
    213     if( x < xcurrent ) break;
    214   }
    215   float ymin=-y0_-0.5;
    216   float ymax=ymin+mSzY_;
    217   if( (y >  ymax) || (y < ymin ) ) return(-1);
    218   float ycurrent=ymin;
    219   for( j=0; j < mSzY_; j++ ) {
    220     ycurrent += 1.;
    221     if( y < ycurrent ) break;
    222   }
    223 
    224 
    225   return (j*mSzX_+i);
    226 }
    227 
    228 //++
    229 void  LocalMap::PixThetaPhi(int_4 k, float& theta, float& phi) const
    230 
     242  AngleProjToPix(theta_aux, phi_aux, x, y);
     243
     244  float xmin= -x0_-0.5;
     245  float xmax= xmin+nSzX_;
     246  if((x >  xmax) || (x < xmin)) return(-1);
     247  float xcurrent= xmin;
     248  for(i = 0; i < nSzX_; i++ )
     249    {
     250      xcurrent += 1.;
     251      if( x < xcurrent ) break;
     252    }
     253  float ymin= -y0_-0.5;
     254  float ymax= ymin+nSzY_;
     255  if((y >  ymax) || (y < ymin)) return(-1);
     256  float ycurrent= ymin;
     257  for(j = 0; j < nSzY_; j++ )
     258    {
     259      ycurrent += 1.;
     260      if( y < ycurrent ) break;
     261    }
     262  return (j*nSzX_+i);
     263}
     264
     265//++
     266template<class T>
     267void LocalMap<T>::PixThetaPhi(int_4 k, float& theta, float& phi) const
     268//
    231269//    Retourne les coordonnées (theta,phi) du milieu du pixel d'indice k
    232270//--
    233271{
    234   if (!(originFlag_==1) || !(SzFlag_==1) ) {
    235     cout << " LocalMap: correspondance carte-sphere non etablie" << endl;
    236     exit(0);
    237   }
     272  if(!(originFlag_) || !(extensFlag_))
     273    {
     274      cout << " LocalMap: correspondance carte-sphere non etablie" << endl;
     275      exit(0);
     276    }
     277
    238278  int i,j;
    239279  Getij(k,i,j);
    240   float X=float(i-x0_);
    241   float Y=float(j-y0_);
     280
     281  float X= float(i-x0_);
     282  float Y= float(j-y0_);
    242283  // situation de ce pixel dans le plan de reference
    243   float x=X*cos_angle_-Y*sin_angle_;
    244   float y=X*sin_angle_+Y* cos_angle_;
     284  float x= X*cos_angle_-Y*sin_angle_;
     285  float y= X*sin_angle_+Y* cos_angle_;
    245286  // projection sur la sphere
    246   PixProjToAngle(x, y,theta, phi);
     287  PixProjToAngle(x, y, theta, phi);
    247288  // retour au plan utilisateur
    248289  ReferenceToUser(theta, phi);
     
    250291 
    251292//++
    252 r_8    LocalMap::PixSolAngle(int_4 k) const
    253 //    Pixel Solid angle  (steradians)
    254 //    All the pixels have not necessarly the same size in (theta, phi)
    255 //    because of the projection scheme which is not yet fixed.
    256 //   
     293template<class T>
     294r_8 LocalMap<T>::PixSolAngle(int_4 k) const
     295//
     296// Pixel Solid angle  (steradians)
     297// All the pixels have not necessarly the same size in (theta, phi)
     298// because of the projection scheme which is not yet fixed.   
    257299//--
    258300{
    259301  int i,j;
    260302  Getij(k,i,j);
    261   float X=float(i-x0_);
    262   float Y=float(j-y0_);
    263   float XR=X+float(i)*0.5;
    264   float XL=X-float(i)*0.5;
    265   float YU=Y+float(j)*0.5;
    266   float YL=Y-float(j)*0.5;
     303  float X= float(i-x0_);
     304  float Y= float(j-y0_);
     305  float XR= X+float(i)*0.5;
     306  float XL= X-float(i)*0.5;
     307  float YU= Y+float(j)*0.5;
     308  float YL= Y-float(j)*0.5;
    267309  // situation  dans le plan de reference
    268   float x0=XL*cos_angle_-YL*sin_angle_;
    269   float y0=XL*sin_angle_+YL* cos_angle_;
    270   float xa=XR*cos_angle_-YL*sin_angle_;
    271   float ya=XR*sin_angle_+YL* cos_angle_;
    272   float xb=XL*cos_angle_-YU*sin_angle_;
    273   float yb=XL*sin_angle_+YU* cos_angle_;
     310  float x0= XL*cos_angle_-YL*sin_angle_;
     311  float y0= XL*sin_angle_+YL*cos_angle_;
     312  float xa= XR*cos_angle_-YL*sin_angle_;
     313  float ya= XR*sin_angle_+YL*cos_angle_;
     314  float xb= XL*cos_angle_-YU*sin_angle_;
     315  float yb= XL*sin_angle_+YU*cos_angle_;
    274316  // projection sur la sphere
    275317  float tet0,phi0,teta,phia,tetb,phib;
    276   PixProjToAngle(x0, y0,tet0, phi0);
    277   PixProjToAngle(xa, ya,teta, phia);
    278   PixProjToAngle(xb, yb,tetb, phib);
     318  PixProjToAngle(x0, y0, tet0, phi0);
     319  PixProjToAngle(xa, ya, teta, phia);
     320  PixProjToAngle(xb, yb, tetb, phib);
    279321  // angle solide
    280   float sol=fabs((xa-x0)*(yb-y0)-(xb-x0)*(ya-y0));
     322  float sol= fabs((xa-x0)*(yb-y0)-(xb-x0)*(ya-y0));
    281323  return r_8(sol);
    282324}
    283325
    284 
    285 //++
    286 void  LocalMap::SetOrigin(float theta0, float phi0, float angle)
    287 
    288 //  
    289 //--
    290 {
    291   theta0_=theta0;
    292   phi0_=phi0;
    293   x0_=mSzX_/2;
    294   y0_=mSzY_/2;
    295   angle=angle*Pi/180.;
    296   cos_angle_=cos(angle);
    297   sin_angle_=sin(angle);
    298   originFlag_ =1;
    299 }
    300 
     326//++
     327template<class T>
     328void  LocalMap<T>::SetOrigin(float theta0, float phi0, float angle)
     329//
     330// Fixe la repere de reference ( angles en degres)
     331//--
     332{
     333  theta0_= (double)theta0;
     334  phi0_  = (double)phi0;
     335  angle_ = (double)angle;
     336  x0_= nSzX_/2;
     337  y0_= nSzY_/2;
     338  cos_angle_= cosdf(angle);
     339  sin_angle_= sindf(angle);
     340  originFlag_= true;
     341  cout << " LocalMap:: set origin 1 done" << endl;
     342}
    301343 
    302344//++
    303 void  LocalMap::SetOrigin(float theta0, float phi0, int_4 x0, int_4 y0, float angle)
    304 
    305 //   
    306 //--
    307 {
    308   theta0_=theta0;
    309   phi0_=phi0;
    310   x0_=x0;
    311   y0_=y0;
    312   angle=angle*Pi/180.;
    313   cos_angle_=cos(angle);
    314   sin_angle_=sin(angle);
    315   originFlag_ =1;
     345template<class T>
     346void  LocalMap<T>::SetOrigin(float theta0, float phi0, int_4 x0, int_4 y0, float angle)
     347//
     348// Fixe le repere de reference (angles en degres) 
     349//--
     350{
     351  theta0_= (double)theta0;
     352  phi0_  = (double)phi0;
     353  angle_ = (double)angle;
     354  x0_= x0;
     355  y0_= y0;
     356  cos_angle_= cosdf(angle);
     357  sin_angle_= sindf(angle);
     358  originFlag_= true;
     359  cout << " LocalMap:: set origin 2 done" << endl;
    316360}
    317361
    318362//++
    319 void  LocalMap::SetSize(float angleX, float angleY)
    320 
    321 //   
    322 //--
    323 {
    324  tgAngleX_=r_8(tan(angleX*Pi/360.));
    325  tgAngleY_=r_8(tan(angleY*Pi/360.));
    326  SzFlag_=1;
    327 }
    328 //++
    329 void  LocalMap::Project(SphericalMap& sphere) const
    330 
    331 //    Projection to spherical map   
    332 //--
    333 {
    334   for (int m=0; m<mNPix_; m++) {
    335     float theta,phi;
    336     PixThetaPhi(m,theta,phi);
    337     sphere(theta,phi)=mPix_[m];
    338     //    cout << "theta " << theta << " phi " << phi << " valeur " << sphere(theta,phi)<< endl;
    339   }
    340 }
    341 
    342 void LocalMap::InitNul()
    343 //
    344 //    initialise à zéro certaines variables internes
    345 {
    346 originFlag_=0;
    347 SzFlag_=0;
    348 cos_angle_=1.;
    349 sin_angle_=0.;
    350 mPix_=NULL;
    351 }
    352 
    353 void LocalMap::Clear()
    354 //
    355 //   
    356 {
    357   if (mPix_)   delete[] mPix_;
    358 }
    359 
    360 void    LocalMap::Getij(int k, int& i, int& j) const
    361 {
    362   i=(k+1)%mSzX_-1;
    363   if (i==-1) i=mSzX_-1;
    364   j=(k-i+2)/mSzX_;
    365 }
    366 
    367 void  LocalMap::ReferenceToUser(float &theta, float &phi) const
    368 
    369 //       
    370 {
    371   if (theta > (r_4)Pi || theta < 0.  || phi<0. || phi >=2* (r_4)Pi ) {
    372     //cout << " LocalMap::ReferenceToUser : exceptions  a mettre en place" <<endl;
    373   //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
    374 
    375     throw "LocalMap::ReferenceToUser (theta,phi) out of range";
    376   }
     363template<class T>
     364void LocalMap<T>::SetSize(float angleX, float angleY)
     365//
     366// Fixe l'extension de la carte (angles en degres)
     367//--
     368{
     369  angleX_= (double)angleX;
     370  angleY_= (double)angleY;
     371
     372  //tgAngleX_= T(tan(angleX*Pi/360.));
     373  //tgAngleY_= T(tan(angleY*Pi/360.));
     374
     375
     376  // tangente de la moitie de l'ouverture angulaire totale
     377  tgAngleX_= tand(0.5*angleX_);
     378  tgAngleY_= tand(0.5*angleY_);
     379
     380  extensFlag_= true;
     381  cout << " LocalMap:: set extension done" << endl;
     382}
     383
     384//++
     385template<class T>
     386void LocalMap<T>::Project(SphericalMap<T>& sphere) const
     387//
     388// Projection to spherical map   
     389//--
     390{
     391  for(int m = 0; m < nPix_; m++)
     392    {
     393      float theta,phi;
     394      PixThetaPhi(m,theta,phi);
     395      sphere(theta,phi)= pixels_(m);
     396      // cout << "theta " << theta << " phi " << phi << " valeur " << sphere(theta,phi)<< endl;
     397    }
     398}
     399
     400//++
     401template<class T>
     402void LocalMap<T>::Getij(int k, int& i, int& j) const
     403//
     404//--
     405{
     406  i= (k+1)%nSzX_-1;
     407  if(i == -1) i= nSzX_-1;
     408  j= (k-i+2)/nSzX_;
     409}
     410
     411//++
     412template<class T>
     413void  LocalMap<T>::ReferenceToUser(float &theta, float &phi) const
     414//
     415// --     
     416{
     417  if(theta > (r_4)Pi || theta < 0.  || phi < 0. || phi >= 2*(r_4)Pi)
     418    {
     419      //cout << " LocalMap::ReferenceToUser : exceptions  a mettre en place" <<endl;
     420      //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
     421      throw "LocalMap::ReferenceToUser (theta,phi) out of range";
     422    }
     423
    377424  //cout << " ReferenceToUser entree, t= " << theta << " phi= " << phi << endl;
    378   theta=(r_4)theta0_+theta-(r_4)Pi*0.5;
    379   if (theta<0.) {
    380     theta=-theta;
    381     phi+=(r_4)Pi;
    382   } else
    383     if (theta>(r_4)Pi) {
    384       theta=2.*(r_4)Pi-theta;
    385       phi+=(r_4)Pi;
     425  theta= (r_4)theta0_*Pi/180.+theta-(r_4)Pi*0.5;
     426  if(theta < 0.)
     427    {
     428      theta= -theta;
     429      phi += (r_4)Pi;
    386430    }
    387  
    388   phi=(r_4)phi0_+phi;
    389   while (phi>=2.*(r_4)Pi) phi-=2.*(r_4)Pi;
    390   if (theta > (r_4)Pi || theta < 0.  || phi<0. || phi >=2* (r_4)Pi ) {
    391     cout <<  " LocalMap::ReferenceToUser : erreur bizarre dans le transfert a la carte utilisateur " << endl;
    392     cout << " theta= " << theta << " phi= " << phi << endl;
    393     exit(0);
    394   }
     431  else
     432    {
     433      if(theta > (r_4)Pi)
     434        {
     435          theta= 2.*(r_4)Pi-theta;
     436          phi += (r_4)Pi;
     437        }
     438    }
     439
     440  phi= (r_4)phi0_*Pi/180.+phi;
     441  while(phi >= 2.*(r_4)Pi) phi-=2.*(r_4)Pi;
     442
     443  if(theta > (r_4)Pi || theta < 0.  || phi < 0. || phi >= 2*(r_4)Pi)
     444    {
     445      cout <<  " LocalMap::ReferenceToUser : erreur bizarre dans le transfert a la carte utilisateur " << endl;
     446      cout << " theta= " << theta << " phi= " << phi << endl;
     447      exit(0);
     448    }
    395449  //cout << " ReferenceToUser sortie, t= " << theta << " phi= " << phi << endl;
    396450}
    397451
    398 void  LocalMap::UserToReference(float &theta, float &phi) const
    399 
    400 //       
    401 {
    402   if (theta > (r_4)Pi || theta < 0.  || phi<0. || phi >=2* (r_4)Pi ) {
    403     cout << " LocalMap::UserToReference : exceptions  a mettre en place" <<endl;
    404   //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
    405 
    406     throw "LocalMap::UserToReference (theta,phi) out of range";
    407   }
    408   float phi1=phi-(r_4)phi0_;
    409   if (phi1<0.) phi1+=2.*(r_4)Pi;
    410 
    411   float theta1=theta-(r_4)theta0_+(r_4)Pi*0.5;
    412   if (theta1<0.) {
    413     theta=-theta1;
    414     phi1+=(r_4)Pi;
    415   } else
    416     if (theta1>(r_4)Pi) {
    417       theta=2.*(r_4)Pi-theta1;
    418       phi1+=(r_4)Pi;
    419     }
    420   while (phi1>=2.*(r_4)Pi) phi1-=2.*(r_4)Pi;
    421   phi=phi1;
    422   if (theta > (r_4)Pi || theta < 0.  || phi<0. || phi >=2* (r_4)Pi ) {
    423     cout <<  " LocalMap::UserToReference : erreur bizarre dans le transfert a la carte de reference " << endl;
    424     cout << " theta= " << theta << " phi= " << phi << endl;
    425     exit(0);
    426   }
    427 }
    428 
    429 void LocalMap::PixProjToAngle(float x, float y,float &theta, float &phi) const {
    430 
    431 // (x,y) representent les coordonnees en unites de pixels d'un point DANS
    432 // LE PLAN DE REFERENCE. On recupere (theta,phi) par rapport au repere "absolu"
    433 // theta=pi/2,phi=0.
    434 
    435 theta=(r_4)Pi*0.5-atan(2*y* tgAngleY_/(float) mSzY_);
    436 phi=atan2(2*x* tgAngleX_,(float) mSzX_);
    437 if( phi< 0. ) phi+= DeuxPi;
    438 }
    439 
    440 void  LocalMap::AngleProjToPix(float theta, float phi, float& x, float& y) const {
    441 
     452//++
     453template<class T>
     454void  LocalMap<T>::UserToReference(float &theta, float &phi) const
     455//
     456// --     
     457{
     458  if(theta > (r_4)Pi || theta < 0.  || phi<0. || phi >= 2*(r_4)Pi )
     459    {
     460      cout << " LocalMap::UserToReference : exceptions  a mettre en place" <<endl;
     461      //    THROW(out_of_range("LocalMap::PIxVal Pixel index out of range"));
     462      throw "LocalMap::UserToReference (theta,phi) out of range";
     463    }
     464
     465  float phi1=phi-(r_4)phi0_*Pi/180.;
     466  if(phi1 < 0.) phi1+=2.*(r_4)Pi;
     467
     468  float theta1= theta-(r_4)theta0_*Pi/180.+(r_4)Pi*0.5;
     469  if(theta1 < 0.)
     470    {
     471      theta= -theta1;
     472      phi1+= (r_4)Pi;
     473    }
     474  else
     475    {
     476      if(theta1 > (r_4)Pi)
     477        {
     478          theta= 2.*(r_4)Pi-theta1;
     479          phi1+= (r_4)Pi;
     480        }
     481    }
     482
     483  while(phi1 >= 2.*(r_4)Pi) phi1-=2.*(r_4)Pi;
     484  phi= phi1;
     485  if(theta > (r_4)Pi || theta < 0.  || phi < 0. || phi >= 2*(r_4)Pi )
     486    {
     487      cout <<  " LocalMap::UserToReference : erreur bizarre dans le transfert a la carte de reference " << endl;
     488      cout << " theta= " << theta << " phi= " << phi << endl;
     489      exit(0);
     490    }
     491}
     492
     493//++
     494template<class T>
     495void LocalMap<T>::PixProjToAngle(float x, float y, float& theta, float& phi) const
     496//
     497// (x,y) representent les coordonnees en unites de pixels d'un point DANS  LE PLAN DE REFERENCE.
     498// On recupere (theta,phi) par rapport au repere "absolu" theta=pi/2 et phi=0.
     499//--
     500{
     501  theta= (r_4)Pi*0.5-atan(2*y*tgAngleY_/(float)nSzY_);
     502  phi= atan2(2*x*tgAngleX_,(float)nSzX_);
     503  if(phi < 0.) phi += DeuxPi;
     504}
     505
     506//++
     507template<class T>
     508void LocalMap<T>::AngleProjToPix(float theta, float phi, float& x, float& y) const
     509//
    442510// (theta,phi) par rapport au repere "absolu" theta=pi/2,phi=0. On recupere
    443511// (i,j)  DANS LE PLAN DE REFERENCE.
    444   if (phi>=(r_4)Pi) phi-= DeuxPi;
     512//--
     513{
     514  if(phi >= (r_4)Pi) phi-= DeuxPi;
    445515  //  y=0.5*mSzY_*cot(theta)/tgAngleY_;  $CHECK-REZA-04/99$
    446   y=0.5*mSzY_/tan(theta)/tgAngleY_;  // ? cot = 1/tan ? 
    447   x=0.5*mSzX_*tan(phi)/tgAngleX_;
    448 }
    449 
    450 
    451 
    452 
    453 
     516  y= 0.5*nSzY_/tan(theta)/tgAngleY_;  // ? cot = 1/tan ? 
     517  x= 0.5*nSzX_*tan(phi)/tgAngleX_;
     518}
     519
     520template<class T>
     521void LocalMap<T>::print(ostream& os) const
     522{
     523  os<<" SzX= "<<nSzX_<<", SzY= "<<nSzY_<<", NPix= "<<nPix_<<endl;
     524  if(LocalMap_isDone())
     525    {
     526      os<<" theta0= "<<theta0_<<", phi0= "<<phi0_<<", angle= "<<angle_<<endl;
     527      os<<" x0= "<<x0_<<", y0= "<<y0_<<endl;
     528      os<<" cos= "<<cos_angle_<<", & sin= "<<sin_angle_<<endl;
     529      os<<" angleX= "<<angleX_<<", angleY= "<<angleY_<<endl;
     530      os<<" tg(angleX)= "<<tgAngleX_<<", tg(angleY)= "<<tgAngleY_<<endl;
     531    }
     532
     533  os << " contenu de pixels : ";
     534  for(int i=0; i < nPix_; i++)
     535    {
     536      if(i%5 == 0) os << endl;
     537      os <<  pixels_(i) <<", ";
     538    }
     539  os << endl;
     540}
     541
     542//*******************************************************************
     543// class FIO_LocalMap<T>
     544//  Les objets delegues pour la gestion de persistance
     545//*******************************************************************
     546
     547template <class T>
     548FIO_LocalMap<T>::FIO_LocalMap()
     549{
     550  dobj= new LocalMap<T>;
     551  ownobj= true;
     552}
     553
     554template <class T>
     555FIO_LocalMap<T>::FIO_LocalMap(string const& filename)
     556{
     557  dobj= new LocalMap<T>;
     558  ownobj= true;
     559  Read(filename);
     560}
     561
     562template <class T>
     563FIO_LocalMap<T>::FIO_LocalMap(const LocalMap<T>& obj)
     564{
     565  dobj= new LocalMap<T>(obj);
     566  ownobj= true;
     567}
     568
     569template <class T>
     570FIO_LocalMap<T>::FIO_LocalMap(LocalMap<T>* obj)
     571{
     572  dobj= obj;
     573  ownobj= false;
     574}
     575
     576template <class T>
     577FIO_LocalMap<T>::~FIO_LocalMap()
     578{
     579  if (ownobj && dobj) delete dobj;
     580}
     581
     582template <class T>
     583AnyDataObj* FIO_LocalMap<T>::DataObj()
     584{
     585  return(dobj);
     586}
     587
     588template <class T>
     589void FIO_LocalMap<T>::ReadSelf(PInPersist& is)
     590{
     591  cout << " FIO_LocalMap:: ReadSelf " << endl;
     592
     593  if(dobj == NULL)
     594    {
     595      dobj= new LocalMap<T>;
     596    }
     597
     598  // Pour savoir s'il y avait un DVList Info associe
     599  char strg[256];
     600  is.GetLine(strg, 255);
     601  bool hadinfo= false;
     602  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
     603  if(hadinfo)
     604    {    // Lecture eventuelle du DVList Info
     605      is >> dobj->Info();
     606    }
     607
     608  int_4 nSzX;
     609  is.GetI4(nSzX);
     610  dobj->setSize_x(nSzX);
     611
     612  int_4 nSzY;
     613  is.GetI4(nSzY);
     614  dobj->setSize_y(nSzY);
     615
     616  int_4 nPix;
     617  is.GetI4(nPix);
     618  dobj->setNbPixels(nPix);
     619
     620  string ss("local mapping is done");
     621  string sso;
     622  is.GetStr(sso);
     623  if(sso == ss)
     624    {
     625      cout<<" ReadSelf:: local mapping"<<endl;
     626      int_4 x0, y0;
     627      float theta, phi, angle;
     628      is.GetI4(x0);
     629      is.GetI4(y0);
     630      is.GetR4(theta);
     631      is.GetR4(phi);
     632      is.GetR4(angle);
     633      dobj->SetOrigin(theta, phi, x0, y0, angle);
     634
     635      float angleX, angleY;
     636      is.GetR4(angleX);
     637      is.GetR4(angleY);
     638      dobj->SetSize(angleX, angleY);
     639    }
     640
     641  T* pixels= new T[nPix];
     642  PIOSReadArray(is, pixels, nPix);
     643  dobj->setDataBlock(pixels, nPix);
     644  delete [] pixels;
     645}
     646
     647template <class T>
     648void FIO_LocalMap<T>::WriteSelf(POutPersist& os) const
     649{
     650  cout << " FIO_LocalMap:: WriteSelf " << endl;
     651
     652  if(dobj == NULL)
     653    {
     654      cout << " WriteSelf:: dobj= null " << endl;
     655      return;
     656    }
     657
     658  char strg[256];
     659  int_4 nSzX= dobj->Size_x();
     660  int_4 nSzY= dobj->Size_y();
     661  int_4 nPix= dobj->NbPixels();
     662 
     663  if(dobj->ptrInfo())
     664    {
     665      sprintf(strg,"LocalMap: NPixX=%6d  NPixY=%9d HasInfo",nSzX,nSzY);
     666      os.PutLine(strg);
     667      os << dobj->Info();
     668    }
     669  else
     670    {
     671      sprintf(strg,"LocalMap: NPixX=%6d  NPixY=%9d ",nSzX,nSzY);
     672      os.PutLine(strg); 
     673    }
     674
     675  os.PutI4(nSzX);
     676  os.PutI4(nSzY);
     677  os.PutI4(nPix);
     678
     679  if(dobj->LocalMap_isDone())
     680    {
     681      string ss("local mapping is done");
     682      os.PutStr(ss);
     683      int_4 x0, y0;
     684      float theta, phi, angle;
     685      dobj->Origin(theta, phi, x0, y0, angle);
     686      os.PutI4(x0);
     687      os.PutI4(y0);
     688      os.PutR4(theta);
     689      os.PutR4(phi);
     690      os.PutR4(angle);
     691
     692      float angleX, angleY;
     693      dobj->Aperture(angleX, angleY);
     694      os.PutR4(angleX);
     695      os.PutR4(angleY);
     696    }
     697  else
     698    {
     699      string ss("no local mapping");
     700      os.PutStr(ss);
     701    }
     702
     703  PIOSWriteArray(os,(dobj->getDataBlock())->Data(), nPix);
     704}
     705
  • trunk/SophyaLib/Samba/localmap.h

    r228 r470  
    44#include "pixelmap.h"
    55#include "sphericalmap.h"
     6#include "ndatablock.h"
     7
     8#include "anydataobj.h"
     9#include "ppersist.h"
    610
    711// A local map of a region of the sky, in cartesian coordinates.
     
    1317//    indice de colonne et j indice de ligne. La carte est supposee resider
    1418//    dans un plan tangent, dont le point de tangence est repere (x0,y0) dans
    15 //    la carte et (theta0, phi0) sur la sphere celeste. L'extension de la
     19//    la carte et (theta0, phi0) sur la sphere celeste. L extension de la
    1620//    carte est definie par les valeurs de deux angles couverts respectivement
    1721//    par la totalite des pixels en x de la carte et la totalite des pixels
    1822//    en y. (SetSize()).
    1923//    On considere un "plan de reference" : plan tangent a la sphere celeste
    20 //    aux angles theta=Pi/2 et phi=0. Dans ce plan L'origine des coordonnees
    21 //    est le point de tangence. L'axe Ox est la tangente parallele a
    22 //    l'equateur, dirige vers les phi croissants, l'axe Oy est parallele
     24//    aux angles theta=Pi/2 et phi=0. Dans ce plan L origine des coordonnees
     25//    est le point de tangence. L axe Ox est la tangente parallele a
     26//    lequateur, dirige vers les phi croissants, l axe Oy est parallele
    2327//    au meridien, dirige vers le pole nord.
    2428//    De maniere interne a la classe une carte est definie dans ce plan de
    25 //    reference et transportee  jusqu'au point (theta0, phi0) de sorte que les //    axes restent paralleles aux meridiens et paralleles. L'utilisateur peut
     29//    reference et transportee  jusqu au point (theta0, phi0) de sorte que les //    axes restent paralleles aux meridiens et paralleles. L utilisateur peut
    2630//    definir sa carte selon un repere en rotation par rapport au repere de
    27 //    reference (par l'angle entre le parallele et l'axe Ox souhaite --
     31//    reference (par l angle entre le parallele et l axe Ox souhaite --
    2832//    methode SetOrigin(...))
    2933
    3034
     35// ***************** Class LocalMap *****************************
    3136
     37template<class T>
     38class LocalMap : public PixelMap<T>, public AnyDataObj
     39{
    3240
     41public:
    3342
     43LocalMap();
     44LocalMap(int_4 nx, int_4 ny);
     45LocalMap(const LocalMap<T>& lm);
     46virtual ~LocalMap();
    3447
     48// ---------- Overloading of () to access pixel number k ----
    3549
    36 class LocalMap : public PixelMap {
    37 public:
    38    LocalMap();
    39    LocalMap(int_4 nx, int_4 ny);
    40    virtual ~LocalMap();
    41    // Overloading of () to access pixel number k.
    42 inline  r_8&        operator()(int_4 k)
    43                           {return(PixVal(k));}
    44 inline  r_8 const&  operator()(int_4 k) const
    45                           {return(PixVal(k));}
    46 inline  r_8&        operator()(int ix, int iy)
    47                 { return PixVal(iy*mSzX_+ix) ; };
    48 inline  r_8 const&        operator()(int ix, int iy) const
    49                 { return PixVal(iy*mSzX_+ix) ; };
     50inline T& operator()(int_4 k) {return(PixVal(k));}
     51inline T const& operator()(int_4 k) const {return(PixVal(k));}
     52inline T& operator()(int ix, int iy) {return PixVal(iy*nSzX_+ix);};
     53inline T const& operator()(int ix, int iy) const {return PixVal(iy*nSzX_+ix);};
    5054   
    51 // ---------- Persistence handling
     55// ---------- Definition of PixelMap abstract methods -------
     56
     57/* return/set the number of pixels */
     58virtual int_4 NbPixels() const;
     59inline void setNbPixels(int_4 n) {nPix_= n;}
     60 
     61/* return the value of pixel number k */
     62virtual T& PixVal(int_4 k);
     63virtual T const& PixVal(int_4 k) const;
     64
     65/* return the index of pixel at (theta,phi) */
     66virtual int_4 PixIndexSph(float theta, float phi) const;
    5267   
    53    enum {classId = 0xF003 };
    54 int_4               ClassId() const        { return classId; }
     68/* return the spherical coordinates of center of pixel number k */
     69virtual void PixThetaPhi(int_4 k, float& theta, float& phi) const;
    5570
    56 virtual void        WriteSelf(POutPersist&) const;
    57 virtual void        ReadSelf(PInPersist&);
     71/* return the Pixel Solid angle  (steradians) */
     72virtual r_8 PixSolAngle(int_4 k) const;
    5873
    59 // ---------- Definition of PixelMap abstract methods
     74// ---------- Specific methods ------------------------------
    6075
    61    // Number of pixels
    62    virtual int_4       NbPixels() const;
    63    
    64    // Value of pixel number k
    65    virtual r_8&        PixVal(int_4 k);
    66    virtual r_8 const&  PixVal(int_4 k) const;
     76void ReSize(int_4 nx, int_4 ny);
    6777
    68    // Index of pixel at (theta,phi)
    69    virtual int_4       PixIndexSph(float theta, float phi) const;
    70    
    71    // Spherical coordinates of center of pixel number k
    72    virtual void        PixThetaPhi(int_4 k, float& theta, float& phi) const;
    73    // Pixel Solid angle  (steradians)
    74    virtual r_8         PixSolAngle(int_4 k) const;
     78inline virtual char* TypeOfMap() const {return "LOCAL";};
     79 
     80/* Origin (with angle between x axis and phi axis, in degrees)  x0,y0  the default: middle of map*/
     81virtual void SetOrigin(float theta=90., float phi=0., float angle=0.);
     82virtual void SetOrigin(float theta,float phi,int_4 x0,int_4 y0,float angle=0.);
    7583
    76 // ---------- Specific methods
     84/* Pixel size (degres) */
     85virtual void SetSize(float angleX, float angleY);
    7786
    78    // Origin (with angle between x axis and phi axis, in degrees)
    79     virtual void  SetOrigin(float theta0, float phi0, float angle=0.); // x0,y0 default: middle of map
    80   virtual void        SetOrigin(float theta0, float phi0, int_4 x0, int_4 y0, float angle=0.);
    81    // Pixel size (degres)
    82    virtual void        SetSize(float angleX, float angleY);
     87/* Check to see if the local mapping is done */
     88inline bool LocalMap_isDone() const {return(originFlag_ && extensFlag_);};
    8389
    84    // Projection to/from spherical map
    85    //virtual void        Extract(SphericalMap const& sphere);
    86    virtual void        Project(SphericalMap& sphere) const;
     90/* Projection to/from spherical map */
     91virtual void Project(SphericalMap<T>& sphere) const;
    8792 
    88    // There should be a more complex algorithm somewhere to combine *several*
    89    // local maps to a full sphere.
    90    //   -> static method, or separate class
     93/* There should be a more complex algorithm somewhere to combine *several* local maps to a full sphere.
     94      -> static method, or separate class */
     95 
     96/* provides a integer characterizing the pixelization refinement  (here : number of pixels) */
     97inline virtual int_4 SizeIndex() const {return(nPix_);}
     98inline int_4 Size_x() const {return nSzX_;}
     99inline void setSize_x(int_4 n) {nSzX_= n;}
     100inline int_4 Size_y() const {return nSzY_;}
     101inline void setSize_y(int_4 n) {nSzY_= n;}
    91102
    92    void Pixelize(int_4,int_4); // Allocate pixel array
     103inline void Origin(float& theta, float& phi,int& x0, int& y0, float& angle) const {theta= (float)theta0_; phi= (float)phi0_; x0= x0_; y0= y0_;angle= (float)angle_;}
    93104
    94 // ------------- méthodes internes ----------------------
     105inline void Aperture(float& anglex, float& angley) const {anglex= (float)angleX_; angley= (float)angleY_;}
     106
     107/* retourne le pointeur vers/remplit  le vecteur des contenus des pixels */
     108inline const NDataBlock<T>* getDataBlock() const {return (&pixels_);}
     109inline void setDataBlock(T* data, int_4 n) {pixels_.FillFrom(n,data);}
     110
     111/* impression */
     112void print(ostream& os) const;
     113
     114// ---------- Méthodes internes -----------------------------
    95115         
    96116private :
    97117
    98    void      InitNul();
    99    void      Clear();
    100    void      Getij(int k, int& i, int& j) const;
    101    void      ReferenceToUser(float &theta, float &phi) const;
    102    void      UserToReference(float &theta, float &phi) const;
    103    void      PixProjToAngle(float x, float y,float &theta, float &phi) const;
    104    void      AngleProjToPix(float theta, float phi, float& x, float& y) const;
    105 // ------------- variables internes -----------------------
     118void InitNul();
     119void Getij(int k, int& i, int& j) const;
     120void ReferenceToUser(float &theta, float &phi) const;
     121void UserToReference(float &theta, float &phi) const;
     122void PixProjToAngle(float x, float y,float &theta, float &phi) const;
     123void AngleProjToPix(float theta, float phi, float& x, float& y) const;
    106124
    107    int_4   mSzX_, mSzY_;
    108    int_4   mNPix_;
    109    int_4   x0_;
    110    int_4   y0_;
    111    int_4    originFlag_;
    112    int_4    SzFlag_;
    113    r_4   cos_angle_;
    114    r_4   sin_angle_;
    115    r_8     theta0_;
    116    r_8     phi0_;
    117    r_8     omeg_;
    118    r_8     tgAngleX_;
    119    r_8     tgAngleY_;
    120    r_8*    mPix_;
     125// ---------- Variables internes ----------------------------
     126
     127int_4 nSzX_;
     128int_4 nSzY_;
     129int_4 nPix_;
     130bool originFlag_;
     131bool extensFlag_;
     132int_4 x0_;
     133int_4 y0_;
     134r_8 theta0_;
     135r_8 phi0_;
     136r_8 angle_;
     137r_4 cos_angle_;
     138r_4 sin_angle_;
     139r_8 angleX_;
     140r_8 angleY_;
     141r_8 tgAngleX_;
     142r_8 tgAngleY_;
     143NDataBlock<T> pixels_;
     144};
     145
     146// ------------- Classe pour la gestion de persistance --
     147template <class T>
     148class FIO_LocalMap : public PPersist 
     149{
     150
     151public:
     152
     153FIO_LocalMap();
     154FIO_LocalMap(string const & filename);
     155FIO_LocalMap(const LocalMap<T>& obj);
     156FIO_LocalMap(LocalMap<T>* obj);
     157virtual ~FIO_LocalMap();
     158virtual AnyDataObj* DataObj();
     159inline operator LocalMap<T>() { return(*dobj); }
     160inline LocalMap<T> getObj() { return(*dobj); }
     161
     162protected :
     163
     164virtual void ReadSelf(PInPersist&);           
     165virtual void WriteSelf(POutPersist&) const; 
     166LocalMap<T>* dobj;
     167bool ownobj;
    121168};
    122169
  • trunk/SophyaLib/Samba/mlobe.cc

    r262 r470  
    133133
    134134/* --Methode-- */
    135 double MainLobe::Convol(SphericalMap& sph)
     135double MainLobe::Convol(SphericalMap<double>& sph)
    136136{
    137137double ret=0.;
  • trunk/SophyaLib/Samba/mlobe.h

    r228 r470  
    2929               void     SetDirection(float teta, float phi);
    3030               double   Value(int kpx, float& teta, float& phi);
    31                double   Convol(SphericalMap& sph);
     31               double   Convol(SphericalMap<double>& sph);
    3232        friend ostream& operator << (ostream& s, MainLobe const& lob);
    3333        inline void     Print() { cout << (*this); }
  • trunk/SophyaLib/Samba/pixelmap.h

    r228 r470  
    1515//      LocalMap
    1616
     17template<class T>
     18class PixelMap 
     19{
    1720
    18 class PixelMap : public PPersist {
    1921public:
    20    PixelMap():mInfo_(NULL) {}
    21    virtual ~PixelMap() {}
     22 
     23PixelMap():mInfo_(NULL) {};
     24virtual ~PixelMap() {};
     25 
     26// Number of pixels
     27virtual int_4 NbPixels() const=0;
    2228   
    23    // Number of pixels
    24    virtual int_4       NbPixels() const=0;
     29// Value of pixel number k
     30virtual T& PixVal(int_4 k)=0;
     31virtual T const& PixVal(int_4 k) const=0;
    2532   
    26    // Value of pixel number k
    27    virtual r_8&        PixVal(int_4 k)=0;
    28    virtual r_8 const&  PixVal(int_4 k) const=0;
    29    
    30    // Index of pixel at (theta,phi)
    31    virtual int_4       PixIndexSph(float theta, float phi) const=0;
     33// Index of pixel at (theta,phi)
     34virtual int_4 PixIndexSph(float theta, float phi) const=0;
    3235
    33    // Value of pixel number at (theta,phi)
    34    virtual r_8&        PixValSph(float theta, float phi)
     36// Value of pixel number at (theta,phi)
     37virtual T& PixValSph(float theta, float phi)
    3538                           {return PixVal(PixIndexSph(theta,phi));}
    36    virtual r_8 const&  PixValSph(float theta, float phi) const
    37                            {return PixVal(PixIndexSph(theta,phi));}                           
    38    
    39    // Spherical coordinates of center of pixel number k
    40    virtual void        PixThetaPhi(int_4 k, float& theta, float& phi) const=0;
     39virtual T const& PixValSph(float theta, float phi) const
     40                           {return PixVal(PixIndexSph(theta,phi));}
    4141
    42    // Pixel  (steradians)
    43    virtual r_8         PixSolAngle(int_4 k) const =0;
     42// Spherical coordinates of center of pixel number k
     43virtual void PixThetaPhi(int_4 k, float& theta, float& phi) const=0;
    4444
    45    // Overloading of () to access pixel number k.
    46    inline  r_8&        operator()(int_4 k)
    47                           {return(PixVal(k));}
    48    inline  r_8 const&  operator()(int_4 k) const
    49                           {return(PixVal(k));}
     45// provides a integer characterizing the pixelization refinement
     46// (depending of the type of the map)             
     47virtual int_4 SizeIndex() const=0;
     48virtual char* TypeOfMap() const =0;
    5049
    51    // Note : no overloading of (float,float) to access pixel (theta,phi).
    52    // overloading of (float,float) in SphericalMap
    53    // overloading of (int,int)     in CartesianMap
     50// Pixel  (steradians)
     51virtual r_8 PixSolAngle(int_4 k) const =0;
     52
     53// Overloading of () to access pixel number k.
     54inline T& operator()(int_4 k) {return(PixVal(k));}
     55inline T const& operator()(int_4 k) const {return(PixVal(k));}
     56
     57// Note : no overloading of (float,float) to access pixel (theta,phi).
     58// overloading of (float,float) in SphericalMap
     59// overloading of (int,int)     in CartesianMap
    5460
    5561//++
    56 DVList&  Info()
     62DVList& Info()
    5763//
    58 //      Renvoie une rM-ifM-irence sur l'objet DVList AssociM-i
     64// Renvoie une reference sur l''objet DVList Associe
    5965//--
    60 {
    61 if (mInfo_ == NULL)  mInfo_ = new DVList;
    62 return(*mInfo_);
    63 }
     66  {
     67    if (mInfo_ == NULL)  mInfo_ = new DVList;
     68    return(*mInfo_);
     69  }
    6470
    65    protected :
     71const DVList*  ptrInfo() const
     72  {
     73    return mInfo_;
     74  }
    6675
    67   DVList* mInfo_;        // Infos (variables) attachees
     76protected :
     77
     78    DVList* mInfo_;        // Infos (variables) attachees
    6879};
    69 
    7080#endif
  • trunk/SophyaLib/Samba/spheregorski.cc

    r276 r470  
    22#include "spheregorski.h"
    33#include "strutil.h"
    4 extern "C" {
     4#include <complex>
     5#include "piocmplx.h"
     6
     7extern "C"
     8{
    59#include <stdio.h>
    610#include <stdlib.h>
     
    812}
    913     
    10 extern "C" {
    11   //void ang2pix_ring_(int&,double&,double&,int&);
    12   //void pix2ang_ring_(int&, int&, double&, double&);
    13 //void ang2pix_nest_(int&,double&,double&,int&);
    14   //void pix2ang_nest_(int&, int&, double&, double&);
    15 //void nest2ring_(int&, int&, int&);
    16 //void ring2nest_(int&, int&, int&);
    17 void anafast_(int&, int&, int&,double&,float*,float*,float*,float*,
    18               float*,float*,float*);
    19 void synfast_(int&, int&, int&,int&, float&,float*,float*,float*,
    20               double*, double*,double*,double*,double*,float*);
    21 void  input_map_(char*,float*,int&);
    22 void  ecrire_fits_(int&,int&,int&,float*,char*,char*,int&,float&,float&);
    23 
    24 }
     14extern "C"
     15{
     16void anafast_(int&, int&, int&,double&,float*,float*,float*,float*,float*,float*,float*);
     17void synfast_(int&, int&, int&,int&, float&,float*,float*,float*,double*, double*,double*,double*,double*,float*);
     18}
     19
     20//*******************************************************************
     21// Class PIXELS_XY
     22//  Construction des tableaux necessaires a la traduction des indices RING en
     23//  indices NESTED (ou l'inverse)
     24//*******************************************************************
     25
     26PIXELS_XY::PIXELS_XY()
     27{
     28  cout << " appel du constructeur PIXELS_XY " <<endl;
     29  pix2x_.ReSize(1024);
     30  pix2x_.Reset();
     31  pix2y_.ReSize(1024);
     32  pix2y_.Reset();
     33  x2pix_.ReSize(128);
     34  x2pix_.Reset();
     35  y2pix_.ReSize(128);
     36  y2pix_.Reset();
     37  mk_pix2xy();
     38  mk_xy2pix();
     39}
     40
     41PIXELS_XY& PIXELS_XY::instance()
     42{
     43  static PIXELS_XY single;
     44  return (single);
     45}
     46
     47void PIXELS_XY::mk_pix2xy()
     48{
     49  /*
     50    ==================================================
     51    subroutine mk_pix2xy
     52    ==================================================
     53    c     constructs the array giving x and y in the face from pixel number
     54    c     for the nested (quad-cube like) ordering of pixels
     55    c
     56    c     the bits corresponding to x and y are interleaved in the pixel number
     57    c     one breaks up the pixel number by even and odd bits
     58    ==================================================
     59    */
     60  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
     61  //  (16/12/98)
     62
     63  int kpix, jpix, IX, IY, IP, ID;
     64 
     65  for(kpix = 0; kpix < 1024; kpix++)
     66    {
     67      jpix = kpix;
     68      IX = 0;
     69      IY = 0;
     70      IP = 1 ;//  ! bit position (in x and y)
     71      while( jpix!=0 )
     72        { // ! go through all the bits
     73          ID=jpix%2;//  ! bit value (in kpix), goes in ix
     74          jpix = jpix/2;
     75          IX = ID*IP+IX;
     76     
     77          ID=jpix%2;//  ! bit value (in kpix), goes in iy
     78          jpix = jpix/2;
     79          IY = ID*IP+IY;
     80     
     81          IP = 2*IP;//        ! next bit (in x and y)
     82        }
     83      pix2x_(kpix) = IX;//     ! in 0,31
     84      pix2y_(kpix) = IY;//     ! in 0,31
     85    }
     86}
     87
     88void PIXELS_XY::mk_xy2pix()
     89{
     90  /*
     91    =================================================
     92    subroutine mk_xy2pix
     93    =================================================
     94    c     sets the array giving the number of the pixel lying in (x,y)
     95    c     x and y are in {1,128}
     96    c     the pixel number is in {0,128**2-1}
     97    c
     98    c     if  i-1 = sum_p=0  b_p * 2^p
     99    c     then ix = sum_p=0  b_p * 4^p
     100    c          iy = 2*ix
     101    c     ix + iy in {0, 128**2 -1}
     102    =================================================
     103    */
     104  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
     105  //  (16/12/98)
     106
     107  int K,IP,I,J,ID;
     108  for(I = 1; I <= 128; I++)
     109    {
     110      J  = I-1;//            !pixel numbers
     111      K  = 0;//
     112      IP = 1;//
     113      truc : if( J==0 )
     114        {
     115          x2pix_(I-1) = K;
     116          y2pix_(I-1) = 2*K;
     117        }
     118      else
     119        {
     120          ID = (int)fmod(J,2);
     121          J  = J/2;
     122          K  = IP*ID+K;
     123          IP = IP*4;
     124          goto truc;
     125        }
     126    }     
     127}
     128
    25129//*******************************************************************
    26130//++
     
    81185//++
    82186
    83 SphereGorski::SphereGorski()
    84 
    85 //--
    86 {
     187template<class T>
     188SphereGorski<T>::SphereGorski()
     189
     190//--
     191{
     192  cout<<" appel du constructeur SphereGorski ()" <<endl;
    87193  InitNul();
    88194}
    89195
    90 /* --Methode-- */
    91 //++
    92 SphereGorski::SphereGorski(char* flnm)
    93 
    94 //    Constructeur : charge une image à partir d'un fichier
    95 //--
    96 {
    97   InitNul();
    98   PInPersist s(flnm);
    99   Read(s);
    100 }
    101 
    102 //++
    103 SphereGorski::SphereGorski(int_4 m)
     196//++
     197template<class T>
     198SphereGorski<T>::SphereGorski(int_4 m)
    104199
    105200//    Constructeur : m est la variable nside de l'algorithme de Gorski
     
    108203//--
    109204{
    110   //printf(" initialisation par defaut SphereGorski \n");
     205  cout<<" appel du constructeur SphereGorski (m)" <<endl;
     206
     207  if(m <= 0 || m > 8192)
     208    {
     209      cout << "SphereGorski : m hors bornes [0,8192], m= " << m << endl;
     210      exit(1);
     211    }
     212  // verifier que m est une puissance de deux
     213  int_4 x=m;
     214  while(x%2 == 0) x/=2;
     215  if(x != 1)
     216    { 
     217      cout<<"SphereGorski: m doit etre une puissance de deux, m= "<<m<<endl;
     218      exit(1);
     219    }
     220  InitNul();
     221  Pixelize(m);
     222}
     223
     224template<class T>
     225SphereGorski<T>::SphereGorski(const SphereGorski<T>& s)
     226{
     227  cout << " constructeur de recopie " << endl;
     228  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
     229
     230  nSide_= s.nSide_;
     231  nPix_ = s.nPix_;
     232  omeg_ = s.omeg_;
     233
     234  pixels_= s.pixels_;
     235
     236  nlmax_= s.nlmax_;
     237  nmmax_= s.nmmax_;
     238  iseed_= s.iseed_;
     239  fwhm_ = s.fwhm_;
     240  quadrupole_ = s.quadrupole_;
     241  sym_cut_deg_= s.sym_cut_deg_;
     242  strcpy(powFile_,s.powFile_);
     243}
     244
     245//++
     246// Titre        Destructeur
     247//--
     248//++
     249template<class T>
     250SphereGorski<T>::~SphereGorski()
     251
     252//--
     253{
     254  InitNul();
     255}
     256
     257//++
     258// Titre        Méthodes
     259//--
     260
     261//++
     262template<class T>
     263void SphereGorski<T>::Resize(int_4 m)
     264
     265//    m est la variable nside de l'algorithme de Gorski
     266//    le nombre total de pixels sera Npix =  12*nside**2
     267//    m DOIT OBLIGATOIREMENT ETRE UNE PUISSANCE DE 2 (<= 8192)
     268//--
     269{
    111270  if (m<=0 || m> 8192) {
    112271    cout << "SphereGorski : m hors bornes [0,8192], m= " << m << endl;
    113272    exit(1);
    114273  }
    115 // verifier que m est une puissance de deux
     274  // verifier que m est une puissance de deux
    116275  int_4 x=m;
    117276  while (x%2==0) x/=2;
    118   if (x!=1) {
    119     cout << "SphereGorski : m doit etre une puissance de deux, m= " << m << endl;
    120     exit(1);
    121   }
    122 
     277  if(x != 1)
     278   
     279      cout<<"SphereGorski: m doit etre une puissance de deux, m= "<<m<<endl;
     280      exit(1);
     281    }
    123282  InitNul();
    124283  Pixelize(m);
    125   if (pix2x_==NULL) {
    126     pix2x_=new int[1024];
    127     pix2y_=new int[1024];
    128     mk_pix2xy(pix2x_,pix2y_);
    129   }
    130   if (x2pix_==NULL) {
    131     x2pix_=new int[128];
    132     y2pix_=new int[128];
    133     mk_xy2pix(x2pix_,y2pix_);
    134   }
    135 }
    136 
    137 
    138 
    139 
    140 
    141 
    142 //++
    143 // Titre        Destructeur
    144 //--
    145 //++
    146 SphereGorski::~SphereGorski()
    147 
    148 //--
    149 {
    150   Clear();
    151 }
    152 
    153 //++
    154 // Titre        Méthodes
    155 //--
    156 
    157 
    158 
    159 
    160 void  SphereGorski::Pixelize( int_4 m)
     284}
     285
     286template<class T>
     287void  SphereGorski<T>::Pixelize( int_4 m)
    161288
    162289//    prépare la pixelisation Gorski (m a la même signification
     
    166293//--
    167294{
    168  
    169295  // On memorise les arguments d'appel
    170296  nSide_ = m; 
    171  
    172  
     297
    173298  // Nombre total de pixels sur la sphere entiere
    174299  nPix_=12*nSide_*nSide_;
    175300
    176 // pour le moment les tableaux qui suivent seront ranges dans l'ordre
    177 // de l'indexation GORSKY "RING"
    178 // on pourra ulterieurement changer de strategie et tirer profit
    179 // de la dualite d'indexation GORSKY (RING er NEST) : tout dependra
    180 // de pourquoi c'est faire
     301  // pour le moment les tableaux qui suivent seront ranges dans l'ordre
     302  // de l'indexation GORSKY "RING"
     303  // on pourra ulterieurement changer de strategie et tirer profit
     304  // de la dualite d'indexation GORSKY (RING et NEST) : tout dependra
     305  // de pourquoi c'est faire
    181306
    182307  // Creation et initialisation du vecteur des contenus des pixels
    183   mPix_ = new r_8[nPix_];
    184   for(int i=0; i<nPix_; i++)  mPix_[i] = 0.;
     308  pixels_.ReSize(nPix_);
     309  pixels_.Reset();
    185310
    186311  // solid angle per pixel   
    187   omeg_=4*Pi/nPix_;
    188 }
    189 
    190 void SphereGorski::InitNul()
     312  omeg_= 4*Pi/nPix_;
     313}
     314
     315template<class T>
     316void SphereGorski<T>::InitNul()
    191317//
    192318//    initialise à zéro les variables de classe
    193319{
    194   nlmax_=0;
    195   nmmax_=0;
    196   iseed_=0;
    197   fwhm_=0.;
    198   quadrupole_=0.;
    199   sym_cut_deg_=0.;
    200   for (int k=0; k<128;k++) powFile_[k]=' ';
    201   nSide_=0;
    202   nPix_ =0;
    203   mPix_ = NULL;
    204   pix2x_=NULL;
    205   pix2y_=NULL;
    206   x2pix_=NULL;
    207   y2pix_=NULL;
    208   pix2xy_=NULL;
    209 }
     320  nSide_= 0;
     321  nPix_ = 0;
     322  omeg_ = 0.;
     323  pixels_.Reset();
     324
     325  nlmax_= 0;
     326  nmmax_= 0;
     327  iseed_= 0;
     328  fwhm_ = 0.;
     329  quadrupole_ = 0.;
     330  sym_cut_deg_= 0.;
     331  for(int k = 0; k < 128; k++) powFile_[k]=' ';
     332}
     333
    210334/* --Methode-- */
    211 void SphereGorski::Clear()
    212 
    213 {
    214   if (mPix_)   delete[] mPix_;
    215   if (pix2x_)  delete[] pix2x_;
    216   if (pix2y_)  delete[] pix2y_;
    217   if (x2pix_)  delete[] x2pix_;
    218   if (y2pix_)  delete[] y2pix_;
    219   if (pix2xy_) delete pix2xy_;
    220 }
    221 //++
    222 void SphereGorski::WriteSelf(POutPersist& s) const
    223 
    224 //    créer un fichier image
    225 //--
    226 {
    227   char strg[256];
    228   if (mInfo_) sprintf(strg, "SphereGorski: NSlices=%6d  NPix=%9d HasInfo", 
    229                    (int_4)nSide_, (int_4)nPix_);
    230   else
    231     sprintf(strg, "SphereGorski: nSide=%6d  nPix=%9d ",
    232           (int_4)nSide_, (int_4)nPix_);
    233   s.PutLine(strg);
    234   if (mInfo_)  s << (*mInfo_);
    235   s.PutI4(nlmax_);
    236   s.PutI4(nmmax_);
    237   s.PutI4(iseed_);
    238   s.PutI4(nSide_);
    239   s.PutI4(nPix_);
    240   s.PutR4(fwhm_);
    241   s.PutR4(quadrupole_);
    242   s.PutR4(sym_cut_deg_);
    243   s.PutR8(omeg_);
    244   s.PutR8s(mPix_, nPix_);
    245   s.PutLine(powFile_);
    246   return;
    247 }
    248 
    249 /* --Methode-- */
    250 //++
    251 void SphereGorski::ReadSelf(PInPersist& s)
    252 
    253 //    relit un fichier d'image
    254 //--
    255 {
    256   Clear();
    257   char strg[256];
    258   s.GetLine(strg, 255);
    259 // Pour savoir s'il y avait un DVList Info associe
    260   bool hadinfo = false;
    261   if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo = true;
    262   if (hadinfo) {    // Lecture eventuelle du DVList Info
    263     if (mInfo_ == NULL)  mInfo_ = new DVList;
    264     s >> (*mInfo_);
    265   }
    266   s.GetI4(nlmax_);
    267   s.GetI4(nmmax_);
    268   s.GetI4(iseed_);
    269   s.GetI4(nSide_);
    270   s.GetI4(nPix_);
    271   s.GetR4(fwhm_);
    272   s.GetR4(quadrupole_);
    273   s.GetR4(sym_cut_deg_);
    274   mPix_=new r_8[nPix_];
    275   s.GetR8(omeg_);
    276   s.GetR8s(mPix_, nPix_);
    277   s.GetLine(powFile_, 127);
    278 
    279   return;
    280 }
    281 
    282 
    283 /* --Methode-- */
    284 //++
    285 void SphereGorski::ReadFits(char flnm[])
    286 
    287 //    remplit la sphere a partir d'un fichier FITS
    288 //--
    289 {
    290   strip(flnm,'B',' ');
    291   if (access(flnm,F_OK) != 0) {perror(flnm); exit(1);}
    292   if(!nPix_) {
    293     cout << " ReadFits : SphereGorski non pixelisee " << endl;
    294     exit(1);
    295   }
    296   int npixtot=nPix_;
    297 
    298 // quand map et mPix_ auront le meme type, map ne sera plus necessaire
    299 
    300   float* map=new float[12*nSide_*nSide_];
    301   input_map_(flnm,map,npixtot);
    302   // Remplissage de la sphère
    303 
    304   for(int  j=0; j<nPix_; j++ ) mPix_[j]=(r_8)map[j];
    305   delete [] map;
    306  
    307 
    308 }
    309 
    310 /* --Methode-- */
    311 //++
    312 void SphereGorski::WriteFits(char flnm[])
    313 
    314 //    ecrit la sphere sur un fichier FITS
    315 
    316 //--
    317 {
    318   strip(flnm,'B',' ');
    319   if (access(flnm,F_OK) == 0) {
    320     cout << " SphereGorski::WriteFits : le fichier existe deja" << endl;
    321     exit(1);
    322   }
    323   //else cout << "un fichier sera cree " << endl;
    324   if(!nPix_) {
    325     cout << " WriteFits : SphereGorski non pixelisee " << endl;
    326     exit(1);
    327   }
    328 
    329 
    330   char infile[128];
    331   for (int k=0; k< 128; k++) infile[k]=powFile_[k];
    332 
    333 // quand map et mPix_ auront le meme type, map ne sera plus necessaire
    334 
    335   float* map=new float[12*nSide_*nSide_];
    336 
    337   for(int  j=0; j<nPix_; j++ ) map[j]=(float)mPix_[j];
    338   int nlmax=nlmax_;
    339   int nsmax=nSide_;
    340   int nmmax=nmmax_;
    341   int iseed=iseed_;
    342   float fwhm=fwhm_;
    343   float quadrupole=quadrupole_;
    344   ecrire_fits_(nlmax,nsmax,nmmax,map,infile,flnm,iseed,fwhm,quadrupole);
    345   delete [] map;
    346  
    347 }
    348 
    349 /* --Methode-- */
    350 //++
    351 int_4 SphereGorski::NbPixels() const
     335//++
     336template<class T>
     337int_4 SphereGorski<T>::NbPixels() const
    352338
    353339//    Retourne le nombre de pixels du découpage
    354340//--
    355 {
     341{ 
    356342  return(nPix_);
    357343}
    358344
    359345//++
    360 int_4 SphereGorski::NbThetaSlices() const
     346template<class T>
     347int_4 SphereGorski<T>::NbThetaSlices() const
    361348
    362349//    Retourne le nombre de tranches en theta sur la sphere
    363350//--
    364 {return int_4(4*nSide_-1);}
    365 
    366 
    367 //++
    368 void  SphereGorski::GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const
     351{
     352  return int_4(4*nSide_-1);
     353}
     354
     355//++
     356template<class T>
     357void  SphereGorski<T>::GetThetaSlice(int_4 index, r_4& theta, TVector<float>& phi, TVector<T>& value) const
    369358
    370359//    Retourne, pour la tranche en theta d'indice 'index' le theta
     
    374363//--
    375364{
    376 
    377 cout << "entree GetThetaSlice, couche no " << index << endl;
    378   if (index<0 || index > NbThetaSlices()) {
    379     // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
    380     cout << " SphereGorski::GetThetaSlice : exceptions  a mettre en place" <<endl;
    381   THROW(rangeCheckErr);
    382   }
    383   int_4 iring=0;
    384   int lring=0;
    385   if (index<nSide_-1) {
    386     iring=2*index*(index+1);
    387     lring=4*(index+1);
    388   }else
    389     if (index<3*nSide_) {
    390       iring=2*nSide_*(2*index-nSide_+1);
    391       lring=4*nSide_;
    392     }else
    393       {
    394         int nc=4*nSide_-1-index;
    395         iring=nPix_-2*nc*(nc+1);
    396         lring=4*nc;
    397       }
    398   phi.Realloc(lring);
    399   value.Realloc(lring);
    400   float T=0.;
    401   float F=0.;
    402   for (int kk=0; kk<lring;kk++) {
    403     PixThetaPhi(kk+iring,T,F);
    404     phi(kk)=F;
    405     value(kk)=PixVal(kk+iring);
    406   }
    407   theta=T;
    408 
    409 }
    410 
    411 
     365  cout << "entree GetThetaSlice, couche no " << index << endl;
     366
     367  if (index<0 || index > NbThetaSlices())
     368    {
     369      // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
     370      cout << " SphereGorski::GetThetaSlice : exceptions  a mettre en place" <<endl;
     371      THROW(rangeCheckErr);
     372    }
     373
     374  int_4 iring= 0;
     375  int lring  = 0;
     376  if(index < nSide_-1)
     377    {
     378      iring= 2*index*(index+1);
     379      lring= 4*(index+1);
     380    }
     381  else if(index < 3*nSide_)
     382    {
     383      iring= 2*nSide_*(2*index-nSide_+1);
     384      lring= 4*nSide_;
     385    }
     386  else
     387    {
     388      int nc= 4*nSide_-1-index;
     389      iring = nPix_-2*nc*(nc+1);
     390      lring = 4*nc;
     391    }
     392
     393  phi.ReSize(lring);
     394  value.ReSize(lring);
     395  float TH=0.;
     396  float F =0.;
     397  for(int kk = 0; kk < lring;kk++)
     398    {
     399      PixThetaPhi(kk+iring,TH,F);
     400      phi(kk)= F;
     401      value(kk)= PixVal(kk+iring);
     402    }
     403  theta= TH;
     404}
    412405
    413406/* --Methode-- */
    414407//++
    415 r_8& SphereGorski::PixVal(int_4 k)
     408template<class T>
     409T& SphereGorski<T>::PixVal(int_4 k)
    416410
    417411//    Retourne la valeur du contenu du pixel d'indice "RING" k
    418412//--
    419413{
    420   if ( (k<0) || (k >= nPix_) ) {
    421     // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
    422     cout << " SphereGorski::PIxVal : exceptions  a mettre en place" <<endl;
    423   THROW(rangeCheckErr);
    424   }
    425   return(mPix_[k]);
     414  if((k < 0) || (k >= nPix_))
     415    {
     416      // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
     417      cout << " SphereGorski::PIxVal : exceptions  a mettre en place" <<endl;
     418      THROW(rangeCheckErr);
     419    }
     420  return pixels_(k);
    426421}
    427422
    428423/* --Methode-- */
    429424//++
    430 r_8 const& SphereGorski::PixVal(int_4 k) const
     425template<class T>
     426T const& SphereGorski<T>::PixVal(int_4 k) const
    431427
    432428//    Retourne la valeur du contenu du pixel d'indice "RING" k
    433429//--
    434430{
    435   if ( (k<0) || (k >= nPix_) ) {
    436     //THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
    437     cout << " SphereGorski::PIxVal : exceptions  a mettre en place" <<endl;
    438   THROW(rangeCheckErr);
    439   }
    440   return(mPix_[k]);
    441 }
    442 
    443 
    444 //++
    445 r_8& SphereGorski::PixValNest(int_4 k)
     431  if((k < 0) || (k >= nPix_))
     432    {
     433      //THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
     434      cout << " SphereGorski::PIxVal : exceptions  a mettre en place" <<endl;
     435      THROW(rangeCheckErr);
     436    }
     437  return *(pixels_.Data()+k);
     438}
     439
     440//++
     441template<class T>
     442T& SphereGorski<T>::PixValNest(int_4 k)
    446443
    447444//    Retourne la valeur du contenu du pixel d'indice "NESTED" k
    448445//--
    449446{
    450   if ( (k<0) || (k >= nPix_) ) {
    451    //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
    452     cout << " SphereGorski::PIxValNest : exceptions  a mettre en place" <<endl;
    453   THROW(rangeCheckErr);
    454   }
    455   return mPix_[nest2ring(nSide_,k)];
    456 }
    457 //++
    458 
    459 r_8 const& SphereGorski::PixValNest(int_4 k) const
     447  if((k < 0) || (k >= nPix_))
     448    {
     449      //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
     450      cout<<" SphereGorski::PIxValNest : exceptions a mettre en place" <<endl;
     451      THROW(rangeCheckErr);
     452    }
     453  return pixels_(nest2ring(nSide_,k));
     454}
     455//++
     456
     457template<class T>
     458T const& SphereGorski<T>::PixValNest(int_4 k) const
    460459
    461460//    Retourne la valeur du contenu du pixel d'indice "NESTED" k
    462461//--
    463462{
    464   if ( (k<0) || (k >= nPix_) ) {
    465    //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
    466     cout << " SphereGorski::PIxValNest : exceptions  a mettre en place" <<endl;
    467   THROW(rangeCheckErr);
    468   }
    469   int_4 pix=nest2ring(nSide_,k);
    470   return mPix_[pix];
    471 }
    472 
    473 
     463  if((k < 0) || (k >= nPix_))
     464    {
     465      //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
     466      cout<<" SphereGorski::PIxValNest : exceptions a mettre en place" <<endl;
     467      THROW(rangeCheckErr);
     468  }
     469  int_4 pix= nest2ring(nSide_,k);
     470  return *(pixels_.Data()+pix);
     471}
    474472
    475473/* --Methode-- */
    476474//++
    477 int_4 SphereGorski::PixIndexSph(r_4 theta, r_4 phi) const
     475template<class T>
     476int_4 SphereGorski<T>::PixIndexSph(r_4 theta, r_4 phi) const
    478477
    479478//    Retourne l'indice "RING" du pixel vers lequel pointe une direction
     
    481480//--
    482481{
    483   return ang2pix_ring(nSide_, double(theta), double(phi));
    484 }
    485 
    486 //++
    487 int_4 SphereGorski::PixIndexSphNest(r_4 theta, r_4 phi) const
     482  return ang2pix_ring(nSide_,double(theta),double(phi));
     483}
     484
     485//++
     486template<class T>
     487int_4 SphereGorski<T>::PixIndexSphNest(r_4 theta, r_4 phi) const
    488488
    489489//    Retourne l'indice NESTED" du pixel vers lequel pointe une direction
     
    491491//--
    492492{
    493   return ang2pix_nest(nSide_, double(theta), double(phi));
     493  return ang2pix_nest(nSide_,double(theta),double(phi));
    494494}
    495495
     
    497497/* --Methode-- */
    498498//++
    499 void SphereGorski::PixThetaPhi(int_4 k, r_4& teta, r_4& phi) const
     499template<class T>
     500void SphereGorski<T>::PixThetaPhi(int_4 k, r_4& teta, r_4& phi) const
    500501
    501502//    Retourne les coordonnées (teta,phi) du milieu du pixel d'indice "RING" k
     
    504505  double t;
    505506  double p;
    506   pix2ang_ring(nSide_,k, t,  p);
    507   teta=(r_4)t;
    508   phi=(r_4)p;
    509 }
    510 
    511 //++
    512 r_8       SphereGorski::PixSolAngle(int_4 dummy) const
     507  pix2ang_ring(nSide_,k, t, p);
     508  teta= (r_4)t;
     509  phi = (r_4)p;
     510}
     511
     512//++
     513template<class T>
     514r_8 SphereGorski<T>::PixSolAngle(int_4 dummy) const
    513515//    Pixel Solid angle  (steradians)
    514516//    All the pixels have the same solid angle. The dummy argument is
     
    520522}
    521523
    522 
    523 //++
    524 void SphereGorski::PixThetaPhiNest(int_4 k, float& teta, float& phi)  const
     524//++
     525template<class T>
     526void SphereGorski<T>::PixThetaPhiNest(int_4 k, float& teta, float& phi)  const
    525527
    526528//    Retourne les coordonnées (teta,phi) du milieu du pixel d'indice
     
    531533  double p;
    532534  pix2ang_nest(nSide_, k, t, p);
    533   teta=(r_4)t;
    534   phi=(r_4)p;
    535 }
    536 
    537 //++
    538 int_4 SphereGorski::NestToRing(int_4 k)
     535  teta= (r_4)t;
     536  phi = (r_4)p;
     537}
     538
     539//++
     540template<class T>
     541int_4 SphereGorski<T>::NestToRing(int_4 k) const
    539542
    540543//    conversion d'index NESTD en un index RING
     
    544547  return  nest2ring(nSide_,k);
    545548}
    546 //++
    547 int_4 SphereGorski::RingToNest(int_4 k)
     549
     550//++
     551template<class T>
     552int_4 SphereGorski<T>::RingToNest(int_4 k) const
    548553//
    549554//    conversion d'index RING en un index NESTED
     
    553558  return  ring2nest(nSide_,k);
    554559}
    555 //++
    556 void SphereGorski::anharm(int nlmax, float sym_c,float* powspec)
     560
     561/*
     562//++
     563template<class T>
     564void SphereGorski<T>::anharm(int nlmax, float sym_c,float* powspec)
    557565//
    558566//    analyse en harmoniques spheriques des valeurs des pixels de la
     
    573581//
    574582{
    575   if (nlmax > 2*nSide_) {
    576     cout << " anharm : nlmax= " << nlmax <<
    577             " doit etre <= 2*nsmax (cf. Nyquist), soit :" << 2*nSide_ << endl;
    578     exit(1);
     583    if (nlmax > 2*nSide_) {
     584          cout << " anharm : nlmax= " << nlmax <<
     585                          " doit etre <= 2*nsmax (cf. Nyquist), soit :" << 2*nSide_ << endl;
     586         exit(1);
    579587  }
    580588  else {
     
    584592  sym_cut_deg_=sym_c;
    585593  float* map=new float[nPix_];
    586   for (int k=0; k<nPix_; k++) map[k]=(float)mPix_[k];
     594  for (int k=0; k<nPix_; k++) map[k]=(float)pixels_(k);
    587595  int nsmax=nSide_;
    588596  int nmmax=nmmax_;
     
    607615  delete [] phas_s;
    608616  delete [] dataw;
    609   delete [] work;
    610  
    611 }
    612 
    613 
    614 //++
    615 void SphereGorski::synharm(int nlmax, int iseed,float fwhm, float* powspec)
     617  delete [] work; 
     618}
     619*/
     620
     621/*
     622//++
     623template<class T>
     624void SphereGorski<T>::synharm(int nlmax, int iseed,float fwhm, float* powspec)
    616625//
    617626//    synthese  des valeurs des pixels de la sphere par l'intermediaire
     
    654663  int nsmax=nSide_;
    655664  int nmmax=nmmax_;
    656   float* alm_T=new float[2*(nlmax+1)*(nmmax+1)];
    657  
    658 
    659 //    tableaux de travail
     665  float* alm_T=new float[2*(nlmax+1)*(nmmax+1)];
     666
     667  //    tableaux de travail
    660668  double* b_north=new double[2*(2*nmmax+1)];
    661669  double* b_south=new double[2*(2*nmmax+1)];
     
    666674  synfast_(nsmax,nlmax,nmmax,iseed,fwhm, map,alm_T, powspec,
    667675                  b_north,b_south,bw,data,work,lread);
    668   for (int k=0; k<nPix_; k++) mPix_[k]=(double)map[k];
     676  for (int k=0; k<nPix_; k++) pixels_(k) = (T)map[k];
    669677  delete [] map;
    670678  delete [] alm_T;
     
    675683  delete [] work;
    676684  delete [] lread;
    677 
    678 }
    679 
    680 int SphereGorski::nest2ring(int nside, int ipnest) const {
     685}
     686*/
     687
     688template<class T>
     689int SphereGorski<T>::nest2ring(int nside, int ipnest) const {
    681690  /*
    682     c=======================================================================
     691    ====================================================
    683692    subroutine nest2ring(nside, ipnest, ipring)
    684     c=======================================================================
     693    ====================================================
    685694    c     conversion from NESTED to RING pixel number
    686     c=======================================================================
    687   */
    688   // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    689   //  (16/12/98)
    690 
    691       int npix, npface, face_num, ncap, n_before;
    692       int ipf, ip_low, ip_trunc, ip_med, ip_hi;
    693       int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
    694       int ns_max=8192;
    695       int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
    696       int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
    697 
    698       if(  nside<1 ||  nside>ns_max ) {
    699         cout << "nside out of range" << endl;
    700         exit(0);
    701       }
    702       npix = 12 *  nside* nside;
    703       if( ipnest<0 || ipnest>npix-1 ) {
    704         cout << "ipnest out of range" << endl;
    705         exit(0);
    706       }
    707 
    708 
    709       ncap  = 2* nside*( nside-1);// ! number of points in the North Polar cap
    710       nl4   = 4* nside;
    711 
    712       //c     finds the face, and the number in the face
    713       npface =  nside* nside;
    714       //cccccc      ip = ipnest - 1         ! in {0,npix-1}
    715 
    716       face_num = ipnest/npface;//  ! face number in {0,11}
    717       ipf =ipnest%npface;//  ! pixel number in the face {0,npface-1}
    718       //c     finds the x,y on the face (starting from the lowest corner)
    719       //c     from the pixel number
    720       ip_low=ipf%1024;                //   ! content of the last 10 bits
    721       ip_trunc =   ipf/1024;         //    ! truncation of the last 10 bits
    722       ip_med=ip_trunc%1024;         //     ! content of the next 10 bits
    723       ip_hi  =     ip_trunc/1024;//   ! content of the high weight 10 bits
    724 
    725       ix = 1024*pix2x_[ip_hi] + 32*pix2x_[ip_med] + pix2x_[ip_low];
    726       iy = 1024*pix2y_[ip_hi] + 32*pix2y_[ip_med] + pix2y_[ip_low];
    727 
    728       //c     transforms this in (horizontal, vertical) coordinates
    729       jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
    730       jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
    731 
    732       //c     computes the z coordinate on the sphere
    733       //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
    734       jr =  jrll[face_num]*nside - jrt - 1;
    735       nr = nside;//                  ! equatorial region (the most frequent)
    736       n_before = ncap + nl4 * (jr - nside);
    737       kshift=(jr - nside)%2;
    738       if( jr<nside ) {//then     ! north pole region
    739          nr = jr;
    740          n_before = 2 * nr * (nr - 1);
    741          kshift = 0;
    742       }
    743       else if( jr>3*nside ) {//then ! south pole region
    744          nr = nl4 - jr;
    745          n_before = npix - 2 * (nr + 1) * nr;
    746          kshift = 0;
    747       }
    748 
    749       //c     computes the phi coordinate on the sphere, in [0,2Pi]
    750       jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
    751 
    752       if( jp>nl4 ) jp = jp - nl4;
    753       if( jp<1 )   jp = jp + nl4;
    754 
    755       int aux=n_before + jp - 1;
    756       return (n_before + jp - 1);// ! in {0, npix-1}
    757 
    758 }
    759 
    760 void SphereGorski::mk_pix2xy(int *pix2x,int *pix2y) {
    761   /*
    762     c=======================================================================
    763     subroutine mk_pix2xy
    764     c=======================================================================
    765     c     constructs the array giving x and y in the face from pixel number
    766     c     for the nested (quad-cube like) ordering of pixels
    767     c
    768     c     the bits corresponding to x and y are interleaved in the pixel number
    769     c     one breaks up the pixel number by even and odd bits
    770     c=======================================================================
    771   */
    772   // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    773   //  (16/12/98)
    774 
    775       int kpix, jpix, IX, IY, IP, ID;
    776       for (int i=0;i<1023;i++ ) pix2x[i]=0;
    777 
    778       for( kpix=0;kpix<1024;kpix++ ) {
    779         jpix = kpix;
    780         IX = 0;
    781         IY = 0;
    782         IP = 1 ;//              ! bit position (in x and y)
    783         while( jpix!=0 ){// ! go through all the bits
    784           ID=jpix%2;//  ! bit value (in kpix), goes in ix
    785           jpix = jpix/2;
    786           IX = ID*IP+IX;
    787          
    788           ID=jpix%2;//  ! bit value (in kpix), goes in iy
    789           jpix = jpix/2;
    790           IY = ID*IP+IY;
    791          
    792           IP = 2*IP;//         ! next bit (in x and y)
    793         }
    794        
    795         pix2x[kpix] = IX;//     ! in 0,31
    796         pix2y[kpix] = IY;//     ! in 0,31
    797       }
    798 }
    799 
    800 int SphereGorski::ring2nest(int nside, int ipring) const {
    801   /*
    802     c=======================================================================
    803     subroutine ring2nest(nside, ipring, ipnest)
    804     c=======================================================================
    805     c     conversion from RING to NESTED pixel number
    806     c=======================================================================
     695    ====================================================
    807696    */
    808697  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    809698  //  (16/12/98)
     699 
     700  const PIXELS_XY& PXY= PIXELS_XY::instance();
     701
     702  int npix, npface, face_num, ncap, n_before;
     703  int ipf, ip_low, ip_trunc, ip_med, ip_hi;
     704  int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
     705  int ns_max=8192;
     706  int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
     707  int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
     708 
     709  if(  nside<1 ||  nside>ns_max ) {
     710    cout << "nside out of range" << endl;
     711    exit(0);
     712  }
     713  npix = 12 *  nside* nside;
     714  if( ipnest<0 || ipnest>npix-1 ) {
     715    cout << "ipnest out of range" << endl;
     716    exit(0);
     717  }
     718
     719  ncap  = 2* nside*( nside-1);// ! number of points in the North Polar cap
     720  nl4   = 4* nside;
     721 
     722  //c     finds the face, and the number in the face
     723  npface =  nside* nside;
     724  //cccccc      ip = ipnest - 1         ! in {0,npix-1}
     725 
     726  face_num = ipnest/npface;//  ! face number in {0,11}
     727  ipf =ipnest%npface;//  ! pixel number in the face {0,npface-1}
     728  //c     finds the x,y on the face (starting from the lowest corner)
     729  //c     from the pixel number
     730  ip_low=ipf%1024;                //   ! content of the last 10 bits
     731  ip_trunc =   ipf/1024;         //    ! truncation of the last 10 bits
     732  ip_med=ip_trunc%1024;         //     ! content of the next 10 bits
     733  ip_hi  =     ip_trunc/1024;//   ! content of the high weight 10 bits
     734 
     735  ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
     736  iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
     737 
     738  //c     transforms this in (horizontal, vertical) coordinates
     739  jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
     740  jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
     741 
     742  //c     computes the z coordinate on the sphere
     743  //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
     744  jr =  jrll[face_num]*nside - jrt - 1;
     745  nr = nside;//                  ! equatorial region (the most frequent)
     746  n_before = ncap + nl4 * (jr - nside);
     747  kshift=(jr - nside)%2;
     748  if( jr<nside ) {//then     ! north pole region
     749    nr = jr;
     750    n_before = 2 * nr * (nr - 1);
     751    kshift = 0;
     752  }
     753  else if( jr>3*nside ) {//then ! south pole region
     754    nr = nl4 - jr;
     755    n_before = npix - 2 * (nr + 1) * nr;
     756    kshift = 0;
     757  }
     758 
     759  //c     computes the phi coordinate on the sphere, in [0,2Pi]
     760  jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
     761 
     762  if( jp>nl4 ) jp = jp - nl4;
     763  if( jp<1 )   jp = jp + nl4;
     764 
     765  int aux=n_before + jp - 1;
     766  return (n_before + jp - 1);// ! in {0, npix-1}
     767}
     768
     769template<class T>
     770int SphereGorski<T>::ring2nest(int nside, int ipring) const
     771{
     772  /*
     773    ==================================================
     774    subroutine ring2nest(nside, ipring, ipnest)
     775    ==================================================
     776    c     conversion from RING to NESTED pixel number
     777    ==================================================
     778    */
     779  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
     780  //  (16/12/98)
     781
     782  const PIXELS_XY& PXY= PIXELS_XY::instance();
    810783
    811784  double fihip, hip;
     
    898871  iy_low = (int)fmod(iy,128);
    899872  iy_hi  = iy/128;
    900   ipf =  (x2pix_[ix_hi]+y2pix_[iy_hi]) * (128 * 128)
    901     + (x2pix_[ix_low]+y2pix_[iy_low]);
     873  ipf=(PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
    902874
    903875  return (ipf + face_num* nside *nside);//   ! in {0, 12*nside**2 - 1}
    904876}
    905877
    906 void SphereGorski::mk_xy2pix(int *x2pix, int *y2pix) {
     878template<class T>
     879int SphereGorski<T>::ang2pix_ring(int nside, double theta, double phi) const
     880{
    907881  /*
    908     c=======================================================================
    909     subroutine mk_xy2pix
    910     c=======================================================================
    911     c     sets the array giving the number of the pixel lying in (x,y)
    912     c     x and y are in {1,128}
    913     c     the pixel number is in {0,128**2-1}
    914     c
    915     c     if  i-1 = sum_p=0  b_p * 2^p
    916     c     then ix = sum_p=0  b_p * 4^p
    917     c          iy = 2*ix
    918     c     ix + iy in {0, 128**2 -1}
    919     c=======================================================================
    920   */
    921   // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    922   //  (16/12/98)
    923 
    924   int K,IP,I,J,ID;
    925 
    926   for( int i(0);i<127;i++ ) x2pix[i]=0;
    927   for( I=1;I<=128;I++ ) {
    928     J  = I-1;//            !pixel numbers
    929     K  = 0;//
    930     IP = 1;//
    931     truc : if( J==0 ) {
    932       x2pix[I-1] = K;
    933       y2pix[I-1] = 2*K;
    934     }
    935     else {
    936       ID = (int)fmod(J,2);
    937       J  = J/2;
    938       K  = IP*ID+K;
    939       IP = IP*4;
    940       goto truc;
    941     }
    942   }     
    943   //c      endif
    944  
    945 }
    946 
    947 int SphereGorski::ang2pix_ring(int nside, double theta, double phi) const {
    948     /*
    949     c=======================================================================
     882    ==================================================
    950883    c     gives the pixel number ipix (RING)
    951884    c     corresponding to angles theta and phi
    952     c=======================================================================
    953   */
     885    c==================================================
     886    */
    954887  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    955888  //  (16/12/98)
     
    1017950  }
    1018951    return (ipix1 - 1);// ! in {0, npix-1}
    1019  
    1020 }
    1021 
    1022 int SphereGorski::ang2pix_nest(int nside, double theta, double phi) const {
     952}
     953
     954template<class T>
     955int SphereGorski<T>::ang2pix_nest(int nside, double theta, double phi) const
     956{
    1023957  /*
    1024     c=======================================================================
     958    ==================================================
    1025959    subroutine ang2pix_nest(nside, theta, phi, ipix)
    1026     c=======================================================================
     960    ==================================================
    1027961    c     gives the pixel number ipix (NESTED)
    1028962    c     corresponding to angles theta and phi
     
    1033967    c     that the treatement of round-off will be consistent
    1034968    c     for every resolution
    1035     c=======================================================================
    1036   */
     969    ==================================================
     970    */
    1037971  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    1038972  //  (16/12/98)
    1039    
    1040       double    z, za, z0, tt, tp, tmp;
    1041       int face_num,jp,jm;
    1042       int ifp, ifm;
    1043       int  ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf, ntt;
    1044       double piover2(Pi/2.), twopi(2.*Pi);
    1045       int ns_max(8192);
    1046 
    1047       if( nside<1 || nside>ns_max ) {
    1048         cout << "nside out of range" << endl;
    1049         exit(0);
    1050       }
    1051       if( theta<0 || theta>Pi ) {
    1052         cout << "theta out of range" << endl;
    1053         exit(0);
    1054       }
    1055       z  = cos(theta);
    1056       za = fabs(z);
    1057       z0 = 2./3.;
    1058       if( phi>=twopi ) phi = phi - twopi;
    1059       if( phi<0. )    phi = phi + twopi;
    1060       tt = phi / piover2;// ! in [0,4[
    1061       if( za<=z0 ) { // then ! equatorial region
    1062        
    1063         //(the index of edge lines increase when the longitude=phi goes up)
    1064         jp = (int)floor(ns_max*(0.5 + tt - z*0.75));// !  ascending edge line index
    1065         jm = (int)floor(ns_max*(0.5 + tt + z*0.75));// ! descending edge line index
    1066 
    1067         //c        finds the face
    1068         ifp = jp / ns_max;//  ! in {0,4}
    1069         ifm = jm / ns_max;
    1070         if( ifp==ifm ) face_num = (int)fmod(ifp,4) + 4; //then          ! faces 4 to 7
    1071         else if( ifp<ifm ) face_num = (int)fmod(ifp,4); // (half-)faces 0 to 3
    1072         else face_num = (int)fmod(ifm,4) + 8;//! (half-)faces 8 to 11
    1073 
    1074         ix = (int)fmod(jm, ns_max);
    1075         iy = ns_max - (int)fmod(jp, ns_max) - 1;
    1076       }
    1077       else { //! polar region, za > 2/3
    1078              
    1079         ntt = (int)floor(tt);
    1080         if( ntt>=4 ) ntt = 3;
    1081         tp = tt - ntt;
    1082         tmp = sqrt( 3.*(1. - za) );//  ! in ]0,1]
    1083 
    1084         //(the index of edge lines increase when distance from the closest pole goes up)
    1085         jp = (int)floor( ns_max * tp          * tmp );// ! line going toward the pole as phi increases
    1086         jm = (int)floor( ns_max * (1. - tp) * tmp );// ! that one goes away of the closest pole
    1087         jp = (int)min(ns_max-1, jp);// ! for points too close to the boundary
    1088         jm = (int)min(ns_max-1, jm);
    1089 
    1090          // finds the face and pixel's (x,y)
    1091          if( z>=0 ) {
    1092            face_num = ntt;//  ! in {0,3}
    1093             ix = ns_max - jm - 1;
    1094             iy = ns_max - jp - 1;
    1095          }
    1096          else {
    1097            face_num = ntt + 8;// ! in {8,11}
    1098             ix =  jp;
    1099             iy =  jm;
    1100          }
    1101       }
    1102 
    1103       ix_low = (int)fmod(ix,128);
    1104       ix_hi  =     ix/128;
    1105       iy_low = (int)fmod(iy,128);
    1106       iy_hi  =     iy/128;
    1107       ipf =  (x2pix_[ix_hi]+y2pix_[iy_hi]) * (128 * 128)+ (x2pix_[ix_low]+y2pix_[iy_low]);
    1108       ipf = ipf / pow(ns_max/nside,2);//  ! in {0, nside**2 - 1}
    1109       return ( ipf + face_num*pow(nside,2));//    ! in {0, 12*nside**2 - 1}
    1110 }
    1111 
    1112 
    1113 void SphereGorski::pix2ang_ring(int nside, int ipix, double& theta,  double& phi) const {
     973 
     974  const PIXELS_XY& PXY= PIXELS_XY::instance();
     975
     976  double    z, za, z0, tt, tp, tmp;
     977  int face_num,jp,jm;
     978  int ifp, ifm;
     979  int  ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf, ntt;
     980  double piover2(Pi/2.), twopi(2.*Pi);
     981  int ns_max(8192);
     982 
     983  if( nside<1 || nside>ns_max ) {
     984    cout << "nside out of range" << endl;
     985    exit(0);
     986  }
     987  if( theta<0 || theta>Pi ) {
     988    cout << "theta out of range" << endl;
     989    exit(0);
     990  }
     991  z  = cos(theta);
     992  za = fabs(z);
     993  z0 = 2./3.;
     994  if( phi>=twopi ) phi = phi - twopi;
     995  if( phi<0. )    phi = phi + twopi;
     996  tt = phi / piover2;// ! in [0,4[
     997  if( za<=z0 ) { // then ! equatorial region
     998   
     999    //(the index of edge lines increase when the longitude=phi goes up)
     1000    jp = (int)floor(ns_max*(0.5 + tt - z*0.75));// !  ascending edge line index
     1001    jm = (int)floor(ns_max*(0.5 + tt + z*0.75));// ! descending edge line index
     1002   
     1003    //c        finds the face
     1004    ifp = jp / ns_max;//  ! in {0,4}
     1005    ifm = jm / ns_max;
     1006    if( ifp==ifm ) face_num = (int)fmod(ifp,4) + 4; //then          ! faces 4 to 7
     1007    else if( ifp<ifm ) face_num = (int)fmod(ifp,4); // (half-)faces 0 to 3
     1008    else face_num = (int)fmod(ifm,4) + 8;//! (half-)faces 8 to 11
     1009   
     1010    ix = (int)fmod(jm, ns_max);
     1011    iy = ns_max - (int)fmod(jp, ns_max) - 1;
     1012  }
     1013  else { //! polar region, za > 2/3
     1014   
     1015    ntt = (int)floor(tt);
     1016    if( ntt>=4 ) ntt = 3;
     1017    tp = tt - ntt;
     1018    tmp = sqrt( 3.*(1. - za) );//  ! in ]0,1]
     1019   
     1020    //(the index of edge lines increase when distance from the closest pole goes up)
     1021    jp = (int)floor(ns_max*tp*tmp); // ! line going toward the pole as phi increases
     1022    jm = (int)floor(ns_max*(1.-tp)*tmp); // ! that one goes away of the closest pole
     1023    jp = (int)min(ns_max-1, jp);// ! for points too close to the boundary
     1024    jm = (int)min(ns_max-1, jm);
     1025   
     1026    // finds the face and pixel's (x,y)
     1027    if( z>=0 ) {
     1028      face_num = ntt;//  ! in {0,3}
     1029      ix = ns_max - jm - 1;
     1030      iy = ns_max - jp - 1;
     1031    }
     1032    else {
     1033      face_num = ntt + 8;// ! in {8,11}
     1034      ix =  jp;
     1035      iy =  jm;
     1036    }
     1037  }
     1038 
     1039  ix_low = (int)fmod(ix,128);
     1040  ix_hi  =     ix/128;
     1041  iy_low = (int)fmod(iy,128);
     1042  iy_hi  =     iy/128;
     1043  ipf= (PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
     1044  ipf = ipf / pow(ns_max/nside,2);//  ! in {0, nside**2 - 1}
     1045  return ( ipf + face_num*pow(nside,2));//    ! in {0, 12*nside**2 - 1}
     1046}
     1047
     1048template<class T>
     1049void SphereGorski<T>::pix2ang_ring(int nside,int ipix,double& theta,double& phi) const {
    11141050  /*
    1115     c=======================================================================
     1051    ===================================================
    11161052    c     gives theta and phi corresponding to pixel ipix (RING)
    11171053    c     for a parameter nside
    1118     c=======================================================================
    1119   */
     1054    ===================================================
     1055    */
    11201056  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    11211057  //  (16/12/98)
     
    11781114}
    11791115
    1180 void SphereGorski::pix2ang_nest(int nside, int ipix, double& theta, double& phi) const {
     1116template<class T>
     1117void SphereGorski<T>::pix2ang_nest(int nside,int ipix,double& theta,double& phi) const {
    11811118  /*
    1182     c=======================================================================
     1119    ==================================================
    11831120    subroutine pix2ang_nest(nside, ipix, theta, phi)
    1184     c=======================================================================
     1121    ==================================================
    11851122    c     gives theta and phi corresponding to pixel ipix (NESTED)
    11861123    c     for a parameter nside
    1187     c=======================================================================
    1188   */
     1124    ==================================================
     1125    */
    11891126  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    11901127  //  (16/12/98)
    1191    
    1192       int npix, npface, face_num;
    1193       int  ipf, ip_low, ip_trunc, ip_med, ip_hi;
    1194       int     ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
    1195       double z, fn, fact1, fact2;
    1196       double piover2(Pi/2.);
    1197       int ns_max(8192);
    1198      
    1199      
    1200       // ! coordinate of the lowest corner of each face
    1201       int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};//! in unit of nside
    1202       int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};// ! in unit of nside/2
    1203      
    1204       if( nside<1 || nside>ns_max ) {
    1205         cout << "nside out of range" << endl;
    1206         exit(0);
    1207       }
    1208       npix = 12 * nside*nside;
    1209       if( ipix<0 || ipix>npix-1 ) {
    1210         cout << "ipix out of range" << endl;
    1211         exit(0);
    1212       }
    1213 
    1214       fn = 1.*nside;
    1215       fact1 = 1./(3.*fn*fn);
    1216       fact2 = 2./(3.*fn);
    1217       nl4   = 4*nside;
    1218 
    1219       //c     finds the face, and the number in the face
    1220       npface = nside*nside;
    1221 
    1222       face_num = ipix/npface;//  ! face number in {0,11}
    1223       ipf = (int)fmod(ipix,npface);//  ! pixel number in the face {0,npface-1}
    1224 
    1225       //c     finds the x,y on the face (starting from the lowest corner)
    1226       //c     from the pixel number
    1227       ip_low = (int)fmod(ipf,1024);//       ! content of the last 10 bits
    1228       ip_trunc =   ipf/1024 ;//       ! truncation of the last 10 bits
    1229       ip_med = (int)fmod(ip_trunc,1024);//  ! content of the next 10 bits
    1230       ip_hi  =     ip_trunc/1024   ;//! content of the high weight 10 bits
    1231 
    1232       ix = 1024*pix2x_[ip_hi] + 32*pix2x_[ip_med] + pix2x_[ip_low];
    1233       iy = 1024*pix2y_[ip_hi] + 32*pix2y_[ip_med] + pix2y_[ip_low];
    1234 
    1235       //c     transforms this in (horizontal, vertical) coordinates
    1236       jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
    1237       jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
    1238 
    1239       //c     computes the z coordinate on the sphere
    1240       //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
    1241       jr =  jrll[face_num]*nside - jrt - 1;
    1242       nr = nside;//                  ! equatorial region (the most frequent)
    1243       z  = (2*nside-jr)*fact2;
    1244       kshift = (int)fmod(jr - nside, 2);
    1245       if( jr<nside ) { //then     ! north pole region
    1246          nr = jr;
    1247          z = 1. - nr*nr*fact1;
    1248          kshift = 0;
    1249       }
    1250       else {
    1251         if( jr>3*nside ) {// then ! south pole region
    1252          nr = nl4 - jr;
    1253          z = - 1. + nr*nr*fact1;
    1254          kshift = 0;
     1128
     1129  const PIXELS_XY& PXY= PIXELS_XY::instance();
     1130   
     1131  int npix, npface, face_num;
     1132  int ipf, ip_low, ip_trunc, ip_med, ip_hi;
     1133  int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
     1134  double z, fn, fact1, fact2;
     1135  double piover2(Pi/2.);
     1136  int ns_max(8192);
     1137         
     1138  // ! coordinate of the lowest corner of each face
     1139  int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};//! in unit of nside
     1140  int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};// ! in unit of nside/2
     1141 
     1142  if( nside<1 || nside>ns_max ) {
     1143    cout << "nside out of range" << endl;
     1144    exit(0);
     1145  }
     1146  npix = 12 * nside*nside;
     1147  if( ipix<0 || ipix>npix-1 ) {
     1148    cout << "ipix out of range" << endl;
     1149    exit(0);
     1150  }
     1151 
     1152  fn = 1.*nside;
     1153  fact1 = 1./(3.*fn*fn);
     1154  fact2 = 2./(3.*fn);
     1155  nl4   = 4*nside;
     1156
     1157  //c     finds the face, and the number in the face
     1158  npface = nside*nside;
     1159 
     1160  face_num = ipix/npface;//  ! face number in {0,11}
     1161  ipf = (int)fmod(ipix,npface);//  ! pixel number in the face {0,npface-1}
     1162 
     1163  //c     finds the x,y on the face (starting from the lowest corner)
     1164  //c     from the pixel number
     1165  ip_low = (int)fmod(ipf,1024);//       ! content of the last 10 bits
     1166  ip_trunc =   ipf/1024 ;//       ! truncation of the last 10 bits
     1167  ip_med = (int)fmod(ip_trunc,1024);//  ! content of the next 10 bits
     1168  ip_hi  =     ip_trunc/1024   ;//! content of the high weight 10 bits
     1169 
     1170  ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
     1171  iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
     1172 
     1173  //c     transforms this in (horizontal, vertical) coordinates
     1174  jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
     1175  jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
     1176 
     1177  //c     computes the z coordinate on the sphere
     1178  //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
     1179  jr =  jrll[face_num]*nside - jrt - 1;
     1180  nr = nside;//                  ! equatorial region (the most frequent)
     1181  z  = (2*nside-jr)*fact2;
     1182  kshift = (int)fmod(jr - nside, 2);
     1183  if( jr<nside ) { //then     ! north pole region
     1184    nr = jr;
     1185    z = 1. - nr*nr*fact1;
     1186    kshift = 0;
     1187  }
     1188  else {
     1189    if( jr>3*nside ) {// then ! south pole region
     1190      nr = nl4 - jr;
     1191      z = - 1. + nr*nr*fact1;
     1192      kshift = 0;
     1193    }
     1194  }
     1195  theta = acos(z);
     1196 
     1197  //c     computes the phi coordinate on the sphere, in [0,2Pi]
     1198  //      jp = (jpll[face_num+1]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
     1199  jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;
     1200  if( jp>nl4 ) jp = jp - nl4;
     1201  if( jp<1 )   jp = jp + nl4;
     1202  phi = (jp - (kshift+1)*0.5) * (piover2 / nr);
     1203}
     1204
     1205// retourne le nom du fichier qui contient le spectre de puissance
     1206template<class T>
     1207void SphereGorski<T>::powfile(char filename[]) const
     1208{
     1209  bool status = false;
     1210  for (int k=0; k< 128; k++)
     1211    {
     1212      if( powFile_[k] != ' ' )
     1213        {
     1214          status = true;
     1215          break;
    12551216        }
    1256       }
    1257       theta = acos(z);
    1258      
    1259       //c     computes the phi coordinate on the sphere, in [0,2Pi]
    1260       //      jp = (jpll[face_num+1]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
    1261       jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;
    1262       if( jp>nl4 ) jp = jp - nl4;
    1263       if( jp<1 )   jp = jp + nl4;
    1264 
    1265       phi = (jp - (kshift+1)*0.5) * (piover2 / nr);
    1266 
    1267 }
    1268 
    1269 
    1270 void SphereGorski::Pix2XY::pix2ang_nest(int nside, int ipix, double& theta, double& phi) const {
    1271   /*
    1272     c=======================================================================
    1273     subroutine pix2ang_nest(nside, ipix, theta, phi)
    1274     c=======================================================================
    1275     c     gives theta and phi corresponding to pixel ipix (NESTED)
    1276     c     for a parameter nside
    1277     c=======================================================================
    1278   */
    1279   // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
    1280   //  (16/12/98)
    1281    
    1282       int npix, npface, face_num;
    1283       int  ipf, ip_low, ip_trunc, ip_med, ip_hi;
    1284       int     ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
    1285       double z, fn, fact1, fact2;
    1286       double piover2(Pi/2.);
    1287       int ns_max(8192);
    1288      
    1289      
    1290       // ! coordinate of the lowest corner of each face
    1291       int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};//! in unit of nside
    1292       int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};// ! in unit of nside/2
    1293      
    1294       if( nside<1 || nside>ns_max ) {
    1295         cout << "nside out of range" << endl;
    1296         exit(0);
    1297       }
    1298       npix = 12 * nside*nside;
    1299       if( ipix<0 || ipix>npix-1 ) {
    1300         cout << "ipix out of range" << endl;
    1301         exit(0);
    1302       }
    1303 
    1304       fn = 1.*nside;
    1305       fact1 = 1./(3.*fn*fn);
    1306       fact2 = 2./(3.*fn);
    1307       nl4   = 4*nside;
    1308 
    1309       //c     finds the face, and the number in the face
    1310       npface = nside*nside;
    1311 
    1312       face_num = ipix/npface;//  ! face number in {0,11}
    1313       ipf = (int)fmod(ipix,npface);//  ! pixel number in the face {0,npface-1}
    1314 
    1315       //c     finds the x,y on the face (starting from the lowest corner)
    1316       //c     from the pixel number
    1317       ip_low = (int)fmod(ipf,1024);//       ! content of the last 10 bits
    1318       ip_trunc =   ipf/1024 ;//       ! truncation of the last 10 bits
    1319       ip_med = (int)fmod(ip_trunc,1024);//  ! content of the next 10 bits
    1320       ip_hi  =     ip_trunc/1024   ;//! content of the high weight 10 bits
    1321 
    1322       ix = 1024*pix2x_[ip_hi] + 32*pix2x_[ip_med] + pix2x_[ip_low];
    1323       iy = 1024*pix2y_[ip_hi] + 32*pix2y_[ip_med] + pix2y_[ip_low];
    1324 
    1325       //c     transforms this in (horizontal, vertical) coordinates
    1326       jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
    1327       jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
    1328 
    1329       //c     computes the z coordinate on the sphere
    1330       //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
    1331       jr =  jrll[face_num]*nside - jrt - 1;
    1332       nr = nside;//                  ! equatorial region (the most frequent)
    1333       z  = (2*nside-jr)*fact2;
    1334       kshift = (int)fmod(jr - nside, 2);
    1335       if( jr<nside ) { //then     ! north pole region
    1336          nr = jr;
    1337          z = 1. - nr*nr*fact1;
    1338          kshift = 0;
    1339       }
    1340       else {
    1341         if( jr>3*nside ) {// then ! south pole region
    1342          nr = nl4 - jr;
    1343          z = - 1. + nr*nr*fact1;
    1344          kshift = 0;
    1345         }
    1346       }
    1347       theta = acos(z);
    1348      
    1349       //c     computes the phi coordinate on the sphere, in [0,2Pi]
    1350       //      jp = (jpll[face_num+1]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
    1351       jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;
    1352       if( jp>nl4 ) jp = jp - nl4;
    1353       if( jp<1 )   jp = jp + nl4;
    1354 
    1355       phi = (jp - (kshift+1)*0.5) * (piover2 / nr);
    1356 
    1357 }
    1358 
    1359 
    1360 
     1217    }
     1218  if ( status )
     1219    {
     1220      strcpy(filename,powFile_);
     1221    }
     1222  else
     1223    {
     1224      strcpy(filename,"no file");
     1225    }
     1226}
     1227
     1228template<class T>
     1229void SphereGorski<T>::getParafast(int_4& nlmax,int_4& nmmax,int_4& iseed,float& fwhm,float& quadr,float& cut) const
     1230{
     1231  nlmax= nlmax_;
     1232  nmmax= nmmax_;
     1233  iseed= iseed_;
     1234  fwhm = fwhm_;
     1235  quadr= quadrupole_;
     1236  cut  = sym_cut_deg_;
     1237}
     1238
     1239template<class T>
     1240void SphereGorski<T>::setParafast(int_4 nlmax,int_4 nmmax,int_4 iseed,float fwhm,float quadr,float cut,char* filename)
     1241{
     1242  nlmax_= nlmax;
     1243  nmmax_= nmmax;
     1244  iseed_= iseed;
     1245  fwhm_ = fwhm;
     1246  quadrupole_ = quadr;
     1247  sym_cut_deg_= cut;
     1248  strcpy(powFile_,filename);
     1249}
     1250
     1251template <class T>
     1252void SphereGorski<T>::print(ostream& os) const
     1253{
     1254  if(mInfo_) os << "  DVList Info= " << *mInfo_ << endl;
     1255  //
     1256  os << " nSide_ = " << nSide_  << endl;
     1257  os << " nPix_   = " << nPix_   << endl;
     1258  os << " omeg_ = " << omeg_   << endl;
     1259
     1260  os << " contenu de pixels : ";
     1261  for(int i=0; i < nPix_; i++)
     1262    {
     1263      if(i%5 == 0) os << endl;
     1264      os <<  pixels_(i) <<", ";
     1265    }
     1266  os << endl;
     1267
     1268  os << endl;
     1269  const PIXELS_XY& PXY= PIXELS_XY::instance();
     1270
     1271  os << endl;  os << " contenu des tableaux conversions "<<endl;
     1272  for(int i=0; i < 5; i++)
     1273    {
     1274      os<<PXY.pix2x_(i)<<", "<<PXY.pix2y_(i)<<", "<<PXY.x2pix_(i)<<", "<<PXY.y2pix_(i)<<endl;
     1275    }
     1276  os << endl;
     1277
     1278  os << " les parametres des modules anafast et synfast " <<endl;
     1279  os << " nlmax, nmmax & iseed= " <<nlmax_<<", "<<nmmax_<<", "<<iseed_<<endl;
     1280  os << " fwhm, quadr & cut = "<<fwhm_<<", "<<quadrupole_<<", "<<sym_cut_deg_<<endl;
     1281  os << " powfile= " << powFile_<<endl;
     1282}
     1283
     1284//*******************************************************************
     1285// Class FIO_SphereGorski<T>
     1286//  Les objets delegues pour la gestion de persistance
     1287//*******************************************************************
     1288
     1289template <class T>
     1290FIO_SphereGorski<T>::FIO_SphereGorski()
     1291{
     1292  dobj= new SphereGorski<T>;
     1293  ownobj= true;
     1294}
     1295
     1296template <class T>
     1297FIO_SphereGorski<T>::FIO_SphereGorski(string const& filename)
     1298{
     1299  dobj= new SphereGorski<T>;
     1300  ownobj= true;
     1301  Read(filename);
     1302}
     1303
     1304template <class T>
     1305FIO_SphereGorski<T>::FIO_SphereGorski(const SphereGorski<T>& obj)
     1306{
     1307  dobj= new SphereGorski<T>(obj);
     1308  ownobj= true;
     1309}
     1310
     1311template <class T>
     1312FIO_SphereGorski<T>::FIO_SphereGorski(SphereGorski<T>* obj)
     1313{
     1314  dobj= obj;
     1315  ownobj= false;
     1316}
     1317
     1318template <class T>
     1319FIO_SphereGorski<T>::~FIO_SphereGorski()
     1320{
     1321  if (ownobj && dobj) delete dobj;
     1322}
     1323
     1324template <class T>
     1325AnyDataObj* FIO_SphereGorski<T>::DataObj()
     1326{
     1327  return(dobj);
     1328}
     1329
     1330template <class T>
     1331void FIO_SphereGorski<T>::ReadSelf(PInPersist& is)
     1332{
     1333  cout << " FIO_SphereGorski:: ReadSelf " << endl;
     1334
     1335  if(dobj == NULL)
     1336    {
     1337      dobj= new SphereGorski<T>;
     1338    }
     1339
     1340  // Pour savoir s'il y avait un DVList Info associe
     1341  char strg[256];
     1342  is.GetLine(strg, 255);
     1343  bool hadinfo= false;
     1344  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
     1345  if(hadinfo)
     1346    {    // Lecture eventuelle du DVList Info
     1347      is >> dobj->Info();
     1348    }
     1349
     1350  int_4 nSide;
     1351  is.GetI4(nSide);
     1352  dobj->setSizeIndex(nSide);
     1353
     1354  int_4 nPix;
     1355  is.GetI4(nPix);
     1356  dobj->setNbPixels(nPix);
     1357
     1358  r_8 Omega;
     1359  is.GetR8(Omega);
     1360  dobj->setPixSolAngle(Omega);
     1361
     1362  T* pixels= new T[nPix];
     1363  PIOSReadArray(is, pixels, nPix);
     1364  dobj->setDataBlock(pixels, nPix);
     1365  delete [] pixels;
     1366
     1367  int_4 nlmax,nmmax,iseed;
     1368  is.GetI4(nlmax);
     1369  is.GetI4(nmmax);
     1370  is.GetI4(iseed);
     1371 
     1372  float fwhm,quadr,cut;
     1373  is.GetR4(fwhm);
     1374  is.GetR4(quadr);
     1375  is.GetR4(cut);
     1376
     1377  char powfl[128];
     1378  is.GetLine(powfl, 127);
     1379
     1380  dobj->setParafast(nlmax,nmmax,iseed,fwhm,quadr,cut,powfl);
     1381}
     1382
     1383template <class T>
     1384void FIO_SphereGorski<T>::WriteSelf(POutPersist& os) const
     1385{
     1386  cout << " FIO_SphereGorski:: WriteSelf " << endl;
     1387
     1388  if(dobj == NULL)
     1389    {
     1390      cout << " WriteSelf:: dobj= null " << endl;
     1391      return;
     1392    }
     1393
     1394  char strg[256];
     1395  int_4 nSide= dobj->SizeIndex();
     1396  int_4 nPix = dobj->NbPixels();
     1397 
     1398  if(dobj->ptrInfo())
     1399    {
     1400      sprintf(strg,"SphereGorski: NSide=%6d  NPix=%9d HasInfo",nSide,nPix);
     1401      os.PutLine(strg);
     1402      os << dobj->Info();
     1403    }
     1404  else
     1405    {
     1406      sprintf(strg,"SphereGorski: NSide=%6d  NPix=%9d ",nSide,nPix);
     1407      os.PutLine(strg); 
     1408    }
     1409
     1410  os.PutI4(nSide);
     1411  os.PutI4(nPix);
     1412  os.PutR8(dobj->PixSolAngle(0));
     1413
     1414  PIOSWriteArray(os,(dobj->getDataBlock())->Data(), nPix);
     1415
     1416  int_4 nlmax,nmmax,iseed;
     1417  float fwhm,quadr,cut;
     1418  dobj->getParafast(nlmax,nmmax,iseed,fwhm,quadr,cut);
     1419  os.PutI4(nlmax);
     1420  os.PutI4(nmmax);
     1421  os.PutI4(iseed);
     1422  os.PutR4(fwhm);
     1423  os.PutR4(quadr);
     1424  os.PutR4(cut);
     1425
     1426  char powfl[128];
     1427  dobj->powfile(powfl);
     1428  os.PutLine(powfl);
     1429}
     1430
     1431#ifdef __CXX_PRAGMA_TEMPLATES__
     1432#pragma define_template SphereGorski<double>
     1433#pragma define_template SphereGorski<float>
     1434#pragma define_template SphereGorski< complex<float> >
     1435#pragma define_template SphereGorski< complex<double> >
     1436#pragma define_template FIO_SphereGorski<double>
     1437#pragma define_template FIO_SphereGorski<float>
     1438#pragma define_template FIO_SphereGorski< complex<float> >
     1439#pragma define_template FIO_SphereGorski< complex<double> >
     1440#endif
     1441#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
     1442template class SphereGorski<double>;
     1443template class SphereGorski<float>;
     1444template class SphereGorski< complex<float> >;
     1445template class SphereGorski< complex<double> >;
     1446template class FIO_SphereGorski<double>;
     1447template class FIO_SphereGorski<float>;
     1448template class FIO_SphereGorski< complex<float> >;
     1449template class FIO_SphereGorski< complex<double> >;
     1450#endif
     1451
  • trunk/SophyaLib/Samba/spheregorski.h

    r228 r470  
    33
    44#include "sphericalmap.h"
    5 #include "cvector.h"
     5#include "tvector.h"
     6#include "ndatablock.h"
     7
     8#include "anydataobj.h"
     9#include "ppersist.h"
    610
    711// les attributs de classe pix2x_ et pix2y_ sont relatifs a la traduction des
    8 // indices  RING en indices NESTED (ou l'inverse). Ce sont des tableaux
     12// indices  RING en indices NESTED (ou l inverse). Ce sont des tableaux
    913// d'entiers initialises et remplis par le constructeur. Dans la version
    1014// FORTRAN de healpix, il s'agissait de tableaux mis en COMMON. Ils etaient
    11 // initialises au premier appel d'une conversion d'indice. Je ne peux pas
     15// initialises au premier appel d'une conversion d indice. Je ne peux pas
    1216// garder cette procedure car, par exemple, la fonction PixValNest() const
    1317// n'autorisera pas la constitution de ces tableaux (a cause du const). Ainsi,
    14 // des la creation d'un objet SphereGorski ces tableaux sont calcules, ce qui
     18// des la creation d un objet SphereGorski ces tableaux sont calcules, ce qui
    1519// est, certes, inutile si on ne se sert pas des indices NESTED. Ca ne me
    16 // rejouit pas, mais c'est le seul moyen que j'ai trouve pour temir compte de
     20// rejouit pas, mais c est le seul moyen que j ai trouve pour temir compte de
    1721// toutes les demandes et des options prises.
    1822//
    1923//                                                G. Le Meur
    2024
    21 class SphereGorski : public SphericalMap {
     25// ***************** CLASSE SphereGorski *****************************
     26
     27template<class T>
     28class SphereGorski : public SphericalMap<T>,  public AnyDataObj
     29{
     30
    2231public :
    23 
    2432
    2533SphereGorski();
    2634SphereGorski(int_4 m);
    27 SphereGorski(char* flnm);
     35SphereGorski(const SphereGorski<T>& s);
    2836virtual ~SphereGorski();
    29 
    30 // ------------ Persistence handling
    31      enum {classId = 0xF002 };
    32 
    33 int_4                  ClassId() const        { return classId; }
    34 
    35 virtual void           WriteSelf(POutPersist&) const;
    36 virtual void           ReadSelf(PInPersist&);
    37 
    38 // -----------   FITS IO (1D FITS ARRAY)
    39 void ReadFits(char flnm[] );
    40 void WriteFits(char flnm[]);
    4137
    4238// ------------------ Definition of PixelMap abstract methods
    4339
    44 /* Nombre de pixels du decoupage                                         */
    45 virtual  int_4           NbPixels() const;
     40/* Nombre de pixels du decoupage */
     41virtual int_4 NbPixels() const;
     42inline void setNbPixels(int_4 n) {nPix_= n;}
    4643
    47 /* Valeur du contenu du pixel d'indice "RING" k                                 */
    48 virtual  r_8&      PixVal(int_4 k);
    49 virtual  r_8  const&    PixVal(int_4 k) const;
     44/* Valeur du contenu du pixel d'indice "RING" k  */
     45virtual T& PixVal(int_4 k);
     46virtual T const& PixVal(int_4 k) const;
    5047
     48/* Nombre de tranches en theta */
    5149int_4 NbThetaSlices() const;
    52 void  GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const;
     50void GetThetaSlice(int_4 index,r_4& theta,TVector<float>& phi,TVector<T>& value) const;
    5351
    5452/* Indice "RING" du pixel vers lequel pointe une direction definie par
    5553ses  coordonnees spheriques */                                   
    56 virtual  int_4          PixIndexSph(float theta, float phi) const;
     54virtual int_4 PixIndexSph(float theta, float phi) const;
    5755
    58 /* Coordonnees spheriques du milieu du pixel d'indice "RING" k       */
    59 virtual  void          PixThetaPhi(int_4 k, float& teta, float& phi) const;
     56/* Coordonnees spheriques du milieu du pixel d'indice "RING" k   */
     57virtual void PixThetaPhi(int_4 k, float& teta, float& phi) const;
    6058
    61 // Pixel Solid angle  (steradians)
    62 virtual r_8         PixSolAngle(int_4 dummy) const;
    63 
     59/* Pixel Solid angle  (steradians) */
     60virtual r_8 PixSolAngle(int_4 dummy) const;
     61inline void setPixSolAngle(r_8 x) {omeg_= x;}
    6462
    6563// --------------- Specific methods
    6664
    67     // NEST indexing
     65virtual void Resize(int_4 m);
     66
     67inline virtual char* TypeOfMap() const {return "RING";};
     68
    6869/* Valeur du contenu du pixel d'indice "NEST" k                                 */
    69 virtual  r_8&      PixValNest(int_4 k);
    70 virtual  r_8 const&      PixValNest(int_4 k) const;
     70virtual T& PixValNest(int_4 k);
     71virtual T const& PixValNest(int_4 k) const;
    7172
    7273/* Indice "NEST" du pixel vers lequel pointe une direction definie par
    7374ses  coordonnees spheriques */                                   
    74 virtual  int_4      PixIndexSphNest(float theta, float phi) const;
     75virtual int_4 PixIndexSphNest(float theta, float phi) const;
    7576
    7677/* Coordonnees spheriques du milieu du pixel d'indice "NEST" k       */
    77 virtual  void      PixThetaPhiNest(int_4 k, float& teta, float& phi) const;
     78virtual void PixThetaPhiNest(int_4 k, float& teta, float& phi) const;
    7879
    79    // algorithme de pixelisation
     80/* algorithme de pixelisation */
    8081void Pixelize(int_4);
    8182
    82 
    8383/* convertit index nested en ring  */
    84 int_4 NestToRing(int_4 );
    85 
     84int_4 NestToRing(int_4 ) const;
    8685
    8786/* convertit index ring en nested" */
    88 int_4 RingToNest(int_4 );
    89 
     87int_4 RingToNest(int_4 ) const;
    9088
    9189/*    analyse en harmoniques spheriques des valeurs des pixels de la
    9290   sphere : appel du module anafast (Gorski-Hivon) */
    93 void anharm(int, float, float*);
     91//void anharm(int, float, float*);
    9492 
    9593/*synthese  des valeurs des pixels de la sphere par l'intermediaire
    9694  des coefficients en harmoniques spheriques reconstitues apartir d'un
    9795  spectre en puissance : appel du module synfast (Gorski-Hivon) */
    98 void synharm(int , int, float, float* );
     96//void synharm(int, int, float, float*);
    9997
     98/* retourne/fixe la valeur du parametre Gorski */
     99inline virtual int_4 SizeIndex() const {return(nSide_);}
     100inline void setSizeIndex(int_4 n) {nSide_= n;}
     101
     102/* retourne les pointeurs /remplit les tableaux */
     103inline const NDataBlock<T>* getDataBlock() const { return (&pixels_); }
     104inline void setDataBlock(T* data, int_4 m) { pixels_.FillFrom(m,data); }
     105
     106/* retourne/fixe les parametres des modules anafast et synfast */
     107void getParafast(int_4& nlmax,int_4& nmmax,int_4& iseed,float& fwhm,float& quadr,float& cut) const;
     108void setParafast(int_4 nlmax,int_4 nmmax,int_4 iseed,float fwhm,float quadr,float cut,char* filename);
     109
     110/* retourne/fixe le nom du fichier qui contient le spectre de puissance */
     111void powfile(char filename[]) const;
     112
     113/* impression */
     114void print(ostream& os) const;
     115         
     116private :
    100117
    101118// ------------- méthodes internes ----------------------
    102          
    103 private :
     119void InitNul();
    104120
    105 void          InitNul();
    106 void          Clear();
    107 int           nest2ring(int nside, int ipnest) const;
    108 void          mk_pix2xy(int *pix2x,int *pix2y);
    109 int           ring2nest(int nside, int ipring) const;
    110 void          mk_xy2pix(int *x2pix, int *y2pix);
    111 int           ang2pix_ring(int nside, double theta, double phi) const;
    112 int           ang2pix_nest(int nside, double theta, double phi) const;
    113 void          pix2ang_ring(int nside, int ipix, double& theta,  double& phi) const;
    114 void          pix2ang_nest(int nside, int ipix, double& theta, double& phi) const;
     121int  nest2ring(int nside, int ipnest) const;
     122int  ring2nest(int nside, int ipring) const;
     123
     124int  ang2pix_ring(int nside, double theta, double phi) const;
     125int  ang2pix_nest(int nside, double theta, double phi) const;
     126void pix2ang_ring(int nside, int ipix, double& theta,  double& phi) const;
     127void pix2ang_nest(int nside, int ipix, double& theta, double& phi) const;
     128
    115129// ------------- variables internes -----------------------
    116                    private :
    117 class Pix2XY {
    118   public :
    119 Pix2XY() {
    120     pix2x_=new int[1024];
    121     pix2y_=new int[1024];
    122     mk_pix2xy(pix2x_,pix2y_);
    123   }
    124 ~Pix2XY() {
    125   if (pix2x_)  delete[] pix2x_;
    126   if (pix2y_)  delete[] pix2y_;
    127   }
    128 void          pix2ang_nest(int nside, int ipix, double& theta, double& phi) const;
     130int_4 nSide_;
     131int_4 nPix_;
     132r_8 omeg_;
    129133
    130 private :
    131 int *pix2x_;
    132 int *pix2y_;
    133 void          mk_pix2xy(int *pix2x,int *pix2y);
    134 
    135 };
     134NDataBlock<T> pixels_;
    136135
    137136int nlmax_;
    138137int nmmax_;
    139138int iseed_;
    140 int  nSide_;
    141 int_4  nPix_;
    142 int *pix2x_;
    143 int *pix2y_;
    144 int *x2pix_;
    145 int *y2pix_;
    146139float fwhm_;
    147140float quadrupole_;
    148141float sym_cut_deg_;
    149 r_8  omeg_;
    150 r_8*    mPix_;
    151142char powFile_[128];
    152 Pix2XY *pix2xy_;
     143};
     144
     145//
     146// ------------- Classe pour la gestion de persistance --
     147//
     148template <class T>
     149class FIO_SphereGorski : public PPersist 
     150{
     151public:
     152
     153FIO_SphereGorski();
     154FIO_SphereGorski(string const & filename);
     155FIO_SphereGorski(const SphereGorski<T>& obj);
     156FIO_SphereGorski(SphereGorski<T>* obj);
     157virtual ~FIO_SphereGorski();
     158virtual AnyDataObj* DataObj();
     159inline operator SphereGorski<T>() { return(*dobj); }
     160inline SphereGorski<T> getObj() { return(*dobj); }
     161
     162protected :
     163
     164virtual void ReadSelf(PInPersist&);           
     165virtual void WriteSelf(POutPersist&) const; 
     166SphereGorski<T>* dobj;
     167bool ownobj;
     168};
     169
     170//
     171// ------------- Classe PIXELS_XY -----------------------
     172//
     173class PIXELS_XY
     174{
     175
     176public :
     177
     178static PIXELS_XY& instance();
     179
     180NDataBlock<int> pix2x_;
     181NDataBlock<int> pix2y_;
     182NDataBlock<int> x2pix_;
     183NDataBlock<int> y2pix_;
     184
     185private :
     186
     187PIXELS_XY();
     188void mk_pix2xy();
     189void mk_xy2pix();
    153190};
    154191#endif
  • trunk/SophyaLib/Samba/spherethetaphi.cc

    r276 r470  
    1 //
    2 //
    31#include "spherethetaphi.h"
    42#include "nbmath.h"
     3#include <complex>
     4#include "piocmplx.h"
    55#include <iostream.h>
     6
     7#ifdef __CXX_PRAGMA_TEMPLATES__
     8#pragma define_template SphereThetaPhi<double>
     9#pragma define_template SphereThetaPhi<float>
     10#pragma define_template SphereThetaPhi< complex<float> >
     11#pragma define_template SphereThetaPhi< complex<double> >
     12#pragma define_template FIO_SphereThetaPhi<double>
     13#pragma define_template FIO_SphereThetaPhi<float>
     14#pragma define_template FIO_SphereThetaPhi< complex<float> >
     15#pragma define_template FIO_SphereThetaPhi< complex<double> >
     16#endif
     17#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
     18template class SphereThetaPhi<double>;
     19template class SphereThetaPhi<float>;
     20template class SphereThetaPhi< complex<float> >;
     21template class SphereThetaPhi< complex<double> >;
     22template class FIO_SphereThetaPhi<double>;
     23template class FIO_SphereThetaPhi<float>;
     24template class FIO_SphereThetaPhi< complex<float> >;
     25template class FIO_SphereThetaPhi< complex<double> >;
     26#endif
     27
    628//***************************************************************
    729//++
     
    3961//++
    4062
    41 
    42 SphereThetaPhi::SphereThetaPhi()
     63template <class T>
     64SphereThetaPhi<T>::SphereThetaPhi()
    4365
    4466//--
     
    4971/* --Methode-- */
    5072//++
    51 SphereThetaPhi::SphereThetaPhi(char* flnm)
     73template <class T>
     74SphereThetaPhi<T>::SphereThetaPhi(char* flnm)
    5275
    5376//    Constructeur : charge une image à partir d'un fichier
     
    5578{
    5679  InitNul();
    57   PInPersist s(flnm);
    58   Read(s);
    59 }
    60 
    61 /* --Methode-- */
    62 
    63 //++
    64 SphereThetaPhi::SphereThetaPhi(int_4 m, int_4 pet)
     80  cout << " ShereThetaPhi:: constructeur lecture sur fichier A FAIRE " << endl;
     81  //PInPersist s(flnm);
     82  //Read(s);
     83}
     84
     85/* --Methode-- */
     86
     87//++
     88template <class T>
     89SphereThetaPhi<T>::SphereThetaPhi(int_4 m)
    6590
    6691//    Constructeur : m est le nombre de bandes en theta sur un hémisphère
     
    7196{
    7297  InitNul();
    73   Pixelize(m,pet);
    74 }
    75 
     98  Pixelize(m);
     99}
     100
     101template <class T>
     102SphereThetaPhi<T>::SphereThetaPhi(const SphereThetaPhi<T>& s)
     103{
     104  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
     105  NTheta_= s.NTheta_;
     106  NPix_  = s.NPix_;
     107  NPhi_  = new int_4[NTheta_];
     108  Theta_ = new r_4[NTheta_+1];
     109  TNphi_ = new int_4[NTheta_+1];
     110  for(int k = 0; k < NTheta_; k++)
     111    {
     112      NPhi_[k] = s.NPhi_[k];
     113      Theta_[k]= s.Theta_[k];
     114      TNphi_[k]= s.TNphi_[k];
     115    }
     116  Theta_[NTheta_]= s.Theta_[NTheta_];
     117  TNphi_[NTheta_]= s.TNphi_[NTheta_];
     118  Omega_ = s.Omega_;
     119  pixels_= s.pixels_;
     120}
    76121
    77122//++
     
    79124//--
    80125//++
    81 SphereThetaPhi::~SphereThetaPhi()
     126template <class T>
     127SphereThetaPhi<T>::~SphereThetaPhi()
    82128
    83129//--
     
    89135// Titre        Méthodes
    90136//--
    91 void SphereThetaPhi::InitNul()
     137template <class T>
     138void SphereThetaPhi<T>::InitNul()
    92139//
    93140//    initialise à zéro les variables de classe pointeurs
    94141{
    95   mTheta = NULL;
    96   mNphi = NULL;
    97   mTNphi = NULL;
    98   // mPix = NULL;
    99   _pixel=NULL;
    100   mNTheta = mNPet = 0;
    101   mNPix = 0;
    102 }
    103 
    104 /* --Methode-- */
    105 void SphereThetaPhi::Clear()
    106 
    107 {
    108   if (mTheta)  delete[] mTheta;
    109   if (mNphi)  delete[] mNphi;
    110   if (mTNphi) delete[] mTNphi;
    111   //if (mPix)   delete[] mPix;
    112   if (_pixel) _pixel->Detach();
    113   mTheta = NULL;
    114   mNphi = NULL;
    115   mTNphi = NULL;
    116   //mPix = NULL;
    117   _pixel=NULL;
    118   mNTheta = mNPet = 0;
    119   mNPix = 0;
    120 }
    121 
    122 /* --Methode-- */
    123 //++
    124 void SphereThetaPhi::WriteSelf(POutPersist& s) const
    125 
    126 //    créer un fichier image
    127 //--
    128 {
    129   char strg[256];
    130   if (mInfo_) {sprintf(strg, "SphereThetaPhi: NSlices=%6d  NPix=%9d HasInfo", (int_4)mNTheta, (int_4)mNPix);
    131   }
    132   else { sprintf(strg, "SphereThetaPhi: NSlices=%6d  NPix=%9d ",
    133                (int_4)mNTheta, (int_4)mNPix);
    134   }
    135   s.PutLine(strg);
    136   if (mInfo_)  s << (*mInfo_);
    137   s.PutI4(mNTheta);
    138   s.PutI4(mNPet);
    139   s.PutI4(mNPix);
    140   s.PutR8(mOmeg);
    141   s.PutR4s(mTheta, mNTheta+1);
    142   s.PutI4s(mNphi, mNTheta);
    143   s.PutI4s(mTNphi, mNTheta+1);
    144   s.PutR8s(_pixel->Data(), mNPix);
    145   //s.PutR8s(mPix, mNPix);
    146   return;
    147 }
    148 
    149 /* --Methode-- */
    150 //++
    151 void SphereThetaPhi::ReadSelf(PInPersist& s)
    152 
    153 //    relit un fichier d'image
     142  NTheta_= 0;
     143  NPix_  = 0;
     144  Theta_ = NULL;
     145  NPhi_  = NULL;
     146  TNphi_ = NULL;
     147  pixels_.Reset();
     148}
     149
     150/* --Methode-- */
     151template <class T>
     152void SphereThetaPhi<T>::Clear()
     153
     154{
     155  if(Theta_)  delete[] Theta_;
     156  if(NPhi_ )  delete[] NPhi_;
     157  if(TNphi_)  delete[] TNphi_;
     158  InitNul();
     159}
     160
     161//++
     162template <class T>
     163void SphereThetaPhi<T>::Resize(int_4 m)
     164//   re-pixelize the sphere
    154165//--
    155166{
    156167  Clear();
    157   char strg[256];
    158   s.GetLine(strg, 255);
    159 // Pour savoir s'il y avait un DVList Info associe
    160   bool hadinfo = false;
    161   if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo = true;
    162   if (hadinfo) {    // Lecture eventuelle du DVList Info
    163     if (mInfo_ == NULL)  mInfo_ = new DVList;
    164     s >> (*mInfo_);
    165   }
    166   s.GetI4(mNTheta);
    167   s.GetI4(mNPet);
    168   s.GetI4(mNPix);
    169   s.GetR8(mOmeg);
    170   mTheta = new r_4[mNTheta+1];
    171   mNphi = new int_4[mNTheta];
    172   mTNphi = new int_4[mNTheta+1];
    173   //mPix = new r_8[mNPix+1];
    174   _pixel=new PDataArray<r_8>(mNPix,true);
    175   s.GetR4s(mTheta, mNTheta+1);
    176   s.GetI4s(mNphi, mNTheta);
    177   s.GetI4s(mTNphi, mNTheta+1);
    178   s.GetR8s(_pixel->Data(), mNPix);
    179   //s.GetR8s(mPix, mNPix);
    180   return;
    181 }
    182 
    183 
    184 /* --Methode-- */
    185 //++
    186 int_4 SphereThetaPhi::NbPixels() const
     168  Pixelize(m);
     169}
     170
     171/* --Methode-- */
     172//++
     173template <class T>
     174int_4 SphereThetaPhi<T>::NbPixels() const
    187175
    188176//    Retourne le nombre de pixels du découpage
    189177//--
    190178{
    191   return(mNPix);
    192 }
    193 
    194 
    195 static r_8 dummy_pixel = 0;
    196 
    197 /* --Methode-- */
    198 //++
    199 r_8& SphereThetaPhi::PixVal(int_4 k)
     179  return(NPix_);
     180}
     181
     182/* --Methode-- */
     183//++
     184template <class T>
     185T& SphereThetaPhi<T>::PixVal(int_4 k)
    200186
    201187//    Retourne la valeur du contenu du pixel d'indice k
    202188//--
    203189{
    204   if ( (k<0) || (k >= mNPix) ) {
    205     //  THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
    206     cout << " SphereThetaPhi::PIxVal : exceptions  a mettre en place" <<endl;
    207   THROW(rangeCheckErr);
    208 
    209     //throw "SphereThetaPhi::PIxVal Pixel index out of range";
    210   }
    211   return (*(_pixel->Data()+k));
    212   //return(mPix[k]);
    213 }
    214 //++
    215 r_8 const& SphereThetaPhi::PixVal(int_4 k) const
     190  if((k < 0) || (k >= NPix_))
     191    {
     192      //  THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
     193      cout << " SphereThetaPhi::PIxVal : exceptions  a mettre en place" <<endl;
     194      THROW(rangeCheckErr);
     195    }
     196  return pixels_(k);
     197}
     198
     199//++
     200template <class T>
     201T const& SphereThetaPhi<T>::PixVal(int_4 k) const
    216202
    217203//    Retourne la valeur du contenu du pixel d'indice k
    218204//--
    219205{
    220   if ( (k<0) || (k >= mNPix) ) {
    221     cout << " SphereThetaPhi::PIxVal : exceptions  a mettre en place" <<endl;
    222   //    THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
    223 
    224     throw "SphereThetaPhi::PIxVal Pixel index out of range";
    225   }
    226   return *(_pixel->Data()+k);
    227   //return(mPix[k]);
    228 }
    229 
    230 
    231 /* --Methode-- */
    232 //++
    233 int_4 SphereThetaPhi::PixIndexSph(r_4 theta, r_4 phi) const
     206  if((k < 0) || (k >= NPix_))
     207    {
     208      cout << " SphereThetaPhi::PIxVal : exceptions  a mettre en place" <<endl;
     209      //    THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
     210      throw "SphereThetaPhi::PIxVal Pixel index out of range";
     211    }
     212  return *(pixels_.Data()+k);
     213}
     214
     215/* --Methode-- */
     216//++
     217template <class T>
     218int_4 SphereThetaPhi<T>::PixIndexSph(r_4 theta, r_4 phi) const
    234219
    235220//    Retourne l'indice du pixel vers lequel pointe une direction définie par
     
    246231 
    247232  // La bande d'indice kt est limitée par les valeurs de theta contenues dans
    248   // mTheta[kt] et mTheta[kt+1]
    249   for( i=1; i< mNTheta; i++ )
    250     if( theta < mTheta[i] ) break;
    251  
    252   dphi= (r_4)DeuxPi/(r_4)mNphi[i-1];
    253  
    254   if (fgzn)  k= mNPix-mTNphi[i]+(int_4)(phi/dphi);
    255   else k= mTNphi[i-1]+(int_4)(phi/dphi);
    256  
     233  // Theta_[kt] et Theta_[kt+1]
     234  for( i=1; i< NTheta_; i++ )
     235    if( theta < Theta_[i] ) break;
     236 
     237  dphi= (r_4)DeuxPi/(r_4)NPhi_[i-1];
     238 
     239  if (fgzn)  k= NPix_-TNphi_[i]+(int_4)(phi/dphi);
     240  else k= TNphi_[i-1]+(int_4)(phi/dphi);
    257241  return(k);
    258242}
    259243
    260 
    261 /* --Methode-- */
    262 //++
    263 void SphereThetaPhi::PixThetaPhi(int_4 k, r_4& theta, r_4& phi) const
     244/* --Methode-- */
     245//++
     246template <class T>
     247void SphereThetaPhi<T>::PixThetaPhi(int_4 k, r_4& theta, r_4& phi) const
    264248
    265249//    Retourne les coordonnées (theta,phi) du milieu du pixel d'indice k
     
    269253  bool fgzn = false;
    270254 
    271   if( (k < 0) || (k >= mNPix) ) {theta = -99999.; phi = -99999.;  return; }
    272   if( k >= mNPix/2)  {fgzn = true;  k = mNPix-1-k; }
     255  if( (k < 0) || (k >= NPix_) ) {theta = -99999.; phi = -99999.;  return; }
     256  if( k >= NPix_/2)  {fgzn = true;  k = NPix_-1-k; }
    273257
    274258  // recupère l'indice i de la tranche qui contient le pixel k
    275   for( i=0; i< mNTheta; i++ )
    276     if( k < mTNphi[i+1] ) break;
     259  for( i=0; i< NTheta_; i++ )
     260    if( k < TNphi_[i+1] ) break;
    277261
    278262  // angle theta
    279   theta= 0.5*(mTheta[i]+mTheta[i+1]);
     263  theta= 0.5*(Theta_[i]+Theta_[i+1]);
    280264  if (fgzn) theta= Pi-theta;
    281265 
    282266  // angle phi
    283   k -= mTNphi[i];
    284   phi= (r_4)DeuxPi/(r_4)mNphi[i]*(r_4)(k+.5);
     267  k -= TNphi_[i];
     268  phi= (r_4)DeuxPi/(r_4)NPhi_[i]*(r_4)(k+.5);
    285269  if (fgzn) phi= DeuxPi-phi;
    286 
    287   return;
    288 }
    289 
    290 
    291 //++
    292 r_8         SphereThetaPhi::PixSolAngle(int_4 dummy) const
     270}
     271
     272//++
     273template <class T>
     274r_8  SphereThetaPhi<T>::PixSolAngle(int_4 dummy) const
     275
    293276//    Pixel Solid angle  (steradians)
    294277//    All the pixels have the same solid angle. The dummy argument is
     
    297280//--
    298281{
    299   return mOmeg;
    300 }
    301 
    302 
    303 /* --Methode-- */
    304 //++
    305 void SphereThetaPhi::Limits(int_4 k, r_4& tetMin, r_4& tetMax,
    306                            r_4& phiMin, r_4& phiMax)
     282  return Omega_;
     283}
     284
     285/* --Methode-- */
     286//++
     287template <class T>
     288void SphereThetaPhi<T>::Limits(int_4 k, r_4& tetMin, r_4& tetMax, r_4& phiMin, r_4& phiMax)
    307289
    308290//    Retourne les valeurs de theta et phi limitant le pixel d'indice k
     
    313295  bool fgzn= false;
    314296 
    315   if( (k< 0) || (k >= mNPix) ) {
     297  if( (k< 0) || (k >= NPix_) ) {
    316298    tetMin= -99999.;
    317299    phiMin= -99999.; 
     
    322304 
    323305  // si on se trouve dans l'hémisphère Sud
    324   if( k >= mNPix/2 ) {
     306  if( k >= NPix_/2 ) {
    325307    fgzn= true;
    326     k= mNPix-1-k;
     308    k= NPix_-1-k;
    327309  }
    328310 
    329311  // on recupere l'indice i de la tranche qui contient le pixel k
    330312  int i;
    331   for( i=0; i< mNTheta; i++ )
    332     if( k< mTNphi[i+1] ) break;
     313  for( i=0; i< NTheta_; i++ )
     314    if( k< TNphi_[i+1] ) break;
    333315 
    334316  // valeurs limites de theta dans l'hemisphere Nord
    335   tetMin= mTheta[i];
    336   tetMax= mTheta[i+1];
     317  tetMin= Theta_[i];
     318  tetMax= Theta_[i+1];
    337319  // valeurs limites de theta dans l'hemisphere Sud
    338320  if (fgzn) {
    339     tetMin= Pi-mTheta[i+1];
    340     tetMax= Pi-mTheta[i];
     321    tetMin= Pi-Theta_[i+1];
     322    tetMax= Pi-Theta_[i];
    341323  }
    342324 
    343325  // pixel correspondant dans l'hemisphere Nord
    344   if (fgzn) k= mTNphi[i+1]-k+mTNphi[i]-1;
     326  if (fgzn) k= TNphi_[i+1]-k+TNphi_[i]-1;
    345327 
    346328  // indice j de discretisation ( phi= j*dphi )
    347   j= k-mTNphi[i];
    348   dphi= (r_4)DeuxPi/(r_4)mNphi[i];
     329  j= k-TNphi_[i];
     330  dphi= (r_4)DeuxPi/(r_4)NPhi_[i];
    349331 
    350332  // valeurs limites de phi
     
    356338/* --Methode-- */
    357339//++
    358 int_4 SphereThetaPhi::NbThetaSlices() const
     340template <class T>
     341int_4 SphereThetaPhi<T>::NbThetaSlices() const
    359342
    360343//    Retourne le nombre de tranches en theta sur la sphere
     
    362345{
    363346  int_4 nbslices;
    364   nbslices= 2*mNTheta;
     347  nbslices= 2*NTheta_;
    365348  return(nbslices);
    366349}
     
    368351/* --Methode-- */
    369352//++
    370 int_4 SphereThetaPhi::NPhi(int_4 kt) const
     353template <class T>
     354int_4 SphereThetaPhi<T>::NPhi(int_4 kt) const
    371355
    372356//    Retourne le nombre de pixels en phi de la tranche kt
    373357//--
    374358{
    375  
    376   int_4 nbpix;
    377  
     359  int_4 nbpix; 
    378360  // verification
    379   if( (kt< 0) || (kt>= 2*mNTheta) ) return(-1);
     361  if( (kt< 0) || (kt>= 2*NTheta_) ) return(-1);
    380362 
    381363  // si on se trouve dans l'hemisphere Sud
    382   if( kt >= mNTheta ) {
    383     kt= 2*mNTheta-1-kt;
     364  if( kt >= NTheta_ ) {
     365    kt= 2*NTheta_-1-kt;
    384366  }
    385367 
    386368  // nombre de pixels
    387   nbpix= mNphi[kt];
     369  nbpix= NPhi_[kt];
    388370  return(nbpix);
    389371}
     
    392374/* --Methode-- */
    393375//++
    394 void SphereThetaPhi::Theta(int_4 kt,r_4& tetMin,r_4& tetMax)
     376template <class T>
     377void SphereThetaPhi<T>::Theta(int_4 kt,r_4& tetMin,r_4& tetMax)
    395378
    396379//    Retourne les valeurs de theta limitant la tranche kt
    397380//--
    398381{
    399  
    400382  bool fgzn= false;
    401  
    402383  // verification
    403   if( (kt< 0) || (kt>= 2*mNTheta) ) {
     384  if( (kt< 0) || (kt>= 2*NTheta_) ) {
    404385    tetMin= -99999.;
    405386    tetMax= -99999.;
     
    408389
    409390  // si on se trouve dans l'hemisphere Sud
    410   if( kt >= mNTheta ) {
     391  if( kt >= NTheta_ ) {
    411392    fgzn= true;
    412     kt= 2*mNTheta-1-kt;
     393    kt= 2*NTheta_-1-kt;
    413394  }
    414395 
    415396  // valeurs limites de theta dans l'hemisphere Nord
    416   tetMin= mTheta[kt];
    417   tetMax= mTheta[kt+1];
     397  tetMin= Theta_[kt];
     398  tetMax= Theta_[kt+1];
    418399  // valeurs limites de theta dans l'hemisphere Sud
    419400  if (fgzn) {
    420     tetMin= Pi-mTheta[kt+1];
    421     tetMax= Pi-mTheta[kt];
     401    tetMin= Pi-Theta_[kt+1];
     402    tetMax= Pi-Theta_[kt];
    422403  } 
    423404}
     
    425406/* --Methode-- */
    426407//++
    427 void SphereThetaPhi::Phi(int_4 kt,int_4 jp,r_4& phiMin,r_4& phiMax)
     408template <class T>
     409void SphereThetaPhi<T>::Phi(int_4 kt,int_4 jp,r_4& phiMin,r_4& phiMax)
    428410
    429411//    Retourne les valeurs de phi limitant le pixel jp de la tranche kt
    430412//--
    431413{
    432  
    433   r_4 dphi;
    434  
    435414  // verification
    436   if( (kt< 0) || (kt>= 2*mNTheta) ) {
     415  if( (kt< 0) || (kt>= 2*NTheta_) ) {
    437416    phiMin= -99999.;
    438417    phiMax= -99999.;
     
    441420 
    442421  // si on se trouve dans l'hemisphere Sud
    443   if( kt >= mNTheta ) kt= 2*mNTheta-1-kt;
     422  if( kt >= NTheta_ ) kt= 2*NTheta_-1-kt;
    444423 
    445424  // verifie si la tranche kt contient au moins jp pixels
    446   if( (jp< 0) || (jp >= mNphi[kt]) ) {
     425  if( (jp< 0) || (jp >= NPhi_[kt]) ) {
    447426    phiMin= -88888.;
    448427    phiMax= -88888.;
     
    450429  }
    451430 
    452   dphi= (r_4)DeuxPi/(r_4)mNphi[kt];
     431  r_4 dphi= (r_4)DeuxPi/(r_4)NPhi_[kt];
    453432  phiMin= dphi*(r_4)(jp);
    454433  phiMax= dphi*(r_4)(jp+1);
     
    458437/* --Methode-- */
    459438//++
    460 int_4 SphereThetaPhi::Index(int_4 kt,int_4 jp) const
     439template <class T>
     440int_4 SphereThetaPhi<T>::Index(int_4 kt,int_4 jp) const
    461441
    462442//    Retourne l'indice du pixel d'indice jp dans la tranche kt
    463443//--
    464444{
    465  
    466445  int_4 k;
    467446  bool fgzn= false;
    468447 
    469448  // si on se trouve dans l'hemisphere Sud
    470   if( kt >= mNTheta ) {
     449  if( kt >= NTheta_ ) {
    471450    fgzn= true;
    472     kt= 2*mNTheta-1-kt;
     451    kt= 2*NTheta_-1-kt;
    473452  }
    474453 
    475454  // si la tranche kt contient au moins i pixels
    476   if( (jp>=0) && (jp<mNphi[kt]) ) {
    477     // dans l'hemisphere Sud
    478     if (fgzn) k= mNPix-mTNphi[kt+1]+jp;
    479     // dans l'hemisphere Nord
    480     else k= mTNphi[kt]+jp;
    481   }
    482   else{
    483     k= 9999;
    484     printf("\n la tranche %d ne contient pas un pixel de rang %d",kt,jp);
    485   }
     455  if( (jp>=0) && (jp<NPhi_[kt]) )
     456    {
     457      // dans l'hemisphere Sud
     458      if (fgzn) k= NPix_-TNphi_[kt+1]+jp;
     459      // dans l'hemisphere Nord
     460      else k= TNphi_[kt]+jp;
     461    }
     462  else
     463    {
     464      k= 9999;
     465      printf("\n la tranche %d ne contient pas un pixel de rang %d",kt,jp);
     466    }
    486467  return(k);
    487468}
     
    489470/* --Methode-- */
    490471//++
    491 void SphereThetaPhi::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp)
     472template <class T>
     473void SphereThetaPhi<T>::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp)
    492474
    493475//    Retourne les indices kt et jp du pixel d'indice k
    494476//--
    495477{
    496  
    497   bool fgzn= false;
    498  
     478  bool fgzn= false; 
    499479  // si on se trouve dans l'hemisphere Sud
    500   if( k >= mNPix/2 ) {
     480  if( k >= NPix_/2 ) {
    501481    fgzn= true;
    502     k= mNPix-1-k;
     482    k= NPix_-1-k;
    503483  }
    504484 
    505485  // on recupere l'indice kt de la tranche qui contient le pixel k
    506486  int i;
    507   for( i=0; i< mNTheta; i++ )
    508     if( k< mTNphi[i+1] ) break;
     487  for( i=0; i< NTheta_; i++ )
     488    if( k< TNphi_[i+1] ) break;
    509489 
    510490  // indice  kt de tranche
    511   if (fgzn) kt= 2*mNTheta-1-i;
     491  if (fgzn) kt= 2*NTheta_-1-i;
    512492  else kt= i;
    513493 
    514494  // indice jp de pixel
    515   if (fgzn) jp= mTNphi[i+1]-k-1;
    516   else jp= k-mTNphi[i];
    517  
    518 }
    519 //++
    520 void  SphereThetaPhi::Pixelize( int_4 m, int_4 pet)
     495  if (fgzn) jp= TNphi_[i+1]-k-1;
     496  else jp= k-TNphi_[i];
     497 
     498}
     499//++
     500template <class T>
     501void  SphereThetaPhi<T>::Pixelize( int_4 m)
    521502
    522503//    effectue le découpage en pixels (m et pet ont la même signification
     
    531512{
    532513  int_4 ntotpix,i,j;
    533   //r_8 x, omeg, omeg2pi, teti, tetm, tet, nphi, costeti;
    534   r_8 omeg2pi;
     514 
    535515  // Decodage et controle des arguments d'appel :
    536516  // au moins 2 et au plus 16384 bandes d'un hemisphere en theta
     
    538518  if (m > 16384) m = 16384;
    539519 
    540   // Au moins 4 et au plus 256 pixels dans la premiere bande decoupee en phi
    541   if (pet < 4) pet = 4;
    542   if (pet > 256) pet = 256;
    543  
    544520  // On memorise les arguments d'appel
    545   mNTheta = m;  mNPet = pet;
     521  NTheta_ = m; 
    546522 
    547523  // On commence par decouper l'hemisphere z>0.
    548524  // Creation des vecteurs contenant :
    549525  // Les valeurs limites de theta (une valeur de plus que le nombre de bandes...)
    550   mTheta = new r_4[m+1];
     526  Theta_= new r_4[m+1];
    551527 
    552528  // Le nombre de pixels en phi de chacune des bandes en theta
    553   mNphi = new int_4[m];
     529  NPhi_ = new int_4[m];
    554530 
    555531  // Le nombre/Deuxpi total des pixels contenus dans les bandes de z superieur a une
    556532  // bande donnee (mTPphi[m] contient le nombre de pixels total de l'hemisphere)
    557   mTNphi = new int_4[m+1];
     533  TNphi_= new int_4[m+1];
    558534 
    559535  // Calcul du nombre total de pixels dans chaque bande pour optimiser
     
    561537 
    562538  //calotte polaire
    563   mTNphi[0]=0;
    564   mNphi[0] = 1;
     539  TNphi_[0]= 0;
     540  NPhi_[0] = 1;
    565541 
    566542  //bandes jusqu'a l'equateur
    567   for(j=1; j < m; j++) {
    568     mTNphi[j] = mTNphi[j-1]+mNphi[j-1];
    569     mNphi[j]  = (int_4)(.5+4.*(double)(m-.5)*sin(Pi*(double)j/(double)(2.*m-1.))) ;
    570   }
     543  for(j = 1; j < m; j++)
     544    {
     545      TNphi_[j]= TNphi_[j-1]+NPhi_[j-1];
     546      NPhi_[j] = (int_4)(.5+4.*(double)(m-.5)*sin(Pi*(double)j/(double)(2.*m-1.))) ;
     547    }
    571548 
    572549  // Nombre total de pixels sur l'hemisphere
    573   ntotpix = mTNphi[m-1]+mNphi[m-1];
    574   mTNphi[m] = ntotpix;
     550  ntotpix  = TNphi_[m-1]+NPhi_[m-1];
     551  TNphi_[m]= ntotpix;
    575552  // et sur la sphere entiere
    576   mNPix=2*ntotpix;
     553  NPix_= 2*ntotpix;
    577554 
    578555  // Creation et initialisation du vecteur des contenus des pixels
    579   //mPix = new r_8[mNPix];
    580   //for(i=0; i<mNPix; i++)  mPix[i] = 0.;
    581   _pixel=new PDataArray<r_8>(mNPix,true);
    582   for(i=0; i<mNPix; i++)  *(_pixel->Data()+i)=0.;
     556  pixels_.ReSize(NPix_);
     557  pixels_.Reset();
     558
    583559  // Determination des limites des bandes en theta :
    584560  // omeg est l'angle solide couvert par chaque pixel,
    585   // une bande donnee kt couvre un angle solide mNphi[kt]*omeg
    586   // egal a 2* Pi*(cos mTheta[kt]-cos mTheta[kt+1]). De meme, l'angle solide
     561  // une bande donnee kt couvre un angle solide NPhi_[kt]*omeg
     562  // egal a 2* Pi*(cos Theta_[kt]-cos Theta_[kt+1]). De meme, l'angle solide
    587563  //de la
    588564  // calotte allant du pole a la limite haute de la bande kt vaut
    589   // 2* Pi*(1.-cos mTheta[kt+1])= mTNphi[kt]*omeg...
    590  
    591   omeg2pi = 1./(r_8)ntotpix;
    592   mOmeg = omeg2pi*DeuxPi;
    593  
    594   for(j=0; j <= m; j++) {
    595     mTheta[j] = acos(1.-(double)mTNphi[j]*omeg2pi);
    596   }
    597 }
    598 
    599 
    600 //++
    601 void  SphereThetaPhi::GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const
     565  // 2* Pi*(1.-cos Theta_[kt+1])= TNphi_[kt]*omeg...
     566 
     567  double omeg2pi= 1./(double)ntotpix;
     568  Omega_ = omeg2pi*DeuxPi;
     569 
     570  for(j=0; j <= m; j++)
     571    {
     572      Theta_[j]= acos(1.-(double)TNphi_[j]*omeg2pi);
     573    }
     574}
     575
     576//++
     577template <class T>
     578void  SphereThetaPhi<T>::GetThetaSlice(int_4 index, r_4& theta, TVector<float>& phi, TVector<T>& value) const
    602579
    603580//    Retourne, pour la tranche en theta d'indice 'index' le theta
     
    609586{
    610587  cout << "entree GetThetaSlice, couche no " << index << endl;
    611   if (index<0 || index > NbThetaSlices()) {
    612     // THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
    613     cout << " SphereThetaPhi::GetThetaSlice : exceptions  a mettre en place" <<endl;
    614   THROW(rangeCheckErr);
    615   }
    616   int_4 iring=Index(index,0);
    617   int_4 bid=this->NPhi(index);
    618   int lring=bid;
     588
     589  if(index < 0 || index > NbThetaSlices())
     590    {
     591      // THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
     592      cout << " SphereThetaPhi::GetThetaSlice : exceptions  a mettre en place" <<endl;
     593      THROW(rangeCheckErr);
     594    }
     595
     596  int_4 iring= Index(index,0);
     597  int_4 bid  = this->NPhi(index);
     598  int lring  = bid;
    619599  cout << " iring= " << iring << " lring= " << lring << endl;
    620   phi.Realloc(lring);
    621   value.Realloc(lring);
    622   float T=0.;
    623   float F=0.;
    624   for (int kk=0; kk<lring;kk++) {
    625     PixThetaPhi(kk+iring,T,F);
    626     phi(kk)=F;
    627     value(kk)=PixVal(kk+iring);
    628   }
    629   theta=T;
    630 
    631 }
    632 
    633 
    634 /* --Methode-- */
    635 
     600
     601  phi.ReSize(lring);
     602  value.ReSize(lring);
     603  float Te= 0.;
     604  float Fi= 0.;
     605  for(int kk = 0; kk < lring; kk++)
     606    {
     607      PixThetaPhi(kk+iring,Te,Fi);
     608      phi(kk)= Fi;
     609      value(kk)= PixVal(kk+iring);
     610    }
     611  theta= Te;
     612}
     613
     614template <class T>
     615void SphereThetaPhi<T>::setmNPhi(int_4* array, int_4 m)
     616  //remplit  le tableau contenant le nombre de pixels en phi de chacune des bandes en theta
     617  //--
     618{
     619  NPhi_= new int_4[m];
     620  for(int k = 0; k < m; k++) NPhi_[k]= array[k];
     621}
     622
     623template <class T>
     624void SphereThetaPhi<T>::setmTNphi(int_4* array, int_4 m)
     625  //remplit  le tableau contenant le nombre/Deuxpi total des pixels contenus dans les bandes
     626  //--
     627{
     628  TNphi_= new int_4[m];
     629  for(int k = 0; k < m; k++) TNphi_[k]= array[k];
     630}
     631
     632template <class T>
     633void SphereThetaPhi<T>::setmTheta(r_4* array, int_4 m)
     634  //remplit  le tableau contenant les valeurs limites de theta
     635  //--
     636{
     637  Theta_= new r_4[m];
     638  for(int k = 0; k < m; k++) Theta_[k]= array[k];
     639}
     640
     641template <class T>
     642void SphereThetaPhi<T>::setDataBlock(T* data, int_4 m)
     643  // remplit  le vecteur des contenus des pixels
     644{
     645  pixels_.FillFrom(m,data);
     646}
     647
     648template <class T>
     649void SphereThetaPhi<T>::print(ostream& os) const
     650{
     651  if(mInfo_) os << "  DVList Info= " << *mInfo_ << endl;
     652  //
     653  os << " NTheta_= " << NTheta_ << endl;
     654  os << " NPix_    = " << NPix_   << endl;
     655  os << " Omega_  =  " << Omega_   << endl;
     656
     657  os << " contenu de NPhi_ : ";
     658  for(int i=0; i < NTheta_; i++)
     659    {
     660      if(i%5 == 0) os << endl;
     661      os << NPhi_[i] <<", ";
     662    }
     663  os << endl;
     664
     665  os << " contenu de Theta_ : ";
     666  for(int i=0; i < NTheta_+1; i++)
     667    {
     668      if(i%5 == 0) os << endl;
     669      os << Theta_[i] <<", ";
     670    }
     671  os << endl;
     672
     673  os << " contenu de TNphi_ : ";
     674  for(int i=0; i < NTheta_+1; i++)
     675    {
     676      if(i%5 == 0) os << endl;
     677      os << TNphi_[i] <<", ";
     678    }
     679  os << endl;
     680
     681  os << " contenu de pixels : ";
     682  for(int i=0; i < NPix_; i++)
     683    {
     684      if(i%5 == 0) os << endl;
     685      os <<  pixels_(i) <<", ";
     686    }
     687  os << endl;
     688}
     689
     690///////////////////////////////////////////////////////////
     691// --------------------------------------------------------
     692//   Les objets delegues pour la gestion de persistance
     693// --------------------------------------------------------
     694//////////////////////////////////////////////////////////
     695
     696template <class T>
     697FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi()
     698{
     699  dobj= new SphereThetaPhi<T>;
     700  ownobj= true;
     701}
     702
     703template <class T>
     704FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(string const& filename)
     705{
     706  dobj= new SphereThetaPhi<T>;
     707  ownobj= true;
     708  Read(filename);
     709}
     710
     711template <class T>
     712FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(const SphereThetaPhi<T>& obj)
     713{
     714  dobj= new SphereThetaPhi<T>(obj);
     715  ownobj= true;
     716}
     717
     718template <class T>
     719FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(SphereThetaPhi<T>* obj)
     720{
     721  dobj= obj;
     722  ownobj= false;
     723}
     724
     725template <class T>
     726FIO_SphereThetaPhi<T>::~FIO_SphereThetaPhi()
     727{
     728  if (ownobj && dobj) delete dobj;
     729}
     730
     731template <class T>
     732AnyDataObj* FIO_SphereThetaPhi<T>::DataObj()
     733{
     734  return(dobj);
     735}
     736
     737template <class T>
     738void FIO_SphereThetaPhi<T>::ReadSelf(PInPersist& is)
     739{
     740  cout << " FIO_SphereThetaPhi:: ReadSelf " << endl;
     741
     742  if(dobj == NULL)
     743    {
     744      dobj= new SphereThetaPhi<T>;
     745    }
     746
     747  // Pour savoir s'il y avait un DVList Info associe
     748  char strg[256];
     749  is.GetLine(strg, 255);
     750  bool hadinfo= false;
     751  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
     752  if(hadinfo)
     753    {    // Lecture eventuelle du DVList Info
     754      is >> dobj->Info();
     755    }
     756
     757  int_4 mNTheta;
     758  is.GetI4(mNTheta); 
     759  dobj->setSizeIndex(mNTheta);
     760
     761  int_4 mNPix;
     762  is.GetI4(mNPix);
     763  dobj->setNbPixels(mNPix);
     764
     765  r_8 mOmeg;
     766  is.GetR8(mOmeg);
     767  dobj->setPixSolAngle(mOmeg);
     768
     769  int_4* mNphi= new int_4[mNTheta];
     770  is.GetI4s(mNphi, mNTheta);
     771  dobj->setmNPhi(mNphi, mNTheta);
     772  delete [] mNphi;
     773
     774  int_4* mTNphi= new int_4[mNTheta+1];
     775  is.GetI4s(mTNphi, mNTheta+1);
     776  dobj->setmTNphi(mTNphi, mNTheta+1);
     777  delete [] mTNphi;
     778
     779  r_4* mTheta= new r_4[mNTheta+1];
     780  is.GetR4s(mTheta, mNTheta+1);
     781  dobj->setmTheta(mTheta, mNTheta+1);
     782  delete [] mTheta;
     783
     784  T* mPixels= new T[mNPix];
     785  //is.Get(mPixels, mNPix);
     786  PIOSReadArray(is, mPixels, mNPix);
     787  dobj->setDataBlock(mPixels, mNPix);
     788  delete [] mPixels;
     789}
     790
     791template <class T>
     792void FIO_SphereThetaPhi<T>::WriteSelf(POutPersist& os) const
     793{
     794  cout << " FIO_SphereThetaPhi:: WriteSelf " << endl;
     795
     796  if(dobj == NULL)
     797    {
     798      cout << " WriteSelf:: dobj= null " << endl;
     799      return;
     800    }
     801
     802  char strg[256];
     803  int_4 mNTheta= dobj->SizeIndex();
     804  int_4 mNPix  = dobj->NbPixels();
     805 
     806  if(dobj->ptrInfo())
     807    {
     808      sprintf(strg,"SphereThetaPhi: NSlices=%6d  NPix=%9d HasInfo",mNTheta,mNPix);
     809      os.PutLine(strg);
     810      os << dobj->Info();
     811    }
     812  else
     813    {
     814      sprintf(strg,"SphereThetaPhi: NSlices=%6d  NPix=%9d ",mNTheta,mNPix);
     815      os.PutLine(strg); 
     816    }
     817
     818  os.PutI4(mNTheta); 
     819  os.PutI4(mNPix);
     820  os.PutR8(dobj->PixSolAngle(0));
     821  os.PutI4s(dobj->getmNPhi() , mNTheta);
     822  os.PutI4s(dobj->getmTNphi(), mNTheta+1);
     823  os.PutR4s(dobj->getmTheta(), mNTheta+1);
     824  //os.Put((dobj->getDataBlock())->Data(), mNPix);
     825  PIOSWriteArray(os,(dobj->getDataBlock())->Data(), mNPix);
     826}
  • trunk/SophyaLib/Samba/spherethetaphi.h

    r228 r470  
    33
    44#include "sphericalmap.h"
    5 #include "pdataarray.h"
    6 #include "cvector.h"
     5#include "ndatablock.h"
     6#include "tvector.h"
    77
    8 // ***************** CLASSE SphereThetaPhi *****************************
     8#include "anydataobj.h"
     9#include "ppersist.h"
    910
     11// ***************** Class SphereThetaPhi *****************************
    1012
    11 class SphereThetaPhi : public SphericalMap {
     13template <class T>
     14class SphereThetaPhi : public SphericalMap<T>, public AnyDataObj
     15{
     16
    1217public :
    1318
    14 
    15 SphereThetaPhi(int_4 m, int_4 pet);
    1619SphereThetaPhi();
     20SphereThetaPhi(int_4 m);
    1721SphereThetaPhi(char* flnm);
     22SphereThetaPhi(const SphereThetaPhi<T>& s);
    1823virtual ~SphereThetaPhi();
    1924
    20 // ------------ Persistence handling
     25// ------------ Definition of PixelMap abstract methods -
    2126
    22      enum {classId = 0xF001 };
    23 int_4                  ClassId() const        { return classId; }
     27/* retourne/fixe le nombre de pixels */
     28virtual int_4 NbPixels() const;
     29inline void setNbPixels(int_4 nbpix) { NPix_= nbpix; }
    2430
    25 virtual void           WriteSelf(POutPersist&) const;
    26 virtual void           ReadSelf(PInPersist&);
     31/* retourne la valeur du pixel d'indice k */
     32virtual T&       PixVal(int_4 k);
     33virtual T const& PixVal(int_4 k) const;
    2734
    28 // ------------------ Definition of PixelMap abstract methods
     35/* retourne l'indice du pixel a (theta,phi) */
     36virtual int_4 PixIndexSph(float theta, float phi) const;
    2937
    30 // number of pixels
    31 virtual  int_4           NbPixels() const;
     38/* retourne les coordonnees Spheriques du centre du pixel d'indice k */
     39virtual void PixThetaPhi(int_4 k, float& theta, float& phi) const;
    3240
    33 // Value of pixel number k
    34 virtual  r_8&       PixVal(int_4 k);
    35 virtual  r_8 const&       PixVal(int_4 k) const;
     41/* retourne/fixe l'angle Solide de Pixel   (steradians) */
     42virtual r_8 PixSolAngle(int_4 dummy) const;
     43inline void setPixSolAngle(r_8 omega) { Omega_= omega; }
     44 
     45/* retourne/fixe la valeur du parametre de decoupage m */
     46inline virtual int_4 SizeIndex() const { return( NTheta_); }
     47inline void setSizeIndex(int_4 nbindex) { NTheta_= nbindex; }
    3648
    37 // Index of pixel at (theta,phi)
    38 virtual  int_4           PixIndexSph(float theta, float phi) const;
     49// ------------- Specific methods  ----------------------
    3950
    40 // Spherical coordinates of center of pixel number k
    41 virtual  void          PixThetaPhi(int_4 k, float& theta, float& phi) const;
     51virtual void Resize(int_4 m);
    4252
    43 // Pixel Solid angle  (steradians)
    44 virtual r_8         PixSolAngle(int_4 dummy) const;
    45 // --------------- Specific methods
     53inline virtual char* TypeOfMap() const {return "TETAFI";};
    4654
     55/* Valeurs de theta des paralleles et phi des meridiens limitant  le pixel d'indice k */
     56virtual void Limits(int_4 k,float& tet1,float& tet2,float& phi1,float& phi2);
    4757
    48 /* Valeurs de theta des paralleles et phi des meridiens limitant          */
    49 /* le pixel d'indice k                                                   */
    50 virtual  void          Limits(int_4 k, float& tet1, float& tet2,
    51                                 float& phi1, float& phi2 );
     58/* Nombre de tranches en theta */
     59int_4 NbThetaSlices() const;
    5260
    53 /* Nombre de tranches en theta                                           */
    54 int_4           NbThetaSlices() const;
    55 
    56 /* Nombre de pixels en phi de la tranche d'indice kt                     */
    57 int_4           NPhi(int_4 kt) const;
     61/* Nombre de pixels en phi de la tranche d'indice kt */
     62int_4 NPhi(int_4 kt) const;
    5863
    5964/* Renvoie dans t1,t2 les valeurs respectives de theta min et theta max  */
    60 /* de la tranche d'indice kt                                             */
    61 void          Theta(int_4 kt, float& t1, float& t2);
     65/* de la tranche d'indice kt  */
     66void Theta(int_4 kt, float& t1, float& t2);
    6267
    6368/* Renvoie dans p1,p2 les valeurs phimin et phimax du pixel d'indice jp  */
    64 /* dans la tranche d'indice kt                                           */
    65 void          Phi(int_4 kt, int_4 jp, float& p1, float& p2);
     69/* dans la tranche d'indice kt  */
     70void Phi(int_4 kt, int_4 jp, float& p1, float& p2);
    6671
    6772/* Renvoie l'indice k du pixel d'indice jp dans la tranche d'indice kt   */
    68 int_4           Index(int_4 kt, int_4 jp) const;
     73int_4 Index(int_4 kt, int_4 jp) const;
    6974
     75/* Indice kt de la tranche et indice jp du pixel d'indice k  */
     76void ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp);
    7077
    71 /* Indice kt de la tranche et indice jp du pixel d'indice k            */
    72 void          ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp);
     78void Pixelize(int_4);
    7379
    74 void Pixelize(int_4,int_4);
    75 void GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const;
     80void GetThetaSlice(int_4 index,r_4& theta,TVector<float>& phi,TVector<T>& value) const;
    7681
     82/*retourne le tableau contenant le nombre de pixels en phi de chacune des bandes en theta */
     83inline const int_4* getmNPhi() const { return(NPhi_); }
     84void setmNPhi(int_4* array, int_4 m);
     85
     86/* retourne/remplit le tableau contenant le nombre/Deuxpi total des pixels contenus dans les bandes */
     87inline const int_4* getmTNphi() const { return(TNphi_); }
     88void setmTNphi(int_4* array, int_4 m);
     89
     90/* retourne/remplit le tableau contenant les valeurs limites de theta */
     91inline const r_4* getmTheta() const { return(Theta_); }
     92void setmTheta(r_4* array, int_4 m);
     93
     94/* retourne le pointeur vers/remplit  le vecteur des contenus des pixels */
     95inline const NDataBlock<T>* getDataBlock() const { return (&pixels_); }
     96void setDataBlock(T* data, int_4 m);
     97
     98/* impression */
     99void print(ostream& os) const;
    77100
    78101private :
    79 // ------------- méthodes internes ----------------------
    80          
    81102
    82 void          InitNul();
    83 void          Clear();
     103// ------------- méthodes internes ----------------------         
     104void InitNul();
     105void Clear();
    84106
    85 // ------------- variables internes -----------------------
    86 int_4 mNTheta,mNPet;
    87 int_4 mNPix;
    88 r_4* mTheta;
    89 r_8  mOmeg;
    90 int_4* mNphi;
    91 int_4* mTNphi;
    92 //r_8* mPix;
    93 PDataArray<r_8>* _pixel;
    94 
    95 
     107// ------------- variables internes ---------------------
     108int_4 NTheta_;
     109int_4 NPix_;
     110r_8 Omega_;
     111int_4* NPhi_;
     112int_4* TNphi_;
     113r_4* Theta_;
     114NDataBlock<T> pixels_;
    96115};
    97116
     117// ------------- Classe pour la gestion de persistance --
     118template <class T>
     119class FIO_SphereThetaPhi : public PPersist 
     120{
     121public:
    98122
     123FIO_SphereThetaPhi();
     124FIO_SphereThetaPhi(string const & filename);
     125FIO_SphereThetaPhi(const SphereThetaPhi<T>& obj);
     126FIO_SphereThetaPhi(SphereThetaPhi<T>* obj);
     127virtual ~FIO_SphereThetaPhi();
     128virtual AnyDataObj* DataObj();
     129inline operator SphereThetaPhi<T>() { return(*dobj); }
     130inline SphereThetaPhi<T> getObj() { return(*dobj); }
     131
     132protected :
     133
     134virtual void ReadSelf(PInPersist&);           
     135virtual void WriteSelf(POutPersist&) const; 
     136SphereThetaPhi<T>* dobj;
     137bool ownobj;
     138};
    99139
    100140#endif
  • trunk/SophyaLib/Samba/sphericalmap.h

    r228 r470  
    66#include <math.h>
    77#include "pixelmap.h"
    8 #include "cvector.h"
     8#include "tvector.h"
     9
    910// Map of pixels on a whole sphere.
    1011// Class hierarchy :
     
    1617//      LocalMap
    1718
    18 class SphericalMap : public PixelMap {
     19template<class T>
     20class SphericalMap : public PixelMap<T>
     21{
     22 
     23public :
    1924
    20 public :
    2125SphericalMap() {};
    2226virtual  ~SphericalMap() {};
    2327
    24    // Overloading of () to access pixel number k.
    25    inline  r_8&        operator()(int_4 k)
    26                           {return(PixVal(k));}
    27    inline  r_8 const&  operator()(int_4 k) const
    28                           {return(PixVal(k));}
    29 inline  r_8&        operator()(float theta, float phi)
    30                 { return(PixValSph(theta, phi)) ; };
    31 inline  r_8 const&        operator()(float theta, float phi) const
    32                 { return(PixValSph(theta, phi)) ; };
     28// Overloading of () to access pixel number k.
     29inline T& operator()(int_4 k) {return(PixVal(k));}
     30inline T  const& operator()(int_4 k) const {return(PixVal(k));}
     31inline T& operator()(float theta,float phi) {return(PixValSph(theta,phi));};
     32inline T  const& operator()(float theta,float phi) const {return(PixValSph(theta,phi));};
    3333
    34 
     34// index characterizing the size pixelization : m for SphereThetaPhi
     35// nside for Gorski sphere...
     36virtual void Resize(int_4 m)=0;
    3537virtual int_4 NbThetaSlices() const=0;
    36 virtual void GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const=0;
     38virtual void GetThetaSlice(int_4 index, r_4& theta, TVector<float>& phi, TVector<T>& value) const=0;
    3739};
    38 
    3940#endif
    4041
Note: See TracChangeset for help on using the changeset viewer.