map2tga_module.cc

00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.sourceforge.net
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*
00028  *  Copyright (C) 2003-2015 Max-Planck-Society
00029  *  Author: Martin Reinecke
00030  */
00031 
00032 #include <sstream>
00033 #include <iomanip>
00034 #include <cstdlib>
00035 #include "safe_ptr.h"
00036 #include "healpix_map.h"
00037 #include "healpix_map_fitsio.h"
00038 #include "rotmatrix.h"
00039 #include "pointing.h"
00040 #include "ls_image.h"
00041 #include "paramfile.h"
00042 #include "levels_facilities.h"
00043 #include "lsconstants.h"
00044 #include "announce.h"
00045 #include "string_utils.h"
00046 
00047 using namespace std;
00048 
00049 namespace {
00050 
00051 void histo_eq (arr2<float> &img, float &minv, float &maxv, arr<double> &newpos)
00052   {
00053   const int nbins=100;
00054   arr<int> bincnt (nbins);
00055   bincnt.fill(0);
00056   int pixels=0;
00057 
00058   double fact = 1./(maxv-minv);
00059   for (tsize i=0; i<img.size1(); ++i)
00060     for (tsize j=0; j<img.size2(); ++j)
00061       if (img[i][j]>-1e30)
00062         {
00063         img[i][j] = float((img[i][j]-minv)*fact);
00064         int idx = int(img[i][j]*nbins);
00065         idx=max(0,min(idx,nbins-1));
00066         ++bincnt[idx];
00067         ++pixels;
00068         }
00069 
00070   newpos.alloc(nbins+1);
00071   int accu=0;
00072   for (int m=0; m<nbins; ++m)
00073     {
00074     newpos[m] = double(accu)/pixels;
00075     accu += bincnt[m];
00076     }
00077   newpos[nbins]=1.;
00078 
00079   for (tsize i=0; i<img.size1(); ++i)
00080     for (tsize j=0; j<img.size2(); ++j)
00081       if (img[i][j]>-1e30)
00082         {
00083         int idx = int(img[i][j]*nbins);
00084         idx=max(0,min(idx,nbins-1));
00085         double frac = nbins*img[i][j] - idx;
00086         img[i][j] = float((1-frac)*newpos[idx] + frac*newpos[idx+1]);
00087         img[i][j] = float(minv+(maxv-minv)*img[i][j]);
00088         }
00089   }
00090 
00091 void pro_mollw (const Healpix_Map<float> &map, double lon0, double lat0,
00092   int xsize, arr2<float> &img, float &minv, float &maxv, bool smooth)
00093   {
00094   int ysize=xsize/2;
00095   img.alloc(xsize,ysize);
00096   img.fill(-1e35);
00097   double xc=(xsize-1)/2., yc=(ysize-1)/2.;
00098 
00099   rotmatrix rot;
00100   rot.Make_CPAC_Euler_Matrix(lon0,-lat0,0);
00101 
00102   minv=1e30;
00103   maxv=-1e30;
00104   for (tsize i=0; i<img.size1(); ++i)
00105     for (tsize j=0; j<img.size2(); ++j)
00106       {
00107       double u = 2*(i-xc)/(xc/1.02);
00108       double v = (j-yc)/(yc/1.02);
00109       bool mask = ((u*u/4 + v*v) <= 1);
00110       if (mask)
00111         {
00112         pointing ptg (halfpi-(asin(2/pi*(asin(v) + v*sqrt((1-v)*(1+v))))),
00113                       -halfpi*u/max(sqrt((1-v)*(1+v)),1e-6));
00114         vec3 pnt = rot.Transform(ptg.to_vec3());
00115         if (smooth)
00116           img[i][j] = map.interpolated_value(pnt);
00117         else
00118           img[i][j] = map[map.ang2pix(pnt)];
00119         if (!approx<double>(img[i][j],Healpix_undef))
00120           {
00121           if (img[i][j]<minv) minv=img[i][j];
00122           if (img[i][j]>maxv) maxv=img[i][j];
00123           }
00124         }
00125       }
00126   }
00127 
00128 void pro_gno (const Healpix_Map<float> &map, double lon0, double lat0,
00129   int xsize, double delta, arr2<float> &img, float &minv, float &maxv,
00130   bool smooth)
00131   {
00132   rotmatrix rot;
00133   rot.Make_CPAC_Euler_Matrix(lon0,-lat0,0);
00134 
00135   double start=-(xsize/2.)*delta;
00136   img.alloc(xsize,xsize);
00137   minv=1e30;
00138   maxv=-1e30;
00139   for (tsize i=0; i<img.size1(); ++i)
00140     for (tsize j=0; j<img.size2(); ++j)
00141       {
00142       vec3 pnt (1,-(start+i*delta), start+j*delta);
00143       pnt = rot.Transform(pnt);
00144         if (smooth)
00145           img[i][j] = map.interpolated_value(pnt);
00146         else
00147           img[i][j] = map[map.ang2pix(pnt)];
00148       if (!approx<double>(img[i][j],Healpix_undef))
00149         {
00150         if (img[i][j]<minv) minv=img[i][j];
00151         if (img[i][j]>maxv) maxv=img[i][j];
00152         }
00153       }
00154   }
00155 
00156 void colorbar (LS_Image &img, const Palette &pal, int xmin, int xmax,
00157   int ymin, int ymax, bool flippal, const arr<double> &newpos)
00158   {
00159   int nbins = newpos.size()-1;
00160   for (int i=xmin; i<=xmax; ++i)
00161     {
00162     double val = (double(i)-xmin)/(xmax-xmin);
00163     if (nbins>0)
00164       {
00165       int idx = int(val*nbins);
00166       idx=max(0,min(idx,nbins-1));
00167       double frac = nbins*val - idx;
00168       val = (1-frac)*newpos[idx] + frac*newpos[idx+1];
00169       }
00170     if (flippal) val=1-val;
00171     Colour c = pal.Get_Colour(float(val));
00172     for (int j=ymin; j<=ymax; ++j)
00173       img.put_pixel(i,j,c);
00174     }
00175   }
00176 
00177 string conv (double val)
00178   {
00179   ostringstream os;
00180   if (abs(val)>100 || abs(val)<0.01)
00181     {
00182     os << setw(10) << setprecision(3) << scientific << val;
00183     return os.str();
00184     }
00185   os << setw(10) << setprecision(6) << fixed << val;
00186   return trim(os.str());
00187   }
00188 
00189 } // unnamed namespace
00190 
00191 int map2tga_module (int argc, const char **argv)
00192   {
00193   module_startup ("map2tga",argc>=2,
00194     "\nUsage:\n"
00195     "  map2tga <init object>\n\n"
00196     "or:\n"
00197     "  map2tga <input file> <output file> [-sig <int>] [-pal <int>]\n"
00198     "    [-xsz <int>] [-bar] [-log] [-asinh] [-lon <float>] [-lat <float>]\n"
00199     "    [-mul <float>] [-add <float>] [-min <float>] [-max <float>]\n"
00200     "    [-res <float>] [-title <string>] [-flippal] [-gnomonic]\n"
00201     "    [-interpol] [-equalize] [-viewer <viewer>]\n\n");
00202 
00203   safe_ptr<paramfile> params;
00204   if (argc>2)
00205     {
00206     vector<string> leading;
00207     map<string,string> dict;
00208     leading.push_back("infile");
00209     leading.push_back("outfile");
00210     parse_cmdline_classic (argc,argv,leading,dict);
00211     if (dict.find("gnomonic")!=dict.end())
00212       {
00213       dict["pro"]="gno";
00214       dict.erase("gnomonic");
00215       }
00216     params.reset(new paramfile(dict,false));
00217     }
00218   else
00219     params.reset(new paramfile(argv[1]));
00220 
00221   string infile = params->find<string>("infile");
00222   string outfile = params->find<string>("outfile");
00223   int colnum = params->find<int>("sig",1);
00224   int palnr = params->find<int>("pal",4);
00225   bool flippal = params->find<bool>("flippal",false);
00226   int xres = params->find<int>("xsz",1024);
00227   bool bar = params->find<bool>("bar",false);
00228   bool logflag = params->find<bool>("log",false);
00229   bool eqflag = params->find<bool>("equalize",false);
00230   bool asinhflag = params->find<bool>("asinh",false);
00231   double lon0 = degr2rad*params->find<double>("lon",0);
00232   double lat0 = degr2rad*params->find<double>("lat",0);
00233   double factor = params->find<float>("mul",1);
00234   double offset = params->find<float>("add",0);
00235   float usermin = params->find<float>("min", -1e30);
00236   bool min_supplied = (usermin>-1e29);
00237   float usermax = params->find<float>("max", 1e30);
00238   bool max_supplied = (usermax<1e29);
00239   double res = arcmin2rad*params->find<double>("res",1);
00240   string title = params->find<string>("title","");
00241   string viewer = params->find<string>("viewer","");
00242   bool mollpro = (params->find<string>("pro","")!="gno");
00243   bool interpol = params->find<bool>("interpol",false);
00244 
00245   Healpix_Map<float> map(0,RING);
00246   read_Healpix_map_from_fits(infile,map,colnum,2);
00247   for (int m=0; m<map.Npix(); ++m)
00248     {
00249     if (!approx<double>(map[m],Healpix_undef))
00250       {
00251       map[m] = float((map[m]+offset)*factor);
00252       if (logflag)
00253         map[m] = (map[m]<=0) ? float(Healpix_undef)
00254                              : float(log(double(map[m]))/ln10);
00255       if (asinhflag)
00256         map[m] = (map[m]>=0) ?
00257           float( log(double( map[m]+sqrt(map[m]*map[m]+1)))) :
00258           float(-log(double(-map[m]+sqrt(map[m]*map[m]+1))));
00259       if (min_supplied) if (map[m] < usermin) map[m] = usermin;
00260       if (max_supplied) if (map[m] > usermax) map[m] = usermax;
00261       }
00262     }
00263 
00264   arr2<float> imgarr;
00265   float minv, maxv;
00266   mollpro ? pro_mollw (map,lon0,lat0,xres,imgarr,minv,maxv,interpol) :
00267             pro_gno (map,lon0,lat0,xres,res,imgarr,minv,maxv,interpol);
00268 
00269   arr<double> newpos;
00270   if (eqflag) histo_eq(imgarr,minv,maxv,newpos);
00271 
00272   if (min_supplied) minv = usermin;
00273   if (max_supplied) maxv = usermax;
00274   if (maxv==minv) maxv=minv+1e-10f;
00275 
00276   int xsz=imgarr.size1();
00277   int ysz=imgarr.size2();
00278   int yofs=ysz;
00279   int scale = max(1,xsz/800);
00280   if (bar) ysz+=60*scale;
00281   if (title != "") { ysz+=50*scale; yofs+=50*scale; }
00282   LS_Image img(xsz,ysz);
00283   img.fill(Colour(1,1,1));
00284   img.set_font (giant_font);
00285   Palette pal;
00286   pal.setPredefined(palnr);
00287   if (title != "")
00288     img.annotate_centered(xsz/2,25*scale,Colour(0,0,0),title,scale);
00289   for (tsize i=0; i<imgarr.size1(); ++i)
00290     for (tsize j=0; j<imgarr.size2(); ++j)
00291       {
00292       if (imgarr[i][j]>-1e32)
00293         {
00294         Colour c(0.5,0.5,0.5);
00295         if (!approx<double>(imgarr[i][j],Healpix_undef))
00296           {
00297           int col = int((imgarr[i][j]-minv)/(maxv-minv)*256);
00298           col = min(255,max(col,0));
00299           float colfrac = (imgarr[i][j]-minv)/(maxv-minv);
00300           if (flippal) colfrac = 1-colfrac;
00301           c = pal.Get_Colour(colfrac);
00302           }
00303         img.put_pixel(i,yofs-j-1,c);
00304         }
00305       }
00306 
00307   if (bar)
00308     {
00309     colorbar (img,pal,xsz/10,(xsz*9)/10,ysz-40*scale,ysz-20*scale,flippal,
00310       newpos);
00311     img.set_font (medium_bold_font);
00312     img.annotate_centered (xsz/20,ysz-30*scale,Colour(0,0,0),conv(minv),scale);
00313     img.annotate_centered ((xsz*19)/20,ysz-30*scale,Colour(0,0,0),conv(maxv),
00314       scale);
00315     }
00316   img.write_TGA(outfile);
00317 
00318   if (viewer!="")
00319     {
00320     int retcode = system((viewer+" "+outfile).c_str());
00321     if (retcode != 0)
00322       cout << "Warning: viewer return code was " << retcode << endl;
00323     }
00324 
00325   return 0;
00326   }

Generated on Thu Oct 8 14:48:52 2015 for Healpix C++