def TES_Instru2coord(TES, ASIC, q, frame='ONAFP', verbose=True): """ From (TES, ASIC) numbering on the instrument to (x,y) coordinates in ONAFP or GRF frame. Returns also the focal plane index. !!! If q is a TD instrument, only ASIC 1 and 2 are acceptable. Parameters ---------- TES: TES number as defined on the instrument ASIC: ASIC number q: QubicInstrument() frame: str 'GRF' or 'ONAFP' only Returns ------- x, y: TES center coordinates. FP_index: Focal Plane index, as used in Qubic soft. index_q: position index of the FP_index in q.detector.index() """ if TES in [4, 36, 68, 100]: raise ValueError('This is a thermometer !') FP_index = tes2index(TES, ASIC) if verbose: print('FP_index =', FP_index) index_q = np.where(q.detector.index == FP_index)[0][0] if verbose: print('Index_q =', index_q) centerGRF = q.detector.center[q.detector.index == FP_index][0] xGRF = centerGRF[0] yGRF = centerGRF[1] if frame not in ['GRF', 'ONAFP']: raise ValueError('The frame is not valid.') elif frame == 'GRF': if verbose: print('X_GRF = {:.3f} mm, Y_GRF = {:.3f} mm'.format( xGRF * 1e3, yGRF * 1e3)) return xGRF, yGRF, FP_index, index_q elif frame == 'ONAFP': xONAFP = -yGRF yONAFP = xGRF if verbose: print('X_ONAFP = {:.3f} mm, Y_ONAFP = {:.3f} mm'.format( xONAFP * 1e3, yONAFP * 1e3)) return xONAFP, yONAFP, FP_index, index_q
def tes_signal2image_fp(tes_signal, asics): """ tes_signal : array of shape (128, #ASICS) Signal on each TES, for each ASIC. asics : list Indices of the asics used between 1 and 8. """ thermos = [4, 36, 68, 100] image_fp = np.empty((34, 34)) image_fp[:] = np.nan for ASIC in asics: for TES in range(128): if TES + 1 not in thermos: index = tes2index(TES + 1, ASIC) image_fp[index // 34, index % 34] = tes_signal[TES, ASIC - 1] return image_fp
def _init_id(self, ident_focalplane, num, asic=None): """ Generates focal plane identifications from user input Parameter: num: is the detector or pixel number. asic: ASIC number if ident_focalplane = TESName and num has to be the tes number. """ if ident_focalplane == 'FileName': self.npix = num self.tes, self.asic = (self.npix, 1) if (self.npix < 128) else (self.npix - 128, 2) self.qpix = tes2pix(self.tes, self.asic) - 1 elif ident_focalplane == 'qsName': FPidentity = make_id_focalplane() self.qpix = num det_index = self.instrument.detector[self.qpix].index[0] self.tes = FPidentity[det_index].TES self.asic = FPidentity[det_index].ASIC self.npix = self.tes if self.asic == 1 else self.tes + 128 elif ident_focalplane == 'TESName': if num > 128: raise ValueError( "Wrong TES value. You gave a TES number greater than 128.") else: if asic == None: raise ValueError( "You choose {} identification but ASIC number is missing." .format(ident_focalplane)) else: self.tes = num self.asic = asic self.npix = self.tes if self.asic == 1 else self.tes + 128 self.qpix = tes2pix(self.tes, self.asic) - 1 if self.verbose: print("You are running fitting in healpix maps.") print("========================================") print("TES number {} asic number {}".format(self.tes, self.asic)) print("In FileName format the number of tes is {}".format( self.npix)) print("Index number: qpack {} qsoft {} ".format(\ tes2index(self.tes, self.asic), self.instrument.detector[self.qpix].index[0] )) print("qubicsoft number: {}".format(self.qpix)) return
def get_tes_xycoords_radial_dist(q): tes_xy = np.zeros((256, 2)) tes_radial_dist = np.zeros(256) for i in range(256): if i < 128: tes = i + 1 asic = 1 else: tes = i - 128 + 1 asic = 2 index = tes2index(tes, asic) # None are the thermometers if index is not None: index_place = np.where(q.detector.index == index)[0][0] x = q.detector.center[index_place, 0] y = q.detector.center[index_place, 1] tes_radial_dist[i] = np.sqrt(x**2 + y**2) print(tes, index, tes_radial_dist[i]) tes_xy[i, :] = ([x, y]) return tes_xy, tes_radial_dist
def get_FL_perTES(tes_xy, alpha, rdist=None, npeaks=9, ntes=256, nsig=3, goodtes=None, approx=True, doplot=True): tes_dist = cdist(tes_xy, tes_xy, 'euclidean') print('TES dist:', tes_dist[0, 1]) print(tes_dist.shape) tanalpha = np.tan(alpha) if goodtes is not None: for i in range(ntes): if i < 128: tes = i + 1 asic = 1 else: tes = i - 128 + 1 asic = 2 index = tes2index(tes, asic) if index not in goodtes: print(i, index) tes_dist[i, :] = np.nan tes_dist[:, i] = np.nan fl_mean = np.zeros((npeaks, ntes)) fl_std = np.zeros((npeaks, ntes)) for peak in range(npeaks): print('Peak ', peak, '\n') if approx: fl = tes_dist / tanalpha[peak] else: fl = np.zeros((ntes, ntes)) for tes1 in range(ntes): for tes2 in range(ntes): print('TES', tes1) # Compute k = Drcos(phi) k = (tes_xy[tes2, 0] - tes_xy[tes1, 0]) * tes_xy[tes1, 0] \ + (tes_xy[tes2, 1] - tes_xy[tes1, 1]) * tes_xy[tes1, 1] D = tes_dist[tes1, tes2] tg = tanalpha[peak, tes1, tes2] Delta = D**4 - 4 * tg**2 * k**2 * (1 + D**2 / k) Xplus = (-2 * k * tg**2 + D**2 + np.sqrt(Delta)) / (2 * tg**2) fl[tes1, tes2] = np.sqrt(Xplus - rdist[tes1]**2) print('fl', fl.shape) np.fill_diagonal(fl, np.nan) # fl = fl[~np.isnan(fl)] # fl_clip, mini, maxi = sigmaclip(fl, low=nsig, high=nsig) # print(mini, maxi) # print('fl_clip', fl_clip) # Mean and STD for each TES fl_mean[peak, :] = np.nanmean(fl, axis=0) fl_std[peak, :] = np.nanstd(fl, axis=0) # Global mean and std fl_global_mean = np.nanmean(fl) fl_global_std = np.nanstd(fl) if doplot: plt.subplots(122) plt.suptitle('Peak {}'.format(peak)) plt.subplot(121) plt.hist(np.ravel(fl), bins=100, label='mean = {:.5f} \n STD = {:.5f}'.format( fl_global_mean, fl_global_std)) plt.xlabel('Focal length [m]') plt.legend() plt.subplot(122) plt.imshow(fl) plt.colorbar() plt.xlabel('TES index') plt.ylabel('TES index') plt.show() return fl_mean, fl_std