Exemplo n.º 1
0
    def buildERRmask(self, chip, dqarr, scale):
        """
        Builds a weight mask from an input DQ array and an ERR array
        associated with the input image.
        """
        sci_chip = self._image[self.scienceExt, chip]

        # Set default value in case of error, or lack of ERR array
        errmask = dqarr

        if self.errExt is not None:
            try:
                # Attempt to open the ERR image.
                err = self.getData(exten=self.errExt + ',' + str(chip))

                log.info("Applying ERR weighting to DQ mask for chip %s" %
                         chip)

                # Multiply the scaled ERR file by the input mask in place.
                #exptime = self.getexptimeimg(chip)
                exptime = sci_chip._exptime
                errmask = (exptime / err)**2 * dqarr

                # Update 'wt_scl' parameter to match use of IVM file
                #sci_chip._wtscl = pow(sci_chip._exptime,2)/pow(scale,4)
                sci_chip._wtscl = 1.0 / pow(scale, 4)

                del err

            except:
                # We cannot find an 'ERR' extension and the data isn't WFPC2.
                # Print a generic warning message and continue on with the
                # final drizzle step.

                print(textutil.textbox(
                    'WARNING: No ERR weighting will be applied to the mask '
                    'used in the final drizzle step!  Weighting will be only '
                    'by exposure time.\n\nThe data provided as input does not '
                    'contain an ERR extension'),
                      file=sys.stderr)
                print('\n Continue with final drizzle step...', sys.stderr)
        else:
            # If we were unable to find an 'ERR' extension to apply, one
            # possible reason was that the input was a 'standard' WFPC2 data
            # file that does not actually contain an error array.  Test for
            # this condition and issue a Warning to the user and continue on to
            # the final drizzle.

            print(textutil.textbox(
                "WARNING: No ERR weighting will be applied to the mask used "
                "in the final drizzle step!  Weighting will be only by "
                "exposure time.\n\nThe WFPC2 data provided as input does not "
                "contain ERR arrays.  WFPC2 data is not supported by this "
                "weighting type.\n\nA workaround would be to create inverse "
                "variance maps and use 'IVM' as the final_wht_type.  See the "
                "HELP file for more details on using inverse variance maps."),
                  file=sys.stderr)
            print("\n Continue with final drizzle step...", file=sys.stderr)

        return errmask.astype(np.float32)
Exemplo n.º 2
0
    def generateRaDec(self):
        """ Convert XY positions into sky coordinates using STWCS methods
        """
        self.prefix = self.PAR_PREFIX

        if not isinstance(self.wcs,pywcs.WCS):
            print(textutil.textbox('WCS not a valid PyWCS object. Conversion of RA/Dec not possible...'),
                  file=sys.stderr)
            raise ValueError
        if self.xypos is None or len(self.xypos[0]) == 0:
            self.xypos = None
            warnstr = textutil.textbox('WARNING: \n'+
                        'No objects found for this image...')
            for line in warnstr.split('\n'):
                log.warning(line)
            print(warnstr)
            return

        if self.radec is None or force:
            if self.wcs is not None:
                print('     Found {:d} objects.'.format(len(self.xypos[0])))
                self.radec = self.wcs.all_pix2world(self.xypos[0],self.xypos[1],self.origin)
            else:
                # If we have no WCS, simply pass along the XY input positions
                # under the assumption they were already sky positions.
                self.radec = self.xypos
Exemplo n.º 3
0
    def generateRaDec(self):
        """ Convert XY positions into sky coordinates using STWCS methods. """
        self.prefix = self.PAR_PREFIX

        if not isinstance(self.wcs, pywcs.WCS):
            print(textutil.textbox('WCS not a valid PyWCS object. '
                                   'Conversion of RA/Dec not possible...'),
                  file=sys.stderr)
            raise ValueError

        if self.xypos is None or len(self.xypos[0]) == 0:
            self.xypos = None
            warnstr = textutil.textbox('WARNING: \n'
                                       'No objects found for this image...')

            for line in warnstr.split('\n'):
                log.warning(line)

            print(warnstr)
            return

        if self.radec is None:
            print('     Found {:d} objects.'.format(len(self.xypos[0])))
            if self.wcs is not None:
                ra, dec = self.wcs.all_pix2world(self.xypos[0], self.xypos[1],
                                                 self.origin)
                self.radec = [ra, dec] + copy.deepcopy(self.xypos[2:])
            else:
                # If we have no WCS, simply pass along the XY input positions
                # under the assumption they were already sky positions.
                self.radec = copy.deepcopy(self.xypos)
Exemplo n.º 4
0
    def buildERRmask(self,chip,dqarr,scale):
        """
        Builds a weight mask from an input DQ array and an ERR array
        associated with the input image.
        """
        sci_chip = self._image[self.scienceExt,chip]

        # Set default value in case of error, or lack of ERR array
        errmask = dqarr

        if self.errExt is not None:
            try:
                # Attempt to open the ERR image.
                err = self.getData(exten=self.errExt+','+str(chip))

                log.info("Applying ERR weighting to DQ mask for chip %s" %
                         chip)

                # Multiply the scaled ERR file by the input mask in place.
                #exptime = self.getexptimeimg(chip)
                exptime = sci_chip._exptime
                errmask = (exptime/err)**2 * dqarr

                # Update 'wt_scl' parameter to match use of IVM file
                #sci_chip._wtscl = pow(sci_chip._exptime,2)/pow(scale,4)
                sci_chip._wtscl = 1.0/pow(scale,4)

                del err

            except:
                # We cannot find an 'ERR' extension and the data isn't WFPC2.
                # Print a generic warning message and continue on with the
                # final drizzle step.

                print(textutil.textbox(
                    'WARNING: No ERR weighting will be applied to the mask '
                    'used in the final drizzle step!  Weighting will be only '
                    'by exposure time.\n\nThe data provided as input does not '
                    'contain an ERR extension'), file=sys.stderr)
                print('\n Continue with final drizzle step...', sys.stderr)
        else:
            # If we were unable to find an 'ERR' extension to apply, one
            # possible reason was that the input was a 'standard' WFPC2 data
            # file that does not actually contain an error array.  Test for
            # this condition and issue a Warning to the user and continue on to
            # the final drizzle.

            print(textutil.textbox(
                "WARNING: No ERR weighting will be applied to the mask used "
                "in the final drizzle step!  Weighting will be only by "
                "exposure time.\n\nThe WFPC2 data provided as input does not "
                "contain ERR arrays.  WFPC2 data is not supported by this "
                "weighting type.\n\nA workaround would be to create inverse "
                "variance maps and use 'IVM' as the final_wht_type.  See the "
                "HELP file for more details on using inverse variance maps."),
                file=sys.stderr)
            print("\n Continue with final drizzle step...", file=sys.stderr)

        return errmask.astype(np.float32)
Exemplo n.º 5
0
def buildASNList(rootnames, asnname, check_for_duplicates=True):
    """
    Return the list of filenames for a given set of rootnames
    """

    # Recognize when multiple valid inputs with the same rootname are present
    # this would happen when both CTE-corrected (_flc) and non-CTE-corrected (_flt)
    # products are in the same directory as an ASN table
    filelist, duplicates = checkForDuplicateInputs(rootnames)

    if check_for_duplicates and duplicates:
        # Build new ASN tables for each set of input files
        origasn = changeSuffixinASN(asnname, 'flt')
        dupasn = changeSuffixinASN(asnname, 'flc')

        errstr = 'ERROR:\nMultiple valid input files found:\n'
        for fname, dname in zip(filelist, duplicates):
            errstr += '    %s    %s\n' % (fname, dname)
        errstr += ('\nNew association files have been generated for each '
                   'version of these files.\n    %s\n    %s\n\nPlease '
                   're-start astrodrizzle using of these new ASN files or '
                   'use widlcards for the input to only select one type of '
                   'input file.' % (dupasn, origasn))

        print(textutil.textbox(errstr), file=sys.stderr)

        # generate new ASN files for each case,
        # report this case of duplicate inputs to the user then quit
        raise ValueError

    return filelist
Exemplo n.º 6
0
    def writeXYCatalog(self, filename):
        """ Write out the X,Y catalog to a file
        """
        if self.xypos is None:
            warnstr = textutil.textbox(
                'WARNING: \n    No X,Y source catalog to write to file. ')
            for line in warnstr.split('\n'):
                log.warning(line)
            print(warnstr)
            return

        f = open(filename, 'w')
        f.write("# Source catalog derived for %s\n" % self.wcs.filename)
        f.write("# Columns: \n")
        if self.use_sharp_round:
            f.write(
                '#    X      Y         Flux       ID      Sharp       Round1       Round2\n'
            )
        else:
            f.write('#    X      Y         Flux       ID\n')
        f.write('#   (%s)   (%s)\n' % (self.in_units, self.in_units))

        for row in range(len(self.xypos[0])):
            for i in range(len(self.xypos)):
                f.write("%g  " % (self.xypos[i][row]))
            f.write("\n")

        f.close()
Exemplo n.º 7
0
    def writeXYCatalog(self,filename):
        """ Write out the X,Y catalog to a file
        """
        if self.xypos is None:
            warnstr = textutil.textbox(
                'WARNING: \n    No X,Y source catalog to write to file. ')
            for line in warnstr.split('\n'):
                log.warning(line)
            print(warnstr)
            return

        f = open(filename,'w')
        f.write("# Source catalog derived for %s\n"%self.wcs.filename)
        f.write("# Columns: \n")
        if self.use_sharp_round:
            f.write('#    X      Y         Flux       ID      Sharp       Round1       Round2\n')
        else:
            f.write('#    X      Y         Flux       ID\n')
        f.write('#   (%s)   (%s)\n'%(self.in_units,self.in_units))

        for row in range(len(self.xypos[0])):
            for i in range(len(self.xypos)):
                f.write("%g  "%(self.xypos[i][row]))
            f.write("\n")

        f.close()
Exemplo n.º 8
0
def buildASNList(rootnames, asnname, check_for_duplicates=True):
    """
    Return the list of filenames for a given set of rootnames
    """

    # Recognize when multiple valid inputs with the same rootname are present
    # this would happen when both CTE-corrected (_flc) and non-CTE-corrected (_flt)
    # products are in the same directory as an ASN table
    filelist, duplicates = checkForDuplicateInputs(rootnames)

    if check_for_duplicates and duplicates:
        # Build new ASN tables for each set of input files
        origasn = changeSuffixinASN(asnname, 'flt')
        dupasn = changeSuffixinASN(asnname, 'flc')

        errstr = 'ERROR:\nMultiple valid input files found:\n'
        for fname, dname in zip(filelist, duplicates):
            errstr += '    %s    %s\n' % (fname, dname)
        errstr += ('\nNew association files have been generated for each '
                   'version of these files.\n    %s\n    %s\n\nPlease '
                   're-start astrodrizzle using of these new ASN files or '
                   'use widlcards for the input to only select one type of '
                   'input file.' % (dupasn, origasn))

        print(textutil.textbox(errstr), file=sys.stderr)

        # generate new ASN files for each case,
        # report this case of duplicate inputs to the user then quit
        raise ValueError

    return filelist
Exemplo n.º 9
0
    def get_filename(self):
        """ Return name of rules file to be used
        It will use a local copy if present, and use the installed version
        by default. Any local copy will take precendence over the default rules.

        This function will return the alphabetically first file that applies
        to the instrument and meets the version requirements
        """
        rules_file = None
        # get all potential local rules
        rfiles = glob.glob('*.rules')
        rfiles.sort()

        # Sort through list and find only applicable rules files
        # This would include picking up any rules files using the default
        # naming convention; namely, <instrument>_header.rules
        for r in rfiles:
            v, i = self.get_rules_header(r)
            if v is None or i is None:
                continue
            if v <= __rules_version__ and i == self.instrument.lower():
                rules_file = r
                break

        if rules_file is None:
            # define default rules name installed with the software
            rules_name = self.instrument.lower() + self.rules_name_suffix
            rules_file = os.path.join(os.path.dirname(__file__), rules_name)
            if not os.path.exists(rules_file):
                rules_name = self.telescope + self.rules_name_suffix
                rules_file = os.path.join(os.path.dirname(__file__),
                                          rules_name)
                if not os.path.exists(rules_file):
                    rules_file = None

        if rules_file is None:
            errmsg = 'ERROR:\n' + '    No valid rules file found for:\n'
            errmsg += '    INSTRUMENT = %s\n' % (self.instrument)
            errmsg += '    RULES Version <= %s\n' % (__rules_version__)
            print(textutil.textbox(errmsg))
            raise ValueError

        self.rules_file = rules_file
        return rules_file
Exemplo n.º 10
0
    def get_filename(self):
        """ Return name of rules file to be used
        It will use a local copy if present, and use the installed version
        by default. Any local copy will take precendence over the default rules.

        This function will return the alphabetically first file that applies
        to the instrument and meets the version requirements
        """
        rules_file = None
        # get all potential local rules
        rfiles = glob.glob('*.rules')
        rfiles.sort()

        # Sort through list and find only applicable rules files
        # This would include picking up any rules files using the default
        # naming convention; namely, <instrument>_header.rules
        for r in rfiles:
            v,i = self.get_rules_header(r)
            if v is None or i is None:
                continue
            if v <= __rules_version__ and i == self.instrument.lower():
                rules_file = r
                break

        if rules_file is None:
            # define default rules name installed with the software
            rules_name = self.instrument.lower()+self.rules_name_suffix
            rules_file = os.path.join(os.path.dirname(__file__),rules_name)
            if not os.path.exists(rules_file):
                rules_name = self.telescope+self.rules_name_suffix
                rules_file = os.path.join(os.path.dirname(__file__),rules_name)
                if not os.path.exists(rules_file):
                    rules_file = None

        if rules_file is None:
            errmsg = 'ERROR:\n'+'    No valid rules file found for:\n'
            errmsg += '    INSTRUMENT = %s\n'%(self.instrument)
            errmsg += '    RULES Version <= %s\n'%(__rules_version__)
            print(textutil.textbox(errmsg))
            raise ValueError

        self.rules_file = rules_file
        return rules_file
Exemplo n.º 11
0
def run(configobj):
    """ Primary Python interface for image registration code
        This task replaces 'tweakshifts'
    """
    print('TweakReg Version %s(%s) started at: %s \n'%(
                    __version__,__version_date__,util._ptime()[0]))
    util.print_pkg_versions()

    # make sure 'updatewcs' is set to False when running from GUI or if missing
    # from configObj:
    if 'updatewcs' not in configobj:
        configobj['updatewcs'] = False

    # Check to see whether or not the imagefindpars parameters have
    # already been loaded, as done through the python interface.
    # Repeat for refimagefindpars
    if PSET_SECTION not in configobj:
        # Manage PSETs for source finding algorithms
        _managePsets(configobj, PSET_SECTION, imagefindpars.__taskname__)
    #print configobj[PSET_SECTION]
    if PSET_SECTION_REFIMG not in configobj:
        # Manage PSETs for source finding algorithms in reference image
        _managePsets(configobj, PSET_SECTION_REFIMG,
                     refimagefindpars.__taskname__)

    log.debug('')
    log.debug("==== TweakReg was invoked with the following parameters: ====")
    log.debug('')
    util.print_cfg(configobj, log.debug)

    # print out user set input parameter values for running this task
    log.info('')
    log.info("USER INPUT PARAMETERS common to all Processing Steps:")
    util.printParams(configobj, log=log)

    # start interpretation of input parameters
    input_files = configobj['input']
    # Start by interpreting the inputs
    use_catfile = True
    expand_refcat = configobj['expand_refcat']
    enforce_user_order = configobj['enforce_user_order']

    filenames, catnames = tweakutils.parse_input(
        input_files, sort_wildcards=not enforce_user_order
    )

    catdict = {}
    for indx,f in enumerate(filenames):
        if catnames is not None and len(catnames) > 0:
            catdict[f] = catnames[indx]
        else:
            catdict[f] = None

    if not filenames:
        print('No filenames matching input %r were found.' % input_files)
        raise IOError

    # Verify that files are writable (based on file permissions) so that
    #    they can be updated if either 'updatewcs' or 'updatehdr' have
    #    been turned on (2 cases which require updating the input files)
    if configobj['updatewcs'] or configobj['UPDATE HEADER']['updatehdr']:
        filenames = util.verifyFilePermissions(filenames)
        if filenames is None or len(filenames) == 0:
            raise IOError

    if configobj['UPDATE HEADER']['updatehdr']:
        wname = configobj['UPDATE HEADER']['wcsname']
        # verify that a unique WCSNAME has been specified by the user
        if not configobj['UPDATE HEADER']['reusename']:
            for fname in filenames:
                uniq = util.verifyUniqueWcsname(fname,wname)
                if not uniq:
                    errstr = 'WCSNAME "%s" already present in "%s".  '%(wname,fname)+\
                    'A unique value for the "wcsname" parameter needs to be ' + \
                    'specified. \n\nQuitting!'
                    print(textutil.textbox(errstr,width=60))
                    raise IOError

    if configobj['updatewcs']:
        print('\nRestoring WCS solutions to original state using updatewcs...\n')
        updatewcs.updatewcs(filenames)

    if catnames in [None,'',' ','INDEF'] or len(catnames) == 0:
        catfile_par = configobj['COORDINATE FILE DESCRIPTION']['catfile']
        # check to see whether the user specified input catalogs through other parameters
        if catfile_par not in [None,'',' ','INDEF']:
            # read in catalog file list provided by user
            catnames,catdict = tweakutils.parse_atfile_cat('@'+catfile_par)
        else:
            use_catfile = False

        if 'exclusions' in configobj and \
            configobj['exclusions'] not in [None,'',' ','INDEF']:
            if os.path.exists(configobj['exclusions']):
                excl_files, excl_dict = tweakutils.parse_atfile_cat(
                    '@'+configobj['exclusions'])

                # make sure the dictionary is well formed and that keys are base
                # file names and that exclusion files have been expanded:
                exclusion_files = []
                exclusion_dict = {}
                rootpath = os.path.abspath(
                    os.path.split(configobj['exclusions'])[0]
                )

                for f in excl_dict.keys():
                    print(f)
                    bf = os.path.basename(f)
                    exclusion_files.append(bf)
                    reglist = excl_dict[f]

                    if reglist is None:
                        exclusion_dict[bf] = None
                        continue

                    new_reglist = []
                    for regfile in reglist:
                        if regfile in [ None, 'None', '', ' ', 'INDEF' ]:
                            new_reglist.append(None)
                        else:
                            abs_regfile = os.path.normpath(
                                os.path.join(rootpath, regfile)
                            )
                            new_reglist.append(abs_regfile)

                    exclusion_dict[bf] = new_reglist

            else:
                raise IOError('Could not find specified exclusions file "{:s}"'
                      .format(configobj['exclusions']))

        else:
            exclusion_files = [None]*len(filenames)
            exclusion_dict = {}

            for f in filenames:
                exclusion_dict[os.path.basename(f)] = None

    # Verify that we have the same number of catalog files as input images
    if catnames is not None and (len(catnames) > 0):
        missed_files = []

        for f in filenames:
            if f not in catdict:
                missed_files.append(f)
            if len(missed_files) > 0:
                print('The input catalogs does not contain entries for the following images:')
                print(missed_files)
                raise IOError
    else:
        # setup array of None values as input to catalog parameter for Image class
        catnames = [None]*len(filenames)
        use_catfile = False

    # convert input images and any provided catalog file names into Image objects
    input_images = []
    # copy out only those parameters needed for Image class
    catfile_kwargs = tweakutils.get_configobj_root(configobj)
    # define default value for 'xyunits' assuming sources to be derived from image directly
    catfile_kwargs['xyunits'] = 'pixels' # initialized here, required by Image class
    del catfile_kwargs['exclusions']

    if use_catfile:
        # reset parameters based on parameter settings in this section
        catfile_kwargs.update(configobj['COORDINATE FILE DESCRIPTION'])
        for sort_par in imgclasses.sortKeys:
            catfile_kwargs['sort_'+sort_par] = catfile_kwargs[sort_par]
    # Update parameter set with 'SOURCE FINDING PARS' now
    catfile_kwargs.update(configobj[PSET_SECTION])
    uphdr_par = configobj['UPDATE HEADER']
    hdrlet_par = configobj['HEADERLET CREATION']
    objmatch_par = configobj['OBJECT MATCHING PARAMETERS']
    catfit_pars = configobj['CATALOG FITTING PARAMETERS']

    catfit_pars['minobj'] = objmatch_par['minobj']
    objmatch_par['residplot'] = catfit_pars['residplot']

    hdrlet_par.update(uphdr_par) # default hdrlet name
    catfile_kwargs['updatehdr'] = uphdr_par['updatehdr']

    shiftpars = configobj['OPTIONAL SHIFTFILE OUTPUT']

    # verify a valid hdrname was provided, if headerlet was set to True
    imgclasses.verify_hdrname(**hdrlet_par)

    print('')
    print('Finding shifts for: ')
    for f in filenames:
        print('    {}'.format(f))
    print('')

    log.info("USER INPUT PARAMETERS for finding sources for each input image:")
    util.printParams(catfile_kwargs, log=log)
    log.info('')

    try:
        minsources = max(1, catfit_pars['minobj'])
        omitted_images = []
        all_input_images = []
        for imgnum in range(len(filenames)):
            # Create Image instances for all input images
            try:
                regexcl = exclusion_dict[os.path.basename(filenames[imgnum])]
            except KeyError:
                regexcl = None
                pass

            img = imgclasses.Image(filenames[imgnum],
                                   input_catalogs=catdict[filenames[imgnum]],
                                   exclusions=regexcl,
                                   **catfile_kwargs)

            all_input_images.append(img)
            if img.num_sources < minsources:
                warn_str = "Image '{}' will not be aligned " \
                           "since it contains fewer than {} sources." \
                           .format(img.name, minsources)
                print('\nWARNING: {}\n'.format(warn_str))
                log.warning(warn_str)
                omitted_images.append(img)
                continue
            input_images.append(img)

    except KeyboardInterrupt:
        for img in input_images:
            img.close()
        print('Quitting as a result of user request (Ctrl-C)...')
        return
    # create set of parameters to pass to RefImage class
    kwargs = tweakutils.get_configobj_root(configobj)
    # Determine a reference image or catalog and
    #    return the full list of RA/Dec positions
    # Determine what WCS needs to be used for reference tangent plane
    refcat_par = configobj['REFERENCE CATALOG DESCRIPTION']
    if refcat_par['refcat'] not in [None,'',' ','INDEF']: # User specified a catalog to use
        # Update kwargs with reference catalog parameters
        kwargs.update(refcat_par)

    # input_images list can be modified below.
    # So, make a copy of the original:
    input_images_orig_copy = copy(input_images)
    do_match_refimg = False

    # otherwise, extract the catalog from the first input image source list
    if configobj['refimage'] not in [None, '',' ','INDEF']: # User specified an image to use
        # A hack to allow different source finding parameters for
        # the reference image:
        ref_sourcefind_pars = \
            tweakutils.get_configobj_root(configobj[PSET_SECTION_REFIMG])
        ref_catfile_kwargs = catfile_kwargs.copy()
        ref_catfile_kwargs.update(ref_sourcefind_pars)
        ref_catfile_kwargs['updatehdr'] = False

        log.info('')
        log.info("USER INPUT PARAMETERS for finding sources for "
                 "the reference image:")
        util.printParams(ref_catfile_kwargs, log=log)

        #refimg = imgclasses.Image(configobj['refimage'],**catfile_kwargs)
        # Check to see whether the user specified a separate catalog
        #    of reference source positions and replace default source list with it
        if refcat_par['refcat'] not in [None,'',' ','INDEF']: # User specified a catalog to use
            ref_source = refcat_par['refcat']
            cat_src = ref_source
            xycat = None
            cat_src_type = 'catalog'
        else:
            try:
                regexcl = exclusion_dict[configobj['refimage']]
            except KeyError:
                regexcl = None
                pass

            refimg = imgclasses.Image(configobj['refimage'],
                                      exclusions=regexcl,
                                      **ref_catfile_kwargs)
            ref_source = refimg.all_radec
            cat_src = None
            xycat = refimg.xy_catalog
            cat_src_type = 'image'

        try:
            if 'use_sharp_round' in ref_catfile_kwargs:
                kwargs['use_sharp_round'] = ref_catfile_kwargs['use_sharp_round']
            refimage = imgclasses.RefImage(configobj['refimage'],
                            ref_source, xycatalog=xycat,
                            cat_origin=cat_src, **kwargs)
            refwcs_fname = refimage.wcs.filename
            if cat_src is not None:
                refimage.name = cat_src

        except KeyboardInterrupt:
            refimage.close()
            for img in input_images:
                img.close()
            print('Quitting as a result of user request (Ctrl-C)...')
            return

        if len(input_images) < 1:
            warn_str = "Fewer than two images are available for alignment. " \
                       "Quitting..."
            print('\nWARNING: {}\n'.format(warn_str))
            log.warning(warn_str)
            for img in input_images:
                img.close()
            return

        image = _max_overlap_image(refimage, input_images, expand_refcat,
                                   enforce_user_order)

    elif refcat_par['refcat'] not in [None,'',' ','INDEF']:
        # a reference catalog is provided but not the reference image/wcs
        if len(input_images) < 1:
            warn_str = "No images available for alignment. Quitting..."
            print('\nWARNING: {}\n'.format(warn_str))
            log.warning(warn_str)
            for img in input_images:
                img.close()
            return

        if len(input_images) == 1:
            image = input_images.pop(0)
        else:
            image, image2 = _max_overlap_pair(input_images, expand_refcat,
                                              enforce_user_order)
            input_images.insert(0, image2)

        # Workaround the defect described in ticket:
        # http://redink.stsci.edu/trac/ssb/stsci_python/ticket/1151
        refwcs = []
        for i in all_input_images:
            refwcs.extend(i.get_wcs())
        kwargs['ref_wcs_name'] = image.get_wcs()[0].filename

        # A hack to allow different source finding parameters for
        # the reference image:
        ref_sourcefind_pars = \
            tweakutils.get_configobj_root(configobj[PSET_SECTION_REFIMG])
        ref_catfile_kwargs = catfile_kwargs.copy()
        ref_catfile_kwargs.update(ref_sourcefind_pars)
        ref_catfile_kwargs['updatehdr'] = False

        log.info('')
        log.info("USER INPUT PARAMETERS for finding sources for "
                 "the reference image (not used):")
        util.printParams(ref_catfile_kwargs, log=log)

        ref_source = refcat_par['refcat']
        cat_src = ref_source
        xycat = None

        try:
            if 'use_sharp_round' in ref_catfile_kwargs:
                kwargs['use_sharp_round'] = ref_catfile_kwargs['use_sharp_round']
            kwargs['find_bounding_polygon'] = True
            refimage = imgclasses.RefImage(refwcs,
                                           ref_source, xycatalog=xycat,
                                           cat_origin=cat_src, **kwargs)
            refwcs_fname = refimage.wcs.filename
            refimage.name = cat_src
            cat_src_type = 'catalog'
        except KeyboardInterrupt:
            refimage.close()
            for img in input_images:
                img.close()
            print('Quitting as a result of user request (Ctrl-C)...')
            return

    else:
        if len(input_images) < 2:
            warn_str = "Fewer than two images available for alignment. " \
                "Quitting..."
            print('\nWARNING: {}\n'.format(warn_str))
            log.warning(warn_str)
            for img in input_images:
                img.close()
            return

        kwargs['use_sharp_round'] = catfile_kwargs['use_sharp_round']

        cat_src = None

        refimg, image = _max_overlap_pair(input_images, expand_refcat,
                                          enforce_user_order)

        refwcs = []
        #refwcs.extend(refimg.get_wcs())
        #refwcs.extend(image.get_wcs())
        #for i in input_images:
            #refwcs.extend(i.get_wcs())
        # Workaround the defect described in ticket:
        # http://redink.stsci.edu/trac/ssb/stsci_python/ticket/1151
        for i in all_input_images:
            refwcs.extend(i.get_wcs())
        kwargs['ref_wcs_name'] = refimg.get_wcs()[0].filename

        try:
            ref_source = refimg.all_radec
            refimage = imgclasses.RefImage(refwcs, ref_source,
                                        xycatalog=refimg.xy_catalog, **kwargs)
            refwcs_fname = refimg.name
            cat_src_type = 'image'
        except KeyboardInterrupt:
            refimage.close()
            for img in input_images:
                img.close()
            print('Quitting as a result of user request (Ctrl-C)...')
            return

        omitted_images.insert(0, refimg) # refimage *must* be first
        do_match_refimg = True

    print("\n{0}\nPerforming alignment in the projection plane defined by the "
          "WCS\nderived from '{1}'\n{0}\n".format('='*63, refwcs_fname))

    if refimage.outxy is not None:
        if cat_src is None:
            cat_src = refimage.name

        try:
            log.info("USER INPUT PARAMETERS for matching sources:")
            util.printParams(objmatch_par, log=log)

            log.info('')
            log.info("USER INPUT PARAMETERS for fitting source lists:")
            util.printParams(configobj['CATALOG FITTING PARAMETERS'], log=log)

            if hdrlet_par['headerlet']:
                log.info('')
                log.info("USER INPUT PARAMETERS for creating headerlets:")
                util.printParams(hdrlet_par, log=log)

            if shiftpars['shiftfile']:
                log.info('')
                log.info("USER INPUT PARAMETERS for creating a shiftfile:")
                util.printParams(shiftpars, log=log)

            # Now, apply reference WCS to each image's sky positions as well as the
            # reference catalog sky positions,
            # then perform the fit between the reference catalog positions and
            #    each image's positions
            quit_immediately = False
            xycat_lines = ''
            xycat_filename = None

            for img in input_images_orig_copy:
                if xycat_filename is None:
                    xycat_filename = img.rootname+'_xy_catfile.list'
                # Keep a record of all the generated input_xy catalogs
                xycat_lines += img.get_xy_catnames()

            retry_flags = len(input_images)*[0]
            objmatch_par['cat_src_type'] = cat_src_type
            while image is not None:
                print ('\n'+'='*20)
                print ('Performing fit for: {}\n'.format(image.name))
                image.match(refimage, quiet_identity=False, **objmatch_par)
                assert(len(retry_flags) == len(input_images))

                if not image.goodmatch:
                    # we will try to match it again once reference catalog
                    # has expanded with new sources:
                    #if expand_refcat:
                    input_images.append(image)
                    retry_flags.append(1)
                    if len(retry_flags) > 0 and retry_flags[0] == 0:
                        retry_flags.pop(0)
                        image = input_images.pop(0)
                        # try to match next image in the list
                        continue
                    else:
                        # no new sources have been added to the reference
                        # catalog and we have already tried to match
                        # images to the existing reference catalog

                        #input_images.append(image) # <- add it back for later reporting
                        #retry_flags.append(1)
                        break

                image.performFit(**catfit_pars)
                if image.quit_immediately:
                    quit_immediately = True
                    image.close()
                    break

                # add unmatched sources to the reference catalog
                # (to expand it):
                if expand_refcat:
                    refimage.append_not_matched_sources(image)

                image.updateHeader(wcsname=uphdr_par['wcsname'],
                                    reusename=uphdr_par['reusename'])
                if hdrlet_par['headerlet']:
                    image.writeHeaderlet(**hdrlet_par)
                if configobj['clean']:
                    image.clean()
                image.close()

                if refimage.dirty and len(input_images) > 0:
                    # The reference catalog has been updated with new sources.
                    # Clear retry flags and get next image:
                    image = _max_overlap_image(
                        refimage, input_images, expand_refcat,
                        enforce_user_order
                    )
                    retry_flags = len(input_images)*[0]
                    refimage.clear_dirty_flag()
                elif len(input_images) > 0 and retry_flags[0] == 0:
                    retry_flags.pop(0)
                    image = input_images.pop(0)
                else:
                    break

            assert(len(retry_flags) == len(input_images))

            if not quit_immediately:
                # process images that have not been matched in order to
                # update their headers:
                si = 0
                if do_match_refimg:
                    image = omitted_images[0]
                    image.match(refimage, quiet_identity=True, **objmatch_par)
                    si = 1

                # process omitted (from start) images separately:
                for image in omitted_images[si:]:
                    image.match(refimage, quiet_identity=False, **objmatch_par)

                # add to the list of omitted images, images that could not
                # be matched:
                omitted_images.extend(input_images)

                if len(input_images) > 0:
                    print("\nUnable to match the following images:")
                    print("-------------------------------------")
                    for image in input_images:
                        print(image.name)
                    print("")

                # update headers:
                for image in omitted_images:
                    image.performFit(**catfit_pars)
                    if image.quit_immediately:
                        quit_immediately = True
                        image.close()
                        break
                    image.updateHeader(wcsname=uphdr_par['wcsname'],
                                    reusename=uphdr_par['reusename'])
                    if hdrlet_par['headerlet']:
                        image.writeHeaderlet(**hdrlet_par)
                    if configobj['clean']:
                        image.clean()
                    image.close()

                if configobj['writecat'] and not configobj['clean']:
                    # Write out catalog file recording input XY catalogs used
                    # This file will be suitable for use as input to 'tweakreg'
                    # as the 'catfile' parameter
                    if os.path.exists(xycat_filename):
                        os.remove(xycat_filename)
                    f = open(xycat_filename, mode='w')
                    f.writelines(xycat_lines)
                    f.close()

                    if expand_refcat:
                        base_reg_name = os.path.splitext(
                            os.path.basename(cat_src))[0]
                        refimage.write_skycatalog(
                            'cumulative_sky_refcat_{:s}.coo' \
                            .format(base_reg_name),
                            show_flux=True, show_id=True
                        )

                # write out shiftfile (if specified)
                if shiftpars['shiftfile']:
                    tweakutils.write_shiftfile(input_images_orig_copy,
                                               shiftpars['outshifts'],
                                               outwcs=shiftpars['outwcs'])

        except KeyboardInterrupt:
            refimage.close()
            for img in input_images_orig_copy:
                img.close()
                del img
            print ('Quitting as a result of user request (Ctrl-C)...')
            return
    else:
        print ('No valid sources in reference frame. Quitting...')
        return
Exemplo n.º 12
0
def run(configobj, wcsmap=None):
    """
    Initial example by Nadia ran MD with configobj EPAR using:
    It can be run in one of two ways:

        from stsci.tools import teal

        1. Passing a config object to teal

        teal.teal('drizzlepac/pars/astrodrizzle.cfg')


        2. Passing a task  name:

        teal.teal('astrodrizzle')

        The example config files are in drizzlepac/pars

    """
    raise_status = RAISE
    #
    # turn on logging, redirecting stdout/stderr messages to a log file
    # while also printing them out to stdout as well
    # also, initialize timing of processing steps
    #
    # We need to define a default logfile name from the user's parameters
    input_list, output, ivmlist, odict = \
            processInput.processFilenames(configobj['input'])

    if output is not None:
        def_logname = output
    elif len(input_list) > 0:
        def_logname = input_list[0]
    else:
        print(textutil.textbox(
            'ERROR:\nNo valid input files found!   Please restart the task '
            'and check the value for the "input" parameter.'), file=sys.stderr)
        def_logname = None
        return

    stateObj = configobj['STATE OF INPUT FILES']
    procSteps = util.ProcSteps()

    print('AstroDrizzle Version %s(%s) started at: %s\n' %
           (__version__, __vdate__, util._ptime()[0]))
    util.print_pkg_versions(log=log)

    #try:
    try:
        # Define list of imageObject instances and output WCSObject instance
        # based on input paramters
        procSteps.addStep('Initialization')
        imgObjList = None
        imgObjList, outwcs = processInput.setCommonInput(configobj)
        procSteps.endStep('Initialization')

        if not imgObjList:
            errmsg = "No valid images found for processing!\n"
            errmsg += "Check log file for full details.\n"
            errmsg += "Exiting AstroDrizzle now..."
            print(textutil.textbox(errmsg,width=65))
            raise_status = DO_NOT_RAISE
            raise ValueError

        log.info("USER INPUT PARAMETERS common to all Processing Steps:")
        util.printParams(configobj, log=log)

        # Call rest of MD steps...
        #create static masks for each image
        staticMask.createStaticMask(imgObjList, configobj,
                                    procSteps=procSteps)

        #subtract the sky
        sky.subtractSky(imgObjList, configobj, procSteps=procSteps)

#       _dbg_dump_virtual_outputs(imgObjList)

        #drizzle to separate images
        adrizzle.drizSeparate(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                              procSteps=procSteps)

#       _dbg_dump_virtual_outputs(imgObjList)

        #create the median images from the driz sep images
        createMedian.createMedian(imgObjList, configobj,
                                  procSteps=procSteps)

        #blot the images back to the original reference frame
        ablot.runBlot(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                      procSteps=procSteps)

        #look for cosmic rays
        drizCR.rundrizCR(imgObjList, configobj,
                         procSteps=procSteps)

        #Make your final drizzled image
        adrizzle.drizFinal(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                           procSteps=procSteps)

        print()
        print(' '.join(['AstroDrizzle Version', __version__,
                        'is finished processing at ',
                        util._ptime()[0]]) + '!\n')
    except:
        print(textutil.textbox(
            'ERROR:\nAstroDrizzle Version %s encountered a problem!  '
            'Processing terminated at %s.' %
            (__version__, util._ptime()[0])), file=sys.stderr)
        procSteps.reportTimes()
        if imgObjList:
            for image in imgObjList:
                image.close()
            del imgObjList
            del outwcs

        # Raise an exception ONLY if requested...
        if raise_status == RAISE:
            raise
        else:
            return

    procSteps.reportTimes()

    if imgObjList:
        for image in imgObjList:
            if stateObj['clean']:
                image.clean()
            image.close()

        del imgObjList
        del outwcs
Exemplo n.º 13
0
    def generateXY(self, **kwargs):
        """ Generate source catalog from input image using DAOFIND-style algorithm
        """
        #x,y,flux,sharp,round = idlphot.find(array,self.pars['hmin'],self.pars['fwhm'],
        #                    roundlim=self.pars['roundlim'], sharplim=self.pars['sharplim'])
        print("  #  Source finding for '{}', EXT={} started at: {}"
              .format(self.fnamenoext, self.wcs.extname, util._ptime()[0]))
        if self.pars['computesig']:
            # compute sigma for this image
            sigma = self._compute_sigma()
        else:
            sigma = self.pars['skysigma']
        skymode = sigma**2
        log.info('   Finding sources using sky sigma = %f'%sigma)
        if self.pars['threshold'] in [None,"INDEF",""," "]:
            hmin = skymode
        else:
            hmin = sigma*self.pars['threshold']

        if 'mask' in kwargs and kwargs['mask'] is not None:
            dqmask = np.asarray(kwargs['mask'], dtype=bool)
        else:
            dqmask = None

        # get the mask for source finding:
        mask = self._combine_exclude_mask(dqmask)

        x, y, flux, src_id, sharp, round1, round2 = tweakutils.ndfind(
            self.source,
            hmin,
            self.pars['conv_width'],
            skymode,
            sharplim=[self.pars['sharplo'],self.pars['sharphi']],
            roundlim=[self.pars['roundlo'],self.pars['roundhi']],
            peakmin=self.pars['peakmin'],
            peakmax=self.pars['peakmax'],
            fluxmin=self.pars['fluxmin'],
            fluxmax=self.pars['fluxmax'],
            nsigma=self.pars['nsigma'],
            ratio=self.pars['ratio'],
            theta=self.pars['theta'],
            mask=mask,
            use_sharp_round=self.use_sharp_round,
            nbright=self.nbright
        )

        if len(x) == 0:
            if  not self.pars['computesig']:
                sigma = self._compute_sigma()
                hmin = sigma * self.pars['threshold']
                log.info('No sources found with original thresholds. Trying automatic settings.')
                x, y, flux, src_id, sharp, round1, round2 = tweakutils.ndfind(
                    self.source,
                    hmin,
                    self.pars['conv_width'],
                    skymode,
                    sharplim=[self.pars['sharplo'],self.pars['sharphi']],
                    roundlim=[self.pars['roundlo'],self.pars['roundhi']],
                    peakmin=self.pars['peakmin'],
                    peakmax=self.pars['peakmax'],
                    fluxmin=self.pars['fluxmin'],
                    fluxmax=self.pars['fluxmax'],
                    nsigma=self.pars['nsigma'],
                    ratio=self.pars['ratio'],
                    theta=self.pars['theta'],
                    mask = mask,
                    use_sharp_round = self.use_sharp_round,
                    nbright=self.nbright
                )
        if len(x) == 0:
            xypostypes = 3*[float]+[int]+(3 if self.use_sharp_round else 0)*[float]
            self.xypos = [np.empty(0, dtype=i) for i in xypostypes]
            warnstr = textutil.textbox('WARNING: \n'+
                'No valid sources found with the current parameter values!')
            for line in warnstr.split('\n'):
                log.warning(line)
            print(warnstr)
        else:
            # convert the positions from numpy 0-based to FITS 1-based
            if self.use_sharp_round:
                self.xypos = [x+1, y+1, flux, src_id+self.start_id, sharp, round1, round2]
            else:
                self.xypos = [x+1, y+1, flux, src_id+self.start_id]

        log.info('###Source finding finished at: %s'%(util._ptime()[0]))

        self.in_units = 'pixels' # Not strictly necessary, but documents units when determined
        self.sharp = sharp
        self.round1 = round1
        self.round2 = round2
        self.numcols = 7 if self.use_sharp_round else 4
        self.num_objects = len(x)
        self._apply_flux_limits = False # limits already applied by 'ndfind'
Exemplo n.º 14
0
def run(configobj, wcsmap=None):
    """
    Initial example by Nadia ran MD with configobj EPAR using:
    It can be run in one of two ways:

        from stsci.tools import teal

        1. Passing a config object to teal

        teal.teal('drizzlepac/pars/astrodrizzle.cfg')


        2. Passing a task  name:

        teal.teal('astrodrizzle')

        The example config files are in drizzlepac/pars

    """
    # turn on logging, redirecting stdout/stderr messages to a log file
    # while also printing them out to stdout as well
    # also, initialize timing of processing steps
    #
    # We need to define a default logfile name from the user's parameters
    input_list, output, ivmlist, odict = \
            processInput.processFilenames(configobj['input'])

    if output is not None:
        def_logname = output
    elif len(input_list) > 0:
        def_logname = input_list[0]
    else:
        print(textutil.textbox(
            "ERROR:\nNo valid input files found!   Please restart the task "
            "and check the value for the 'input' parameter."),
              file=sys.stderr)
        def_logname = None
        return

    # Build name of output trailer file
    logging_handlers = logging.getLogger().handlers
    log_name = [lh.name for lh in logging_handlers if lh.level > 0]
    logfile = log_name[0] if log_name else "{}.tra".format(def_logname)
    print("AstroDrizzle log file: {}".format(logfile))

    clean = configobj['STATE OF INPUT FILES']['clean']
    procSteps = util.ProcSteps()

    print("AstroDrizzle Version {:s} started at: {:s}\n".format(
        __version__,
        util._ptime()[0]))
    util.print_pkg_versions(log=log)

    log.debug('')
    log.debug(
        "==== AstroDrizzle was invoked with the following parameters: ====")
    log.debug('')
    util.print_cfg(configobj, log.debug)

    try:
        # Define list of imageObject instances and output WCSObject instance
        # based on input paramters
        imgObjList = None
        procSteps.addStep('Initialization')
        imgObjList, outwcs = processInput.setCommonInput(configobj)
        procSteps.endStep('Initialization')

        if imgObjList is None or not imgObjList:
            errmsg = "No valid images found for processing!\n"
            errmsg += "Check log file for full details.\n"
            errmsg += "Exiting AstroDrizzle now..."
            print(textutil.textbox(errmsg, width=65))
            print(textutil.textbox(
                'ERROR:\nAstroDrizzle Version {:s} encountered a problem!  '
                'Processing terminated at {:s}.'.format(
                    __version__,
                    util._ptime()[0])),
                  file=sys.stderr)
            return

        log.info("USER INPUT PARAMETERS common to all Processing Steps:")
        util.printParams(configobj, log=log)

        # Call rest of MD steps...
        # create static masks for each image
        staticMask.createStaticMask(imgObjList, configobj, procSteps=procSteps)

        # subtract the sky
        sky.subtractSky(imgObjList, configobj, procSteps=procSteps)

        #       _dbg_dump_virtual_outputs(imgObjList)

        # drizzle to separate images
        adrizzle.drizSeparate(imgObjList,
                              outwcs,
                              configobj,
                              wcsmap=wcsmap,
                              logfile=logfile,
                              procSteps=procSteps)

        #       _dbg_dump_virtual_outputs(imgObjList)

        # create the median images from the driz sep images
        createMedian.createMedian(imgObjList, configobj, procSteps=procSteps)

        # blot the images back to the original reference frame
        ablot.runBlot(imgObjList,
                      outwcs,
                      configobj,
                      wcsmap=wcsmap,
                      procSteps=procSteps)

        # look for cosmic rays
        drizCR.rundrizCR(imgObjList, configobj, procSteps=procSteps)

        # Make your final drizzled image
        adrizzle.drizFinal(imgObjList,
                           outwcs,
                           configobj,
                           wcsmap=wcsmap,
                           logfile=logfile,
                           procSteps=procSteps)

        print()
        print("AstroDrizzle Version {:s} is finished processing at {:s}.\n".
              format(__version__,
                     util._ptime()[0]))
        print("", flush=True)

    except Exception:
        clean = False
        print(textutil.textbox(
            "ERROR:\nAstroDrizzle Version {:s} encountered a problem!  "
            "Processing terminated at {:s}.".format(__version__,
                                                    util._ptime()[0])),
              file=sys.stderr)
        raise

    finally:
        procSteps.reportTimes()
        if imgObjList:
            for image in imgObjList:
                if clean:
                    image.clean()
                image.close()
            del imgObjList
            del outwcs
Exemplo n.º 15
0
def buildEmptyDRZ(input, output):
    """
    Create an empty DRZ file.

    This module creates an empty DRZ file in a valid FITS format so that the HST
    pipeline can handle the Multidrizzle zero expossure time exception
    where all data has been excluded from processing.

    Parameters
    ----------
    input : str
        filename of the initial input to process_input
    output : str
        filename of the default empty _drz.fits file to be generated

    """

    # Identify the first input image
    inputfile = parseinput.parseinput(input)[0]
    if not inputfile:
        print('\n******* ERROR *******', file=sys.stderr)
        print(
            'No input file found!  Check specification of parameter '
            '"input". ',
            file=sys.stderr)
        print('Quitting...', file=sys.stderr)
        print('******* ***** *******\n', file=sys.stderr)
        return  # raise IOError, "No input file found!"

    # Set up output file here...
    if output is None:
        if len(input) == 1:
            oname = fileutil.buildNewRootname(input[0])
        else:
            oname = 'final'
        output = fileutil.buildNewRootname(oname, extn='_drz.fits')
    else:
        if '_drz' not in output:
            output = fileutil.buildNewRootname(output, extn='_drz.fits')

    print('Building emtpy DRZ file with output name: %s' % output)

    # Open the first image (of the excludedFileList?) to use as a template to build
    # the DRZ file.
    try:
        log.info('Building empty DRZ file from %s' % inputfile[0])
        img = fits.open(inputfile[0], memmap=False)
    except:
        raise IOError('Unable to open file %s \n' % inputfile)

    # Create the fitsobject
    fitsobj = fits.HDUList()
    # Copy the primary header
    hdu = img[0].copy()
    fitsobj.append(hdu)

    # Modify the 'NEXTEND' keyword of the primary header to 3 for the
    #'sci, wht, and ctx' extensions of the newly created file.
    fitsobj[0].header['NEXTEND'] = 3

    # Create the 'SCI' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'SCI'
    fitsobj.append(hdu)

    # Create the 'WHT' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'WHT'
    fitsobj.append(hdu)

    # Create the 'CTX' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'CTX'
    fitsobj.append(hdu)

    # Add HISTORY comments explaining the creation of this file.
    fitsobj[0].header.add_history("** AstroDrizzle has created this empty "
                                  "DRZ product because**")
    fitsobj[0].header.add_history("** all input images were excluded from "
                                  "processing.**")

    # Change the filename in the primary header to reflect the name of the output
    # filename.
    fitsobj[0].header['FILENAME'] = str(output)  # +"_drz.fits"

    # Change the ROOTNAME keyword to the ROOTNAME of the output PRODUCT
    fitsobj[0].header['ROOTNAME'] = str(output.split('_drz.fits')[0])
    # Modify the ASN_MTYP keyword to contain "PROD-DTH" so it can be properly
    # ingested into the archive catalog.

    # stis has this keyword in the [1] header, so I am directing the code
    #t o first look in the primary, then the 1
    try:
        fitsobj[0].header['ASN_MTYP'] = 'PROD-DTH'
    except:
        fitsobj[1].header['ASN_MTYP'] = 'PROD-DTH'

    # If the file is already on disk delete it and replace it with the
    # new file
    dirfiles = os.listdir(os.curdir)
    if dirfiles.count(output) > 0:
        os.remove(output)
        log.info("       Replacing %s..." % output)

    # Write out the empty DRZ file
    fitsobj.writeto(output)

    print(textutil.textbox(
        'ERROR:\nAstroDrizzle has created an empty DRZ product because all '
        'input images were excluded from processing or a user requested the '
        'program to stop.') + '\n',
          file=sys.stderr)

    return
Exemplo n.º 16
0
def setCommonInput(configObj, createOutwcs=True):
    """
    The common interface interpreter for MultiDrizzle tasks which not only runs
    'process_input()' but 'createImageObject()' and 'defineOutput()' as well to
    fully setup all inputs for use with the rest of the MultiDrizzle steps either
    as stand-alone tasks or internally to MultiDrizzle itself.

    Parameters
    ----------
    configObj : object
        configObj instance or simple dictionary of input parameters
    imageObjectList : list of imageObject objects
        list of imageObject instances, 1 for each input exposure
    outwcs : object
        imageObject instance defining the final output frame

    Notes
    -----
    At a minimum, the configObj instance (dictionary) should contain:
        configObj = {'input':None,'output':None }

    If provided, the configObj should contain the values of all the multidrizzle parameters
    as set by the user with TEAL. If no configObj is given, it will retrieve
    the default values automatically.  In either case, the values from the input_dict
    will be merged in with the configObj before being used by the rest of the
    code.

    Examples
    --------
    You can set *createOutwcs=False* for the cases where you only want the
    images processed and no output wcs information in necessary; as in:

    >>> imageObjectList,outwcs = processInput.processCommonInput(configObj)


    """
    # make sure 'updatewcs' is set to False when running from GUI or if missing
    # from configObj:
    if 'updatewcs' not in configObj:
        configObj['updatewcs'] = False

    if not createOutwcs or not configObj['coeffs']:
        # we're probably just working on single images here
        configObj['updatewcs']=False

    # maybe we can chunk this part up some more so that we can call just the
    # parts we want

    # Interpret input, read and convert and update input files, then return
    # list of input filenames and derived output filename
    asndict, ivmlist, output = process_input(
            configObj['input'], configObj['output'],
            updatewcs=configObj['updatewcs'], wcskey=configObj['wcskey'],
            **configObj['STATE OF INPUT FILES'])

    if not asndict:
        return None, None
    # convert the filenames from asndict into a list of full filenames
    files = [fileutil.buildRootname(f) for f in asndict['order']]
    original_files = asndict['original_file_names']

    # interpret MDRIZTAB, if specified, and update configObj accordingly
    # This can be done here because MDRIZTAB does not include values for
    # input, output, or updatewcs.
    if 'mdriztab' in configObj and configObj['mdriztab']:
        print("Reading in MDRIZTAB parameters for {} files".format(len(files)))
        mdriztab_dict = mdzhandler.getMdriztabParameters(files)

        # Update configObj with values from mpars
        cfgpars.mergeConfigObj(configObj, mdriztab_dict)

    # Convert interpreted list of input files from process_input into a list
    # of imageObject instances for use by the MultiDrizzle tasks.
    instrpars = configObj['INSTRUMENT PARAMETERS']
    # pass in 'proc_unit' to initialize unit conversions as necessary
    instrpars['proc_unit'] = configObj['proc_unit']

    undistort = True
    if not configObj['coeffs']:
        undistort = False

    # determine whether parallel processing will be performed
    use_parallel = False
    if util.can_parallel:
        # look to see whether steps which can be run using multiprocessing
        # have been turned on
        for stepnum in parallel_steps:
            sname = util.getSectionName(configObj,stepnum[0])
            if configObj[sname][stepnum[1]]:
                use_parallel = True
                break

    # interpret all 'bits' related parameters and convert them to integers
    configObj['resetbits'] = interpret_bit_flags(configObj['resetbits'])
    step3name = util.getSectionName(configObj,3)
    configObj[step3name]['driz_sep_bits'] = interpret_bit_flags(
                                        configObj[step3name]['driz_sep_bits']
    )
    step7name = util.getSectionName(configObj,7)
    configObj[step7name]['final_bits'] = interpret_bit_flags(
                                        configObj[step7name]['final_bits']
    )

    # Verify any refimage parameters to be used
    step3aname = util.getSectionName(configObj,'3a')
    if not util.verifyRefimage(configObj[step3aname]['driz_sep_refimage']):
        msg = 'No refimage with WCS found!\n '+\
        ' This could be caused by one of 2 problems:\n'+\
        '   * filename does not specify an extension with a valid WCS.\n'+\
        '   * can not find the file.\n'+\
        'Please check the filename specified in the "refimage" parameter.'
        print(textutil.textbox(msg))
        return None,None
    step7aname = util.getSectionName(configObj,'7a')
    if not util.verifyRefimage(configObj[step7aname]['final_refimage']):
        msg = 'No refimage with WCS found!\n '+\
        ' This could be caused by one of 2 problems:\n'+\
        '   * filename does not specify an extension with a valid WCS.\n'+\
        '   * can not find the file.\n'+\
        'Please check the filename specified in the "refimage" parameter.'
        print(textutil.textbox(msg))
        return None,None


    # Build imageObject list for all the valid, shift-updated input files
    log.info('-Creating imageObject List as input for processing steps.')
    if 'in_memory' in configObj:
        virtual = configObj['in_memory']
    else:
        virtual = False

    imageObjectList = createImageObjectList(files, instrpars,
                                            group=configObj['group'],
                                            undistort=undistort,
                                            inmemory=virtual)

    # Add original file names as "hidden" attributes of imageObject
    assert(len(original_files) == len(imageObjectList)) #TODO: remove after extensive testing
    for i in range(len(imageObjectList)):
        imageObjectList[i]._original_file_name = original_files[i]

    # apply context parameter
    applyContextPar(imageObjectList, configObj['context'])

    # reset DQ bits if requested by user
    resetDQBits(imageObjectList, cr_bits_value=configObj['resetbits'])

    # Add info about input IVM files at this point to the imageObjectList
    addIVMInputs(imageObjectList, ivmlist)

    if createOutwcs:
        log.info('-Creating output WCS.')

        # Build output WCS and update imageObjectList with output WCS info
        outwcs = wcs_functions.make_outputwcs(imageObjectList, output,
                                              configObj=configObj, perfect=True)
        outwcs.final_wcs.printwcs()
    else:
        outwcs = None

    try:
        # Provide user with some information on resource usage for this run
        # raises ValueError Exception in interactive mode and user quits
        num_cores = configObj.get('num_cores') if use_parallel else 1

        reportResourceUsage(imageObjectList, outwcs, num_cores)
    except ValueError:
        imageObjectList = None

    return imageObjectList, outwcs
Exemplo n.º 17
0
def setCommonInput(configObj, createOutwcs=True):
    """
    The common interface interpreter for MultiDrizzle tasks which not only runs
    'process_input()' but 'createImageObject()' and 'defineOutput()' as well to
    fully setup all inputs for use with the rest of the MultiDrizzle steps either
    as stand-alone tasks or internally to MultiDrizzle itself.

    Parameters
    ----------
    configObj : object
        configObj instance or simple dictionary of input parameters
    imageObjectList : list of imageObject objects
        list of imageObject instances, 1 for each input exposure
    outwcs : object
        imageObject instance defining the final output frame

    Notes
    -----
    At a minimum, the configObj instance (dictionary) should contain:
        configObj = {'input':None,'output':None }

    If provided, the configObj should contain the values of all the multidrizzle parameters
    as set by the user with TEAL. If no configObj is given, it will retrieve
    the default values automatically.  In either case, the values from the input_dict
    will be merged in with the configObj before being used by the rest of the
    code.

    Examples
    --------
    You can set *createOutwcs=False* for the cases where you only want the
    images processed and no output wcs information in necessary; as in:

    >>> imageObjectList,outwcs = processInput.processCommonInput(configObj)


    """
    # make sure 'updatewcs' is set to False when running from GUI or if missing
    # from configObj:
    if 'updatewcs' not in configObj:
        configObj['updatewcs'] = False

    if not createOutwcs or not configObj['coeffs']:
        # we're probably just working on single images here
        configObj['updatewcs'] = False

    # maybe we can chunk this part up some more so that we can call just the
    # parts we want

    # Interpret input, read and convert and update input files, then return
    # list of input filenames and derived output filename
    asndict, ivmlist, output = process_input(
        configObj['input'],
        configObj['output'],
        updatewcs=configObj['updatewcs'],
        wcskey=configObj['wcskey'],
        **configObj['STATE OF INPUT FILES'])

    if not asndict:
        return None, None
    # convert the filenames from asndict into a list of full filenames
    files = [fileutil.buildRootname(f) for f in asndict['order']]
    original_files = asndict['original_file_names']

    # interpret MDRIZTAB, if specified, and update configObj accordingly
    # This can be done here because MDRIZTAB does not include values for
    # input, output, or updatewcs.
    if 'mdriztab' in configObj and configObj['mdriztab']:
        print("Reading in MDRIZTAB parameters for {} files".format(len(files)))
        mdriztab_dict = mdzhandler.getMdriztabParameters(files)

        # Update configObj with values from mpars
        cfgpars.mergeConfigObj(configObj, mdriztab_dict)

    # Convert interpreted list of input files from process_input into a list
    # of imageObject instances for use by the MultiDrizzle tasks.
    instrpars = configObj['INSTRUMENT PARAMETERS']
    # pass in 'proc_unit' to initialize unit conversions as necessary
    instrpars['proc_unit'] = configObj['proc_unit']

    undistort = True
    if not configObj['coeffs']:
        undistort = False

    # determine whether parallel processing will be performed
    use_parallel = False
    if util.can_parallel:
        # look to see whether steps which can be run using multiprocessing
        # have been turned on
        for stepnum in parallel_steps:
            sname = util.getSectionName(configObj, stepnum[0])
            if configObj[sname][stepnum[1]]:
                use_parallel = True
                break

    # interpret all 'bits' related parameters and convert them to integers
    configObj['resetbits'] = interpret_bit_flags(configObj['resetbits'])
    step3name = util.getSectionName(configObj, 3)
    configObj[step3name]['driz_sep_bits'] = interpret_bit_flags(
        configObj[step3name]['driz_sep_bits'])
    step4name = util.getSectionName(configObj, 4)
    if len(files) > 5 and 'minmed' in configObj[step4name]['combine_type']:
        msg = '“minmed” is highly recommended for three images, \n'+\
        ' and is good for four to six images, \n'+\
        ' but should be avoided for ten or more images.\n'
        print(textutil.textbox(msg))

    step7name = util.getSectionName(configObj, 7)
    configObj[step7name]['final_bits'] = interpret_bit_flags(
        configObj[step7name]['final_bits'])

    # Verify any refimage parameters to be used
    step3aname = util.getSectionName(configObj, '3a')
    if not util.verifyRefimage(configObj[step3aname]['driz_sep_refimage']):
        msg = 'No refimage with WCS found!\n '+\
        ' This could be caused by one of 2 problems:\n'+\
        '   * filename does not specify an extension with a valid WCS.\n'+\
        '   * can not find the file.\n'+\
        'Please check the filename specified in the "refimage" parameter.'
        print(textutil.textbox(msg))
        return None, None
    step7aname = util.getSectionName(configObj, '7a')
    if not util.verifyRefimage(configObj[step7aname]['final_refimage']):
        msg = 'No refimage with WCS found!\n '+\
        ' This could be caused by one of 2 problems:\n'+\
        '   * filename does not specify an extension with a valid WCS.\n'+\
        '   * can not find the file.\n'+\
        'Please check the filename specified in the "refimage" parameter.'
        print(textutil.textbox(msg))
        return None, None

    # Build imageObject list for all the valid, shift-updated input files
    log.info('-Creating imageObject List as input for processing steps.')
    if 'in_memory' in configObj:
        virtual = configObj['in_memory']
    else:
        virtual = False

    imageObjectList = createImageObjectList(files,
                                            instrpars,
                                            output=asndict['output'],
                                            group=configObj['group'],
                                            undistort=undistort,
                                            inmemory=virtual)

    # Add original file names as "hidden" attributes of imageObject
    assert (len(original_files) == len(imageObjectList)
            )  #TODO: remove after extensive testing
    for i in range(len(imageObjectList)):
        imageObjectList[i]._original_file_name = original_files[i]

    # apply context parameter
    applyContextPar(imageObjectList, configObj['context'])

    # reset DQ bits if requested by user
    resetDQBits(imageObjectList, cr_bits_value=configObj['resetbits'])

    # Add info about input IVM files at this point to the imageObjectList
    addIVMInputs(imageObjectList, ivmlist)

    if createOutwcs:
        log.info('-Creating output WCS.')

        # Build output WCS and update imageObjectList with output WCS info
        outwcs = wcs_functions.make_outputwcs(imageObjectList,
                                              output,
                                              configObj=configObj,
                                              perfect=True)
        outwcs.final_wcs.printwcs()
    else:
        outwcs = None

    try:
        # Provide user with some information on resource usage for this run
        # raises ValueError Exception in interactive mode and user quits
        num_cores = configObj.get('num_cores') if use_parallel else 1

        reportResourceUsage(imageObjectList, outwcs, num_cores)
    except ValueError:
        imageObjectList = None

    return imageObjectList, outwcs
Exemplo n.º 18
0
    def generateXY(self, **kwargs):
        """ Generate source catalog from input image using DAOFIND-style algorithm
        """
        #x,y,flux,sharp,round = idlphot.find(array,self.pars['hmin'],self.pars['fwhm'],
        #                    roundlim=self.pars['roundlim'], sharplim=self.pars['sharplim'])
        print("  #  Source finding for '{}', EXT={} started at: {}".format(
            self.fnamenoext, self.wcs.extname,
            util._ptime()[0]))
        if self.pars['computesig']:
            # compute sigma for this image
            sigma = self._compute_sigma()
        else:
            sigma = self.pars['skysigma']
        skymode = sigma**2
        log.info('   Finding sources using sky sigma = %f' % sigma)
        if self.pars['threshold'] in [None, "INDEF", "", " "]:
            hmin = skymode
        else:
            hmin = sigma * self.pars['threshold']

        if 'mask' in kwargs and kwargs['mask'] is not None:
            dqmask = np.asarray(kwargs['mask'], dtype=bool)
        else:
            dqmask = None

        # get the mask for source finding:
        mask = self._combine_exclude_mask(dqmask)

        x, y, flux, src_id, sharp, round1, round2 = tweakutils.ndfind(
            self.source,
            hmin,
            self.pars['conv_width'],
            skymode,
            sharplim=[self.pars['sharplo'], self.pars['sharphi']],
            roundlim=[self.pars['roundlo'], self.pars['roundhi']],
            peakmin=self.pars['peakmin'],
            peakmax=self.pars['peakmax'],
            fluxmin=self.pars['fluxmin'],
            fluxmax=self.pars['fluxmax'],
            nsigma=self.pars['nsigma'],
            ratio=self.pars['ratio'],
            theta=self.pars['theta'],
            mask=mask,
            use_sharp_round=self.use_sharp_round,
            nbright=self.nbright)

        if len(x) == 0:
            if not self.pars['computesig']:
                sigma = self._compute_sigma()
                hmin = sigma * self.pars['threshold']
                log.info(
                    'No sources found with original thresholds. Trying automatic settings.'
                )
                x, y, flux, src_id, sharp, round1, round2 = tweakutils.ndfind(
                    self.source,
                    hmin,
                    self.pars['conv_width'],
                    skymode,
                    sharplim=[self.pars['sharplo'], self.pars['sharphi']],
                    roundlim=[self.pars['roundlo'], self.pars['roundhi']],
                    peakmin=self.pars['peakmin'],
                    peakmax=self.pars['peakmax'],
                    fluxmin=self.pars['fluxmin'],
                    fluxmax=self.pars['fluxmax'],
                    nsigma=self.pars['nsigma'],
                    ratio=self.pars['ratio'],
                    theta=self.pars['theta'],
                    mask=mask,
                    use_sharp_round=self.use_sharp_round,
                    nbright=self.nbright)
        if len(x) == 0:
            xypostypes = 3 * [float] + [
                int
            ] + (3 if self.use_sharp_round else 0) * [float]
            self.xypos = [np.empty(0, dtype=i) for i in xypostypes]
            warnstr = textutil.textbox(
                'WARNING: \n' +
                'No valid sources found with the current parameter values!')
            for line in warnstr.split('\n'):
                log.warning(line)
            print(warnstr)
        else:
            # convert the positions from numpy 0-based to FITS 1-based
            if self.use_sharp_round:
                self.xypos = [
                    x + 1, y + 1, flux, src_id + self.start_id, sharp, round1,
                    round2
                ]
            else:
                self.xypos = [x + 1, y + 1, flux, src_id + self.start_id]

        log.info('###Source finding finished at: %s' % (util._ptime()[0]))

        self.in_units = 'pixels'  # Not strictly necessary, but documents units when determined
        self.sharp = sharp
        self.round1 = round1
        self.round2 = round2
        self.numcols = 7 if self.use_sharp_round else 4
        self.num_objects = len(x)
        self._apply_flux_limits = False  # limits already applied by 'ndfind'
Exemplo n.º 19
0
def buildEmptyDRZ(input, output):
    """
    Create an empty DRZ file.

    This module creates an empty DRZ file in a valid FITS format so that the HST
    pipeline can handle the Multidrizzle zero expossure time exception
    where all data has been excluded from processing.

    Parameters
    ----------
    input : str
        filename of the initial input to process_input
    output : str
        filename of the default empty _drz.fits file to be generated

    """

    # Identify the first input image
    inputfile = parseinput.parseinput(input)[0]
    if not inputfile:
        print('\n******* ERROR *******', file=sys.stderr)
        print(
              'No input file found!  Check specification of parameter '
              '"input". ', file=sys.stderr)
        print('Quitting...',  file=sys.stderr)
        print('******* ***** *******\n',  file=sys.stderr)
        return # raise IOError, "No input file found!"

    # Set up output file here...
    if output is None:
        if len(input) == 1:
            oname = fileutil.buildNewRootname(input[0])
        else:
            oname = 'final'
        output = fileutil.buildNewRootname(oname, extn='_drz.fits')
    else:
        if 'drz' not in output:
            output = fileutil.buildNewRootname(output, extn='_drz.fits')

    log.info('Setting up output name: %s' % output)

    # Open the first image (of the excludedFileList?) to use as a template to build
    # the DRZ file.
    try :
        log.info('Building empty DRZ file from %s' % inputfile[0])
        img = fits.open(inputfile[0], memmap=False)
    except:
        raise IOError('Unable to open file %s \n' % inputfile)

    # Create the fitsobject
    fitsobj = fits.HDUList()
    # Copy the primary header
    hdu = img[0].copy()
    fitsobj.append(hdu)

    # Modify the 'NEXTEND' keyword of the primary header to 3 for the
    #'sci, wht, and ctx' extensions of the newly created file.
    fitsobj[0].header['NEXTEND'] = 3

    # Create the 'SCI' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'SCI'
    fitsobj.append(hdu)

    # Create the 'WHT' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'WHT'
    fitsobj.append(hdu)

    # Create the 'CTX' extension
    hdu = fits.ImageHDU(header=img['sci', 1].header.copy())
    hdu.header['EXTNAME'] = 'CTX'
    fitsobj.append(hdu)

    # Add HISTORY comments explaining the creation of this file.
    fitsobj[0].header.add_history("** AstroDrizzle has created this empty "
                                  "DRZ product because**")
    fitsobj[0].header.add_history("** all input images were excluded from "
                                  "processing.**")


    # Change the filename in the primary header to reflect the name of the output
    # filename.
    fitsobj[0].header['FILENAME'] = str(output)  # +"_drz.fits"

    # Change the ROOTNAME keyword to the ROOTNAME of the output PRODUCT
    fitsobj[0].header['ROOTNAME'] = str(output.split('_drz.fits')[0])
    # Modify the ASN_MTYP keyword to contain "PROD-DTH" so it can be properly
    # ingested into the archive catalog.

    # stis has this keyword in the [1] header, so I am directing the code
    #t o first look in the primary, then the 1
    try:
        fitsobj[0].header['ASN_MTYP'] = 'PROD-DTH'
    except:
        fitsobj[1].header['ASN_MTYP'] = 'PROD-DTH'

    # If the file is already on disk delete it and replace it with the
    # new file
    dirfiles = os.listdir(os.curdir)
    if dirfiles.count(output) > 0:
        os.remove(output)
        log.info("       Replacing %s..." % output)

    # Write out the empty DRZ file
    fitsobj.writeto(output)

    print(textutil.textbox(
        'ERROR:\nAstroDrizzle has created an empty DRZ product because all '
        'input images were excluded from processing or a user requested the '
        'program to stop.') + '\n', file=sys.stderr)

    return
Exemplo n.º 20
0
def run(configobj, wcsmap=None):
    """
    Initial example by Nadia ran MD with configobj EPAR using:
    It can be run in one of two ways:

        from stsci.tools import teal

        1. Passing a config object to teal

        teal.teal('drizzlepac/pars/astrodrizzle.cfg')


        2. Passing a task  name:

        teal.teal('astrodrizzle')

        The example config files are in drizzlepac/pars

    """
    # turn on logging, redirecting stdout/stderr messages to a log file
    # while also printing them out to stdout as well
    # also, initialize timing of processing steps
    #
    # We need to define a default logfile name from the user's parameters
    input_list, output, ivmlist, odict = \
            processInput.processFilenames(configobj['input'])

    if output is not None:
        def_logname = output
    elif len(input_list) > 0:
        def_logname = input_list[0]
    else:
        print(textutil.textbox(
            'ERROR:\nNo valid input files found!   Please restart the task '
            'and check the value for the "input" parameter.'),
              file=sys.stderr)
        def_logname = None
        return

    stateObj = configobj['STATE OF INPUT FILES']
    procSteps = util.ProcSteps()

    print('AstroDrizzle Version %s(%s) started at: %s\n' %
          (__version__, __version_date__, util._ptime()[0]))
    util.print_pkg_versions(log=log)

    try:
        # Define list of imageObject instances and output WCSObject instance
        # based on input paramters
        imgObjList = None
        procSteps.addStep('Initialization')
        imgObjList, outwcs = processInput.setCommonInput(configobj)
        procSteps.endStep('Initialization')

        if imgObjList is None or not imgObjList:
            errmsg = "No valid images found for processing!\n"
            errmsg += "Check log file for full details.\n"
            errmsg += "Exiting AstroDrizzle now..."
            print(textutil.textbox(errmsg, width=65))
            print(textutil.textbox(
                'ERROR:\nAstroDrizzle Version %s encountered a problem!  '
                'Processing terminated at %s.' %
                (__version__, util._ptime()[0])),
                  file=sys.stderr)
            procSteps.reportTimes()
            return

        log.info("USER INPUT PARAMETERS common to all Processing Steps:")
        util.printParams(configobj, log=log)

        # Call rest of MD steps...
        #create static masks for each image
        staticMask.createStaticMask(imgObjList, configobj, procSteps=procSteps)

        #subtract the sky
        sky.subtractSky(imgObjList, configobj, procSteps=procSteps)

        #       _dbg_dump_virtual_outputs(imgObjList)

        #drizzle to separate images
        adrizzle.drizSeparate(imgObjList,
                              outwcs,
                              configobj,
                              wcsmap=wcsmap,
                              procSteps=procSteps)

        #       _dbg_dump_virtual_outputs(imgObjList)

        #create the median images from the driz sep images
        createMedian.createMedian(imgObjList, configobj, procSteps=procSteps)

        #blot the images back to the original reference frame
        ablot.runBlot(imgObjList,
                      outwcs,
                      configobj,
                      wcsmap=wcsmap,
                      procSteps=procSteps)

        #look for cosmic rays
        drizCR.rundrizCR(imgObjList, configobj, procSteps=procSteps)

        #Make your final drizzled image
        adrizzle.drizFinal(imgObjList,
                           outwcs,
                           configobj,
                           wcsmap=wcsmap,
                           procSteps=procSteps)

        print()
        print(' '.join([
            'AstroDrizzle Version', __version__, 'is finished processing at ',
            util._ptime()[0]
        ]) + '!\n')
    except:
        print(textutil.textbox(
            'ERROR:\nAstroDrizzle Version %s encountered a problem!  '
            'Processing terminated at %s.' % (__version__, util._ptime()[0])),
              file=sys.stderr)
        procSteps.reportTimes()
        if imgObjList is not None:
            for image in imgObjList:
                image.close()
            del imgObjList
            del outwcs

    procSteps.reportTimes()

    if imgObjList is not None:
        for image in imgObjList:
            if stateObj['clean']:
                image.clean()
            image.close()

        del imgObjList
        del outwcs
Exemplo n.º 21
0
def run(configobj, wcsmap=None):
    """
    Initial example by Nadia ran MD with configobj EPAR using:
    It can be run in one of two ways:

        from stsci.tools import teal

        1. Passing a config object to teal

        teal.teal('drizzlepac/pars/astrodrizzle.cfg')


        2. Passing a task  name:

        teal.teal('astrodrizzle')

        The example config files are in drizzlepac/pars

    """
    # turn on logging, redirecting stdout/stderr messages to a log file
    # while also printing them out to stdout as well
    # also, initialize timing of processing steps
    #
    # We need to define a default logfile name from the user's parameters
    input_list, output, ivmlist, odict = \
            processInput.processFilenames(configobj['input'])

    if output is not None:
        def_logname = output
    elif len(input_list) > 0:
        def_logname = input_list[0]
    else:
        print(textutil.textbox(
            "ERROR:\nNo valid input files found!   Please restart the task "
            "and check the value for the 'input' parameter."), file=sys.stderr)
        def_logname = None
        return

    clean = configobj['STATE OF INPUT FILES']['clean']
    procSteps = util.ProcSteps()

    print("AstroDrizzle Version {:s} ({:s}) started at: {:s}\n"
          .format(__version__, __version_date__, util._ptime()[0]))
    util.print_pkg_versions(log=log)

    log.debug('')
    log.debug(
        "==== AstroDrizzle was invoked with the following parameters: ===="
    )
    log.debug('')
    util.print_cfg(configobj, log.debug)

    try:
        # Define list of imageObject instances and output WCSObject instance
        # based on input paramters
        imgObjList = None
        procSteps.addStep('Initialization')
        imgObjList, outwcs = processInput.setCommonInput(configobj)
        procSteps.endStep('Initialization')

        if imgObjList is None or not imgObjList:
            errmsg = "No valid images found for processing!\n"
            errmsg += "Check log file for full details.\n"
            errmsg += "Exiting AstroDrizzle now..."
            print(textutil.textbox(errmsg, width=65))
            print(textutil.textbox(
                'ERROR:\nAstroDrizzle Version {:s} encountered a problem!  '
                'Processing terminated at {:s}.'
                .format(__version__, util._ptime()[0])), file=sys.stderr)
            return

        log.info("USER INPUT PARAMETERS common to all Processing Steps:")
        util.printParams(configobj, log=log)

        # Call rest of MD steps...
        #create static masks for each image
        staticMask.createStaticMask(imgObjList, configobj,
                                    procSteps=procSteps)

        #subtract the sky
        sky.subtractSky(imgObjList, configobj, procSteps=procSteps)

#       _dbg_dump_virtual_outputs(imgObjList)

        #drizzle to separate images
        adrizzle.drizSeparate(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                              procSteps=procSteps)

#       _dbg_dump_virtual_outputs(imgObjList)

        #create the median images from the driz sep images
        createMedian.createMedian(imgObjList, configobj, procSteps=procSteps)

        #blot the images back to the original reference frame
        ablot.runBlot(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                      procSteps=procSteps)

        #look for cosmic rays
        drizCR.rundrizCR(imgObjList, configobj, procSteps=procSteps)

        #Make your final drizzled image
        adrizzle.drizFinal(imgObjList, outwcs, configobj, wcsmap=wcsmap,
                           procSteps=procSteps)

        print()
        print("AstroDrizzle Version {:s} is finished processing at {:s}.\n"
              .format(__version__, util._ptime()[0]))

    except:
        clean = False
        print(textutil.textbox(
            "ERROR:\nAstroDrizzle Version {:s} encountered a problem!  "
            "Processing terminated at {:s}."
            .format(__version__, util._ptime()[0])), file=sys.stderr)
        raise

    finally:
        procSteps.reportTimes()
        if imgObjList:
            for image in imgObjList:
                if clean:
                    image.clean()
                image.close()
            del imgObjList
            del outwcs