Healpix C++  3.82
alice3.cc
Go to the documentation of this file.
1 /*
2  * This file is part of Healpix_cxx.
3  *
4  * Healpix_cxx is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * Healpix_cxx is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Healpix_cxx; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * For more information about HEALPix, see http://healpix.sourceforge.net
19  */
20 
21 /*
22  * Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
23  * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
24  * (DLR).
25  */
26 
27 /*! \file alice3.cc
28  * Copyright (C) 2005-2015 David Larson, Max-Planck-Society
29  * \author David Larson \author Martin Reinecke
30  */
31 
32 #include <iostream>
33 #include "announce.h"
34 #include "paramfile.h"
35 #include "healpix_map_fitsio.h"
36 #include "lsconstants.h"
37 #include "arr.h"
38 #include "fitshandle.h"
39 #include "vec3.h"
40 #include "string_utils.h"
41 #include "alm.h"
42 #include "alm_healpix_tools.h"
43 #include "planck_rng.h"
44 #include "healpix_map.h"
45 
46 using namespace std;
47 
48 class PolarizationHolder
49  {
50  public:
52 
53  void getQU(const pointing &p, double &q, double &u) const
54  {
55  fix_arr<int,4> pix;
56  fix_arr<double,4> wgt;
57  Q.get_interpol(p,pix,wgt);
58  q=u=0.f;
59  for (tsize i=0;i<4;++i) {q+=Q[pix[i]]*wgt[i];u+=U[pix[i]]*wgt[i]; }
60  }
61 
62  vec3 getQUDir(const vec3 &loc) const
63  {
64  double q,u;
65  getQU(loc,q,u);
66  vec3 east(1,0,0);
67  if (abs(loc.x)+abs(loc.y) > 0.0)
68  east = vec3(-loc.y,loc.x,0).Norm();
69  vec3 north = crossprod(loc, east);
70  double angle = 0.5*safe_atan2(u,q);
71  return north*(-cos(angle)) + east*sin(angle);
72  }
73 
74  // Return the magnitude of the polarization at some pointing.
75  double getQUMagnitude(const pointing& p) const
76  {
77  double q,u;
78  getQU(p,q,u);
79  return sqrt(q*q + u*u);
80  }
81  };
82 
83 /*! Steps from loc in direction dir for an angle theta and updates loc and dir. */
84 void get_step(const PolarizationHolder &ph, vec3 &loc, vec3 &dir, double theta)
85  {
86  loc=(loc+dir*theta).Norm();
87  vec3 tdir=ph.getQUDir(loc);
88  dir = (dotprod(dir,tdir)<0) ? -tdir : tdir;
89  }
90 
91 /*! Performs one Runge-Kutta second order step. Updates loc and dir. */
92 void runge_kutta_step(vec3 &loc, vec3 &dir, const PolarizationHolder &ph,
93  double theta)
94  {
95  // Take a half-theta step
96  vec3 tloc=loc;
97  get_step(ph, tloc, dir, theta/2.0);
98 
99  // Then take a full step with the new direction
100  get_step(ph, loc, dir, theta);
101  }
102 
103 /*! Second order Runge-Kutta integration on the sphere. Given a
104  starting location, a qu map of the sky, and a step size theta, this
105  subroutine returns an array of vectors extending in both
106  directions from the starting location. */
107 void runge_kutta_2(const vec3 &location, const PolarizationHolder &ph,
108  double theta, arr<vec3> &locs)
109  {
110  vec3 first_dir=ph.getQUDir(location);
111  vec3 dir = first_dir;
112  vec3 loc = location;
113 
114  locs[locs.size()/2] = loc;
115 
116  for(int i = 1 + locs.size()/2; i<int(locs.size()); i++)
117  {
118  runge_kutta_step(loc, dir, ph, theta);
119  locs[i] = loc;
120  }
121 
122  dir = -first_dir;
123  loc = location;
124  for(int i = -1 + locs.size()/2; i>=0; i--)
125  {
126  runge_kutta_step(loc, dir, ph, theta);
127  locs[i] = loc;
128  }
129  }
130 
131 /*! Create a sinusoidal kernel. */
132 void make_kernel(arr<double> &kernel)
133  {
134  for(tsize i=0; i<kernel.size(); i++)
135  {
136  double sinx = sin(pi*(i+1) / (kernel.size()+1));
137  kernel[i] = sinx*sinx;
138  }
139  }
140 
141 /*! Convolve an array with a kernel. */
142 void convolve(const arr<double> &kernel, const arr<double> &raw, arr<double> &convolution)
143  {
144  convolution.alloc(raw.size()-kernel.size()+1);
145  for(tsize i=0; i<convolution.size(); i++)
146  {
147  double total=0;
148  for (tsize j=0; j<kernel.size(); j++)
149  total += kernel[j] * raw[i+j];
150  convolution[i] = total;
151  }
152  }
153 
154 /*! Perform line integral convolution on sphere. */
156  const PolarizationHolder &ph, const Healpix_Map<double> &th, int steps,
157  int kernel_steps, double step_radian)
158  {
159  arr<double> kernel(kernel_steps), convolution, rawtexture;
160  make_kernel(kernel);
161  arr<vec3> curve(steps);
162 
163  texture.fill(0.);
164  int num_curves=0;
165 
166  for(int i=0; i<texture.Npix(); i++)
167  {
168  if (hitcount[i]<1.0)
169  {
170  num_curves++;
171  runge_kutta_2(texture.pix2vec(i), ph, step_radian, curve);
172  rawtexture.alloc(curve.size());
173  for (tsize i2=0; i2<curve.size(); i2++)
174  rawtexture[i2] = th.interpolated_value(curve[i2]);
175  convolve(kernel, rawtexture, convolution);
176  for (tsize j=0; j<convolution.size(); j++)
177  {
178  int k = texture.vec2pix(curve[j+kernel.size()/2]);
179  texture[k] += convolution[j];
180  hitcount[k] += 1.;
181  }
182  }
183  }
184  return num_curves;
185  }
186 
187 /*! Expose line integral convolution for external use. */
190  int steps, int kernel_steps, double step_radian, double polmin, double polmax)
191  {
192  PolarizationHolder ph;
193  ph.Q = Q;
194  ph.U = U;
195 
196  hit.fill(0.);
197 
198  for (int i=0; i<mag.Npix(); i++)
199  {
200  pointing p = mag.pix2ang(i);
201 
202  mag[i] = min(polmax,max(polmin,ph.getQUMagnitude(p)));
203  tex[i] = th.interpolated_value(p);
204  }
205 
206  lic_function(hit, tex, ph, th, steps, kernel_steps, step_radian);
207 
208  for (int i=0; i<tex.Npix(); ++i)
209  tex[i]/=hit[i];
210  double tmin,tmax,mmin,mmax;
211  tex.minmax(tmin,tmax);
212  mag.minmax(mmin,mmax);
213  for (int i=0; i<tex.Npix(); ++i)
214  {
215  mag[i]*=(tex[i]-tmin);
216  tex[i]=1.0-(tex[i]-tmin)/(tmax-tmin);
217  }
218  mag.minmax(mmin,mmax);
219  for (int i=0; i<mag.Npix(); ++i)
220  mag[i]=1.0-(mag[i]-mmin)/(mmax-mmin);
221  }
222 
223 int main(int argc, const char** argv)
224  {
225  module_startup ("alice3", argc, argv);
226  paramfile params (getParamsFromCmdline(argc,argv));
227 
228  Healpix_Map<double> Q, U;
229  // Load a polarized fits file, with Q and U as the second
230  // and third columns (the standard form).
231  read_Healpix_map_from_fits(params.find<string>("in"), Q, 2, 2);
232  read_Healpix_map_from_fits(params.find<string>("in"), U, 3, 2);
233 
234  int nside = params.find<int>("nside");
235  int steps = params.find<int>("steps",100);
236  double step_radian=arcmin2rad*params.find<double>("step_arcmin",10.);
237  int kernel_steps = params.find<int>("kernel_steps",50);
238  double polmin = params.find<double>("polmin",-1e30),
239  polmax = params.find<double>("polmax",1e30);
240  string out = params.find<string>("out");
241 
242  Healpix_Map<double> th(nside,RING,SET_NSIDE);
243  if (params.param_present("texture"))
244  read_Healpix_map_from_fits(params.find<string>("texture"),th);
245  else
246  {
247  planck_rng rng(params.find<int>("rand_seed",42));
248  if (params.param_present("ell"))
249  {
250  int ell = params.find<int>("ell");
251  if (ell<0) ell=2*nside;
252  Alm<xcomplex<double> > a(ell,ell);
253  a.SetToZero();
254  cout << "Background texture using ell = " << ell << endl;
255 
256  a(ell,0)=fcomplex(rng.rand_gauss(),0.);
257  for (int m=0; m<=ell; m++)
258  { a(ell,m).real(rng.rand_gauss()); a(ell,m).imag(rng.rand_gauss()); }
259  alm2map(a, th);
260  }
261  else
262  {
263  for (int i=0; i<th.Npix(); i++)
264  th[i] = rng.rand_uni() - 0.5;
265  }
266  }
267 
268  Healpix_Map<double> hit(nside,RING,SET_NSIDE),
269  tex(nside,RING,SET_NSIDE),
270  mag(nside,RING,SET_NSIDE);
271 
272  {
273  PolarizationHolder ph;
274  ph.Q = Q;
275  ph.U = U;
276 
277  for (int i=0; i<mag.Npix(); i++)
278  tex[i] = th.interpolated_value(mag.pix2ang(i));
279  write_Healpix_map_to_fits(out+"_background.fits",tex,PLANCK_FLOAT32);
280  }
281 
282  lic_main(Q, U, th, hit, tex, mag, steps, kernel_steps, step_radian, polmin, polmax);
283 
284  write_Healpix_map_to_fits(out+"_texture.fits",tex,PLANCK_FLOAT32);
285  write_Healpix_map_to_fits(out+"_mod_texture.fits",mag,PLANCK_FLOAT32);
286  }
void minmax(T &Min, T &Max) const
Definition: healpix_map.cc:75
vec3 pix2vec(I pix) const
Definition: healpix_base.h:193
I vec2pix(const vec3 &vec) const
Definition: healpix_base.h:162
void lic_main(const Healpix_Map< double > &Q, const Healpix_Map< double > &U, const Healpix_Map< double > &th, Healpix_Map< double > &hit, Healpix_Map< double > &tex, Healpix_Map< double > &mag, int steps, int kernel_steps, double step_radian, double polmin, double polmax)
Definition: alice3.cc:188
void make_kernel(arr< double > &kernel)
Definition: alice3.cc:132
Definition: alm.h:88
int lic_function(Healpix_Map< double > &hitcount, Healpix_Map< double > &texture, const PolarizationHolder &ph, const Healpix_Map< double > &th, int steps, int kernel_steps, double step_radian)
Definition: alice3.cc:155
void runge_kutta_2(const vec3 &location, const PolarizationHolder &ph, double theta, arr< vec3 > &locs)
Definition: alice3.cc:107
void read_Healpix_map_from_fits(fitshandle &inp, Healpix_Map< T > &map, int colnum)
T interpolated_value(const pointing &ptg) const
Definition: healpix_map.h:219
void get_interpol(const pointing &ptg, fix_arr< I, 4 > &pix, fix_arr< double, 4 > &wgt) const
void write_Healpix_map_to_fits(fitshandle &out, const Healpix_Map< T > &map, PDT datatype)
void alm2map(const Alm< xcomplex< T > > &alm, Healpix_Map< T > &map, bool add_map)
void get_step(const PolarizationHolder &ph, vec3 &loc, vec3 &dir, double theta)
Definition: alice3.cc:84
pointing pix2ang(I pix) const
Definition: healpix_base.h:185
void convolve(const arr< double > &kernel, const arr< double > &raw, arr< double > &convolution)
Definition: alice3.cc:142
void runge_kutta_step(vec3 &loc, vec3 &dir, const PolarizationHolder &ph, double theta)
Definition: alice3.cc:92
I Npix() const
Definition: healpix_base.h:429
void fill(const T &val)
Definition: healpix_map.h:90

Generated on Thu Jul 28 2022 17:32:07 for Healpix C++