Exemplo n.º 1
0
 def data_section(self, dataset, pretty=False, **args):
     # Since this descriptor function accesses keywords in the headers of
     # the pixel data extensions, always construct a dictionary where the
     # key of the dictionary is an (EXTNAME, EXTVER) tuple.
     ret_data_section = {}
     
     # Determine the region of interest keyword from the global keyword
     # dictionary 
     keyword1 = self.get_descriptor_key("key_lowrow")
     keyword2 = self.get_descriptor_key("key_hirow")
     keyword3 = self.get_descriptor_key("key_lowcol")
     keyword4 = self.get_descriptor_key("key_hicol")
     
     # Get the value of the region of interest keyword from the header of
     # each pixel data extension as a dictionary where the key of the
     # dictionary is an ("*", EXTVER) tuple
     coord_dict = gmu.get_key_value_dict(
         adinput=dataset, keyword=[keyword1, keyword2, keyword3, keyword4])
     
     x_start_dict = coord_dict[keyword1]
     x_end_dict = coord_dict[keyword2]
     y_start_dict = coord_dict[keyword3]
     y_end_dict = coord_dict[keyword4]
     
     if None in [x_start_dict, x_end_dict, y_start_dict, y_end_dict]:
         # The get_key_value_dict() function returns None if a value cannot
         # be found and stores the exception info. Re-raise the exception.
         # It will be dealt with by the CalculatorInterface.
         if hasattr(dataset, "exception_info"):
             raise dataset.exception_info
     
     for ext_name_ver, x_start in x_start_dict.iteritems():
         x_end = x_end_dict[ext_name_ver]
         y_start = y_start_dict[ext_name_ver]
         y_end = y_end_dict[ext_name_ver]
         
         if None in [x_start, x_end, y_start, y_end]:
             data_section = None
         elif pretty:
             # Return a dictionary with the data section string that uses
             # 1-based indexing as the value in the form [x1:x2,y1:y2] 
             data_section = "[%d:%d,%d:%d]" % (
                 x_start + 1, x_end + 1, y_start + 1, y_end + 1)
         else:
             # Return a dictionary with the data section list that uses
             # 0-based, non-inclusive indexing as the value in the form
             # [x1, x2, y1, y2]
             data_section = [x_start, x_end + 1, y_start, y_end + 1]
         
         # Update the dictionary with the data section value
         ret_data_section.update({ext_name_ver:data_section})
     
     # Instantiate the return DescriptorValue (DV) object
     ret_dv = DescriptorValue(ret_data_section, name="data_section",
                              ad=dataset)
     return ret_dv
Exemplo n.º 2
0
 def nominal_photometric_zeropoint(self, dataset, **args):
     # Since this descriptor function accesses keywords in the headers of
     # the pixel data extensions, always construct a dictionary where the
     # key of the dictionary is an (EXTNAME, EXTVER) tuple
     ret_nominal_photometric_zeropoint = {}
     
     table = Lookups.get_lookup_table("Gemini/NIRI/Nominal_Zeropoints",
                                      "nominal_zeropoints")
     
     # Get the values of the gain, detector name and filter name using the
     # appropriate descriptors. Use as_pytype() to return the values as the
     # default python type rather than an object.
     gain = dataset.gain().as_pytype()
     camera = dataset.camera().as_pytype()
     filter_name = dataset.filter_name(pretty=True).as_pytype()
     
     if gain is None or camera is None or filter_name is None:
         # The descriptor functions return None if a value cannot be
         # found and stores the exception info. Re-raise the exception.
         # It will be dealt with by the CalculatorInterface.
         if hasattr(dataset, "exception_info"):
             raise dataset.exception_info
     
     # Get the value of the BUNIT keyword from the header of each pixel data
     # extension as a dictionary where the key of the dictionary is an
     # ("*", EXTVER) tuple 
     bunit_dict = gmu.get_key_value_dict(adinput=dataset, keyword="BUNIT")
     
     for ext_name_ver, bunit in bunit_dict.iteritems():
         # If bunit is "electron" or None, set the gain factor to 0.0 
         gain_factor = 0.0
         
         if bunit == "adu":
             gain_factor = 2.5 * math.log10(gain)
             
         nominal_zeropoint_key = (filter_name, camera)
         
         if nominal_zeropoint_key in table:
             nominal_photometric_zeropoint = (
                 table[nominal_zeropoint_key] - gain_factor)
         else:
             raise Errors.TableKeyError()
         
         # Update the dictionary with the nominal photometric zeropoint
         # value 
         ret_nominal_photometric_zeropoint.update({
             ext_name_ver:nominal_photometric_zeropoint})
     
     # Instantiate the return DescriptorValue (DV) object
     ret_dv = DescriptorValue(ret_nominal_photometric_zeropoint,
                              name="nominal_photometric_zeropoint",
                              ad=dataset)
     return ret_dv
def _get_static_bias_level(adinput=None):
    """
    Determine the static bias level value from GMOS data.
    """

    # Since this function accesses keywords in the headers of the pixel data
    # extensions, always construct a dictionary where the key of the dictionary
    # is an EXTVER integer
    static_bias_level = {}
    
    # Get the static bias level lookup table
    gmosampsBias, gmosampsBiasBefore20060831 = Lookups.get_lookup_table(
        "Gemini/GMOS/GMOSAmpTables", "gmosampsBias",
        "gmosampsBiasBefore20060831")
    
    # Get the UT date, read speed setting and gain setting values using the
    # appropriate descriptors
    ut_date_dv = adinput.ut_date()
    read_speed_setting_dv = adinput.read_speed_setting()
    gain_setting_dv = adinput.gain_setting()
    
    # Get the name of the detector amplifier from the header of each pixel data
    # extension as a dictionary
    ampname_dict = gmu.get_key_value_dict(
        adinput=adinput, keyword="AMPNAME", dict_key_extver=True)
    
    if not (ut_date_dv.is_none() and read_speed_setting_dv.is_none() and
            gain_setting_dv.is_none()) and ampname_dict is not None:
        
        # Use as_pytype() to return the values as the default python type
        # rather than an object
        ut_date = str(ut_date_dv)
        read_speed_setting = read_speed_setting_dv.as_pytype()
        
        # Create a gain setting dictionary where the key of the dictionary is
        # an EXTVER integer
        gain_setting_dict = gain_setting_dv.collapse_by_extver()
        
        if not gain_setting_dv.validate_collapse_by_extver(gain_setting_dict):
            # The validate_collapse_by_extver function returns False if the
            # values in the dictionary with the same EXTVER are not equal 
            raise Errors.CollapseError()
        
        obs_ut_date = datetime(*strptime(ut_date, "%Y-%m-%d")[0:6])
        old_ut_date = datetime(2006, 8, 31, 0, 0)
        
        for extver, gain_setting in gain_setting_dict.iteritems():
            ampname  = ampname_dict[extver]
            bias_key = (read_speed_setting, gain_setting, ampname)

            bias_level = None
            if obs_ut_date > old_ut_date:
                if bias_key in gmosampsBias:
                    bias_level = gmosampsBias[bias_key]
            else:
                if bias_key in gmosampsBiasBefore20060831:
                    bias_level = gmosampsBiasBefore20060831[bias_key]
            
            # Update the dictionary with the bias level value
            static_bias_level.update({extver: bias_level})
    
    # if len(static_bias_level) == 1:
    #     # Only one value will be returned
    #     ret_static_bias_level = static_bias_level.values()[0]  #!! Not a dict !
    # else:

    unique_values = set(static_bias_level.values())

    if len(unique_values) == 1 and None in unique_values:
        # The bias level was not found for any of the pixel data extensions
        # (all the values in the dictionary are equal to None)
        ret_static_bias_level = None
    else:
        ret_static_bias_level = static_bias_level
    
    return ret_static_bias_level
def _get_bias_level_estimate(adinput=None):
    """
    Determine an estiamte of the bias level value from GMOS data.
    """
    # Since this function accesses keywords in the headers of the pixel data
    # extensions, always construct a dictionary where the key of the dictionary
    # is an EXTVER integer
    ret_bias_level = {}
    
    # Get the overscan value and the raw bias level from the header of each
    # pixel data extension as a dictionary where the key of the dictionary is
    # an EXTVER integer
    keyword_value_dict = gmu.get_key_value_dict(adinput=adinput, 
                                                keyword=["OVERSCAN", "RAWBIAS"], 
                                                dict_key_extver=True)
    overscan_value_dict = keyword_value_dict["OVERSCAN"]
    raw_bias_level_dict = keyword_value_dict["RAWBIAS"]
    
    if overscan_value_dict is None:
        
        # If there is no overscan value for any extensions, use the raw bias
        # level value as the value for the bias level
        if raw_bias_level_dict is None:
            
            # If there is no raw bias level value for any extensions, use the
            # static bias levels from the lookup table as the value for the
            # bias level
            ret_bias_level = _get_static_bias_level(adinput=adinput)
        else:
            # Use the raw bias level value as the value for the bias level
            for extver, raw_bias_level in raw_bias_level_dict.iteritems():
                
                if raw_bias_level is None:
                    # If the raw bias level does not exist for a given
                    # extension, use the static bias levels from the lookup
                    # table as the value for the bias level
                    bias_level = _get_static_bias_level_for_ext(
                        adinput=adinput[SCI,extver])
                else:
                    bias_level = raw_bias_level
                
                # Update the dictionary with the bias level value
                ret_bias_level.update({extver: bias_level})
    else:
        for extver, overscan_value in overscan_value_dict.iteritems():
            if overscan_value is None:
                
                # If the overscan value does not exist for a given extension,
                # use the raw bias level value from the header as the value for
                # the bias level
                if raw_bias_level_dict is None:
                    
                    # If there is no raw bias level value for any extensions,
                    # use the static bias levels from the lookup table as the
                    # value for the bias level 
                    bias_level = _get_static_bias_level_for_ext(
                        adinput=adinput[SCI,extver])
                else:
                    raw_bias_level = raw_bias_level_dict[extver]
                    if raw_bias_level is None:
                        
                        # If the raw bias level does not exist for a given 
                        # extension, use the static bias levels from the lookup
                        # table as the value for the bias level 
                        bias_level = _get_static_bias_level_for_ext(
                            adinput=adinput[SCI,extver])
                    else:
                        bias_level = raw_bias_level
            else:
                bias_level = overscan_value
            
            # Update the dictionary with the bias level value
            ret_bias_level.update({ext_name_ver: bias_level})
    
    unique_values = set(ret_bias_level.values())

    if len(unique_values) == 1 and None in unique_values:
        # The bias level was not found for any of the pixel data extensions
        # (all the values in the dictionary are equal to None)
        ret_bias_level = None
        
    return ret_bias_level
Exemplo n.º 5
0
    def gain(self, dataset, **args):
        # Since this descriptor function accesses keywords in the headers of
        # the pixel data extensions, always construct a dictionary where the
        # key of the dictionary is an (EXTNAME, EXTVER) tuple
        ret_gain_dict = {}

        # If the data have been prepared, take the gain value directly from the
        # appropriate keyword. At some point, a check for the STDHDRSI header
        # keyword should be added, since the function that overwrites the gain
        # keyword also writes the STDHDRSI keyword.
        if "PREPARED" in dataset.types:

            # Determine the gain keyword from the global keyword dictionary
            keyword = self.get_descriptor_key("key_gain")

            # Get the value of the gain keyword from the header of each pixel
            # data extension as a dictionary where the key of the dictionary is
            # an ("*", EXTVER) tuple
            gain_dict = gmu.get_key_value_dict(adinput=dataset,
                                               keyword=keyword)
            if gain_dict is None:
                # The get_key_value_dict() function returns None if a value
                # cannot be found and stores the exception info. Re-raise the
                # exception. It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            ret_gain_dict = gain_dict

        else:
            # Get the lookup table containing the gain values by amplifier
            gmosampsGain = GMOSAmpTables.gmosampsGain
            gmosampsGainBefore20150826 = GMOSAmpTables.gmosampsGainBefore20150826
            gmosampsGainBefore20060831 = GMOSAmpTables.gmosampsGainBefore20060831

            # Determine the amplifier integration time keyword (ampinteg) from
            # the global keyword dictionary
            keyword = self.get_descriptor_key("key_ampinteg")

            # Get the value of the amplifier integration time keyword from the
            # header of the PHU
            ampinteg = dataset.phu_get_key_value(keyword)

            if ampinteg is None:
                # The phu_get_key_value() function returns None if a value
                # cannot be found and stores the exception info. Re-raise the
                # exception. It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            # Get the UT date, gain setting and read speed setting values using
            # the appropriate descriptors
            ut_date_dv = dataset.ut_date()
            gain_setting_dv = dataset.gain_setting()
            read_speed_setting_dv = dataset.read_speed_setting()

            if (ut_date_dv.is_none() or gain_setting_dv.is_none() or
                    read_speed_setting_dv.is_none()):
                # The descriptor functions return None if a value cannot be
                # found and stores the exception info. Re-raise the exception.
                # It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            # Use as_dict() and as_pytype() to return the values as a
            # dictionary where the key of the dictionary is an ("*", EXTVER)
            # tuple and the default python type, respectively, rather than an
            # object
            ut_date = str(ut_date_dv)
            gain_setting_dict = gain_setting_dv.as_dict()
            read_speed_setting = read_speed_setting_dv.as_pytype()

            obs_ut_date = datetime(*strptime(ut_date, "%Y-%m-%d")[0:6])
            # These dates really shouldn't be hard wired so sloppily all over
            # the place (including gempy gemini_data_calculations.py) but that
            # goes as far as the dictionary names so leave it for a possible
            # future clean up of how the dictionaries are keyed.
            change_2015_ut = datetime(2015, 8, 26, 0, 0)
            change_2006_ut = datetime(2006, 8, 31, 0, 0)

            # Determine the name of the detector amplifier keyword (ampname)
            # from the global keyword dictionary
            keyword = self.get_descriptor_key("key_ampname")

            # Get the value of the name of the detector amplifier keyword from
            # the header of each pixel data extension as a dictionary where the
            # key of the dictionary is an ("*", EXTVER) tuple
            ampname_dict = gmu.get_key_value_dict(adinput=dataset,
                                                  keyword=keyword)
            if ampname_dict is None:
                # The get_key_value_dict() function returns None if a value
                # cannot be found and stores the exception info. Re-raise the
                # exception. It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            for ext_name_ver, ampname in ampname_dict.iteritems():
                gain_setting = gain_setting_dict[ext_name_ver]

                if ampname is None or gain_setting is None:
                    gain = None
                else:
                    gain_key = (read_speed_setting, gain_setting, ampname)

                    if obs_ut_date > change_2015_ut:
                        gain_dict = gmosampsGain
                    elif obs_ut_date > change_2006_ut:
                        gain_dict = gmosampsGainBefore20150826
                    else:
                        gain_dict = gmosampsGainBefore20060831

                    if gain_key in gain_dict:
                        gain = gain_dict[gain_key]
                    else:
                        raise Errors.TableKeyError()

                # Update the dictionary with the gain value
                ret_gain_dict.update({ext_name_ver: gain})

        # Instantiate the return DescriptorValue (DV) object
        ret_dv = DescriptorValue(ret_gain_dict, name="gain", ad=dataset)

        return ret_dv
Exemplo n.º 6
0
    def read_noise(self, dataset, **args):
        # Since this descriptor function accesses keywords in the headers of
        # the pixel data extensions, always construct a dictionary where the
        # key of the dictionary is an (EXTNAME, EXTVER) tuple
        ret_read_noise_dict = {}

        # If the data have been prepared, take the read noise value directly
        # from the appropriate keyword. At some point, a check for the STDHDRSI
        # header keyword should be added, since the function that overwrites
        # the read noise keyword also writes the STDHDRSI keyword.
        if "PREPARED" in dataset.types:

            # Determine the read noise keyword from the global keyword
            # dictionary
            keyword = self.get_descriptor_key("key_read_noise")

            # Get the value of the read noise keyword from the header of each
            # pixel data extension as a dictionary where the key of the
            # dictionary is an ("*", EXTVER) tuple
            read_noise_dict = gmu.get_key_value_dict(adinput=dataset,
                                                     keyword=keyword)
            if read_noise_dict is None:
                # The get_key_value_dict() function returns None if a value
                # cannot be found and stores the exception info. Re-raise the
                # exception. It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            for ext_name_ver, raw_read_noise in read_noise_dict.iteritems():
                if raw_read_noise is None:
                    read_noise = None
                else:
                    read_noise = float(raw_read_noise)

                # Update the dictionary with the read noise value
                ret_read_noise_dict.update({ext_name_ver: read_noise})
        else:
            # Get the lookup table containing the read noise values by
            # amplifier
            gmosampsRdnoise = GMOSAmpTables.gmosampsRdnoise
            gmosampsRdnoiseBefore20150826 = GMOSAmpTables.gmosampsRdnoiseBefore20150826
            gmosampsRdnoiseBefore20060831 = GMOSAmpTables.gmosampsRdnoiseBefore20060831

            # Get the UT date, gain setting and read speed setting values using
            # the appropriate descriptors
            ut_date_dv = dataset.ut_date()
            gain_setting_dv = dataset.gain_setting()
            read_speed_setting_dv = dataset.read_speed_setting()

            if (ut_date_dv.is_none() or gain_setting_dv.is_none() or
                    read_speed_setting_dv.is_none()):
                # The descriptor functions return None if a value cannot be
                # found and stores the exception info. Re-raise the exception.
                # It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            # Use as_dict() and as_pytype() to return the values as a
            # dictionary and the default python type, respectively, rather than
            # an object
            ut_date = str(ut_date_dv)
            gain_setting_dict = gain_setting_dv.as_dict()
            read_speed_setting = read_speed_setting_dv.as_pytype()

            obs_ut_date = datetime(*strptime(ut_date, "%Y-%m-%d")[0:6])
            change_2015_ut = datetime(2015, 8, 26, 0, 0)
            change_2006_ut = datetime(2006, 8, 31, 0, 0)
            # Determine the name of the detector amplifier keyword (ampname)
            # from the global keyword dictionary
            keyword = self.get_descriptor_key("key_ampname")

            # Get the value of the name of the detector amplifier keyword from
            # the header of each pixel data extension as a dictionary where the
            # key of the dictionary is an ("*", EXTVER) tuple
            ampname_dict = gmu.get_key_value_dict(adinput=dataset,
                                                  keyword=keyword)
            if ampname_dict is None:
                # The get_key_value_dict() function returns None if a value
                # cannot be found and stores the exception info. Re-raise the
                # exception. It will be dealt with by the CalculatorInterface.
                if hasattr(dataset, "exception_info"):
                    raise dataset.exception_info

            for ext_name_ver, ampname in ampname_dict.iteritems():
                gain_setting = gain_setting_dict[ext_name_ver]

                if ampname is None or gain_setting is None:
                    read_noise = None
                else:
                    read_noise_key = (
                        read_speed_setting, gain_setting, ampname)

                    if obs_ut_date > change_2015_ut:
                        read_noise_dict = gmosampsRdnoise
                    elif obs_ut_date > change_2006_ut:
                        read_noise_dict = gmosampsRdnoiseBefore20150826
                    else:
                        read_noise_dict = gmosampsRdnoiseBefore20060831

                    if read_noise_key in read_noise_dict:
                        read_noise = read_noise_dict[read_noise_key]
                    else:
                        raise Errors.TableKeyError()

                # Update the dictionary with the read noise value
                ret_read_noise_dict.update({ext_name_ver: read_noise})

        # Instantiate the return DescriptorValue (DV) object
        ret_dv = DescriptorValue(ret_read_noise_dict, name="read_noise",
                                 ad=dataset)
        return ret_dv
Exemplo n.º 7
0
 def filter_name(self, dataset, stripID=False, pretty=False, **args):
     # Since this descriptor function accesses keywords in the headers of
     # the pixel data extensions, always construct a dictionary where the
     # key of the dictionary is an (EXTNAME, EXTVER) tuple.
     ret_filter_name = {}
     
     # For NICI, the red filter is defined in the first science extension,
     # while the blue filter is defined in the second science extension.
     #
     # Determine the filter name keyword from the global keyword dictionary 
     keyword1 = self.get_descriptor_key("key_filter_r")
     keyword2 = self.get_descriptor_key("key_filter_b")
     
     # Get the value of the filter name keyword from the header of each
     # pixel data extension as a dictionary where the key of the dictionary
     # is an ("*", EXTVER) tuple
     filter_dict = gmu.get_key_value_dict(adinput=dataset,
                                          keyword=[keyword1, keyword2])
     
     filter_r_dict = filter_dict[keyword1]
     filter_b_dict = filter_dict[keyword2]
     
     # The following code contains duplication so that the case when a user
     # loops over extensions in an AstroData object and calls the
     # filter_name descriptor on each extension, i.e.,
     #
     #   for ext in ad:
     #       print ext.filter_name()
     #
     # is handled appropriately. There may be a better way to do this ...
     if filter_r_dict is None:
         if filter_b_dict is None:
             # The get_key_value_dict() function returns None if a value
             # cannot be found and stores the exception info. Re-raise the
             # exception. It will be dealt with by the CalculatorInterface.
             if hasattr(dataset, "exception_info"):
                 raise dataset.exception_info
         else:
             for ext_name_ver, filter_b in filter_b_dict.iteritems():
                 if filter_b is None:
                     raw_filter = None
                 else:
                     raw_filter = filter_b
                 
                 if pretty:
                     stripID = True
                 if stripID:
                     # Strip the component ID from the filter name value
                     if raw_filter is not None:
                         filter = gmu.removeComponentID(raw_filter)
                 else:
                     filter = raw_filter
                 
                 # Update the dictionary with the filter name value
                 ret_filter_name.update({ext_name_ver:filter})
     else:
         for ext_name_ver, filter_r in filter_r_dict.iteritems():
             if filter_b_dict is not None:
                 filter_b = filter_b_dict[ext_name_ver]
             else:
                 filter_b = None
             
             if filter_r is None and filter_b is None:
                 raw_filter = None
             elif filter_r is None and filter_b is not None:
                 raw_filter = filter_b
             elif filter_r is not None and filter_b is None:
                 raw_filter = filter_r
             else:
                 # Both filter_r and filter_b are defined for a single
                 # extension, which is incorrect 
                 raise Errors.CorruptDataError()
             
             if pretty:
                 stripID = True
             if stripID:
                 # Strip the component ID from the filter name value
                 if raw_filter is not None:
                     filter = gmu.removeComponentID(raw_filter)
             else:
                 filter = raw_filter
             
             # Update the dictionary with the filter name value
             ret_filter_name.update({ext_name_ver:filter})
     
     # Instantiate the return DescriptorValue (DV) object
     ret_dv = DescriptorValue(ret_filter_name, name="filter_name",
                              ad=dataset)
     return ret_dv
Exemplo n.º 8
0
 def pixel_scale(self, dataset, **args):
     # First try to calculate the pixel scale using the values of the WCS
     # matrix elements keywords
     #
     # Since this descriptor function accesses keywords in the headers of
     # the pixel data extensions, always construct a dictionary where the
     # key of the dictionary is an (EXTNAME, EXTVER) tuple.
     ret_pixel_scale_dict = {}
     
     # Determine the WCS matrix elements keywords from the global keyword
     # dictionary
     keyword1 = self.get_descriptor_key("key_cd11")
     keyword2 = self.get_descriptor_key("key_cd12")
     keyword3 = self.get_descriptor_key("key_cd21")
     keyword4 = self.get_descriptor_key("key_cd22")
     
     # Get the value of the WCS matrix elements keywords from the header of
     # each pixel data extension as a dictionary where the key of the
     # dictionary is an ("*", EXTVER) tuple
     cd_dict = gmu.get_key_value_dict(
         adinput=dataset, keyword=[keyword1, keyword2, keyword3, keyword4])
     
     cd11_dict = cd_dict[keyword1]
     cd12_dict = cd_dict[keyword2]
     cd21_dict = cd_dict[keyword3]
     cd22_dict = cd_dict[keyword4]
     
     if cd11_dict is None:
         # Get the pixel scale value using the value of the pixel scale
         # keyword in the PHU
         pixel_scale = self._get_pixel_scale_from_header(dataset=dataset)
         
         # Loop over the pixel data extensions in the dataset
         pixel_scale_dict = {}
         for ext in dataset[pixel_exts]:
             # Update the dictionary with the pixel_scale value
             pixel_scale_dict.update(
                 {(ext.extname(), ext.extver): pixel_scale})
         
         # Instantiate the DescriptorValue (DV) object
         dv = DescriptorValue(pixel_scale_dict)
         
         # Create a new dictionary where the key of the dictionary is an
         # EXTVER integer
         extver_dict = dv.collapse_by_extver()
         
         if not dv.validate_collapse_by_extver(extver_dict):
             # The validate_collapse_by_extver function returns False if the
             # values in the dictionary with the same EXTVER are not equal
             raise Errors.CollapseError()
         
         ret_pixel_scale_dict = pixel_scale_dict
     
     else:
         for ext_name_ver, cd11 in cd11_dict.iteritems():
             cd12 = None
             if cd12_dict is not None:
                 cd12 = cd12_dict[ext_name_ver]
             cd21 = None
             if cd21_dict is not None:
                 cd21 = cd21_dict[ext_name_ver]
             cd22 = None
             if cd22_dict is not None:
                 cd22 = cd22_dict[ext_name_ver]
             
             pixel_scale = None
             if not None in [cd11, cd12, cd21, cd22]:
                 # Calculate the pixel scale using the WCS matrix elements
                 pixel_scale = 3600 * (
                   math.sqrt(math.pow(cd11, 2) + math.pow(cd12, 2)) +
                   math.sqrt(math.pow(cd21, 2) + math.pow(cd22, 2))) / 2
             
             if pixel_scale is None or pixel_scale == 0.0:
                 # Get the pixel scale value using the value of the pixel
                 # scale keyword
                 pixel_scale = self._get_pixel_scale_from_header(
                     dataset=dataset)
             
             # Update the dictionary with the pixel scale value
             ret_pixel_scale_dict.update({ext_name_ver: pixel_scale})
     
     # Instantiate the return DescriptorValue (DV) object using the newly
     # created dictionary
     ret_dv = DescriptorValue(ret_pixel_scale_dict, name="pixel_scale",
                              ad=dataset)
     return ret_dv