26 from astro_metadata_translator
import fix_header, DecamTranslator
31 from ._instrument
import DarkEnergyCamera
33 __all__ = [
"DecamRawIngestTask",
"DecamIngestArgumentParser",
"DecamIngestTask",
"DecamParseTask"]
37 """Task for ingesting raw DECam data into a Gen3 Butler repository.
43 for i
in range(1, fitsData.countHdus()):
45 header = fitsData.readMetadata()
46 if header[
'CCDNUM'] > 62:
55 FormatterClass = instrument.getRawFormatter(datasets[0].dataId)
57 self.
log.
debug(f
"Found images for {len(datasets)} detectors in {filename}")
58 return RawFileData(datasets=datasets, filename=filename,
59 FormatterClass=FormatterClass,
60 instrumentClass=
type(instrument))
64 """Gen2 DECam ingest additional arguments.
68 super(DecamIngestArgumentParser, self).
__init__(*args, **kwargs)
69 self.add_argument(
"--filetype", default=
"raw", choices=[
"instcal",
"raw"],
70 help=
"Data processing level of the files to be ingested")
74 """Gen2 DECam file ingest task.
76 ArgumentParser = DecamIngestArgumentParser
79 super(DecamIngestTask, self).
__init__(*args, **kwargs)
82 """Ingest all specified files and add them to the registry
84 if args.filetype ==
"instcal":
86 with self.register.openRegistry(root, create=args.create, dryrun=args.dryrun)
as registry:
87 for infile
in args.files:
88 fileInfo, hduInfoList = self.parse.
getInfo(infile, args.filetype)
89 if len(hduInfoList) > 0:
90 outfileInstcal = os.path.join(root, self.parse.getDestination(args.butler,
93 outfileDqmask = os.path.join(root, self.parse.getDestination(args.butler,
94 hduInfoList[0], infile,
96 outfileWtmap = os.path.join(root, self.parse.getDestination(args.butler,
97 hduInfoList[0], infile,
100 ingestedInstcal = self.
ingest(fileInfo[
"instcal"], outfileInstcal,
101 mode=args.mode, dryrun=args.dryrun)
102 ingestedDqmask = self.
ingest(fileInfo[
"dqmask"], outfileDqmask,
103 mode=args.mode, dryrun=args.dryrun)
104 ingestedWtmap = self.
ingest(fileInfo[
"wtmap"], outfileWtmap,
105 mode=args.mode, dryrun=args.dryrun)
107 if not (ingestedInstcal
or ingestedDqmask
or ingestedWtmap):
110 for info
in hduInfoList:
111 self.register.addRow(registry, info, dryrun=args.dryrun, create=args.create)
113 elif args.filetype ==
"raw":
114 IngestTask.run(self, args)
118 """Parse an image filename to get the required information to
119 put the file in the correct location and populate the registry.
123 super(ParseTask, self).
__init__(*args, **kwargs)
133 def _listdir(self, path, prefix):
134 for file
in os.listdir(path):
135 fileName = os.path.join(path, file)
137 fix_header(md, translator_class=DecamTranslator)
138 if "EXPNUM" not in md.names():
140 expnum = md.getScalar(
"EXPNUM")
148 """Extract exposure numbers from filenames to set self.expnumMapper
153 Location on disk of instcal, dqmask, and wtmap subdirectories.
157 instcalPath = basepath
160 if instcalPath == dqmaskPath:
161 raise RuntimeError(
"instcal and mask directories are the same")
162 if instcalPath == wtmapPath:
163 raise RuntimeError(
"instcal and weight map directories are the same")
165 if not os.path.isdir(dqmaskPath):
166 raise OSError(
"Directory %s does not exist" % (dqmaskPath))
167 if not os.path.isdir(wtmapPath):
168 raise OSError(
"Directory %s does not exist" % (wtmapPath))
171 for path, prefix
in zip((instcalPath, dqmaskPath, wtmapPath),
176 """Get metadata header info from multi-extension FITS decam image file.
178 The science pixels, mask, and weight (inverse variance) are
179 stored in separate files each with a unique name but with a
180 common unique identifier EXPNUM in the FITS header. We have
181 to aggregate the 3 filenames for a given EXPNUM and return
182 this information along with that returned by the base class.
187 Image file to retrieve info from.
189 One of "raw" or "instcal".
194 Primary header unit info.
195 infoList : `list` of `dict`
196 Info for the other HDUs.
200 For filetype="instcal", we expect a directory structure that looks
209 The user creates the registry by running:
213 ingestImagesDecam.py outputRepository --filetype=instcal --mode=link instcal/*fits
215 if filetype ==
"instcal":
221 phuInfo, infoList = super(DecamParseTask, self).
getInfo(filename)
222 expnum = phuInfo[
"visit"]
226 for info
in infoList:
227 expnum = info[
"visit"]
232 elif filetype ==
"raw":
233 phuInfo, infoList = super(DecamParseTask, self).
getInfo(filename)
234 for info
in infoList:
242 for key
in (
"ccdnum",
"hdu",
"ccd",
"calib_hdu"):
243 if key
not in phuInfo:
246 return phuInfo, infoList
249 """Get destination for the file
253 butler : `lsst.daf.persistence.Butler`
256 File properties, used as dataId for the butler.
263 Destination filename.
265 raw = butler.get(
"%s_filename"%(filetype), info)[0]