def make_sample(outfile, noise=0.0, pixsize=1.0): '''Create a sample data file for mpi-mapmaker-test/ Creates a small rectangular map of a circular Gaussian and scans row of detectors across the map in two orientations. Optionally add noise. ''' # create a fake map (from a Gaussian) nx = 32 ny = 16 gaussfwhm = 4 xx = (np.arange(nx)-nx/2)**2 yy = (np.arange(ny)-ny/2)**2 rr = xx[:,np.newaxis] + yy gausssig = gaussfwhm / 2.354 image = np.exp(-rr/2.0/gausssig**2) # scan once horizontally and twice vertically ndet = 16 nsamp = 64 # allocate arrays det_x = np.zeros([ndet, nsamp], dtype=np.int32) det_y = np.zeros_like(det_x) det_s = np.zeros_like(det_x, dtype=np.float64) # horizontal scan offs = 0 for i in range(nx): for j in range(ndet): det_x[j,offs+i] = i det_y[j,offs+i] = j det_s[j,offs+i] = image[det_x[j,offs+i],det_y[j,offs+i]] # first half vertical offs += nx for i in range(ny): for j in range(ndet): det_x[j,offs+i] = j det_y[j,offs+i] = i det_s[j,offs+i] = image[det_x[j,offs+i],det_y[j,offs+i]] # second half vertical offs += ny for i in range(ny): for j in range(ndet): det_x[j,offs+i] = nx/2+j det_y[j,offs+i] = i det_s[j,offs+i] = image[det_x[j,offs+i],det_y[j,offs+i]] # add noise det_s += np.random.randn(ndet, nsamp) * noise # create data file # initialize data class out_data = MapData(outfile, ndet, nsamp) # write attributes out_data.set_nx(nx) out_data.set_ny(ny) out_data.set_pixsize(pixsize) # set data arrays out_data.x[...] = det_x out_data.y[...] = det_y out_data.s[...] = det_s out_data.q[...] = np.zeros([ndet,nsamp], dtype=np.uint32) # done out_data.close()
def convert_data(infile, outfile, pixsize, verbose=False): '''convert data file for use by mpi_makemap Convert input data file, as created by Jack Sayer's simulator, to format used as input to mpi_makemap. Calculates tangent-plane projection and saves pixel position for each sample. Arguments: input: name of input file (as created from Jack Sayer's simulator) output: name of output file pixsize: size of pixels (in degrees) verbose: print progress messages [False] ''' # get data from file f = h5py.File(infile) det_ra = f[det_ra_name].value det_dec = f[det_dec_name].value tel_ra = f[tel_ra_name].value tel_dec = f[tel_dec_name].value scannum = f[scannum_name].value # check that coordinate system is supported coordsys = f[det_ra_name].attrs["coordinate_system"][0] if coordsys != "radec": sys.stderr.write("error: coordinate system must be 'radec'") sys.exit() # get data lengths nsamp,ndet = f[signal_name].shape # use mean telescope pointing as tangent point tan_ra = tel_ra.mean() tan_dec = tel_dec.mean() # WCS for coordinate transformations w = wcs.WCS(naxis=2) w.wcs.crpix = [0, 0] w.wcs.cdelt = np.array([-pixsize, pixsize]) w.wcs.crval = [tan_ra, tan_dec] w.wcs.ctype = ["RA---TAN", "DEC--TAN"] # initialize min/max collectors minx = np.infty maxx = -np.infty miny = np.infty maxy = -np.infty if verbose: print "Calculating map extent:" # loop over detectors and calculate pixel position to get map range for d in range(ndet): if verbose: print "\tdetector {} of {}".format(d, ndet) # project into tangent plane x,y = w.wcs_world2pix(tel_ra-det_ra[d]/np.cos(tel_dec*np.pi/180), tel_dec+det_dec[d], 0) # convert to integers x = np.floor(x) y = np.floor(y) minx = min(x.min(), minx) maxx = max(x.max(), maxx) miny = min(y.min(), miny) maxy = max(y.max(), maxy) # determine map range nx = maxx - minx + 1 ny = maxy - miny + 1 if verbose: print "opening output file '{}'".format(outfile) # set up output data file out_data = MapData(outfile, ndet, nsamp) out_data.set_nx(nx) out_data.set_ny(ny) out_data.set_pixsize(pixsize) if verbose: print "writing data to file:" # figure out block dimensions (powers of two, assuming blocksize is # power of two) ndata_block = blocksize / out_data.s.dtype.itemsize blocksize_sqrt = np.sqrt(ndata_block) ndet_block = np.int(np.exp2(np.floor(np.log2(blocksize_sqrt)))) ndet_block = min(ndet_block, ndet) nsamp_block = np.int(ndata_block / ndet_block) nsamp_block = min(nsamp_block, nsamp) # loop over data set and write to output this_det0 = 0 while this_det0 < ndet: # number of detectors in this block this_ndet = min(ndet_block, ndet-this_det0) this_det1 = this_det0 + this_ndet if verbose: print "Read/write block: det {}-{} of {}".format( this_det0, this_det1, ndet) this_samp0 = 0 while this_samp0 < nsamp: # number of samples in this block this_nsamp = min(nsamp_block, nsamp-this_samp0) this_samp1 = this_samp0 + this_nsamp # create ra/det blocks ra_block = tel_ra[this_samp0:this_samp1] - \ det_ra[this_det0:this_det1,np.newaxis] / \ np.cos(tel_dec[this_samp0:this_samp1]*np.pi/180) dec_block = tel_dec[this_samp0:this_samp1] + \ det_dec[this_det0:this_det1,np.newaxis] x,y = w.wcs_world2pix(ra_block,dec_block, 0) x = np.floor(x) - minx y = np.floor(y) - miny # write to file out_data.x[this_det0:this_det1,this_samp0:this_samp1] = x out_data.y[this_det0:this_det1,this_samp0:this_samp1] = y out_data.s[this_det0:this_det1,this_samp0:this_samp1] = \ np.transpose(f[signal_name][this_samp0:this_samp1, this_det0:this_det1]) # quality (0 -> good when scannum >= 0) thisqual = (scannum[this_samp0:this_samp1] < 0).astype(np.uint32) out_data.q[this_det0:this_det1,this_samp0:this_samp1] = thisqual # increment samp pointer this_samp0 = this_samp1 # increment det pointer this_det0 = this_det1 if verbose: print "closing files" # done f.close() out_data.close()