def determine_fit_quality(imglist,filteredTable, print_fit_parameters=True):
    """Determine the quality of the fit to the data

    Parameters
    ----------
    imglist : list
        output of interpret_fits. Contains sourcelist tables, newly computed WCS info, etc. for every chip of every valid
        input image.  This list should have been  updated, in-place, with the new RMS values;
        specifically,

            * 'FIT_RMS': RMS of the separations between fitted image positions and reference positions
            * 'TOTAL_RMS': mean of the FIT_RMS values for all observations
            * 'NUM_FITS': number of images/group_id's with successful fits included in the TOTAL_RMS

        These entries are added to the 'fit_info' dictionary.

    filteredTable : object
        Astropy Table object containing data pertaining to the associated dataset, including
        the doProcess bool.  It is intended this table is updated by subsequent functions for
        bookkeeping purposes.

    print_fit_parameters : bool
        Specify whether or not to print out FIT results for each chip

    Returns
    -------
    max_rms_val : float
        The best Total rms determined from all of the images

    num_xmatches: int
        The number of stars used in matching the data


    fitQual : int
        fit quality catagory:
        1 = valid solution with rms < 10 mas;
        2 = Valid but compromised solution with rms < 10 mas;
        3 = Valid solution with RMS >= 10 mas;
        4 = Valid but compromised solution with RMS >= 10 mas;
        5 = Not valid solution

    filteredTable : object
        modified filteredTable objecgt

    fitStatusDict : dictionary
        Dictionary containing the following:
            overall fit validity (Boolean)
            total (visit-level) RMS value in mas (float)
            number of matched sources (int)
            fit compromised status (Boolean)
            reason fit is considered 'compromised' (only populated if 'compromised' field is "True")
    """
    tweakwcs_info_keys = OrderedDict(imglist[0].meta['fit_info']).keys()
    max_rms_val = 1e9
    num_xmatches = 0
    fitStatusDict={}
    xshifts=[]
    yshifts=[]
    overall_valid = True
    overall_comp = False
    for item in imglist:
        if item.meta['fit_info']['status'].startswith('FAILED') != True:
            xshifts.append(item.meta['fit_info']['shift'][0])
            yshifts.append(item.meta['fit_info']['shift'][1])

    for item in imglist:
        image_name = item.meta['name']
        chip_num = item.meta['chip']

        # Build fitStatusDict entry
        dictKey = "{},{}".format(image_name, chip_num)
        fitStatusDict[dictKey] = {'valid': False,
                                  'max_rms': max_rms_val,
                                  'num_matches': num_xmatches,
                                  'compromised': False,
                                  'reason': ""} # Initialize dictionary entry for current image/chip
        #Handle fitting failures (no matches found)
        if item.meta['fit_info']['status'].startswith("FAILED") == True:
                log.warning("No cross matches found in any catalog for {} - no processing done.".format(image_name))
                continue
        fit_rms_val = item.meta['fit_info']['FIT_RMS']
        max_rms_val = item.meta['fit_info']['TOTAL_RMS']
        num_xmatches = item.meta['fit_info']['nmatches']
        fitStatusDict[dictKey]['max_rms'] = max_rms_val
        fitStatusDict[dictKey]['num_matches'] = num_xmatches

        if num_xmatches < MIN_CROSS_MATCHES:
            if catalogIndex < numCatalogs-1:
                log.warning("Not enough cross matches found between astrometric catalog and sources found in {}".format(image_name))
                continue

        # Execute checks
        nmatchesCheck = False
        if num_xmatches > 4:
            nmatchesCheck = True

        radialOffsetCheck = False
        radialOffset = math.sqrt(float(item.meta['fit_info']['shift'][0])**2 +
                                 float(item.meta['fit_info']['shift'][0])**2)*item.wcs.pscale #radial offset in arssec
        if float(num_xmatches) * 0.36 > 0.8 + (radialOffset/10.0)**8:
            radialOffsetCheck = True

        largeRmsCheck = True
        if fit_rms_val > 150. or max_rms_val > 150.:
            largeRmsCheck = False

        # fitRmsCheck = False
        # if fit_rms_val < max_rms_val:
        #     fitRmsCheck = True

        consistencyCheck = True
        rms_limit = max(item.meta['fit_info']['TOTAL_RMS'], 10.)
        if not math.sqrt(np.std(np.asarray(xshifts)) ** 2 + np.std(np.asarray(yshifts)) ** 2) <= (
                    rms_limit / 1000.0) / (item.wcs.pscale):
            consistencyCheck = False

        # Decide if fit solutions are valid based on checks
        if consistencyCheck == False: # Failed consistency check
            fitStatusDict[dictKey]['valid'] = False
            fitStatusDict[dictKey]['compromised'] = False
            fitStatusDict[dictKey]['reason'] = "Consistency violation!"
        elif largeRmsCheck == False: # RMS value(s) too large
            fitStatusDict[dictKey]['valid'] = False
            fitStatusDict[dictKey]['compromised'] = False
            fitStatusDict[dictKey]['reason'] = "RMS too large (>150 mas)!"
        elif radialOffsetCheck == False: # Failed radial offset check
            fitStatusDict[dictKey]['valid'] = False
            fitStatusDict[dictKey]['compromised'] = False
            fitStatusDict[dictKey]['reason'] = "Radial offset value too large!"
        elif nmatchesCheck == False: # Too few matches
            fitStatusDict[dictKey]['valid'] = True
            fitStatusDict[dictKey]['compromised'] = True
            fitStatusDict[dictKey]['reason'] = "Too few matches!"
        else: # all checks passed. Valid solution.
            fitStatusDict[dictKey]['valid'] = True
            fitStatusDict[dictKey]['compromised'] = False
            fitStatusDict[dictKey]['reason'] = ""
        # for now, generate overall valid and compromised values. Basically, if any of the entries for "valid" is False,
        # treat the whole dataset as not valid. Same goes for compromised.
        if fitStatusDict[dictKey]['valid'] == False:
            overall_valid = False
        if fitStatusDict[dictKey]['compromised'] == True:
            overall_comp = True

        log.info('RESULTS FOR {} Chip {}: FIT_RMS = {} mas, TOTAL_RMS = {} mas, NUM =  {}'.format(image_name, item.meta['chip'], fit_rms_val, max_rms_val, num_xmatches))
        # print fit params to screen
        if print_fit_parameters:
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FIT PARAMETERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
            log.info("image: {}".format(image_name))
            log.info("chip: {}".format(item.meta['chip']))
            log.info("group_id: {}".format(item.meta['group_id']))
            for tweakwcs_info_key in tweakwcs_info_keys:
                if not tweakwcs_info_key.startswith("matched"):
                    log.info("{} : {}".format(tweakwcs_info_key,item.meta['fit_info'][tweakwcs_info_key]))
            log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
            log.info("nmatchesCheck: {} radialOffsetCheck: {} largeRmsCheck: {}, consistencyCheck: {}".format(nmatchesCheck,radialOffsetCheck,largeRmsCheck,consistencyCheck))


    # determine which fit quality category this latest fit falls into
    if overall_valid == False:
        fitQual = 5
        log.info("FIT SOLUTION REJECTED")
        filteredTable['status'][:] = 1
        for ctr in range(0, len(filteredTable)):
            filteredTable[ctr]['processMsg'] = fitStatusDict[filteredTable[ctr]['imageName'] + ",1"]["reason"]
    else:
        for ctr in range(0, len(filteredTable)):
            filteredTable[ctr]['processMsg'] = ""
        if overall_comp == False and max_rms_val < 10.:
            log.info("Valid solution with RMS < 10 mas found!")
            fitQual = 1
        elif overall_comp == True and max_rms_val < 10.:
            log.info("Valid but compromised solution with RMS < 10 mas found!")
            fitQual = 2
        elif overall_comp == False and max_rms_val >= 10.:
            log.info("Valid solution with RMS >= 10 mas found!")
            fitQual = 3
        else:
            log.info("Valid but compromised solution with RMS >= 10 mas found!")
            fitQual = 4

    if print_fit_parameters:
        for item in imglist: log.info(fitStatusDict["{},{}".format(item.meta['name'], item.meta['chip'])])

    if max_rms_val > MAX_FIT_RMS:
        log.info("Total fit RMS value = {} mas greater than the maximum threshold value {}.".format(max_rms_val, MAX_FIT_RMS))
    if not overall_valid:
        log.info("The fit solution for some or all of the images is not valid.")
    if max_rms_val > MAX_FIT_RMS or overall_valid == False:
        log.info("Try again with the next catalog")
    else:
        log.info("Fit calculations successful.")
    return max_rms_val, num_xmatches, fitQual, filteredTable, fitStatusDict