1/* 2 * This file is part of Healpix Java. 3 * 4 * This code 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 * This code 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 this code; 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 21package healpix.essentials; 22 23import java.util.Arrays; 24 25/** Class representing a full HEALPix map containing <type> values. 26 This class is conceptually very similar the the Healpix_Map<<type>> 27 class of Healpix_cxx. 28 29 @copyright 2011,2012 Max-Planck-Society 30 @author Martin Reinecke */ 31public class HealpixMap<Type> extends HealpixBase 32 { 33 private <type>[] data; 34 35 public static final <type> undef=(<type>)(-1.6375e30); 36 37 public HealpixMap<Type>() throws Exception 38 { this(1,Scheme.NESTED); } 39 public HealpixMap<Type>(long nside_in, Scheme scheme_in) throws Exception 40 { 41 super(nside_in,scheme_in); 42 HealpixUtils.check(nside<=(1<<13),"resolution too high"); 43 data=new <type>[(int)getNpix()]; 44 } 45 public HealpixMap<Type>(<type>[] data_in, Scheme scheme_in) throws Exception 46 { 47 super(npix2Nside(data_in.length),scheme_in); 48 HealpixUtils.check(nside<=(1<<13),"resolution too high"); 49 data=data_in; 50 } 51 52 /** Adjusts the object to nside_in. 53 @param nside_in the new Nside parameter */ 54 public void setNside (long nside_in) throws Exception 55 { 56 if (nside_in!=nside) 57 { 58 super.setNside(nside_in); 59 HealpixUtils.check(nside<=(1<<13),"resolution too high"); 60 data=new <type>[(int)getNpix()]; 61 } 62 } 63 64 /** Adjusts the object to nside_in and scheme_in. 65 @param nside_in the new Nside parameter 66 @param scheme_in the new ordering scheme */ 67 public void setNsideAndScheme (long nside_in, Scheme scheme_in) 68 throws Exception 69 { 70 super.setNsideAndScheme(nside_in,scheme_in); 71 HealpixUtils.check(nside<=(1<<13),"resolution too high"); 72 data=new <type>[(int)getNpix()]; 73 } 74 75 /** Adjusts the object to scheme_in, and sets pixel data to data_in. 76 @param data_in pixel data; must have a valid length (12*nside^2) 77 @param scheme_in the new ordering scheme */ 78 public void setDataAndScheme(<type>[] data_in, Scheme scheme_in) 79 throws Exception 80 { 81 super.setNsideAndScheme(npix2Nside(data_in.length),scheme_in); 82 data=data_in; 83 } 84 85 /** Sets all map pixel to a specific value. 86 @param val pixel value to use */ 87 public void fill(<type> val) 88 { Arrays.fill(data,val); } 89 90 /** Converts the map from NESTED to RING scheme or vice versa. 91 This operation is done in-place, i.e. it does not require additional 92 memory. */ 93 public void swapScheme() throws Exception 94 { 95 HealpixUtils.check((order>=0) && (order<=13), 96 "swapping not supported for this Nside"); 97 for (int m=0; m<swap_cycle[order].length; ++m) 98 { 99 int istart = swap_cycle[order][m]; 100 101 <type> pixbuf = data[istart]; 102 long iold = istart, 103 inew = (scheme==Scheme.RING) ? nest2ring(istart) : ring2nest(istart); 104 while (inew != istart) 105 { 106 data[(int)iold] = data[(int)inew]; 107 iold = inew; 108 inew = (scheme==Scheme.RING) ? nest2ring(inew) : ring2nest(inew); 109 } 110 data[(int)iold] = pixbuf; 111 } 112 scheme = (scheme==Scheme.RING) ? Scheme.NESTED : Scheme.RING; 113 } 114 115 /** Returns the value of the pixel with a given index. 116 @param ipix index of the requested pixel 117 @return pixel value */ 118 public <type> getPixel(int ipix) 119 { return data[ipix]; } 120 /** Returns the value of the pixel with a given index. 121 @param ipix index of the requested pixel 122 @return pixel value */ 123 public <type> getPixel(long ipix) 124 { return data[(int)ipix]; } 125 /** Sets the value of a specific pixel. 126 @param ipix index of the pixel 127 @param val new value for the pixel */ 128 public void setPixel(int ipix, <type> val) 129 { data[ipix] = val; } 130 /** Sets the value of a specific pixel. 131 @param ipix index of the pixel 132 @param val new value for the pixel */ 133 public void setPixel(long ipix, <type> val) 134 { data[(int)ipix] = val; } 135 136 /** Returns the array containing all map pixels. 137 @return the map array */ 138 public <type>[] getData() 139 { return data; } 140 141 /** Imports the map "orig" to this object, adjusting pixel ordering. 142 @param orig map to import */ 143 public void importNograde (HealpixMap<Type> orig) throws Exception 144 { 145 HealpixUtils.check (nside==orig.nside, 146 "importNograde: maps have different nside"); 147 if (orig.scheme == scheme) 148 System.arraycopy(orig.data,0,data,0,(int)npix); 149 else 150 for (int m=0; m<npix; ++m) 151 data[scheme==Scheme.NESTED ? (int)ring2nest(m) : (int)nest2ring(m)] 152 = orig.data[m]; 153 } 154 /** Imports the map "orig" to this object, adjusting pixel ordering 155 and increasing resolution. 156 @param orig map to import */ 157 public void importUpgrade (HealpixMap<Type> orig) throws Exception 158 { 159 HealpixUtils.check(nside>orig.nside,"importUpgrade: this is no upgrade"); 160 int fact = (int)(nside/orig.nside); 161 HealpixUtils.check(nside==orig.nside*fact, 162 "the larger Nside must be a multiple of the smaller one"); 163 164 for (int m=0; m<orig.npix; ++m) 165 { 166 Xyf xyf = orig.pix2xyf(m); 167 int x=xyf.ix, y=xyf.iy, f=xyf.face; 168 for (int j=fact*y; j<fact*(y+1); ++j) 169 for (int i=fact*x; i<fact*(x+1); ++i) 170 { 171 long mypix = xyf2pix(i,j,f); 172 data[(int)mypix] = orig.data[m]; 173 } 174 } 175 } 176 /** Imports the map "orig" to this object, adjusting pixel ordering 177 and reducing resolution. 178 @param orig map to import 179 @param pessimistic if true, set a pixel to undefined if at least one the 180 original subpixels was undefined; otherwise only set it to undefined if 181 all original subpixels were undefined. */ 182 public void importDegrade (HealpixMap<Type> orig, boolean pessimistic) 183 throws Exception 184 { 185 HealpixUtils.check(nside<orig.nside,"importDegrade: this is no degrade"); 186 int fact = (int)(orig.nside/nside); 187 HealpixUtils.check(orig.nside==nside*fact, 188 "the larger Nside must be a multiple of the smaller one"); 189 190 int minhits = pessimistic ? fact*fact : 1; 191 for (int m=0; m<npix; ++m) 192 { 193 Xyf xyf = pix2xyf(m); 194 int x=xyf.ix, y=xyf.iy, f=xyf.face; 195 int hits = 0; 196 double sum = 0; 197 for (int j=fact*y; j<fact*(y+1); ++j) 198 for (int i=fact*x; i<fact*(x+1); ++i) 199 { 200 int opix = (int)orig.xyf2pix(i,j,f); 201 if (!HealpixUtils.approx(orig.data[opix],undef,1e-5)) 202 { 203 ++hits; 204 sum += orig.data[opix]; 205 } 206 } 207 data[m] = (hits<minhits) ? undef : (<type>) (sum/hits); 208 } 209 } 210 /** Imports the map "orig" to this object, adjusting pixel ordering 211 and resolution if necessary. 212 @param orig map to import 213 @param pessimistic only used when resolution must be reduced: if true, 214 set a pixel to undefined if at least one the original subpixels 215 was undefined; otherwise only set it to undefined if all original 216 subpixels were undefined. */ 217 public void importGeneral (HealpixMap<Type> orig, boolean pessimistic) 218 throws Exception 219 { 220 if (orig.nside==nside) 221 importNograde(orig); 222 else if (orig.nside<nside) // upgrading 223 importUpgrade(orig); 224 else 225 importDegrade(orig,pessimistic); 226 } 227 } 228