35 #include "paramfile.h" 38 #include "fitshandle.h" 39 #include "lsconstants.h" 49 virtual int lmin (
int band)
const = 0;
50 virtual int lmax (
int band)
const = 0;
51 virtual std::vector<double> getBand(
int band)
const = 0;
55 class needlet:
public needlet_base
58 enum { npoints=1000 };
59 std::vector<double> val;
62 double phi(
double t)
const 65 double pos=1.-2*B/(B-1.)*(t-1./B);
66 double p2=(val.size()-1)*abs(pos);
67 size_t ip2=size_t(p2);
68 if (ip2>=val.size()-1)
return (pos>0.) ? 1. : 0.;
70 double v=val[ip2] + delta*(val[ip2+1]-val[ip2]);
71 return (pos>0) ? 0.5+v : 0.5-v;
73 double b2 (
double xi)
const 74 {
return phi(xi/B) - phi(xi); }
77 needlet (
double B_) : val(npoints), B(B_)
82 for (
int i=1; i<npoints-1; ++i)
84 double p0=double(i)/(npoints-1);
85 double v=exp(-1./(1-p0*p0));
86 val[i]=val[i-1]+0.5*(vold+v);
89 val[npoints-1]=val[npoints-2]+0.5*vold;
90 double xnorm=.5/val[npoints-1];
91 for (
int i=0; i<npoints; ++i)
95 virtual int lmin (
int band)
const 96 {
return int(std::pow(B,band-1)+1.+1e-10); }
97 virtual int lmax (
int band)
const 98 {
return int(std::pow(B,band+1)-1e-10); }
99 virtual std::vector<double> getBand(
int band)
const 102 double fct=pow(B,-band);
103 vector<double> res(lmax(band)+1);
104 for (
int i=0; i<lmin(band); ++i) res[i] = 0;
105 for (
int i=lmin(band); i<int(res.size()); ++i)
106 res[i]=sqrt(b2(i*fct));
111 class sdw:
public needlet_base
114 enum { npoints=1000 };
115 std::vector<double> val;
118 double f_s2dw(
double k)
120 if ((k<=1./B)||(k>=1.))
return 0;
121 double t = (k - (1. / B)) * (2.0 * B / (B-1.)) - 1.;
122 return exp(-2.0 / (1.0 - t*t)) / k;
124 double phi (
double t)
const 127 double p2= (t-1./B)*(val.size()-1)/(1.-1./B);
129 if (ip2>=
int(val.size()-1))
return 0;
130 if (p2<=0.)
return 1;
132 return 1.-(val[ip2] + delta*(val[ip2+1]-val[ip2]));
134 double b2 (
double xi)
const 135 {
return phi(xi/B) - phi(xi); }
138 sdw (
double B_) : val(npoints), B(B_)
143 for (
int i=1; i<npoints-1; ++i)
145 double p0=1./B+double(i)/(npoints-1)*(1-1./B);
147 val[i]=val[i-1]+0.5*(v+vold);
150 val[npoints-1]=val[npoints-2]+0.5*vold;
151 double xnorm=1./val[npoints-1];
152 for (
int i=0; i<npoints; ++i)
156 virtual int lmin (
int band)
const 157 {
return int(std::pow(B,band-1)+1.+1e-10); }
158 virtual int lmax (
int band)
const 159 {
return int(std::pow(B,band+1)-1e-10); }
160 virtual std::vector<double> getBand(
int band)
const 163 double fct=pow(B,-band);
164 vector<double> res(lmax(band)+1);
165 for (
int i=0; i<lmin(band); ++i) res[i] = 0;
166 for (
int i=lmin(band); i<int(res.size()); ++i)
167 res[i]=sqrt(b2(i*fct));
172 class spline:
public needlet_base
177 static double psi (
double x)
179 if (x<=0.)
return 1.;
180 if (x>=1.)
return 0.;
181 return (x>=0.5) ? 2.*(1.-x)*(1.-x)*(1.-x)
182 : 12.*x*x*(.5*x-.5) + 1.;
185 double h (
double xi)
const 186 {
return psi(xi/B)-psi(xi); }
189 spline (
double B_) : B(B_) {}
191 virtual int lmin (
int )
const 193 virtual int lmax (
int band)
const 194 {
return int(std::pow(B,band+1)-1e-10); }
195 virtual std::vector<double> getBand(
int band)
const 198 double fct=pow(B,-band);
199 vector<double> res(lmax(band)+1);
200 for (
int i=0; i<lmin(band); ++i) res[i] = 0;
201 for (
int i=lmin(band); i<int(res.size()); ++i)
202 res[i]=sqrt(h(i*fct));
207 class cosine:
public needlet_base
210 std::vector<int> llim;
212 void checkBand(
int band)
const 214 planck_assert((band>=0) && (band<
int(llim.size()-2)),
"illegal band");
218 cosine (
const std::vector<int> &llim_) : llim(llim_)
220 planck_assert(llim.size()>=3,
"llim vector needs at least 3 entries");
221 if ((llim[0]==0) && (llim[1]==0))
223 for (tsize i=1; i<llim.size(); ++i)
224 planck_assert(llim[i]>llim[i-1],
"llim not strictly increasing");
227 virtual int lmin (
int band)
const 232 virtual int lmax (
int band)
const 235 return llim[band+2]-1;
237 virtual std::vector<double> getBand(
int band)
const 240 vector<double> res(lmax(band)+1);
241 for (
int i=0; i<lmin(band); ++i) res[i]=0.;
242 for (
int i=lmin(band); i<=llim[band+1]; ++i)
243 res[i]=cos(halfpi*(llim[band+1]-i)/(llim[band+1]-llim[band]));
244 for (
int i=llim[band+1]; i<=lmax(band); ++i)
245 res[i]=cos(halfpi*(i-llim[band+1])/(llim[band+2]-llim[band+1]));
250 template<
typename T>
void needlet_tool (paramfile ¶ms)
252 string mode = params.template find<string>(
"mode");
253 planck_assert ((mode==
"split") || (mode==
"assemble") ||
254 (mode==
"write_coefficients"),
"invalid mode");
255 bool split = mode==
"split";
256 unique_ptr<needlet_base> needgen;
257 string ntype = params.template find<string>(
"needlet_type");
260 vector<string> lps=tokenize(params.template find<string>(
"llim"),
',');
262 for (
auto x:lps) lpeak.push_back(stringToData<int>(x));
263 needgen.reset(
new cosine(lpeak));
265 else if (ntype==
"needatool")
266 needgen.reset(
new needlet(params.template find<double>(
"B")));
267 else if (ntype==
"sdw")
268 needgen.reset(
new sdw(params.template find<double>(
"B")));
269 else if (ntype==
"spline")
270 needgen.reset(
new spline(params.template find<double>(
"B")));
272 planck_fail(
"unknown needlet type");
273 int loband=params.template find<int>(
"minband");
274 int hiband=params.template find<int>(
"maxband")+1;
276 if (mode==
"write_coefficients")
278 for (
int i=loband; i<hiband; ++i)
281 out.create (params.template find<string>(
"outfile_needlets")
282 +intToString(i,3)+
".fits");
283 vector<fitscolumn> cols;
284 cols.push_back(fitscolumn(
"coeff",
"[none]",1,PLANCK_FLOAT64));
285 out.insert_bintab(cols);
286 out.write_column(1,needgen->getBand(i));
291 string infile = params.template find<string>(
"infile");
292 string outfile = params.template find<string>(
"outfile");
293 bool polarisation = params.template find<bool>(
"polarisation",
false);
300 auto alm = read_Alm_from_fits<T>(infile,nlmax,nmmax);
301 for (
int i=loband; i<hiband; ++i)
303 int lmax_t=min(nlmax,needgen->lmax(i)),
304 mmax_t=min(nmmax, lmax_t);
306 for (
int m=0; m<=mmax_t; ++m)
307 for (
int l=m; l<=lmax_t; ++l)
308 atmp(l,m) = alm(l,m);
309 atmp.ScaleL(needgen->getBand(i));
317 for (
int i=loband; i<hiband; ++i)
320 get_almsize(infile+intToString(i,3)+
".fits", nlmax, nmmax);
321 auto atmp = read_Alm_from_fits<T>(infile+intToString(i,3)+
".fits",
323 atmp.ScaleL(needgen->getBand(i));
324 for (
int m=0; m<=alm.
Mmax(); ++m)
325 for (
int l=m; l<=alm.
Lmax(); ++l)
326 atmp(l,m) += alm(l,m);
334 planck_fail(
"polarisation not yet supported");
340 int needlet_tool (
int argc,
const char **argv)
342 module_startup (
"needlet_tool", argc, argv);
343 paramfile params (getParamsFromCmdline(argc,argv));
345 bool dp = params.find<
bool> (
"double_precision",
false);
346 dp ? needlet_tool<double>(params) : needlet_tool<float>(params);
void write_Alm_to_fits(fitshandle &out, const Alm< xcomplex< T > > &alms, int lmax, int mmax, PDT datatype)
void get_almsize(fitshandle &inp, int &lmax, int &mmax)