def hashresponse(band, events, verbose=0): """ Given detector xi, eta, return the response at each position. :param band: The band being used, either 'FUV' or 'NUV'. :type band: str :param events: The set of photon events. :type events: dict :param verbose: Verbosity level, a value of 0 is minimum verbosity. :type verbose: int :returns: dict -- The photon event properties, updated with the response at each position. """ # Hash out the response correction. if verbose: mc.print_inline("Applying the response correction.") flat, _ = cal.flat(band) events['col'], events['row'] = xieta2colrow(events['xi'], events['eta'], band) events['flat'] = flat[np.array(events['col'], dtype='int16'), np.array(events['row'], dtype='int16')] events['scale'] = gxt.compute_flat_scale(events['t'], band) # [Future]: Separately do the binlinearly interpolated response. events['response'] = (events['flat'] * events['scale']) return events
def hashresponse(band, events, verbose=0): """ Given detector xi, eta, return the response at each position. :param band: The band being used, either 'FUV' or 'NUV'. :type band: str :param events: The set of photon events. :type events: dict :param verbose: Verbosity level, a value of 0 is minimum verbosity. :type verbose: int :returns: dict -- The photon event properties, updated with the response at each position. """ # Hash out the response correction. if verbose: mc.print_inline("Applying the response correction.") flat, _ = cal.flat(band) events['col'], events['row'] = xieta2colrow( events['xi'], events['eta'], band) events['flat'] = flat[np.array(events['col'], dtype='int16'), np.array(events['row'], dtype='int16')] events['scale'] = gxt.compute_flat_scale(events['t'], band) # [Future]: Separately do the binlinearly interpolated response. events['response'] = (events['flat']*events['scale']) return events
def test_compute_flat_scale_NUV_array(self): band = 'NUV' ts=[869777733.995,901049156.995] scales=[0.986709143129,0.994262914909] out = gt.compute_flat_scale(ts,band,verbose=0) self.assertEqual(len(ts),len(out)) self.assertAlmostEqual(out[0],scales[0]) self.assertAlmostEqual(out[0],scales[0])
def test_compute_flat_scale_FUV_array(self): band = 'FUV' ts=[869777733.995,901049156.995] scales=[0.991157347104,0.999816178202] out = gt.compute_flat_scale(ts,band,verbose=0) self.assertEqual(len(ts),len(out)) self.assertAlmostEqual(out[0],scales[0]) self.assertAlmostEqual(out[0],scales[0])
def create_rr(csvfile, band, eclipse, aspfile=None, expstart=None, expend=None, retries=20, detsize=1.25, pltscl=68.754932): """ DEPRECATED: Creates a relative response map for an eclipse, given a photon list. :param csvfile: Name of CSV file containing photon events. :type csvfile: str :param band: The band being used, either 'FUV' or 'NUV'. :type band: str :param eclipse: The eclipse number the data are taken from. :type eclipse: int :param aspfile: The aspect file to use with the CSV file. :type aspfile: str :param expstart: Start of the exposure, in seconds. :type expstart: float :param expend: End of the exposure, in seconds. :type expend: float :param retries: Number of query retries before giving up. :type retries: int :param detsize: Effective size of the detector, in degrees. :type detsize: float :param pltscl: The plate scale in arcseconds. :type pltscl: float :returns: tuple -- A two-element tuple containing the relative response and the effective exposure time. The relative response is a 2D array of values. """ aspum = pltscl / 1000.0 print("Loading flat file...") flat, flatinfo = cal.flat(band) npixx = flat.shape[0] npixy = flat.shape[1] pixsz = flatinfo['CDELT2'] flatfill = detsize / (npixx * pixsz) print("Retrieving aspect data...") if aspfile: (aspra, aspdec, asptwist, asptime, aspheader, aspflags) = load_aspect([aspfile]) else: (aspra, aspdec, asptwist, asptime, aspheader, aspflags) = web_query_aspect(eclipse, retries=retries) minasp = min(asptime) maxasp = max(asptime) print(" trange= ( " + str(minasp) + " , " + str(maxasp) + " )") ra0, dec0, roll0 = aspheader['RA'], aspheader['DEC'], aspheader['ROLL'] print(" [RA, DEC, ROLL] = [" + str(ra0) + ", " + str(dec0) + ", " + str(roll0) + "]") print("Computing aspect vectors...") print("Calculating aspect solution vectors...") xi_vec, eta_vec = np.array([]), np.array([]) xi_vec, eta_vec = gnomfwd_simple(ra0, dec0, aspra, aspdec, -asptwist, 1.0 / 36000.0, 0.) flat_scale = compute_flat_scale(asptime.mean(), band) if not expstart: expstart = asptime.min() + GPSSECS if not expend: expend = asptime.max() + GPSSECS flatbuff = np.zeros([960, 960]) # Rotate the flat into the correct orientation to start flatbuff[80:960 - 80, 80:960 - 80] = np.flipud(np.rot90(flat)) expt = 0 rr = np.zeros([960, 960]) col = (((xi_vec / 36000.) / (detsize / 2.) * flatfill + 1.) / 2. * npixx) - 400. row = (((eta_vec / 36000.) / (detsize / 2.) * flatfill + 1.) / 2. * npixy) - 400. for i in range(len(asptime) - 1): if (asptime[i] + GPSSECS) < expstart or (asptime[i] + GPSSECS) > expend: print(" ", asptime[i] + GPSSECS, " out of range.") continue elif (aspflags[i] % 2 != 0) or (aspflags[i + 1] % 2 != 0): print(" ", asptime[i] + GPSSECS, " flagged.") continue else: rr += scipy.ndimage.interpolation.shift( scipy.ndimage.interpolation.rotate(flatbuff, -asptwist[i], reshape=False, order=0, prefilter=False), [col[i], row[i]], order=0, prefilter=False) expt += 1 # Need to modify this to handle NUV files better. t, x, y, flags = load_txy(csvfile) exp = compute_exposure(t, x, y, flags, band, eclipse) deadt = compute_deadtime(t, x, y, band, eclipse) return rr * flat_scale * (1 - deadt), exp
def test_compute_flat_scale_NUV(self): band = 'NUV' ts=[869777733.995,901049156.995] scales=[0.986709143129,0.994262914909] for t,scl in zip(ts,scales): self.assertAlmostEqual(gt.compute_flat_scale(t,band,verbose=0),scl)
def test_compute_flat_scale_FUV(self): band = 'FUV' ts=[869777733.995,901049156.995] scales=[0.991157347104,0.999816178202] for t,scl in zip(ts,scales): self.assertAlmostEqual(gt.compute_flat_scale(t,band,verbose=0),scl)
def create_rr(csvfile, band, eclipse, aspfile=None, expstart=None, expend=None, retries=20, detsize=1.25, pltscl=68.754932): """ DEPRECATED: Creates a relative response map for an eclipse, given a photon list. :param csvfile: Name of CSV file containing photon events. :type csvfile: str :param band: The band being used, either 'FUV' or 'NUV'. :type band: str :param eclipse: The eclipse number the data are taken from. :type eclipse: int :param aspfile: The aspect file to use with the CSV file. :type aspfile: str :param expstart: Start of the exposure, in seconds. :type expstart: float :param expend: End of the exposure, in seconds. :type expend: float :param retries: Number of query retries before giving up. :type retries: int :param detsize: Effective size of the detector, in degrees. :type detsize: float :param pltscl: The plate scale in arcseconds. :type pltscl: float :returns: tuple -- A two-element tuple containing the relative response and the effective exposure time. The relative response is a 2D array of values. """ aspum = pltscl/1000.0 print("Loading flat file...") flat, flatinfo = cal.flat(band) npixx = flat.shape[0] npixy = flat.shape[1] pixsz = flatinfo['CDELT2'] flatfill = detsize/(npixx*pixsz) print("Retrieving aspect data...") if aspfile: (aspra, aspdec, asptwist, asptime, aspheader, aspflags) = load_aspect([aspfile]) else: (aspra, aspdec, asptwist, asptime, aspheader, aspflags) = web_query_aspect(eclipse, retries=retries) minasp = min(asptime) maxasp = max(asptime) print(" trange= ( "+str(minasp)+" , "+str(maxasp)+" )") ra0, dec0, roll0 = aspheader['RA'], aspheader['DEC'], aspheader['ROLL'] print(" [RA, DEC, ROLL] = ["+str(ra0)+", "+str(dec0)+ ", "+str(roll0)+"]") print("Computing aspect vectors...") print("Calculating aspect solution vectors...") xi_vec, eta_vec = np.array([]), np.array([]) xi_vec, eta_vec = gnomfwd_simple(ra0, dec0, aspra, aspdec, -asptwist, 1.0/36000.0, 0.) flat_scale = compute_flat_scale(asptime.mean(), band) if not expstart: expstart = asptime.min()+GPSSECS if not expend: expend = asptime.max()+GPSSECS flatbuff = np.zeros([960, 960]) # Rotate the flat into the correct orientation to start flatbuff[80:960-80, 80:960-80] = np.flipud(np.rot90(flat)) expt = 0 rr = np.zeros([960, 960]) col = (((xi_vec/36000.)/(detsize/2.)*flatfill + 1.)/2. * npixx)-400. row = (((eta_vec/36000.)/(detsize/2.)*flatfill + 1.)/2. * npixy)-400. for i in range(len(asptime)-1): if (asptime[i]+GPSSECS) < expstart or (asptime[i]+GPSSECS) > expend: print(" ", asptime[i]+GPSSECS, " out of range.") continue elif (aspflags[i]%2 != 0) or (aspflags[i+1]%2 != 0): print(" ", asptime[i]+GPSSECS, " flagged.") continue else: rr += scipy.ndimage.interpolation.shift( scipy.ndimage.interpolation.rotate(flatbuff, -asptwist[i], reshape=False, order=0, prefilter=False), [col[i], row[i]], order=0, prefilter=False) expt += 1 # Need to modify this to handle NUV files better. t, x, y, flags = load_txy(csvfile) exp = compute_exposure(t, x, y, flags, band, eclipse) deadt = compute_deadtime(t, x, y, band, eclipse) return rr*flat_scale*(1-deadt), exp
def calibrate_photons(photon_file, band, overwrite=False): """This function takes the raw photon events and produces calibrated photon events.""" xfilename = '{d}{base}-x.csv'.format(d=photon_file[:-13], base=photon_file[-13:-4]) if os.path.exists(xfilename) and not overwrite: return pd.read_csv(xfilename, index_col=None) data = pd.read_csv(photon_file, names=[ 't', 'x', 'y', 'xa', 'ya', 'q', 'xi', 'eta', 'ra', 'dec', 'flags' ]) events = pd.DataFrame() flat, _ = gPhoton.cal.flat(band) col, row = gPhoton.curvetools.xieta2colrow(np.array(data['xi']), np.array(data['eta']), band) # Use only data that is on the detector. ix = np.where((col > 0) & (col < 800) & (row > 0) & (row < 800)) events['t'] = pd.Series( (np.array(data.iloc[ix]['t']) / 1000.).byteswap().newbyteorder()) events['ra'] = pd.Series( (np.array(data.iloc[ix]['ra'])).byteswap().newbyteorder()) events['dec'] = pd.Series( (np.array(data.iloc[ix]['dec'])).byteswap().newbyteorder()) events['flags'] = pd.Series( (np.array(data.iloc[ix]['flags'])).byteswap().newbyteorder()) events['col'] = pd.Series((col[ix]).byteswap().newbyteorder()) events['row'] = pd.Series((row[ix]).byteswap().newbyteorder()) flat = flat[np.array(events['col'], dtype='int16'), np.array(events['row'], dtype='int16')] events['flat'] = pd.Series((flat).byteswap().newbyteorder()) scale = gt.compute_flat_scale(np.array(data.iloc[ix]['t']) / 1000., band) events['scale'] = pd.Series((scale).byteswap().newbyteorder()) response = np.array(events['flat']) * np.array(events['scale']) events['response'] = pd.Series((response).byteswap().newbyteorder()) # Define the hotspot mask mask, maskinfo = gPhoton.cal.mask(band) events['mask'] = pd.Series(((mask[np.array(col[ix], dtype='int64'), np.array(row[ix], dtype='int64')] == 0) ).byteswap().newbyteorder()) # Add the remaining photon list parameters back in for completeness. events['x'] = pd.Series( (np.array(data.iloc[ix]['x'])).byteswap().newbyteorder()) events['y'] = pd.Series( (np.array(data.iloc[ix]['y'])).byteswap().newbyteorder()) events['xa'] = pd.Series( (np.array(data.iloc[ix]['xa'])).byteswap().newbyteorder()) events['ya'] = pd.Series( (np.array(data.iloc[ix]['ya'])).byteswap().newbyteorder()) events['q'] = pd.Series( (np.array(data.iloc[ix]['q'])).byteswap().newbyteorder()) events['xi'] = pd.Series( (np.array(data.iloc[ix]['xi'])).byteswap().newbyteorder()) events['eta'] = pd.Series( (np.array(data.iloc[ix]['eta'])).byteswap().newbyteorder()) print('Writing {xf}'.format(xf=xfilename)) events.to_csv(xfilename, index=None) return events