00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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 }
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 }