| [658] | 1 | #include <math.h>
 | 
|---|
 | 2 | #include "anagen.h"
 | 
|---|
 | 3 | #include "lambuilder.h"
 | 
|---|
 | 4 | #include "fftserver.h"
 | 
|---|
 | 5 | 
 | 
|---|
 | 6 | /* assumes the map is symmetric about the equator and that
 | 
|---|
 | 7 | each strip is divided equally*/
 | 
|---|
 | 8 |  
 | 
|---|
 | 9 | extern "C" {
 | 
|---|
 | 10 |   void fft_gpd_(long double* ,int& ,int& ,int& ,int& ,long double*);
 | 
|---|
 | 11 |            }
 | 
|---|
 | 12 | 
 | 
|---|
 | 13 | void map2almgen(int nsmax,int nlmax,int nmmax,const SphericalMap<double>& map,
 | 
|---|
 | 14 |              vector< vector< complex<double> > >& alm, double cos_theta_cut){
 | 
|---|
 | 15 |   
 | 
|---|
 | 16 |   //       REAL*4  map(12*nsmax**2)               ! 4*12*nsmax**2
 | 
|---|
 | 17 |   
 | 
|---|
 | 18 |   //       REAL*4 powspec(0:nlmax)
 | 
|---|
 | 19 |     
 | 
|---|
 | 20 |   //       integer npmiss,npmt,id_miss(10000)
 | 
|---|
 | 21 |   
 | 
|---|
 | 22 |   alm.resize(nlmax+1);
 | 
|---|
 | 23 |   for (int i=0; i< (signed) alm.size();i++)
 | 
|---|
 | 24 |     {
 | 
|---|
 | 25 |       alm[i].resize(nmmax+1);
 | 
|---|
 | 26 |       for (int j=0; j< (signed) alm[i].size();j++)alm[i][j]=0;
 | 
|---|
 | 27 |     }
 | 
|---|
 | 28 |   
 | 
|---|
 | 29 |   /*-----------------------------------------------------------------------
 | 
|---|
 | 30 |     computes the integral in phi : phas_m(theta)
 | 
|---|
 | 31 |     for each parallele from north to south pole
 | 
|---|
 | 32 |     -----------------------------------------------------------------------*/
 | 
|---|
 | 33 |   
 | 
|---|
 | 34 |   vector< complex<double> > phas_n(nmmax+1), phas_s(nmmax+1);
 | 
|---|
 | 35 |   for (int ith = 0; ith <= (map.NbThetaSlices()+1)/2-1;ith++){
 | 
|---|
 | 36 |     int nph;
 | 
|---|
 | 37 |     double phi0;
 | 
|---|
 | 38 |     double theta;
 | 
|---|
 | 39 |     Vector phin, datan, datas;
 | 
|---|
 | 40 |     TVector<double> phis;
 | 
|---|
 | 41 |     map.GetThetaSlice(map.NbThetaSlices()-ith-1,theta,phis,datas);
 | 
|---|
 | 42 |     map.GetThetaSlice(ith,theta,phin,datan);
 | 
|---|
 | 43 |     for (int i=0;i< nmmax+1;i++){
 | 
|---|
 | 44 |       phas_n[i]=0; phas_s[i]=0;
 | 
|---|
 | 45 |     }
 | 
|---|
 | 46 |     nph = phin.NElts();
 | 
|---|
 | 47 |     phi0 = phin(0); 
 | 
|---|
 | 48 |     double cth = cos(theta);
 | 
|---|
 | 49 | 
 | 
|---|
 | 50 |     //part of the sky out of the symetric cut
 | 
|---|
 | 51 |     bool keep_it = (abs(cth) >= cos_theta_cut); 
 | 
|---|
 | 52 | 
 | 
|---|
 | 53 |     //make sure that map is well defined
 | 
|---|
 | 54 |     if (keep_it){
 | 
|---|
 | 55 |       comp_phas2gen(nsmax,nlmax,nmmax,datan,nph,phas_n,phi0);
 | 
|---|
 | 56 |     }
 | 
|---|
 | 57 | 
 | 
|---|
 | 58 |     if (ith != map.NbThetaSlices()/2 && keep_it){
 | 
|---|
 | 59 |       comp_phas2gen(nsmax,nlmax,nmmax,datas,nph,phas_s,phi0);
 | 
|---|
 | 60 |     }
 | 
|---|
 | 61 |     /*-----------------------------------------------------------------------
 | 
|---|
 | 62 |       computes the a_lm by integrating over theta
 | 
|---|
 | 63 |       lambda_lm(theta) * phas_m(theta)
 | 
|---|
 | 64 |       for each m and l
 | 
|---|
 | 65 |       -----------------------------------------------------------------------*/
 | 
|---|
 | 66 |     LambdaBuilder lb(acos(cth),nlmax,nmmax);
 | 
|---|
 | 67 |     double domega=map.PixSolAngle(map.PixIndexSph(theta,phi0));
 | 
|---|
 | 68 |     for (int m = 0; m <= nmmax; m++)
 | 
|---|
 | 69 |       {
 | 
|---|
 | 70 |         alm[m][m] += (lb.lamlm(m,m) * (phas_n[m] + phas_s[m])) * domega; //m,m even
 | 
|---|
 | 71 |         for (int l = m+1; l<= nlmax; l++)
 | 
|---|
 | 72 |           {
 | 
|---|
 | 73 |             alm[l][m] += (lb.lamlm(l,m) * phas_n[m] + lb.lamlm(l,m,-1)*phas_s[m])*domega; //assuming the map is symmetric about the equator
 | 
|---|
 | 74 |           }
 | 
|---|
 | 75 |       }
 | 
|---|
 | 76 |   }
 | 
|---|
 | 77 | }
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 | 
 | 
|---|
 | 80 | void comp_phas2gen(int nsmax,int nlmax,int nmmax, Vector datain,
 | 
|---|
 | 81 |                 int nph,vector< complex<double> >& dataout,double phi0){
 | 
|---|
 | 82 |   /*=======================================================================
 | 
|---|
 | 83 |     integrates (data * phi-dependence-of-Ylm) over phi
 | 
|---|
 | 84 |     --> function of m can be computed by FFT
 | 
|---|
 | 85 |     with  0<= m <= npoints/2 (: Nyquist)
 | 
|---|
 | 86 |     because the data is real the negative m are the conjugate of the 
 | 
|---|
 | 87 |     positive ones
 | 
|---|
 | 88 |     
 | 
|---|
 | 89 |     arguments d'appels : GLM
 | 
|---|
 | 90 |     =======================================================================*/
 | 
|---|
 | 91 | 
 | 
|---|
 | 92 |   //FFTVector inf(datain);
 | 
|---|
 | 93 |   //FFTVector outf=FFTServer::solve(inf,-1);
 | 
|---|
 | 94 |   FFTServer fft;
 | 
|---|
 | 95 |   Vector outf;
 | 
|---|
 | 96 |   //cout<<"in :"<<datain<<endl;
 | 
|---|
 | 97 |   fft.fftb(datain,outf);
 | 
|---|
 | 98 |   //  cout<<outf<<endl;
 | 
|---|
 | 99 |   long double * data = new long double[nph*2];
 | 
|---|
 | 100 |   //outf.d((double*)data, nph);
 | 
|---|
 | 101 |   data[0]=outf(0); data[1]=0;
 | 
|---|
 | 102 |   for (int i=2;i<=nph;i++) data[i]=outf(i-1);
 | 
|---|
 | 103 |   for (int i=nph+1;i<2*nph;i++) data[i]=0;
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 |   int ksign = -1;
 | 
|---|
 | 106 | //   long double data[nph*2];
 | 
|---|
 | 107 | 
 | 
|---|
 | 108 | //   for (int i = 0; i< nph;i++){
 | 
|---|
 | 109 | //     data[2*i] = datain(i);
 | 
|---|
 | 110 | //     data[2*i+1]=0;
 | 
|---|
 | 111 | //   }
 | 
|---|
 | 112 | 
 | 
|---|
 | 113 | //   long double work[nph*2];
 | 
|---|
 | 114 | //   int dum1=1;
 | 
|---|
 | 115 | //   int dum0=0;
 | 
|---|
 | 116 | //   fft_gpd_(data,nph,dum1,ksign,dum0,work); /* real to complex 
 | 
|---|
 | 117 | //                                    for any nph (not necessary power of 2)*/
 | 
|---|
 | 118 | //     //in the output the frequencies are respectively 0,1,2,..,nph/2,-nph/2+1,..,-2,-1
 | 
|---|
 | 119 | //     //     only the first nph/2+1 (positive freq.) are interesting
 | 
|---|
 | 120 | //   for (int i=0;i<nph*2;i++){cout << "heh"<<test[i]<<" "<<data[i]<<endl;}*/
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 |   int im_max = min(nph/2,nmmax);
 | 
|---|
 | 123 |   dataout.resize(nmmax+1);
 | 
|---|
 | 124 |   for (int i = 1;i <= im_max + 1;i++){
 | 
|---|
 | 125 |     int  m = ksign*(i-1);
 | 
|---|
 | 126 |     complex<double> shit(data[2*(i-1)],data[2*(i-1)+1]);
 | 
|---|
 | 127 |     complex<double> fuck(cos(m*phi0),sin(m*phi0));
 | 
|---|
 | 128 |     dataout[i-1]=shit*fuck;
 | 
|---|
 | 129 |   }
 | 
|---|
 | 130 |   for (int i = im_max + 2;i <= nmmax + 1;i++){
 | 
|---|
 | 131 |          dataout[i-1] = 0;
 | 
|---|
 | 132 |   }
 | 
|---|
 | 133 |   delete data;
 | 
|---|
 | 134 | }
 | 
|---|