#include "sopnamsp.h" #include "tarray.h" #include "cimage.h" #include "skymap.h" #include "mapoperation.h" #include "sambainit.h" #include "fftwserver.h" #include //-------------------------------------------------------------------------- // Classe pour projeter localement (dans un tableau indexe i,j) // des coordonnees spheriques class MtxLM { public: MtxLM(double latdeg, double longdeg, double deltheta_min, double delphi_min, int_4 npixtheta, int_4 npixphi); MtxLM(TMatrix & mtx, bool uselat=true); virtual ~MtxLM(); void Init(double latdeg, double longdeg, double deltheta_min, double delphi_min, int_4 npixtheta, int_4 npixphi); // Conversion d'index de pixel (ip,jt) (ip: Phi/X/Column, jt: Theta/Y/Row ) // en Theta,Phi void ip_jt2tp(int_4 ip, int_4 jt, double& theta, double& phi); // Conversion de (Theta,Phi) en index de pixel (ip,jt) // (ip: Phi/X/Column, jt: Theta/Y/Row ) void tp2ipjt(double theta, double phi, int_4& ip, int_4& jt); double _latdeg, _longdeg; double _deltheta_min, _delphi_min; int_4 _npixtheta, _npixphi; double _theta0, _phi0; double _thetaC, _phiC; double _deltatheta, _deltaphi; static double _deuxpi; }; double MtxLM::_deuxpi = 2.*M_PI; MtxLM::MtxLM(double latdeg, double longdeg, double deltheta_min, double delphi_min, int_4 npixtheta, int_4 npixphi) { Init(latdeg, longdeg, deltheta_min, delphi_min, npixtheta, npixphi ); } //-------------------------------------------------------------------------- MtxLM::MtxLM(TMatrix & mtx, bool uselat) { double latdeg = (uselat) ? (double)mtx.Info()["Latitude_C"] : 0.; double longdeg = mtx.Info()["Longitude_C"]; double deltheta_min = mtx.Info()["LatPixSize"]; double delphi_min = mtx.Info()["LongPixSize"]; int_4 npixtheta = mtx.NRows(); int_4 npixphi = mtx.NCols(); Init(latdeg, longdeg, deltheta_min, delphi_min, npixtheta, npixphi); } MtxLM::~MtxLM() { } void MtxLM::Init(double latdeg, double longdeg, double deltheta_min, double delphi_min, int_4 npixtheta, int_4 npixphi) { _latdeg = latdeg; _longdeg = longdeg; _deltheta_min = deltheta_min; _delphi_min = delphi_min; _npixtheta = npixtheta; _npixphi = npixphi; _thetaC = (90.-latdeg)*M_PI/180.; _phiC = longdeg*M_PI/180.; _deltatheta = deltheta_min*M_PI/(180.*60.); _deltaphi = delphi_min*M_PI/(180.*60.)/sin(_thetaC); _theta0 = _thetaC-0.5*(double)_npixtheta*_deltatheta; if ((_thetaC + 0.5*(double)_npixtheta*_deltatheta) > M_PI-1.e-6) throw RangeCheckError("MtxLM::Init() ThetaMax out of range (> M_PI-1.e-6)"); if ((_thetaC - 0.5*(double)_npixtheta*_deltatheta) < 1.e-6) throw RangeCheckError("MtxLM::Init() ThetaMin out of range (< 1.e-6)"); double deltaphitot = delphi_min*M_PI/(180.*60.)/sin(_thetaC + 0.5*(double)_npixtheta*_deltatheta); if (deltaphitot*_npixphi > _deuxpi) throw RangeCheckError("MtxLM::Init() Wrapping will occur for Phi at ThetaMax ! "); deltaphitot = delphi_min*M_PI/(180.*60.)/sin(_thetaC - 0.5*(double)_npixtheta*_deltatheta); if (deltaphitot*_npixphi > _deuxpi) throw RangeCheckError("MtxLM::Init() Wrapping will occur for Phi at ThetaMin ! "); _phi0 = _phiC-0.5*(double)_npixphi*_deltaphi; return; } void MtxLM::ip_jt2tp(int_4 ip, int_4 jt, double& theta, double& phi) { theta = jt*_deltatheta+_theta0; if ( (theta<0.) || (theta > M_PI) ) throw RangeCheckError(" MtxLM::ip_jt2tp - Theta out of range !"); double delphi = _delphi_min*M_PI/(180.*60.)/sin(theta); double phi0 = _phiC-0.5*(double)_npixphi*delphi; // phi = ip*_deltaphi+_phi0; phi = ip*delphi+phi0; while (phi < 0.) phi += _deuxpi; while (phi >=_deuxpi ) phi -= _deuxpi; if ( (phi<0.) || (phi > _deuxpi) ) throw RangeCheckError(" MtxLM::ip_jt2tp - Phi out of range !"); return; } void MtxLM::tp2ipjt(double theta, double phi, int_4& ip, int_4& jt) { if ( (theta<0.) || (theta > M_PI) ) throw RangeCheckError(" MtxLM::tp2ipjt - Theta out of range !"); if ( (phi<0.) || (phi > _deuxpi) ) throw RangeCheckError(" MtxLM::tp2ipjt - Phi out of range !"); jt = (theta-_theta0)/_deltatheta; double delphi = _delphi_min*M_PI/(180.*60.)/sin(theta); double phi0 = _phiC-0.5*(double)_npixphi*delphi; if (phi0 < 0.) phi0 += 2*M_PI; // ip = (phi-_phi0)/_deltaphi; ip = (phi-phi0)/delphi; if ((ip < 0) || (ip >= _npixphi) ) throw RangeCheckError(" MtxLM::ip_jt2tp - ip out of range !"); if ((jt < 0) || (jt >= _npixtheta) ) throw RangeCheckError(" MtxLM::ip_jt2tp - jt out of range !"); return; } //-------------------------------------------------------------------------- // Fonction de filtrage de carte de type Matrix //-------------------------------------------------------------------------- template void FilterMtxMap(TMatrix & mtx, TMatrix & mxout, int filw=1) { if (filw < 1) return; mxout = mtx; sa_size_t r,c; sa_size_t fw = 2*filw+1; // Filtering // Filling holes in Matrix for(r=filw; r void Sph2LocalMap(SphericalMap & in, LocalMap & out) { out.SetPixels(0); int kout; double teta,phi; // Projecting to localMap for(kout=0; kout void ProjectMatrix2Sph(TMatrix & mtx, SphericalMap & out, bool userot=false) { if (userot) { double phi = (double)mtx.Info()["Longitude_C"]+90.; double psi = -((double)mtx.Info()["Latitude_C"])*M_PI/180.; while (phi >= 360.) phi -= 360.; phi *= (M_PI/180.); Vector3d omega(M_PI/2., phi); ProjMatrix2RotateSph(mtx, out, omega, psi, false); } else ProjMatrix2Sph(mtx, out); return; } //-------------------------------------------------------------------------- // Projection depuis une matrice ds carte spherique sans rotation explicite //-------------------------------------------------------------------------- template void ProjMatrix2Sph(TMatrix & mtx, SphericalMap & out) { int kout; double teta,phi; // Projecting to Matrix sa_size_t i,j,r,c; MtxLM mtxlm(mtx); for(r=0; r void ProjMatrix2RotateSph(TMatrix & mtx, SphericalMap & out, Vector3d& omega, double phirot, bool uselat=true) { double teta,phi; // Projecting to Matrix sa_size_t r,c; MtxLM mtxlm(mtx, uselat); for(r=0; r void Sphere2Matrix(SphericalMap & in, TMatrix & mtx, bool userot=false) { if (userot) { double phi = (double)mtx.Info()["Longitude_C"]+90.; double psi = -((double)mtx.Info()["Latitude_C"])*M_PI/180.; while (phi >= 360.) phi -= 360.; phi *= (M_PI/180.); Vector3d omega(M_PI/2., phi); RotateSph2Matrix(in, mtx, omega, psi, false); } else Sph2Matrix(in, mtx); return; } //-------------------------------------------------------------------------- // Projection depuis carte spherique ds une matrice sans rotation explicite //-------------------------------------------------------------------------- template void Sph2Matrix(SphericalMap & in, TMatrix & mtx) { int kout; double teta,phi; // Projecting to Matrix sa_size_t i,j,r,c; MtxLM mtxlm(mtx); for(r=0; r void RotateSph2Matrix(SphericalMap & in, TMatrix & mtx, Vector3d& omega,double phirot, bool uselat=true) { double teta,phi; // Projecting to Matrix sa_size_t r,c; MtxLM mtxlm(mtx,uselat); for(r=0; r void CheckRotatedProjection(SphericalMap & in); //-------------------------------------------------------------------------- // ************** Le main ***************** //-------------------------------------------------------------------------- int main(int narg, char* arg[]) { #define NLM 9 // Tableau des theta,phi des cartes partielles // latitude_map : Latitude en degre // longitude_map : longitude en degre // nx_map : Nb de pixels selon la longitude (Phi) // ny_map : Nb de pixels selon la latitude (Theta) // resolx_map : Resolution cartes selon la longitude (phi) // resoly_map : Resolution cartes selon la latitue (theta) // double latitude_map[NLM] = {0., -15., -15., 65., 65., 65., 65.}; double latitude_map[NLM] = {0., -15., -15., -28., 50., 60., 50., 75., 75.}; // double thetadeg_map[NLM] = {90., 105., 105., 25., 25., 25., 25.}; // double thetadeg_map[NLM] = {90., 105., 105., 115., 40., 30., 40., 15., 15.}; double thetadeg_map[NLM]; // = 90.-latitude_map[lnm] double longitude_map[NLM] = {95., 100., 120., 130., 82., 90., 200., 140., 200.}; int nx_map[NLM] = {512, 512, 512, 512, 512, 512, 512, 512, 512}; int ny_map[NLM] = {512, 512, 512, 512, 512, 512, 512, 512, 512}; double resolx_map[NLM] = {2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}; double resoly_map[NLM] = {2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}; if ( (narg > 1) && (strcmp(arg[1], "-h") == 0) ) { cout << " Usage: sph2lm InHealPixPPFName OutPPFName [-userot/-tstrot] [Filter1/2W = 0] " << endl; exit(0); } if (narg < 3) { cout << " sph2lm/Erreur argument - sph2lm -h for usage" << endl; exit(0); } bool userot = false; bool tstrot = false; if (narg > 3) { if (strcmp(arg[3],"-userot") == 0) { userot = true; cout << " sph2lm: Explicit rotation will be used -> userot=true " << endl; } if (strcmp(arg[3],"-tstrot") == 0) { userot = true; cout << " sph2lm: Test rotated projection -> tstrot=true / CheckRotatedProjection() " << endl; } } int filw = 0; if (narg > 4) filw = atoi(arg[4]); cout << "\n >>>> Starting sph2lm: arg[1]= " << arg[1] << " arg[2]= " << arg[2] << " FW=" << filw << endl; // We handle exception at the high level try { // This macro initialize the library // static objects handle this - However, not all loader call // the constructor for static objects SophyaInit(); cout << " --- Reading input SphericalMap from file " << arg[1] << endl; PInPersist inppf(arg[1]); PPersist * pps = inppf.ReadObject(); AnyDataObj * obj = pps->DataObj(); cout << " Object type read from input PPF file : " << typeid(*obj).name() << endl; SphereHEALPix * ps8 = dynamic_cast< SphereHEALPix* > (obj); SphereHEALPix sphin; if (ps8 != NULL) sphin.Share(*ps8); else { SphereHEALPix * ps4 = dynamic_cast< SphereHEALPix* > (obj); if (ps4 != NULL) { cout << " -- Converting SphereHEALPix to SphereHEALPix " << endl; sphin.Resize(ps4->SizeIndex()); for(int kp=0; kp exit() " << endl; return(0); } cout << " --- Opening output PPF file " << arg[1] << endl; POutPersist outppf(arg[2]); FFTWServer FFTServ; SphereHEALPix sphck(128); SphereHEALPix sphckmtx(128); int nlm; for(nlm=0; nlm > fftmtx; FFTServ.FFTForward(mtx, fftmtx); name = "fftmtx" + (string)num; cout << " Writing fftmtx to OutPPF " << endl; outppf.PutObject(fftmtx, name); if (filw < 1) continue; TMatrix fmtx; cout << " Filtering mtx FilterW= " << filw << endl; FilterMtxMap(mtx, fmtx, filw); cout << " Calling FFTServ.FFTForward(fmtx, fftfmtx) " << endl; TMatrix< complex > fftfmtx; FFTServ.FFTForward(fmtx, fftfmtx); cout << " Writing fmtx and fftfmtx to OutPPF " << endl; name = "fmtx" + (string)num; outppf.PutObject(fmtx, name); name = "fftfmtx" + (string)num; outppf.PutObject(fftfmtx, name); } // cout << " Doing Sph2Sph(sphin, lm) ... " << endl; // Sph2Sph(sphin, lm); cout << "\n --- Writing sphck and sphckmtxsphericalmap to OutPPF " << endl; outppf.PutObject(sphck, "sphck"); outppf.PutObject(sphckmtx, "sphckmtx"); } catch (PThrowable & exc) { cerr << " Catched Exception " << (string)typeid(exc).name() << " - Msg= " << exc.Msg() << endl; } catch (...) { cerr << " some other exception was caught ! " << endl; } cout << " >>>> End of sph2lm <<<< " << endl; } //-------------------------------------------------------------------------- // Fonction pour la verification des projection avec rotation //-------------------------------------------------------------------------- template void CheckRotatedProjection(SphericalMap & in) { cout << " >>> CheckRotatedProjection() : Testing rotated projection with matrices " << endl; SphereHEALPix sphckrot(128); double latdeg = 0.; double longdeg = 90.; int nr = 512; int nc = 512; double resol = 2.5; TMatrix mtx(nr, nc); TMatrix mtxA, mtxB, mtxC; mtx.Info()["Latitude_C"] = latdeg; mtx.Info()["Longitude_C"] = longdeg; mtx.Info()["LatPixSize"] = resol; mtx.Info()["LongPixSize"] = resol; mtx = 100.; ProjMatrix2Sph(mtx, sphckrot); Sph2Matrix(in, mtx); mtxA = mtx; Vector3d omega(M_PI/2., M_PI); mtx = 200.; ProjMatrix2RotateSph(mtx, sphckrot, omega, -M_PI/2.); RotateSph2Matrix(in, mtx, omega, -M_PI/2.); mtxB = mtx; mtx = 300.; ProjMatrix2RotateSph(mtx, sphckrot, omega, -M_PI/4.); RotateSph2Matrix(in, mtx, omega, -M_PI/4.); mtxC = mtx; string ppfname = "rotproj.ppf"; cout << " -- Writing mtxA,B,C & sphckrot to OutPPF " << ppfname << endl; POutPersist outppf(ppfname); outppf.PutObject(mtxA, "mtxA"); outppf.PutObject(mtxB, "mtxB"); outppf.PutObject(mtxC, "mtxC"); outppf.PutObject(sphckrot, "sphckrot"); cout << " >>> End of CheckRotatedProjection() " << endl; return; }