def runr(self): """ Map and run the requested or defaulted recipe. Parameters ---------- <void> Returns ------- <void> """ recipe = None try: ffiles = self._check_files(self.files) except OSError as err: log.error(str(err)) raise try: adinputs = self._convert_inputs(ffiles) except OSError as err: log.error(str(err)) raise # build mapper inputs, pass no 'ad' objects. # mappers now receive tags and instr pkg name, e.g., 'gmos' datatags = set(list(adinputs[0].tags)[:]) instpkg = adinputs[0].instrument(generic=True).lower() rm = RecipeMapper(datatags, instpkg, mode=self.mode, drpkg=self.drpkg, recipename=self.recipename) try: recipe = rm.get_applicable_recipe() except ModeError as err: log.warning("WARNING: {}".format(err)) pass except RecipeNotFound: log.warning( "No recipe can be found in {} recipe libs.".format(instpkg)) log.warning("Searching primitives ...") rm = None # PrimitiveMapper now returns the primitive class, not an instance. pm = PrimitiveMapper(datatags, instpkg, mode=self.mode, drpkg=self.drpkg) try: pclass = pm.get_applicable_primitives() except PrimitivesNotFound as err: log.error(str(err)) raise p = pclass(adinputs, mode=self.mode, ucals=self.ucals, uparms=self.uparms, upload=self.upload) # Clean references to avoid keeping adinputs objects in memory one # there are no more needed. adinputs = None # If the RecipeMapper was unable to find a specified user recipe, # it is possible that the recipe passed was a primitive name. # Here we examine the primitive set to see if this recipe is actually # a primitive name. norec_msg = "{} recipes do not define a '{}' recipe for these data." if recipe is None and self.recipename == '_default': raise RecipeNotFound(norec_msg.format(instpkg.upper(), self.mode)) if recipe is None: try: primitive_as_recipe = getattr(p, self.recipename) except AttributeError as err: err = "Recipe {} Not Found".format(self.recipename) log.error(str(err)) raise RecipeNotFound("No primitive named {}".format( self.recipename)) pname = primitive_as_recipe.__name__ log.stdinfo("Found '{}' as a primitive.".format(pname)) self._logheader(pname) try: primitive_as_recipe() except Exception as err: log_traceback(log) log.error(str(err)) raise else: self._logheader(recipe) try: recipe(p) except Exception: log.error( "Reduce received an unhandled exception. Aborting ...") log_traceback(log) log.stdinfo("Writing final outputs ...") self._write_final(p.streams['main']) self._output_filenames = [ ad.filename for ad in p.streams['main'] ] raise self._write_final(p.streams['main']) self._output_filenames = [ad.filename for ad in p.streams['main']] log.stdinfo("\nreduce completed successfully.")
def main(args): """ 'main' is called with a Namespace 'args' parameter, or an object that presents an equivalent interface. Eg., Get "args' from the defined reduce parser: >>> args = buildParser(version).parse_args() >>> import reduce_alpha >>> reduce_alpha.main(args) In the above example, 'args' is -- argparse Namespace instance Use of the reduce_utils function buildParser will get the caller a fully defined reduce Namespace instance, values for which can be then be adjusted as desired. Eg., buildParser: ----------- >>> args = buildParser(version).parse_args() >>> args.logfile 'reduce.log' >>> args.files [] >>> args.files.append('some_fits_file.fits') Once 'args' attributes have been appropriately set, the caller then simply calls main(): >>> reduce_alpha.main(args) :parameter args: argparse Namespace object :type args: <Namespace> :return: exit code :rtype: <int> """ estat = 0 log = logutils.get_logger(__name__) try: assert log.root.handlers log.root.handlers = [] logutils.config(mode=args.logmode, file_name=args.logfile) log = logutils.get_logger(__name__) log.info("Logging configured for application: reduce") log.info(" ") except AssertionError: pass # Config local calibration manager with passed args object if localmanager_available: set_calservice(local_db_dir=args.local_db_dir) log.stdinfo("\n\t\t\t--- reduce v{} ---".format(rs_version)) log.stdinfo("\nRunning on Python {}".format(sys.version.split()[0])) r_reduce = Reduce(args) try: r_reduce.runr() except KeyboardInterrupt: log.error("Caught KeyboardInterrupt (^C) signal") estat = signal.SIGINT except RecipeNotFound as err: log.error(str(err)) estat = signal.SIGABRT except Exception as err: log.error("reduce caught an unhandled exception.\n") log.error(err) log_traceback(log) log.error("\nReduce instance aborted.") estat = signal.SIGABRT if estat != 0: log.stdinfo("\n\nreduce exit status: %d\n" % estat) else: pass return estat