22 """Gen3 Butler Formatters for Dark Energy Camera raw data. 
   25 import astro_metadata_translator
 
   32 from . 
import DarkEnergyCamera
 
   34 __all__ = (
"DarkEnergyCameraRawFormatter", 
"DarkEnergyCameraCPCalibFormatter")
 
   39 detector_to_hdu = {25: 1, 26: 2, 27: 3, 32: 4, 33: 5, 34: 6, 19: 7, 20: 8, 13: 9,
 
   40                    14: 10, 8: 11, 4: 12, 39: 13, 40: 14, 45: 15, 46: 16, 51: 17, 56: 18, 21: 19,
 
   41                    22: 20, 23: 21, 24: 22, 17: 23, 18: 24, 15: 25, 16: 26, 9: 27, 10: 28, 11: 29,
 
   42                    12: 30, 5: 31, 6: 32, 7: 33, 1: 34, 2: 35, 3: 36, 35: 37, 36: 38, 37: 39,
 
   43                    38: 40, 28: 41, 29: 42, 30: 43, 31: 44, 41: 45, 42: 46, 43: 47, 44: 48, 49: 49,
 
   44                    50: 50, 47: 51, 48: 52, 52: 53, 53: 54, 54: 55, 55: 56, 57: 57, 58: 58, 59: 59,
 
   45                    60: 60, 61: 61, 62: 62, 72: 63, 71: 64, 64: 65, 63: 66, 73: 67, 74: 68, 70: 69,
 
   51     translatorClass = astro_metadata_translator.DecamTranslator
 
   52     filterDefinitions = DarkEnergyCamera.filterDefinitions
 
   55         return DarkEnergyCamera().getCamera()[id]
 
   57     def _scanHdus(self, filename, detectorId):
 
   58         """Scan through a file for the HDU containing data from one detector. 
   63             The file to search through. 
   65             The detector id to search for. 
   70             The index of the HDU with the requested data. 
   71         metadata: `lsst.daf.base.PropertyList` 
   72             The metadata read from the header for that detector id. 
   77             Raised if detectorId is not found in any of the file HDUs 
   80         log.debug(
"Did not find detector=%s at expected HDU=%s in %s: scanning through all HDUs.",
 
   81                   detectorId, detector_to_hdu[detectorId], filename)
 
   85         for i 
in range(1, fitsData.countHdus()):
 
   87             metadata = fitsData.readMetadata()
 
   88             if metadata[
'CCDNUM'] == detectorId:
 
   91             raise ValueError(f
"Did not find detectorId={detectorId} as CCDNUM in any HDU of {filename}.")
 
   93     def _determineHDU(self, detectorId):
 
   94         """Determine the correct HDU number for a given detector id. 
   99             The detector id to search for. 
  104             The index of the HDU with the requested data. 
  105         metadata : `lsst.daf.base.PropertyList` 
  106             The metadata read from the header for that detector id. 
  111             Raised if detectorId is not found in any of the file HDUs 
  113         filename = self.fileDescriptor.location.path
 
  115             index = detector_to_hdu[detectorId]
 
  117             if metadata[
'CCDNUM'] != detectorId:
 
  119                 return self.
_scanHdus(filename, detectorId)
 
  122                 fitsData.setHdu(index)
 
  123                 return index, metadata
 
  126             return self.
_scanHdus(filename, detectorId)
 
  129         index, metadata = self.
_determineHDU(self.dataId[
'detector'])
 
  130         astro_metadata_translator.fix_header(metadata)
 
  134         index, metadata = self.
_determineHDU(self.dataId[
'detector'])
 
  135         return lsst.afw.image.ImageI(self.fileDescriptor.location.path, index)
 
  139     """DECam Community Pipeline calibrations (bias, dark, flat, fringe) are 
  140     multi-extension FITS files with detector=index+1. 
  143     def _determineHDU(self, detectorId):
 
  144         """The HDU to read is the same as the detector number.""" 
  145         filename = self.fileDescriptor.location.path
 
  147         if metadata[
'CCDNUM'] != detectorId:
 
  148             msg = f
"Found CCDNUM={metadata['CCDNUM']} instead of {detectorId} in {filename} HDU={detectorId}." 
  149             raise ValueError(msg)
 
  150         return detectorId, metadata
 
  153         index, metadata = self.
_determineHDU(self.dataId[
'detector'])
 
  154         return lsst.afw.image.ImageF(self.fileDescriptor.location.path, index)