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
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
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
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
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
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