def from_file(par_file): params = config.read(par_file) # Try known first-level keys for key in ['TELESCOPE', 'Telescope', 'telescope']: if key in params.keys(): return Telescope(**params[key]) # Try full parameter set try: return Telescope(**params) except TypeError: raise RuntimeError(f"Could not identify parameters for initializing a Telescope instance in parameter " f"file {par_file}")
def from_file(par_file): params = config.read(par_file) # Try known first-level keys for key in ['DETECTOR', 'Detector', 'detector']: if key in params.keys(): return Detector(**params[key]) # Try full parameter set try: return Detector(**params) except TypeError: raise RuntimeError( f"Could not identify parameters for initializing a Detector instance in parameter " f"file {par_file}")
def gather_header_information(path, instrument, par_file=None, list_file=None, sort_by=None): """Sets up the data reduction parameter file and file list. Args: path (str): Path to the files. instrument (str): Name of the instrument that took the data. This must be covered by config/instruments.cfg. par_file (str, optional): Name of the output default parameter file for the reduction. list_file (str): Name of the output file that contains all the file names and header information. sort_by (str, optional): Header card that is used for the sorting of files. """ # Defaults header_cards = [ 'OBSTYPE', 'OBJECT', 'FILTER', 'EXPTIME', 'nFRAMES', 'DATE' ] dtypes = [str, str, str, float, int, str] instrument_config_file = os.path.join(os.path.dirname(__file__), '../config/instruments.cfg') # Read config configs = config.read(instrument_config_file) instrument = configs['INSTRUMENTS'][instrument] instrument_header_cards = configs[instrument] # Double check whether all aliases are defined for card in header_cards: try: instrument_header_cards[card] except KeyError: logger.info( f"Dropping header card {card} from setup identification, as there is no description in the config file." f"\nCheck out {instrument_config_file} for details.") header_cards.remove(card) # Apply fall back values if path is None: path = '../reduction' if list_file is None: list_file = 'files.tab' if par_file is None: par_file = 'reduction.yaml' # Find files if '*' in path: files = glob.glob(path) else: files = glob.glob(os.path.join(path, '*fits')) if len(files): logger.info(f"Found {len(files)} file(s)") files.sort() else: logger.error(f"Found no files in {path}!") raise RuntimeError(f"Found no files in {path}!") # Initialize output file information table table = Table(names=['FILE'] + header_cards, dtype=[str] + dtypes) # Read data from files for file in files: logger.info(f"Retrieving header information from file {file}") hdr = fits.getheader(file) new_row = [os.path.basename(file)] for card in header_cards: try: new_row.append(hdr[instrument_header_cards[card]]) except KeyError: logger.info( f"Skipping file {os.path.basename(file)} due to at least one missing header card " f"({instrument_header_cards[card]}).") break if len(new_row) == len(table.columns): table.add_row(new_row) # Sort table entries by default properties and user request table.sort('FILE') table.sort('OBSTYPE') if sort_by: table.sort(sort_by) # Identify instrument setups setups = identify_instrument_setups(table) table.add_column(setups) # Save table logger.info(f"Writing header information to {list_file}") table.write(list_file, format='ascii.fixed_width', overwrite=True) # Write dummy parameter file for the reduction _, ext = os.path.splitext(par_file) if 'yaml' in ext: logger.info( f"Creating default reduction YAML parameter file {par_file}") par_file_content = f"PATHS:\n filePath: {path}\n fileList: {list_file}\n outDir: Science/\n tmpDir: tmp/" \ f"\n\nFLAT:\n masterFlatFile: MasterFlat.fits" \ f"\n\nSKY:\n method: scalar" else: logger.info( f"Creating default reduction INI parameter file {par_file}") par_file_content = f"[PATHS]\nfilePath = {path}\nfileList = {list_file}\noutDir = Science/\ntmpDir = tmp/" \ f"\n\n[FLAT]\nmasterFlatFile = MasterFlat.fits" \ f"\n\n[SKY]\nmethod = scalar" with open(par_file, 'w+') as par_file: par_file.write(par_file_content)
def main(): # Parse args parser = GeneralArgParser() args = parser.parse_args() if args.debug: logger.setLevel('DEBUG') logger.debug(args) if args.gui: start() # Execute the script of the corresponding command if args.command is 'generate': # Read parameters from file and generate exposures target, telescope, detector, parameters = get_objects(args.parfile, debug=args.debug) generate_exposure(target=target, telescope=telescope, detector=detector, debug=args.debug, **parameters) elif args.command is 'reduce': # In setup mode if args.setup: run.setup(path=args.path, instrument=args.instrument, par_file=args.parfile, list_file=args.filelist, sort_by=args.sortby) # Else start reduction following the parameter file else: params = config.read(args.parfile) run.full_reduction(params, debug=args.debug) elif args.command is 'ssa': # Prepare path information and execute reconstruction if args.tmpdir is not None and not os.path.isdir(args.tmpdir): os.mkdir(args.tmpdir) ssa(args.files, mode=args.mode, tmp_dir=args.tmpdir, outfile=args.outfile, box_indexes=args.box_indexes, debug=args.debug) elif args.command is 'holography': # Read parameters from file and execute reconstruction defaults_file = os.path.join(os.path.dirname(__file__), '../config/holography.cfg') defaults_file = os.path.abspath(defaults_file) params = config.read(defaults_file) params = config.update_from_file(params, args.parfile) holography(params, mode=params['OPTIONS']['reconstructionMode'], debug=args.debug) elif args.command is 'aperture': if args.mode == 'psf1d': logger.info("Extract 1D PSF profile") analysis.get_psf_1d(args.file, args.index, args.radius, args.out_file, args.normalize, debug=args.debug) elif args.mode == 'variance': logger.info("Extract 1D PSF variation") analysis.get_psf_variation(args.file, args.index, args.radius, args.out_file, args.normalize, args.debug) else: logger.warning(f"Aperture mode {args.mode} not recognized!") elif args.command is 'extract': if args.out_file is None: args.out_file = 'sources_' + os.path.basename( args.file_name).replace('.fits', '.dat') extract_sources(image=args.file_name, noise_threshold=args.noise_threshold, fwhm=args.fwhm, image_var=args.var, write_to=args.out_file) elif args.command == 'plot': plot = Plot.from_file(file_name=args.file, extension=args.extension, columns=args.columns, format=args.format, layout=args.layout, debug=args.debug) plot.apply_layout(layout=args.layout) plot.save() plot.show() elif args.command is 'apodization': get_resolution_parameters(wavelength=args.wavelength, diameter=args.diameter, pixel_scale=args.pixel_scale)
def test_read(self): config = read(self.par_file)
def get_objects(parameter_file, debug=False): """Get objects from parameter file. Args: parameter_file (str): File from which the objects are instantiated. debug (bool, optional): Show debugging information. Returns: target (Target object): telescope (Telescope object): detector (Detector object): parameters (dict): Dictionary containing the parameters parsed toward generate exposure beyond the three objects. """ # Set logger level if debug: logger.setLevel('DEBUG') # Check whether files exist if not os.path.isfile(parameter_file): raise FileNotFoundError(f"Parameter file {parameter_file} not found!") # Read parameter file params = config.read(parameter_file) # Create objects from the parameters target = Target(**params['TARGET']) logger.debug(f"Initialized Target instance:\n{target}") telescope = Telescope(**params['TELESCOPE']) logger.debug(f"Initialized Telescope instance:\n{telescope}") detector = Detector(**params['DETECTOR']) logger.debug(f"Initialized Detector instance:\n{detector}") # Extract and interpret other kez word parameters if 'KWARGS' in params: parameters = params['KWARGS'] elif 'PARAMETERS' in params: parameters = params['PARAMETERS'] else: parameters = {} # Interpret str-type key word arguments for key in parameters.keys(): if isinstance(parameters[key], str): try: parameters[key] = eval(parameters[key]) logger.debug( f"Kwarg {key} evaluated as {parameters[key]} ({type(parameters[key])})" ) except SyntaxError: parameters[key] = Quantity(parameters[key]) logger.debug( f"Kwarg {key} evaluated as {parameters[key]} ({type(parameters[key])})" ) except NameError: logger.debug( f"Kwarg {key} not evaluated {parameters[key]} ({type(parameters[key])})" ) return target, telescope, detector, parameters
def setup(path, instrument, par_file=None, list_file=None, sort_by=None): """Sets up the data reduction parameter file and file list. Args: path (str): Path to the files. instrument (str): Name of the instrument that took the data. This must be covered by config/instruments.cfg. par_file (str, optional): Name of the output default parameter file for the reduction. list_file (str): Name of the output file that contains all the file names and header information. sort_by (str, optional): Header card that is used for the sorting of files. """ # Defaults default_cards = ['OBSTYPE', 'OBJECT', 'FILTER', 'EXPTIME', 'nFRAMES', 'DATE'] dtypes = [str, str, str, float, int, str] instrument_config_file = os.path.join(os.path.dirname(__file__), '../config/instruments.cfg') # Read config configs = config.read(instrument_config_file) instrument_cards = configs[instrument.upper()] # Double check whether all aliases are defined cards = [] for card in default_cards: try: cards.append(instrument_cards[card]) except KeyError: logger.info( f"Dropping header card {card} from setup identification, as there is no description in the config file." f"\nCheck out {instrument_config_file} for details.") cards.append(None) for card, dtype, header_card in zip(cards, dtypes, default_cards): if card is None: cards.remove(card) dtypes.remove(dtype) default_cards.remove(header_card) # Apply fall back values if path is None: path = '.' if list_file is None: list_file = 'files.tab' if par_file is None: par_file = 'reduction.yaml' # Find files if '*' in path: files = glob.glob(path) else: files = glob.glob(os.path.join(path, '*fits')) if len(files): logger.info(f"Found {len(files)} file(s)") files.sort() else: logger.error(f"Found no files in {path}!") raise RuntimeError(f"Found no files in {path}!") # Initialize a file archive raw_files = FileArchive(files, cards=cards, dtypes=dtypes, names=default_cards, sort_by=sort_by) raw_files.identify_setups(['FILTER', 'EXPTIME']) raw_files.write_table(file_name=list_file) # Write dummy parameter file for the reduction _, ext = os.path.splitext(par_file) if 'yaml' in ext: logger.info(f"Creating default reduction YAML parameter file {par_file}") par_file_content = f"PATHS:\n filePath: {path}\n fileList: {list_file}\n outDir: Science/\n tmpDir: tmp/" \ f"\n prefix: r" \ f"\n\nFLAT:\n masterFlatFile: MasterFlat.fits" \ f"\n\nSKY:\n method: scalar" else: logger.info(f"Creating default reduction INI parameter file {par_file}") par_file_content = f"[PATHS]\nfilePath = {path}\nfileList = {list_file}\noutDir = Science/\ntmpDir = tmp/" \ f"\nprefix = r" \ f"\n\n[FLAT]\nmasterFlatFile = MasterFlat.fits" \ f"\n\n[SKY]\nmethod = scalar" with open(par_file, 'w+') as par_file: par_file.write(par_file_content)