def fake_hexagon_focalplane( n_pix=7, width_deg=5.0, samplerate=1.0, epsilon=0.0, net=1.0, fmin=0.0, alpha=1.0, fknee=0.05, ): pol_A = hex_pol_angles_qu(n_pix, offset=0.0) pol_B = hex_pol_angles_qu(n_pix, offset=90.0) quat_A = hex_layout(n_pix, width_deg, "D", "A", pol_A) quat_B = hex_layout(n_pix, width_deg, "D", "B", pol_B) det_data = dict(quat_A) det_data.update(quat_B) nrings = hex_nring(n_pix) detfwhm = 0.5 * 60.0 * width_deg / (2 * nrings - 1) for det in det_data.keys(): det_data[det]["pol_leakage"] = epsilon det_data[det]["fmin"] = fmin det_data[det]["fknee"] = fknee det_data[det]["alpha"] = alpha det_data[det]["NET"] = net det_data[det]["fwhm_arcmin"] = detfwhm det_data[det]["fsample"] = samplerate return Focalplane(detector_data=det_data, sample_rate=samplerate)
def get_focalplane(args, comm, hw, det_index, verbose=False): """ Translate hardware configuration into a TOAST focalplane dictionary """ if comm.world_rank == 0: detector_data = {} band_params = {} for band_name, band_data in hw.data["bands"].items(): band_params[band_name] = BandParams(band_name, band_data) # User may force the effective focal plane radius to be larger # than the default. This will widen the size of the simulated # atmosphere but has no other effect for the time being. fpradius = None try: fpradius = args.focalplane_radius_deg except: pass if fpradius is None: fpradius = 0 for det_name, det_data in hw.data["detectors"].items(): # RNG index for this detector index = det_index[det_name] wafer = det_data["wafer"] # Determine which tube has this wafer for tube_name, tube_data in hw.data["tubes"].items(): if wafer in tube_data["wafers"]: break # Determine which telescope has this tube for telescope_name, telescope_data in hw.data["telescopes"].items( ): if tube_name in telescope_data["tubes"]: break else: raise RuntimeError( "Unable to match tube {} to a telescope".format(tube_name)) fpradius = max(fpradius, FOCALPLANE_RADII_DEG[telescope_name]) det_params = DetectorParams( det_data, band_params[det_data["band"]], wafer, tube_name, telescope_name, index, ) detector_data[det_name] = det_params.get_dict() # Create a focal plane in the telescope focalplane = Focalplane( detector_data=detector_data, sample_rate=args.sample_rate, radius_deg=fpradius, ) else: focalplane = None if comm.comm_world is not None: focalplane = comm.comm_world.bcast(focalplane) return focalplane
def load_focalplanes(args, comm, schedules): """ Attach a focalplane to each of the schedules. Args: schedules (list) : List of Schedule instances. Each schedule has two members, telescope and ceslist, a list of CES objects. Returns: detweights (dict) : Inverse variance noise weights for every detector across all focal planes. In [K_CMB^-2]. They can be used to bin the TOD. """ timer = Timer() timer.start() # Load focalplane information focalplanes = [] if comm.world_rank == 0: for fpfile in args.focalplane.split(","): focalplanes.append( Focalplane( fname_pickle=fpfile, sample_rate=args.sample_rate, radius_deg=args.focalplane_radius_deg, )) if comm.comm_world is not None: focalplanes = comm.comm_world.bcast(focalplanes) if len(focalplanes) == 1 and len(schedules) > 1: focalplanes *= len(schedules) if len(focalplanes) != len(schedules): raise RuntimeError( "Number of focalplanes must equal number of schedules or be 1.") # Append a focal plane and telescope to each entry in the schedules # list and assemble a detector weight dictionary that represents all # detectors in all focalplanes detweights = {} for schedule, focalplane in zip(schedules, focalplanes): schedule.telescope.focalplane = focalplane detweights.update(schedule.telescope.focalplane.detweights) timer.stop() if comm.world_rank == 0: timer.report("Loading focalplanes") return detweights
def load_focalplane(args, comm, schedule): focalplane = None # Load focalplane information if comm.comm_world is None or comm.comm_world.rank == 0: if args.focalplane is None: detector_data = {} ZAXIS = np.array([0, 0, 1.0]) # in this case, create a fake detector at the boresight # with a pure white noise spectrum. fake = {} fake["quat"] = np.array([0, 0, 0, 1.0]) fake["fwhm"] = 30.0 fake["fknee"] = 0.0 fake["fmin"] = 1e-9 fake["alpha"] = 1.0 fake["NET"] = 1.0 fake["color"] = "r" detector_data["bore1"] = fake # Second detector at 22.5 degree polarization angle fake2 = {} zrot = qa.rotation(ZAXIS, np.radians(22.5)) fake2["quat"] = qa.mult(fake["quat"], zrot) fake2["fwhm"] = 30.0 fake2["fknee"] = 0.0 fake2["fmin"] = 1e-9 fake2["alpha"] = 1.0 fake2["NET"] = 1.0 fake2["color"] = "r" detector_data["bore2"] = fake2 # Third detector at 45 degree polarization angle fake3 = {} zrot = qa.rotation(ZAXIS, np.radians(45)) fake3["quat"] = qa.mult(fake["quat"], zrot) fake3["fwhm"] = 30.0 fake3["fknee"] = 0.0 fake3["fmin"] = 1e-9 fake3["alpha"] = 1.0 fake3["NET"] = 1.0 fake3["color"] = "r" detector_data["bore3"] = fake3 # Fourth detector at 67.5 degree polarization angle fake4 = {} zrot = qa.rotation(ZAXIS, np.radians(67.5)) fake4["quat"] = qa.mult(fake["quat"], zrot) fake4["fwhm"] = 30.0 fake4["fknee"] = 0.0 fake4["fmin"] = 1e-9 fake4["alpha"] = 1.0 fake4["NET"] = 1.0 fake4["color"] = "r" detector_data["bore4"] = fake4 focalplane = Focalplane(detector_data=detector_data, sample_rate=args.sample_rate) else: focalplane = Focalplane(fname_pickle=args.focalplane, sample_rate=args.sample_rate) if comm.comm_world is not None: focalplane = comm.comm_world.bcast(focalplane, root=0) if args.debug: if comm.comm_world is None or comm.comm_world.rank == 0: outfile = "{}/focalplane.png".format(args.outdir) plot_focalplane(focalplane, 6, 6, outfile) schedule.telescope.focalplane = focalplane detweights = focalplane.detweights return detweights