diff --git a/doc/developer-guide/developer-guide.rst b/doc/developer-guide/developer-guide.rst
index 5e01b1bf..cbc47e0c 100644
--- a/doc/developer-guide/developer-guide.rst
+++ b/doc/developer-guide/developer-guide.rst
@@ -51,8 +51,6 @@ This module is a high-level module to use other modules.
:caption: Class diagram of wep
* **WfEstimator**: Calculate the wavefront error in annular Zernike polynomials up to 22 terms based on the defocal donut images.
-* **Utility**: Utility functions used in WEP.
-* **PlotUtil**: Plot utility functions used in WEP.
* **ParamReader**: Parameter reader class to read the yaml configuration files used in the calculation.
* **DonutImageCheck**: Donut image check class to judge the donut image is effective or not.
* **DonutDetector**: Detect donuts directly from an out of focus image by convolution with a template image.
@@ -71,7 +69,6 @@ This module calculates the wavefront error by solving the TIE.
* **CompensableImage**: Compensable image class to project the donut image from the image plane to the pupil plane.
* **Image**: Image class to have the function to get the donut center.
* **Instrument**: Instrument class to have the instrument information used in the Algorithm class to solve the TIE.
-* **Tool**: Annular Zernike polynomials related functions.
* **CentroidFindFactory**: Factory for creating the centroid find object to calculate the centroid of donut.
* **CentroidDefault**: Default centroid class.
* **CentroidRandomWalk**: CentroidDefault child class to get the centroid of donut by the random walk model.
@@ -144,6 +141,20 @@ This module has the tasks to run WEP as a pipeline with Gen 3 LSST DM middleware
* **GenerateDonutFromRefitWcsTaskConfig**: Configuration setup for GenerateDonutFromRefitWcsTask.
* **GenerateDonutCatalogUtils**: Common utility functions for the GenerateDonutCatalog...Tasks.
+.. _WEP_modules_wep_utils:
+
+wep.utils
+-------------
+
+This module contains utility functions that are used elsewhere in WEP.
+
+* **enumUtils**: Enum definitions and related functions.
+* **ioUtils**: Functions for reading and writing files.
+* **taskUtils**: Functions for running command line tasks from a python script.
+* **zernikeUtils**: Functions for evaluating and fitting Zernike polynomials.
+* **plotUtils**: Functions for plotting results.
+* **miscUtils**: Miscellaneous utility functions.
+
.. _WEP_API:
Python API reference
@@ -163,6 +174,9 @@ This section is autogenerated from docstrings.
.. automodapi:: lsst.ts.wep.task
:no-inheritance-diagram:
+.. automodapi:: lsst.ts.wep.utils
+ :no-inheritance-diagram:
+
.. _WEP_contributing:
Contributing
diff --git a/doc/versionHistory.rst b/doc/versionHistory.rst
index eee112cb..d6d3650b 100644
--- a/doc/versionHistory.rst
+++ b/doc/versionHistory.rst
@@ -5,6 +5,15 @@
##################
Version History
##################
+
+.. _lsst.ts.wep-7.0.0:
+
+-------------
+7.0.0
+-------------
+
+* Organize all utility functions inside the ``utils`` module.
+
.. _lsst.ts.wep-6.4.12:
-------------
diff --git a/python/lsst/ts/wep/__init__.py b/python/lsst/ts/wep/__init__.py
index 9ccac8a2..3246b1fc 100644
--- a/python/lsst/ts/wep/__init__.py
+++ b/python/lsst/ts/wep/__init__.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-from .utility import *
# This class needs the scons to build the cython code. In the Jenkins test,
# this will be a problem to import.
diff --git a/python/lsst/ts/wep/cwfs/__init__.py b/python/lsst/ts/wep/cwfs/__init__.py
index 49f51077..2db09b56 100644
--- a/python/lsst/ts/wep/cwfs/__init__.py
+++ b/python/lsst/ts/wep/cwfs/__init__.py
@@ -13,4 +13,3 @@
from .donutTemplatePhosim import *
from .image import *
from .instrument import *
-from .tool import *
diff --git a/python/lsst/ts/wep/cwfs/algorithm.py b/python/lsst/ts/wep/cwfs/algorithm.py
index fdac5c22..1a122f4b 100644
--- a/python/lsst/ts/wep/cwfs/algorithm.py
+++ b/python/lsst/ts/wep/cwfs/algorithm.py
@@ -27,15 +27,15 @@
import galsim
import numpy as np
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.cwfs.tool import (
+from lsst.ts.wep.paramReader import ParamReader
+from lsst.ts.wep.utils import (
+ DefocalType,
ZernikeAnnularEval,
ZernikeMaskedFit,
extractArray,
padArray,
+ plotZernike,
)
-from lsst.ts.wep.paramReader import ParamReader
-from lsst.ts.wep.plotUtil import plotZernike
-from lsst.ts.wep.utility import DefocalType
from scipy.ndimage import (
binary_dilation,
binary_erosion,
diff --git a/python/lsst/ts/wep/cwfs/baseCwfsTestCase.py b/python/lsst/ts/wep/cwfs/baseCwfsTestCase.py
index 08fc4414..e653676b 100644
--- a/python/lsst/ts/wep/cwfs/baseCwfsTestCase.py
+++ b/python/lsst/ts/wep/cwfs/baseCwfsTestCase.py
@@ -27,7 +27,7 @@
from lsst.ts.wep.cwfs.algorithm import Algorithm
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import DefocalType, getConfigDir
+from lsst.ts.wep.utils import DefocalType, getConfigDir
class BaseCwfsTestCase(object):
diff --git a/python/lsst/ts/wep/cwfs/centroidFindFactory.py b/python/lsst/ts/wep/cwfs/centroidFindFactory.py
index bccf0f0c..ca1e012f 100644
--- a/python/lsst/ts/wep/cwfs/centroidFindFactory.py
+++ b/python/lsst/ts/wep/cwfs/centroidFindFactory.py
@@ -24,7 +24,7 @@
from lsst.ts.wep.cwfs.centroidConvolveTemplate import CentroidConvolveTemplate
from lsst.ts.wep.cwfs.centroidOtsu import CentroidOtsu
from lsst.ts.wep.cwfs.centroidRandomWalk import CentroidRandomWalk
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
class CentroidFindFactory(object):
diff --git a/python/lsst/ts/wep/cwfs/compensableImage.py b/python/lsst/ts/wep/cwfs/compensableImage.py
index 34380795..3bfbc494 100644
--- a/python/lsst/ts/wep/cwfs/compensableImage.py
+++ b/python/lsst/ts/wep/cwfs/compensableImage.py
@@ -28,14 +28,17 @@
import numpy as np
from galsim.utilities import horner2d
from lsst.ts.wep.cwfs.image import Image
-from lsst.ts.wep.cwfs.tool import (
+from lsst.ts.wep.paramReader import ParamReader
+from lsst.ts.wep.utils import (
+ CentroidFindType,
+ DefocalType,
+ FilterType,
ZernikeAnnularGrad,
ZernikeAnnularJacobian,
extractArray,
padArray,
+ rotMatrix,
)
-from lsst.ts.wep.paramReader import ParamReader
-from lsst.ts.wep.utility import CentroidFindType, DefocalType, FilterType, rotMatrix
from scipy.interpolate import RectBivariateSpline
from scipy.ndimage import (
binary_dilation,
diff --git a/python/lsst/ts/wep/cwfs/donutTemplateFactory.py b/python/lsst/ts/wep/cwfs/donutTemplateFactory.py
index eeca981c..47ccbcc4 100644
--- a/python/lsst/ts/wep/cwfs/donutTemplateFactory.py
+++ b/python/lsst/ts/wep/cwfs/donutTemplateFactory.py
@@ -23,7 +23,7 @@
from lsst.ts.wep.cwfs.donutTemplateModel import DonutTemplateModel
from lsst.ts.wep.cwfs.donutTemplatePhosim import DonutTemplatePhosim
-from lsst.ts.wep.utility import DonutTemplateType
+from lsst.ts.wep.utils import DonutTemplateType
class DonutTemplateFactory(object):
diff --git a/python/lsst/ts/wep/cwfs/donutTemplateModel.py b/python/lsst/ts/wep/cwfs/donutTemplateModel.py
index 71ea8020..9f5198f6 100644
--- a/python/lsst/ts/wep/cwfs/donutTemplateModel.py
+++ b/python/lsst/ts/wep/cwfs/donutTemplateModel.py
@@ -27,7 +27,7 @@
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.donutTemplateDefault import DonutTemplateDefault
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import CamType, FilterType, getConfigDir, readPhoSimSettingData
+from lsst.ts.wep.utils import CamType, FilterType, getConfigDir, readPhoSimSettingData
class DonutTemplateModel(DonutTemplateDefault):
diff --git a/python/lsst/ts/wep/cwfs/donutTemplatePhosim.py b/python/lsst/ts/wep/cwfs/donutTemplatePhosim.py
index b25ec653..1770a06a 100644
--- a/python/lsst/ts/wep/cwfs/donutTemplatePhosim.py
+++ b/python/lsst/ts/wep/cwfs/donutTemplatePhosim.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.cwfs.donutTemplateDefault import DonutTemplateDefault
-from lsst.ts.wep.utility import DefocalType, getConfigDir
+from lsst.ts.wep.utils import DefocalType, getConfigDir
class DonutTemplatePhosim(DonutTemplateDefault):
diff --git a/python/lsst/ts/wep/cwfs/image.py b/python/lsst/ts/wep/cwfs/image.py
index 588207fc..9fb153a7 100644
--- a/python/lsst/ts/wep/cwfs/image.py
+++ b/python/lsst/ts/wep/cwfs/image.py
@@ -27,7 +27,7 @@
import numpy as np
from astropy.io import fits
from lsst.ts.wep.cwfs.centroidFindFactory import CentroidFindFactory
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
class Image(object):
diff --git a/python/lsst/ts/wep/cwfs/instrument.py b/python/lsst/ts/wep/cwfs/instrument.py
index 19f20df5..4f118d4b 100644
--- a/python/lsst/ts/wep/cwfs/instrument.py
+++ b/python/lsst/ts/wep/cwfs/instrument.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.paramReader import ParamReader
-from lsst.ts.wep.utility import CamType, getCamNameFromCamType, getConfigDir
+from lsst.ts.wep.utils import CamType, getCamNameFromCamType, getConfigDir
class Instrument(object):
diff --git a/python/lsst/ts/wep/deblend/deblendAdapt.py b/python/lsst/ts/wep/deblend/deblendAdapt.py
index 687a3b93..5f385571 100644
--- a/python/lsst/ts/wep/deblend/deblendAdapt.py
+++ b/python/lsst/ts/wep/deblend/deblendAdapt.py
@@ -25,7 +25,7 @@
from lsst.ts.wep.cwfs.centroidFindFactory import CentroidFindFactory
from lsst.ts.wep.deblend.deblendDefault import DeblendDefault
from lsst.ts.wep.deblend.nelderMeadModify import nelderMeadModify
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
from scipy.ndimage import (
binary_closing,
binary_erosion,
diff --git a/python/lsst/ts/wep/deblend/deblendDefault.py b/python/lsst/ts/wep/deblend/deblendDefault.py
index 9ae05d82..027279b0 100644
--- a/python/lsst/ts/wep/deblend/deblendDefault.py
+++ b/python/lsst/ts/wep/deblend/deblendDefault.py
@@ -23,7 +23,7 @@
import numpy as np
from lsst.ts.wep.cwfs.centroidFindFactory import CentroidFindFactory
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
class DeblendDefault(object):
diff --git a/python/lsst/ts/wep/deblend/deblendDonutFactory.py b/python/lsst/ts/wep/deblend/deblendDonutFactory.py
index e5c8376b..5f9550c3 100644
--- a/python/lsst/ts/wep/deblend/deblendDonutFactory.py
+++ b/python/lsst/ts/wep/deblend/deblendDonutFactory.py
@@ -22,7 +22,7 @@
__all__ = ["DeblendDonutFactory"]
from lsst.ts.wep.deblend.deblendAdapt import DeblendAdapt
-from lsst.ts.wep.utility import DeblendDonutType
+from lsst.ts.wep.utils import DeblendDonutType
class DeblendDonutFactory(object):
diff --git a/python/lsst/ts/wep/donutDetector.py b/python/lsst/ts/wep/donutDetector.py
index 8e5b0c57..0fa15a0a 100644
--- a/python/lsst/ts/wep/donutDetector.py
+++ b/python/lsst/ts/wep/donutDetector.py
@@ -27,7 +27,7 @@
import pandas as pd
from lsst.ts.wep.cwfs.centroidFindFactory import CentroidFindFactory
from lsst.ts.wep.deblend.deblendAdapt import DeblendAdapt
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
from scipy.spatial.distance import cdist
diff --git a/python/lsst/ts/wep/task/calcZernikesTask.py b/python/lsst/ts/wep/task/calcZernikesTask.py
index a60a0cb3..ddefcfe0 100644
--- a/python/lsst/ts/wep/task/calcZernikesTask.py
+++ b/python/lsst/ts/wep/task/calcZernikesTask.py
@@ -29,7 +29,7 @@
from lsst.pipe.base import connectionTypes
from lsst.ts.wep.task.combineZernikesSigmaClipTask import CombineZernikesSigmaClipTask
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
createInstDictFromConfig,
getCamTypeFromButlerName,
diff --git a/python/lsst/ts/wep/task/cutOutDonutsBase.py b/python/lsst/ts/wep/task/cutOutDonutsBase.py
index 24d1261c..d041ca89 100644
--- a/python/lsst/ts/wep/task/cutOutDonutsBase.py
+++ b/python/lsst/ts/wep/task/cutOutDonutsBase.py
@@ -36,7 +36,7 @@
from lsst.ts.wep.cwfs.instrument import Instrument
from lsst.ts.wep.task.donutStamp import DonutStamp
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DonutTemplateType,
createInstDictFromConfig,
getCamTypeFromButlerName,
diff --git a/python/lsst/ts/wep/task/cutOutDonutsCwfsTask.py b/python/lsst/ts/wep/task/cutOutDonutsCwfsTask.py
index be5462bd..48e04c7b 100644
--- a/python/lsst/ts/wep/task/cutOutDonutsCwfsTask.py
+++ b/python/lsst/ts/wep/task/cutOutDonutsCwfsTask.py
@@ -35,7 +35,7 @@
CutOutDonutsBaseTaskConnections,
)
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import DefocalType
+from lsst.ts.wep.utils import DefocalType
from lsst.utils.timer import timeMethod
diff --git a/python/lsst/ts/wep/task/cutOutDonutsScienceSensorTask.py b/python/lsst/ts/wep/task/cutOutDonutsScienceSensorTask.py
index 2289ba1e..b426a47e 100644
--- a/python/lsst/ts/wep/task/cutOutDonutsScienceSensorTask.py
+++ b/python/lsst/ts/wep/task/cutOutDonutsScienceSensorTask.py
@@ -39,7 +39,7 @@
CutOutDonutsBaseTaskConnections,
)
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import DefocalType
+from lsst.ts.wep.utils import DefocalType
from lsst.utils.timer import timeMethod
diff --git a/python/lsst/ts/wep/task/donutSourceSelectorTask.py b/python/lsst/ts/wep/task/donutSourceSelectorTask.py
index 03b13896..d85af5d2 100644
--- a/python/lsst/ts/wep/task/donutSourceSelectorTask.py
+++ b/python/lsst/ts/wep/task/donutSourceSelectorTask.py
@@ -32,7 +32,7 @@
from lsst.afw.cameraGeom import FIELD_ANGLE, PIXELS
from lsst.meas.algorithms.sourceSelector import _getFieldFromCatalog
from lsst.ts.wep.paramReader import ParamReader
-from lsst.ts.wep.utility import getConfigDir
+from lsst.ts.wep.utils import getConfigDir
from lsst.utils.timer import timeMethod
from sklearn.neighbors import NearestNeighbors
diff --git a/python/lsst/ts/wep/task/donutStamp.py b/python/lsst/ts/wep/task/donutStamp.py
index 17c0fa9f..4ef8bd6a 100644
--- a/python/lsst/ts/wep/task/donutStamp.py
+++ b/python/lsst/ts/wep/task/donutStamp.py
@@ -32,7 +32,7 @@
from lsst.afw.cameraGeom import FIELD_ANGLE, PIXELS
from lsst.meas.algorithms.stamps import AbstractStamp
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
-from lsst.ts.wep.utility import DefocalType, FilterType, getFilterTypeFromBandLabel
+from lsst.ts.wep.utils import DefocalType, FilterType, getFilterTypeFromBandLabel
@dataclass
diff --git a/python/lsst/ts/wep/task/generateDonutDirectDetectTask.py b/python/lsst/ts/wep/task/generateDonutDirectDetectTask.py
index b7bfac2d..2b1395d5 100644
--- a/python/lsst/ts/wep/task/generateDonutDirectDetectTask.py
+++ b/python/lsst/ts/wep/task/generateDonutDirectDetectTask.py
@@ -34,7 +34,7 @@
from lsst.ts.wep.cwfs.donutTemplateFactory import DonutTemplateFactory
from lsst.ts.wep.task.donutQuickMeasurementTask import DonutQuickMeasurementTask
from lsst.ts.wep.task.donutSourceSelectorTask import DonutSourceSelectorTask
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
DonutTemplateType,
createInstDictFromConfig,
diff --git a/python/lsst/ts/wep/utility.py b/python/lsst/ts/wep/utility.py
deleted file mode 100644
index a10e3137..00000000
--- a/python/lsst/ts/wep/utility.py
+++ /dev/null
@@ -1,767 +0,0 @@
-# This file is part of ts_wep.
-#
-# Developed for the LSST Telescope and Site Systems.
-# This product includes software developed by the LSST Project
-# (https://www.lsst.org).
-# See the COPYRIGHT file at the top-level directory of this distribution
-# for details of code ownership.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-__all__ = [
- "FilterType",
- "CamType",
- "BscDbType",
- "DefocalType",
- "ImageType",
- "CentroidFindType",
- "DonutTemplateType",
- "DeblendDonutType",
- "getModulePath",
- "getConfigDir",
- "getObsLsstCmdTaskConfigDir",
- "runProgram",
- "searchDonutPos",
- "writeFile",
- "readPhoSimSettingData",
- "mapFilterRefToG",
- "getBscDbType",
- "getImageType",
- "getCentroidFindType",
- "getDeblendDonutType",
- "getDonutTemplateType",
- "getAmpImagesFromDir",
- "writePipetaskCmd",
- "writeCleanUpRepoCmd",
- "getCamType",
- "getCamTypeFromButlerName",
- "getDefocalDisInMm",
-]
-
-import os
-import re
-import subprocess
-from enum import IntEnum, auto
-
-import numpy as np
-from lsst.afw.cameraGeom import DetectorType
-from lsst.utils import getPackageDir
-from scipy.ndimage import center_of_mass
-
-
-class FilterType(IntEnum):
- LSST_U = 1
- LSST_G = auto()
- LSST_R = auto()
- LSST_I = auto()
- LSST_Z = auto()
- LSST_Y = auto()
- REF = auto()
-
-
-class CamType(IntEnum):
- LsstCam = 1
- LsstFamCam = auto()
- ComCam = auto()
- AuxTel = auto()
- AuxTelZWO = auto()
-
-
-class BscDbType(IntEnum):
- LocalDb = 1
- LocalDbForStarFile = auto()
-
-
-class DefocalType(IntEnum):
- Intra = 1
- Extra = auto()
-
-
-class ImageType(IntEnum):
- Amp = 1
- Eimg = auto()
-
-
-class CentroidFindType(IntEnum):
- RandomWalk = 1
- Otsu = auto()
- ConvolveTemplate = auto()
-
-
-class DonutTemplateType(IntEnum):
- Model = 1
- Phosim = auto()
-
-
-class DeblendDonutType(IntEnum):
- Adapt = 1
-
-
-def getModulePath():
- """Get the path of module.
-
- Returns
- -------
- str
- Directory path of module.
- """
-
- return getPackageDir("ts_wep")
-
-
-def getConfigDir():
- """Get the directory of configuration files.
-
- Returns
- -------
- str
- Directory of configuration files.
- """
-
- return os.path.join(getModulePath(), "policy")
-
-
-def getObsLsstCmdTaskConfigDir():
- """Get the obs_lsst command line task configuration directory.
-
- Returns
- -------
- str
- obs_lsst command line task configuration directory.
- """
-
- return os.path.join(getPackageDir("obs_lsst"), "config")
-
-
-def runProgram(command, binDir=None, argstring=None):
- """Run the program w/o arguments.
-
- Parameters
- ----------
- command : str
- Command of application.
- binDir : str, optional
- Directory of binary application. (the default is None.)
- argstring : str, optional
- Arguments of program. (the default is None.)
-
- Raises
- ------
- RuntimeError
- Error running of command.
- """
-
- # Directory of binary application
- if binDir is not None:
- command = os.path.join(binDir, command)
-
- # Arguments for the program
- if argstring is not None:
- command += " " + argstring
-
- # Call the program w/o arguments
- if subprocess.call(command, shell=True) != 0:
- raise RuntimeError("Error running: %s" % command)
-
-
-def searchDonutPos(img):
- """Search the position of donut on image.
-
- Parameters
- ----------
- img : numpy.ndarray
- Donut image.
-
- Returns
- -------
- float
- X position of donut center in pixel.
- float
- Y position of donut center in pixel.
- """
-
- # Search the donut position by the center of mass
- # Need to update this method to the more robust one such as the convolution
- realcy, realcx = center_of_mass(img)
-
- return realcx, realcy
-
-
-def writeFile(filePath, content):
- """Write the content to file.
-
- Parameters
- ----------
- filePath : str
- File path.
- content : str
- File content.
- """
-
- with open(filePath, "w") as file:
- file.write(content)
-
-
-def readPhoSimSettingData(folderPath, fileName, atype):
- """Read the PhoSim setting data (segmentation or focal plane layout).
-
- Parameters
- ----------
- folderPath : str
- Path to folder.
- fileName : str
- File name ("segmentation.txt", "focalplanelayout.txt").
- atype : str
- Type of data to read ("readOutDim", "darkCurrent", "fieldCenter",
- "eulerRot").
-
- Returns
- -------
- dict
- Needed CCD data.
-
- Raises
- ------
- ValueError
- File can not be read.
- ValueError
- Type is not correct.
- """
-
- # Check the file name
- if fileName not in ("segmentation.txt", "focalplanelayout.txt"):
- raise ValueError("'%s' can not be read." % fileName)
-
- # Check the type
- if atype not in ("readOutDim", "darkCurrent", "fieldCenter", "eulerRot"):
- raise ValueError("'%s' can not be read." % atype)
-
- # Get the file path
- pathToFile = os.path.join(folderPath, fileName)
-
- # Amplifier list (only list the scientific ccd here)
- ampList = [
- "C00",
- "C01",
- "C02",
- "C03",
- "C04",
- "C05",
- "C06",
- "C07",
- "C10",
- "C11",
- "C12",
- "C13",
- "C14",
- "C15",
- "C16",
- "C17",
- ]
-
- # Open the file to read
- ccdData = {}
- fid = open(pathToFile)
- for line in fid:
- line = line.strip()
-
- # Get each element
- lineElement = line.split()
-
- data = []
- # Analyze the sensor name to find the amplifier
- if fileName == "segmentation.txt":
- sensorNameStr = lineElement[0].split("_")
- if len(sensorNameStr) == 3:
- if sensorNameStr[2] in ampList:
- # Get the segmentation in txt file
- if atype == "readOutDim":
- # parallel prescan, serial overscan, serial prescan,
- # parallel overscan (pixel)
- data = lineElement[15:19]
- elif atype == "darkCurrent":
- data = lineElement[13:15]
-
- elif fileName == "focalplanelayout.txt":
- # Analyze the sensor name to make sure this line of data is
- # needed
- sensorNameStr = lineElement[0].split("_")
- if len(sensorNameStr) == 2 or len(sensorNameStr) == 3:
- if atype == "fieldCenter":
- # Collect the field center:
- # x position (microns), y position (microns), pixel
- # size (microns) number of x pixels, number of y pixels
- data = lineElement[1:6]
- elif atype == "eulerRot":
- # Collect the euler Rotation (degrees)
- data = lineElement[12:15]
-
- # Collect the data
- if data:
- ccdData.update({lineElement[0]: data})
-
- # Close the file
- fid.close()
-
- return ccdData
-
-
-def mapFilterRefToG(filterType):
- """Map the reference filter to the G filter.
-
- Parameters
- ----------
- filterType : enum 'FilterType'
- Filter type.
-
- Returns
- -------
- enum 'FilterType'
- Mapped filter type.
- """
-
- if filterType == FilterType.REF:
- return FilterType.LSST_G
- else:
- return filterType
-
-
-def getBscDbType(bscDbType):
- """Get the bright star catalog (BSC) database type.
-
- Parameters
- ----------
- bscDbType : str
- BSC database type to use (localDb or file).
-
- Returns
- -------
- enum 'BscDbType'
- BSC database type.
-
- Raises
- ------
- ValueError
- The bscDb is not supported.
- """
-
- if bscDbType == "localDb":
- return BscDbType.LocalDb
- elif bscDbType == "file":
- return BscDbType.LocalDbForStarFile
- else:
- raise ValueError("The bscDb (%s) is not supported." % bscDbType)
-
-
-def getImageType(imageType):
- """Get the image type.
-
- Parameters
- ----------
- imageType : str
- Image type to use (amp or eimage).
-
- Returns
- -------
- enum 'ImageType'
- ImageType enum.
-
- Raises
- ------
- ValueError
- The image type is not supported.
- """
-
- if imageType == "amp":
- return ImageType.Amp
- elif imageType == "eimage":
- return ImageType.Eimg
- else:
- raise ValueError("The %s is not supported." % imageType)
-
-
-def getCentroidFindType(centroidFindType):
- """Get the centroid find type.
-
- Parameters
- ----------
- centroidFindType : str
- Centroid find algorithm to use (randomWalk, otsu, or convolveTemplate).
-
- Returns
- -------
- enum 'CentroidFindType'
- Centroid find type algorithm.
-
- Raises
- ------
- ValueError
- The centroid find type is not supported.
- """
-
- if centroidFindType == "randomWalk":
- return CentroidFindType.RandomWalk
- elif centroidFindType == "otsu":
- return CentroidFindType.Otsu
- elif centroidFindType == "convolveTemplate":
- return CentroidFindType.ConvolveTemplate
- else:
- raise ValueError("The %s is not supported." % centroidFindType)
-
-
-def getDeblendDonutType(deblendDonutType):
- """Get the deblend donut type.
-
- Parameters
- ----------
- deblendDonutType : str
- Deblend donut algorithm to use (adapt).
-
- Returns
- -------
- enum 'DeblendDonutType'
- Deblend donut type algorithm.
-
- Raises
- ------
- ValueError
- The deblend donut type is not supported.
- """
-
- if deblendDonutType == "adapt":
- return DeblendDonutType.Adapt
- else:
- raise ValueError("The %s is not supported." % deblendDonutType)
-
-
-def getDonutTemplateType(donutTemplateType):
- """Get the donut template type.
-
- Parameters
- ----------
- donutTemplateType : str
- Donut template type to use (model or phosim).
-
- Returns
- -------
- enum 'DonutTemplateType'
- Donut template type algorithm.
-
- Raises
- ------
- ValueError
- The donut template type is not supported.
- """
-
- if donutTemplateType == "model":
- return DonutTemplateType.Model
- elif donutTemplateType == "phosim":
- return DonutTemplateType.Phosim
- else:
- raise ValueError(f"The {donutTemplateType} is not supported.")
-
-
-def getAmpImagesFromDir(rawExpDir):
- """Apply regular expression to find
- repackaged amplifier image files.
- Use the negative lookahead to find those
- fits files that do not contain '_e' in their name.
-
- Parameters
- ----------
- rawExpDir : str
- path to the input directory with raw repackaged files
-
- Returns
- -------
- list [str]
- raw amplifier image files
- """
- return list(filter(re.compile(r"^((?!_e).)*fits$").match, os.listdir(rawExpDir)))
-
-
-def writePipetaskCmd(
- repoDir, runName, instrument, collections, taskName=None, pipelineYaml=None
-):
- """
- Format a command line call to run a Gen 3 pipeline task.
- Can also be a set of tasks if specified in a pipeline yaml file.
-
- Parameters
- ----------
- repoDir: str
- Location of Gen 3 repository.
- runName: str
- Name of collection for data produced by the task.
- instrument: str
- The instrument to use for the task.
- collections: str
- The data collections needed for the task.
- taskName: str, optional
- Full task function name in lsst namespace. One of taskName
- or pipelineYaml must be specified to run. (The default is None).
- pipelineYaml: str, optional
- Yaml file that specifies a pipeline configuration to run
- instead of a single task. (The default is None.)
-
- Returns
- -------
- str
- Pipetask run command.
-
- Raises
- ------
- ValueError
- Need to at least specify name of task or name of pipeline file.
- """
- if (taskName is None) and (pipelineYaml is None):
- raise ValueError("At least one of taskName or pipelineYaml must not be None")
-
- pipetaskCmd = "pipetask run "
- pipetaskCmd += f"-b {repoDir} " # Specify repo
- pipetaskCmd += f"-i {collections} " # Specify collections with data to use
- pipetaskCmd += f"--instrument {instrument} "
- pipetaskCmd += f"--register-dataset-types --output-run {runName}"
- if taskName is not None:
- pipetaskCmd += f" -t {taskName}"
- if pipelineYaml is not None:
- pipetaskCmd += f" -p {pipelineYaml}"
-
- return pipetaskCmd
-
-
-def writeCleanUpRepoCmd(repoDir, runName):
- """
- Format a command line call to clean up the data created by a pipeline.
-
- Parameters
- ----------
- repoDir: str
- Location of Gen 3 repository.
- runName: str
- Name of collection for data produced by the task.
-
- Returns
- -------
- str
- Butler prune-collection command.
- """
-
- cleanUpCmd = "butler remove-runs "
- cleanUpCmd += f"{repoDir} {runName} --no-confirm"
-
- return cleanUpCmd
-
-
-def getCamType(instName):
- """Get the camera type from instrument name.
-
- Parameters
- ----------
- instName : str
- Instrument name.
-
- Returns
- -------
- camType : enum 'CamType'
- Camera type.
-
- Raises
- ------
- ValueError
- Instrument name is not supported.
- """
- if instName == "lsst":
- return CamType.LsstCam
- elif instName == "lsstfam":
- return CamType.LsstFamCam
- elif instName == "comcam":
- return CamType.ComCam
- elif instName == "auxTel":
- return CamType.AuxTel
- else:
- raise ValueError(f"Instrument name ({instName}) is not supported.")
-
-
-def getCamNameFromCamType(camType):
- """Get the camera name for policy files from CamType.
-
- Parameters
- ----------
- camType : enum 'CamType'
- Camera Type.
-
- Returns
- -------
- str
- Instrument Name.
-
- Raises
- ------
- ValueError
- Camera Type is not supported.
- """
-
- if camType == CamType.LsstCam:
- return "lsst"
- elif camType == CamType.LsstFamCam:
- return "lsstfam"
- elif camType == CamType.ComCam:
- return "comcam"
- elif camType == CamType.AuxTel:
- return "auxTel"
- elif camType == CamType.AuxTelZWO:
- return "auxTelZWO"
- else:
- raise ValueError(f"CamType ({camType}) is not supported.")
-
-
-def getCamTypeFromButlerName(instName, detectorType):
- """Get the camera type from instrument name used by the LSST DM
- middleware for each instrument.
-
- Parameters
- ----------
- instName : str
- Instrument name.
- detectorType : lsst.afw.cameraGeom.DetectorType
- Type of CCD. "SCIENCE" or "WAVEFRONT".
-
- Returns
- -------
- camType : enum 'CamType'
- Camera type.
-
- Raises
- ------
- ValueError
- Combination of instrument name and detector type is not supported.
- ValueError
- Detector type is not supported.
- """
- if detectorType == DetectorType.WAVEFRONT:
- if instName == "LSSTCam":
- return CamType.LsstCam
- else:
- raise ValueError(
- f"Wavefront sensors for instrument name ({instName}) are not supported."
- )
- elif detectorType == DetectorType.SCIENCE:
- if instName == "LSSTCam":
- return CamType.LsstFamCam
- elif instName == "LSSTComCam":
- return CamType.ComCam
- elif instName == "LATISS":
- return CamType.AuxTel
- else:
- raise ValueError(
- f"Science sensors for instrument name ({instName}) are not supported."
- )
- else:
- raise ValueError(f"Detector Type ({detectorType.name}) is not supported.")
-
-
-def getFilterTypeFromBandLabel(bandLabel):
- """Get the FilterType associated with the name of the bandpass
- accessed in an exposure using `exposure.filter.bandLabel`.
-
- Parameters
- ----------
- bandLabel : str
- Bandpass label of the exposure.
-
- Returns
- -------
- filterType : enum `FilterType`
- Filter type.
- """
- filterLabelDict = {}
- filterLabelDict["u"] = FilterType.LSST_U
- filterLabelDict["g"] = FilterType.LSST_G
- filterLabelDict["r"] = FilterType.LSST_R
- filterLabelDict["i"] = FilterType.LSST_I
- filterLabelDict["z"] = FilterType.LSST_Z
- filterLabelDict["y"] = FilterType.LSST_Y
-
- return filterLabelDict.get(bandLabel, FilterType.REF)
-
-
-def getDefocalDisInMm(instName):
- """
- Get the defocal distance for the instrument
-
- Parameters
- ----------
- instName : str
- Instrument name, one of
- 'lsst', 'lsstfam', 'comcam',
- 'auxTel'
-
- Returns
- -------
- defocalDisInMm : float
- Defocal distance in mm.
-
- Raises
- ------
- ValueError
- Instrument name is not supported.
- """
- if instName in ["lsst", "lsstfam", "comcam"]:
- return 1.5
- elif instName == "auxTel":
- return 0.8
- else:
- raise ValueError(f"Instrument name ({instName}) is not supported.")
-
-
-def createInstDictFromConfig(config):
- """Create configuration dictionary for the instrument.
-
- Parameters
- ----------
- config : lsst.pipe.base.PipelineTaskConfig
- Task configuration.
-
- Returns
- -------
- dict
- Instrument configuration parameters
- """
-
- return {
- "obscuration": config.instObscuration,
- "focalLength": config.instFocalLength,
- "apertureDiameter": config.instApertureDiameter,
- "offset": config.instDefocalOffset,
- "pixelSize": config.instPixelSize,
- }
-
-
-def rotMatrix(thetaDegrees):
- """Create a 2-d rotation matrix for given angle.
-
- Parameters
- ----------
- thetaDegrees : float
- Rotation angle in degrees.
-
- Returns
- -------
- np.ndarray
- Rotation matrix for theta.
- """
-
- theta = np.radians(thetaDegrees)
- return np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
diff --git a/python/lsst/ts/wep/utils/__init__.py b/python/lsst/ts/wep/utils/__init__.py
new file mode 100644
index 00000000..1498f37c
--- /dev/null
+++ b/python/lsst/ts/wep/utils/__init__.py
@@ -0,0 +1,6 @@
+from .enumUtils import *
+from .ioUtils import *
+from .miscUtils import *
+from .plotUtils import *
+from .taskUtils import *
+from .zernikeUtils import *
diff --git a/python/lsst/ts/wep/utils/enumUtils.py b/python/lsst/ts/wep/utils/enumUtils.py
new file mode 100644
index 00000000..30fab0a4
--- /dev/null
+++ b/python/lsst/ts/wep/utils/enumUtils.py
@@ -0,0 +1,381 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+__all__ = [
+ "FilterType",
+ "CamType",
+ "BscDbType",
+ "DefocalType",
+ "ImageType",
+ "CentroidFindType",
+ "DonutTemplateType",
+ "DeblendDonutType",
+ "getFilterTypeFromBandLabel",
+ "mapFilterRefToG",
+ "getCamType",
+ "getCamNameFromCamType",
+ "getCamTypeFromButlerName",
+ "getBscDbType",
+ "getImageType",
+ "getCentroidFindType",
+ "getDonutTemplateType",
+ "getDeblendDonutType",
+]
+
+from enum import IntEnum, auto
+
+from lsst.afw.cameraGeom import DetectorType
+
+
+class FilterType(IntEnum):
+ LSST_U = 1
+ LSST_G = auto()
+ LSST_R = auto()
+ LSST_I = auto()
+ LSST_Z = auto()
+ LSST_Y = auto()
+ REF = auto()
+
+
+class CamType(IntEnum):
+ LsstCam = 1
+ LsstFamCam = auto()
+ ComCam = auto()
+ AuxTel = auto()
+ AuxTelZWO = auto()
+
+
+class BscDbType(IntEnum):
+ LocalDb = 1
+ LocalDbForStarFile = auto()
+
+
+class DefocalType(IntEnum):
+ Intra = 1
+ Extra = auto()
+
+
+class ImageType(IntEnum):
+ Amp = 1
+ Eimg = auto()
+
+
+class CentroidFindType(IntEnum):
+ RandomWalk = 1
+ Otsu = auto()
+ ConvolveTemplate = auto()
+
+
+class DonutTemplateType(IntEnum):
+ Model = 1
+ Phosim = auto()
+
+
+class DeblendDonutType(IntEnum):
+ Adapt = 1
+
+
+def getFilterTypeFromBandLabel(bandLabel):
+ """Get the FilterType associated with the name of the bandpass
+ accessed in an exposure using `exposure.filter.bandLabel`.
+
+ Parameters
+ ----------
+ bandLabel : str
+ Bandpass label of the exposure.
+
+ Returns
+ -------
+ filterType : enum `FilterType`
+ Filter type.
+ """
+ filterLabelDict = {}
+ filterLabelDict["u"] = FilterType.LSST_U
+ filterLabelDict["g"] = FilterType.LSST_G
+ filterLabelDict["r"] = FilterType.LSST_R
+ filterLabelDict["i"] = FilterType.LSST_I
+ filterLabelDict["z"] = FilterType.LSST_Z
+ filterLabelDict["y"] = FilterType.LSST_Y
+
+ return filterLabelDict.get(bandLabel, FilterType.REF)
+
+
+def mapFilterRefToG(filterType):
+ """Map the reference filter to the G filter.
+
+ Parameters
+ ----------
+ filterType : enum 'FilterType'
+ Filter type.
+
+ Returns
+ -------
+ enum 'FilterType'
+ Mapped filter type.
+ """
+
+ if filterType == FilterType.REF:
+ return FilterType.LSST_G
+ else:
+ return filterType
+
+
+def getCamType(instName):
+ """Get the camera type from instrument name.
+
+ Parameters
+ ----------
+ instName : str
+ Instrument name.
+
+ Returns
+ -------
+ camType : enum 'CamType'
+ Camera type.
+
+ Raises
+ ------
+ ValueError
+ Instrument name is not supported.
+ """
+ if instName == "lsst":
+ return CamType.LsstCam
+ elif instName == "lsstfam":
+ return CamType.LsstFamCam
+ elif instName == "comcam":
+ return CamType.ComCam
+ elif instName == "auxTel":
+ return CamType.AuxTel
+ else:
+ raise ValueError(f"Instrument name ({instName}) is not supported.")
+
+
+def getCamNameFromCamType(camType):
+ """Get the camera name for policy files from CamType.
+
+ Parameters
+ ----------
+ camType : enum 'CamType'
+ Camera Type.
+
+ Returns
+ -------
+ str
+ Instrument Name.
+
+ Raises
+ ------
+ ValueError
+ Camera Type is not supported.
+ """
+
+ if camType == CamType.LsstCam:
+ return "lsst"
+ elif camType == CamType.LsstFamCam:
+ return "lsstfam"
+ elif camType == CamType.ComCam:
+ return "comcam"
+ elif camType == CamType.AuxTel:
+ return "auxTel"
+ elif camType == CamType.AuxTelZWO:
+ return "auxTelZWO"
+ else:
+ raise ValueError(f"CamType ({camType}) is not supported.")
+
+
+def getCamTypeFromButlerName(instName, detectorType):
+ """Get the camera type from instrument name used by the LSST DM
+ middleware for each instrument.
+
+ Parameters
+ ----------
+ instName : str
+ Instrument name.
+ detectorType : lsst.afw.cameraGeom.DetectorType
+ Type of CCD. "SCIENCE" or "WAVEFRONT".
+
+ Returns
+ -------
+ camType : enum 'CamType'
+ Camera type.
+
+ Raises
+ ------
+ ValueError
+ Combination of instrument name and detector type is not supported.
+ ValueError
+ Detector type is not supported.
+ """
+ if detectorType == DetectorType.WAVEFRONT:
+ if instName == "LSSTCam":
+ return CamType.LsstCam
+ else:
+ raise ValueError(
+ f"Wavefront sensors for instrument name ({instName}) are not supported."
+ )
+ elif detectorType == DetectorType.SCIENCE:
+ if instName == "LSSTCam":
+ return CamType.LsstFamCam
+ elif instName == "LSSTComCam":
+ return CamType.ComCam
+ elif instName == "LATISS":
+ return CamType.AuxTel
+ else:
+ raise ValueError(
+ f"Science sensors for instrument name ({instName}) are not supported."
+ )
+ else:
+ raise ValueError(f"Detector Type ({detectorType.name}) is not supported.")
+
+
+def getBscDbType(bscDbType):
+ """Get the bright star catalog (BSC) database type.
+
+ Parameters
+ ----------
+ bscDbType : str
+ BSC database type to use (localDb or file).
+
+ Returns
+ -------
+ enum 'BscDbType'
+ BSC database type.
+
+ Raises
+ ------
+ ValueError
+ The bscDb is not supported.
+ """
+
+ if bscDbType == "localDb":
+ return BscDbType.LocalDb
+ elif bscDbType == "file":
+ return BscDbType.LocalDbForStarFile
+ else:
+ raise ValueError("The bscDb (%s) is not supported." % bscDbType)
+
+
+def getImageType(imageType):
+ """Get the image type.
+
+ Parameters
+ ----------
+ imageType : str
+ Image type to use (amp or eimage).
+
+ Returns
+ -------
+ enum 'ImageType'
+ ImageType enum.
+
+ Raises
+ ------
+ ValueError
+ The image type is not supported.
+ """
+
+ if imageType == "amp":
+ return ImageType.Amp
+ elif imageType == "eimage":
+ return ImageType.Eimg
+ else:
+ raise ValueError("The %s is not supported." % imageType)
+
+
+def getCentroidFindType(centroidFindType):
+ """Get the centroid find type.
+
+ Parameters
+ ----------
+ centroidFindType : str
+ Centroid find algorithm to use (randomWalk, otsu, or convolveTemplate).
+
+ Returns
+ -------
+ enum 'CentroidFindType'
+ Centroid find type algorithm.
+
+ Raises
+ ------
+ ValueError
+ The centroid find type is not supported.
+ """
+
+ if centroidFindType == "randomWalk":
+ return CentroidFindType.RandomWalk
+ elif centroidFindType == "otsu":
+ return CentroidFindType.Otsu
+ elif centroidFindType == "convolveTemplate":
+ return CentroidFindType.ConvolveTemplate
+ else:
+ raise ValueError("The %s is not supported." % centroidFindType)
+
+
+def getDonutTemplateType(donutTemplateType):
+ """Get the donut template type.
+
+ Parameters
+ ----------
+ donutTemplateType : str
+ Donut template type to use (model or phosim).
+
+ Returns
+ -------
+ enum 'DonutTemplateType'
+ Donut template type algorithm.
+
+ Raises
+ ------
+ ValueError
+ The donut template type is not supported.
+ """
+
+ if donutTemplateType == "model":
+ return DonutTemplateType.Model
+ elif donutTemplateType == "phosim":
+ return DonutTemplateType.Phosim
+ else:
+ raise ValueError(f"The {donutTemplateType} is not supported.")
+
+
+def getDeblendDonutType(deblendDonutType):
+ """Get the deblend donut type.
+
+ Parameters
+ ----------
+ deblendDonutType : str
+ Deblend donut algorithm to use (adapt).
+
+ Returns
+ -------
+ enum 'DeblendDonutType'
+ Deblend donut type algorithm.
+
+ Raises
+ ------
+ ValueError
+ The deblend donut type is not supported.
+ """
+
+ if deblendDonutType == "adapt":
+ return DeblendDonutType.Adapt
+ else:
+ raise ValueError("The %s is not supported." % deblendDonutType)
diff --git a/python/lsst/ts/wep/utils/ioUtils.py b/python/lsst/ts/wep/utils/ioUtils.py
new file mode 100644
index 00000000..0b620f9a
--- /dev/null
+++ b/python/lsst/ts/wep/utils/ioUtils.py
@@ -0,0 +1,208 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+__all__ = [
+ "getModulePath",
+ "getConfigDir",
+ "getObsLsstCmdTaskConfigDir",
+ "writeFile",
+ "readPhoSimSettingData",
+ "getAmpImagesFromDir",
+]
+
+import os
+import re
+
+from lsst.utils import getPackageDir
+
+
+def getModulePath():
+ """Get the path of module.
+
+ Returns
+ -------
+ str
+ Directory path of module.
+ """
+
+ return getPackageDir("ts_wep")
+
+
+def getConfigDir():
+ """Get the directory of configuration files.
+
+ Returns
+ -------
+ str
+ Directory of configuration files.
+ """
+
+ return os.path.join(getModulePath(), "policy")
+
+
+def getObsLsstCmdTaskConfigDir():
+ """Get the obs_lsst command line task configuration directory.
+
+ Returns
+ -------
+ str
+ obs_lsst command line task configuration directory.
+ """
+
+ return os.path.join(getPackageDir("obs_lsst"), "config")
+
+
+def writeFile(filePath, content):
+ """Write the content to file.
+
+ Parameters
+ ----------
+ filePath : str
+ File path.
+ content : str
+ File content.
+ """
+
+ with open(filePath, "w") as file:
+ file.write(content)
+
+
+def readPhoSimSettingData(folderPath, fileName, atype):
+ """Read the PhoSim setting data (segmentation or focal plane layout).
+
+ Parameters
+ ----------
+ folderPath : str
+ Path to folder.
+ fileName : str
+ File name ("segmentation.txt", "focalplanelayout.txt").
+ atype : str
+ Type of data to read ("readOutDim", "darkCurrent", "fieldCenter",
+ "eulerRot").
+
+ Returns
+ -------
+ dict
+ Needed CCD data.
+
+ Raises
+ ------
+ ValueError
+ File can not be read.
+ ValueError
+ Type is not correct.
+ """
+
+ # Check the file name
+ if fileName not in ("segmentation.txt", "focalplanelayout.txt"):
+ raise ValueError("'%s' can not be read." % fileName)
+
+ # Check the type
+ if atype not in ("readOutDim", "darkCurrent", "fieldCenter", "eulerRot"):
+ raise ValueError("'%s' can not be read." % atype)
+
+ # Get the file path
+ pathToFile = os.path.join(folderPath, fileName)
+
+ # Amplifier list (only list the scientific ccd here)
+ ampList = [
+ "C00",
+ "C01",
+ "C02",
+ "C03",
+ "C04",
+ "C05",
+ "C06",
+ "C07",
+ "C10",
+ "C11",
+ "C12",
+ "C13",
+ "C14",
+ "C15",
+ "C16",
+ "C17",
+ ]
+
+ # Open the file to read
+ ccdData = {}
+ fid = open(pathToFile)
+ for line in fid:
+ line = line.strip()
+
+ # Get each element
+ lineElement = line.split()
+
+ data = []
+ # Analyze the sensor name to find the amplifier
+ if fileName == "segmentation.txt":
+ sensorNameStr = lineElement[0].split("_")
+ if len(sensorNameStr) == 3:
+ if sensorNameStr[2] in ampList:
+ # Get the segmentation in txt file
+ if atype == "readOutDim":
+ # parallel prescan, serial overscan, serial prescan,
+ # parallel overscan (pixel)
+ data = lineElement[15:19]
+ elif atype == "darkCurrent":
+ data = lineElement[13:15]
+
+ elif fileName == "focalplanelayout.txt":
+ # Analyze the sensor name to make sure this line of data is
+ # needed
+ sensorNameStr = lineElement[0].split("_")
+ if len(sensorNameStr) == 2 or len(sensorNameStr) == 3:
+ if atype == "fieldCenter":
+ # Collect the field center:
+ # x position (microns), y position (microns), pixel
+ # size (microns) number of x pixels, number of y pixels
+ data = lineElement[1:6]
+ elif atype == "eulerRot":
+ # Collect the euler Rotation (degrees)
+ data = lineElement[12:15]
+
+ # Collect the data
+ if data:
+ ccdData.update({lineElement[0]: data})
+
+ # Close the file
+ fid.close()
+
+ return ccdData
+
+
+def getAmpImagesFromDir(rawExpDir):
+ """Apply regular expression to find
+ repackaged amplifier image files.
+ Use the negative lookahead to find those
+ fits files that do not contain '_e' in their name.
+
+ Parameters
+ ----------
+ rawExpDir : str
+ path to the input directory with raw repackaged files
+
+ Returns
+ -------
+ list [str]
+ raw amplifier image files
+ """
+ return list(filter(re.compile(r"^((?!_e).)*fits$").match, os.listdir(rawExpDir)))
diff --git a/python/lsst/ts/wep/utils/miscUtils.py b/python/lsst/ts/wep/utils/miscUtils.py
new file mode 100644
index 00000000..228b1cff
--- /dev/null
+++ b/python/lsst/ts/wep/utils/miscUtils.py
@@ -0,0 +1,216 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+__all__ = [
+ "searchDonutPos",
+ "getDefocalDisInMm",
+ "createInstDictFromConfig",
+ "rotMatrix",
+ "padArray",
+ "extractArray",
+]
+
+import numpy as np
+from scipy.ndimage import center_of_mass
+
+
+def searchDonutPos(img):
+ """Search the position of donut on image.
+
+ Parameters
+ ----------
+ img : numpy.ndarray
+ Donut image.
+
+ Returns
+ -------
+ float
+ X position of donut center in pixel.
+ float
+ Y position of donut center in pixel.
+ """
+
+ # Search the donut position by the center of mass
+ # Need to update this method to the more robust one such as the convolution
+ realcy, realcx = center_of_mass(img)
+
+ return realcx, realcy
+
+
+def getDefocalDisInMm(instName):
+ """
+ Get the defocal distance for the instrument
+
+ Parameters
+ ----------
+ instName : str
+ Instrument name, one of
+ 'lsst', 'lsstfam', 'comcam',
+ 'auxTel'
+
+ Returns
+ -------
+ defocalDisInMm : float
+ Defocal distance in mm.
+
+ Raises
+ ------
+ ValueError
+ Instrument name is not supported.
+ """
+ if instName in ["lsst", "lsstfam", "comcam"]:
+ return 1.5
+ elif instName == "auxTel":
+ return 0.8
+ else:
+ raise ValueError(f"Instrument name ({instName}) is not supported.")
+
+
+def createInstDictFromConfig(config):
+ """Create configuration dictionary for the instrument.
+
+ Parameters
+ ----------
+ config : lsst.pipe.base.PipelineTaskConfig
+ Task configuration.
+
+ Returns
+ -------
+ dict
+ Instrument configuration parameters
+ """
+
+ return {
+ "obscuration": config.instObscuration,
+ "focalLength": config.instFocalLength,
+ "apertureDiameter": config.instApertureDiameter,
+ "offset": config.instDefocalOffset,
+ "pixelSize": config.instPixelSize,
+ }
+
+
+def rotMatrix(thetaDegrees):
+ """Create a 2-d rotation matrix for given angle.
+
+ Parameters
+ ----------
+ thetaDegrees : float
+ Rotation angle in degrees.
+
+ Returns
+ -------
+ np.ndarray
+ Rotation matrix for theta.
+ """
+
+ theta = np.radians(thetaDegrees)
+ return np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
+
+
+def padArray(inArray, dim):
+ """Extend the boundary of image.
+
+ For example, the input image is 120x120 matrix. This function will create
+ an image such as 140x140 (dim x dim) matrix and put the input image in the
+ center of new image.
+
+ Parameters
+ ----------
+ inArray : numpy.ndarray
+ Input central image.
+ dim : int
+ Dimension of new extended image.
+
+ Returns
+ -------
+ numpy.ndarray
+ Extended image from the dimension of inArray to dim x dim.
+
+ Raises
+ ------
+ Exception
+ Check the dimension of inArray is n by n or not.
+ Exception
+ Check the extending dimension is bigger than the dimension of inArray
+ or not.
+ """
+
+ # Check the conditions
+ m, n = inArray.shape
+ if m != n:
+ raise Exception("padArray: array is not square.")
+
+ if m > dim:
+ raise Exception("padArray: array is larger than dimension.")
+
+ # Extend the boundary of image by creating a bigger matrix and putting the
+ # input image in the center
+ out = np.zeros([dim, dim])
+ ii = int(np.floor((dim - m) / 2))
+
+ # Put the original image in the center of extended image
+ out[ii : ii + m, ii : ii + m] = inArray
+
+ return out
+
+
+def extractArray(inArray, dim):
+ """Extract the central image.
+
+ For example, the input image is a 140x140 matrix. This function will
+ extract the central matrix with the dimension of 120x120 (dim x dim).
+
+ Parameters
+ ----------
+ inArray : numpy.ndarray
+ Input image.
+ dim : int
+ Dimension of extracted image.
+
+ Returns
+ -------
+ numpy.ndarray
+ Extracted central image from the dimension of inArray to dim x dim.
+
+ Raises
+ ------
+ Exception
+ Check the dimension of inArray is n by n or not.
+ Exception
+ Check the extracted dimension is smaller than the dimension of inArray
+ or not.
+ """
+
+ # Check the conditions
+ m, n = inArray.shape
+ if m != n:
+ raise Exception("extractArray: array is not square.")
+
+ if m < dim:
+ raise Exception("extractArray: array is smaller than dimension")
+
+ # Calculate the begining index to extract the central image
+ ii = int(np.floor((m - dim) / 2))
+
+ # Extract the central image
+ out = inArray[ii : ii + dim, ii : ii + dim]
+
+ return out
diff --git a/python/lsst/ts/wep/plotUtil.py b/python/lsst/ts/wep/utils/plotUtils.py
similarity index 100%
rename from python/lsst/ts/wep/plotUtil.py
rename to python/lsst/ts/wep/utils/plotUtils.py
diff --git a/python/lsst/ts/wep/utils/taskUtils.py b/python/lsst/ts/wep/utils/taskUtils.py
new file mode 100644
index 00000000..03394781
--- /dev/null
+++ b/python/lsst/ts/wep/utils/taskUtils.py
@@ -0,0 +1,133 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+__all__ = [
+ "runProgram",
+ "writePipetaskCmd",
+ "writeCleanUpRepoCmd",
+]
+
+import os
+import subprocess
+
+
+def runProgram(command, binDir=None, argstring=None):
+ """Run the program w/o arguments.
+
+ Parameters
+ ----------
+ command : str
+ Command of application.
+ binDir : str, optional
+ Directory of binary application. (the default is None.)
+ argstring : str, optional
+ Arguments of program. (the default is None.)
+
+ Raises
+ ------
+ RuntimeError
+ Error running of command.
+ """
+
+ # Directory of binary application
+ if binDir is not None:
+ command = os.path.join(binDir, command)
+
+ # Arguments for the program
+ if argstring is not None:
+ command += " " + argstring
+
+ # Call the program w/o arguments
+ if subprocess.call(command, shell=True) != 0:
+ raise RuntimeError("Error running: %s" % command)
+
+
+def writePipetaskCmd(
+ repoDir, runName, instrument, collections, taskName=None, pipelineYaml=None
+):
+ """
+ Format a command line call to run a Gen 3 pipeline task.
+ Can also be a set of tasks if specified in a pipeline yaml file.
+
+ Parameters
+ ----------
+ repoDir: str
+ Location of Gen 3 repository.
+ runName: str
+ Name of collection for data produced by the task.
+ instrument: str
+ The instrument to use for the task.
+ collections: str
+ The data collections needed for the task.
+ taskName: str, optional
+ Full task function name in lsst namespace. One of taskName
+ or pipelineYaml must be specified to run. (The default is None).
+ pipelineYaml: str, optional
+ Yaml file that specifies a pipeline configuration to run
+ instead of a single task. (The default is None.)
+
+ Returns
+ -------
+ str
+ Pipetask run command.
+
+ Raises
+ ------
+ ValueError
+ Need to at least specify name of task or name of pipeline file.
+ """
+ if (taskName is None) and (pipelineYaml is None):
+ raise ValueError("At least one of taskName or pipelineYaml must not be None")
+
+ pipetaskCmd = "pipetask run "
+ pipetaskCmd += f"-b {repoDir} " # Specify repo
+ pipetaskCmd += f"-i {collections} " # Specify collections with data to use
+ pipetaskCmd += f"--instrument {instrument} "
+ pipetaskCmd += f"--register-dataset-types --output-run {runName}"
+ if taskName is not None:
+ pipetaskCmd += f" -t {taskName}"
+ if pipelineYaml is not None:
+ pipetaskCmd += f" -p {pipelineYaml}"
+
+ return pipetaskCmd
+
+
+def writeCleanUpRepoCmd(repoDir, runName):
+ """
+ Format a command line call to clean up the data created by a pipeline.
+
+ Parameters
+ ----------
+ repoDir: str
+ Location of Gen 3 repository.
+ runName: str
+ Name of collection for data produced by the task.
+
+ Returns
+ -------
+ str
+ Butler prune-collection command.
+ """
+
+ cleanUpCmd = "butler remove-runs "
+ cleanUpCmd += f"{repoDir} {runName} --no-confirm"
+
+ return cleanUpCmd
diff --git a/python/lsst/ts/wep/cwfs/tool.py b/python/lsst/ts/wep/utils/zernikeUtils.py
similarity index 79%
rename from python/lsst/ts/wep/cwfs/tool.py
rename to python/lsst/ts/wep/utils/zernikeUtils.py
index ef3edc9c..c25938eb 100644
--- a/python/lsst/ts/wep/cwfs/tool.py
+++ b/python/lsst/ts/wep/utils/zernikeUtils.py
@@ -29,8 +29,6 @@
"ZernikeEval",
"ZernikeFit",
"ZernikeMaskedFit",
- "padArray",
- "extractArray",
]
import numpy as np
@@ -320,94 +318,3 @@ def ZernikeMaskedFit(s, x, y, numTerms, mask, e):
# Calculate coefficients of normal/ spherical Zernike polynomials
return ZernikeAnnularFit(s, x, y, numTerms, e)
-
-
-def padArray(inArray, dim):
- """Extend the boundary of image.
-
- For example, the input image is 120x120 matrix. This function will create
- an image such as 140x140 (dim x dim) matrix and put the input image in the
- center of new image.
-
- Parameters
- ----------
- inArray : numpy.ndarray
- Input central image.
- dim : int
- Dimension of new extended image.
-
- Returns
- -------
- numpy.ndarray
- Extended image from the dimension of inArray to dim x dim.
-
- Raises
- ------
- Exception
- Check the dimension of inArray is n by n or not.
- Exception
- Check the extending dimension is bigger than the dimension of inArray
- or not.
- """
-
- # Check the conditions
- m, n = inArray.shape
- if m != n:
- raise Exception("padArray: array is not square.")
-
- if m > dim:
- raise Exception("padArray: array is larger than dimension.")
-
- # Extend the boundary of image by creating a bigger matrix and putting the
- # input image in the center
- out = np.zeros([dim, dim])
- ii = int(np.floor((dim - m) / 2))
-
- # Put the original image in the center of extended image
- out[ii : ii + m, ii : ii + m] = inArray
-
- return out
-
-
-def extractArray(inArray, dim):
- """Extract the central image.
-
- For example, the input image is a 140x140 matrix. This function will
- extract the central matrix with the dimension of 120x120 (dim x dim).
-
- Parameters
- ----------
- inArray : numpy.ndarray
- Input image.
- dim : int
- Dimension of extracted image.
-
- Returns
- -------
- numpy.ndarray
- Extracted central image from the dimension of inArray to dim x dim.
-
- Raises
- ------
- Exception
- Check the dimension of inArray is n by n or not.
- Exception
- Check the extracted dimension is smaller than the dimension of inArray
- or not.
- """
-
- # Check the conditions
- m, n = inArray.shape
- if m != n:
- raise Exception("extractArray: array is not square.")
-
- if m < dim:
- raise Exception("extractArray: array is smaller than dimension")
-
- # Calculate the begining index to extract the central image
- ii = int(np.floor((m - dim) / 2))
-
- # Extract the central image
- out = inArray[ii : ii + dim, ii : ii + dim]
-
- return out
diff --git a/python/lsst/ts/wep/wfEstimator.py b/python/lsst/ts/wep/wfEstimator.py
index c2db057a..ae17190a 100644
--- a/python/lsst/ts/wep/wfEstimator.py
+++ b/python/lsst/ts/wep/wfEstimator.py
@@ -24,7 +24,7 @@
from lsst.ts.wep.cwfs.algorithm import Algorithm
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import CamType, CentroidFindType, DefocalType, FilterType
+from lsst.ts.wep.utils import CamType, CentroidFindType, DefocalType, FilterType
class WfEstimator(object):
diff --git a/tests/cwfs/test_algorithm.py b/tests/cwfs/test_algorithm.py
index 5d5b7e85..eb65ba0c 100644
--- a/tests/cwfs/test_algorithm.py
+++ b/tests/cwfs/test_algorithm.py
@@ -26,7 +26,7 @@
from lsst.ts.wep.cwfs.algorithm import Algorithm
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import CamType, DefocalType, getConfigDir, getModulePath
+from lsst.ts.wep.utils import CamType, DefocalType, getConfigDir, getModulePath
class TestAlgorithm(unittest.TestCase):
diff --git a/tests/cwfs/test_centroidFindFactory.py b/tests/cwfs/test_centroidFindFactory.py
index 0110471d..12f225a8 100644
--- a/tests/cwfs/test_centroidFindFactory.py
+++ b/tests/cwfs/test_centroidFindFactory.py
@@ -25,7 +25,7 @@
from lsst.ts.wep.cwfs.centroidFindFactory import CentroidFindFactory
from lsst.ts.wep.cwfs.centroidOtsu import CentroidOtsu
from lsst.ts.wep.cwfs.centroidRandomWalk import CentroidRandomWalk
-from lsst.ts.wep.utility import CentroidFindType
+from lsst.ts.wep.utils import CentroidFindType
class TestCentroidFindFactory(unittest.TestCase):
diff --git a/tests/cwfs/test_centroidOtsu.py b/tests/cwfs/test_centroidOtsu.py
index 12a0a300..59570165 100644
--- a/tests/cwfs/test_centroidOtsu.py
+++ b/tests/cwfs/test_centroidOtsu.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.cwfs.centroidOtsu import CentroidOtsu
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestCentroidOtsu(unittest.TestCase):
diff --git a/tests/cwfs/test_centroidRandomWalk.py b/tests/cwfs/test_centroidRandomWalk.py
index 79c0265f..84921086 100644
--- a/tests/cwfs/test_centroidRandomWalk.py
+++ b/tests/cwfs/test_centroidRandomWalk.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.cwfs.centroidRandomWalk import CentroidRandomWalk
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestCentroidRandomWalk(unittest.TestCase):
diff --git a/tests/cwfs/test_compensableImage.py b/tests/cwfs/test_compensableImage.py
index d25044ca..869d4d92 100644
--- a/tests/cwfs/test_compensableImage.py
+++ b/tests/cwfs/test_compensableImage.py
@@ -27,7 +27,7 @@
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.image import Image
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
CamType,
DefocalType,
FilterType,
diff --git a/tests/cwfs/test_donutTemplateFactory.py b/tests/cwfs/test_donutTemplateFactory.py
index a03528f1..491939a7 100644
--- a/tests/cwfs/test_donutTemplateFactory.py
+++ b/tests/cwfs/test_donutTemplateFactory.py
@@ -24,7 +24,7 @@
from lsst.ts.wep.cwfs.donutTemplateFactory import DonutTemplateFactory
from lsst.ts.wep.cwfs.donutTemplateModel import DonutTemplateModel
from lsst.ts.wep.cwfs.donutTemplatePhosim import DonutTemplatePhosim
-from lsst.ts.wep.utility import DonutTemplateType
+from lsst.ts.wep.utils import DonutTemplateType
class TestTemplateMakerFactory(unittest.TestCase):
diff --git a/tests/cwfs/test_donutTemplateModel.py b/tests/cwfs/test_donutTemplateModel.py
index 12daaf85..d9af9174 100644
--- a/tests/cwfs/test_donutTemplateModel.py
+++ b/tests/cwfs/test_donutTemplateModel.py
@@ -23,7 +23,7 @@
import numpy as np
from lsst.ts.wep.cwfs.donutTemplateModel import DonutTemplateModel
-from lsst.ts.wep.utility import CamType, DefocalType
+from lsst.ts.wep.utils import CamType, DefocalType
class TestTemplateModel(unittest.TestCase):
diff --git a/tests/cwfs/test_donutTemplatePhosim.py b/tests/cwfs/test_donutTemplatePhosim.py
index 5605dc18..a12c79b0 100644
--- a/tests/cwfs/test_donutTemplatePhosim.py
+++ b/tests/cwfs/test_donutTemplatePhosim.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.cwfs.donutTemplatePhosim import DonutTemplatePhosim
-from lsst.ts.wep.utility import DefocalType, getModulePath
+from lsst.ts.wep.utils import DefocalType, getModulePath
class TestTemplatePhosim(unittest.TestCase):
diff --git a/tests/cwfs/test_image.py b/tests/cwfs/test_image.py
index ed0ed0ec..ee20e033 100644
--- a/tests/cwfs/test_image.py
+++ b/tests/cwfs/test_image.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.cwfs.centroidRandomWalk import CentroidRandomWalk
from lsst.ts.wep.cwfs.image import Image
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestImage(unittest.TestCase):
diff --git a/tests/cwfs/test_imgsAuxTelZWO.py b/tests/cwfs/test_imgsAuxTelZWO.py
index a92250d9..dd86dac1 100644
--- a/tests/cwfs/test_imgsAuxTelZWO.py
+++ b/tests/cwfs/test_imgsAuxTelZWO.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.cwfs.baseCwfsTestCase import BaseCwfsTestCase
from lsst.ts.wep.cwfs.image import Image
-from lsst.ts.wep.utility import CamType, CentroidFindType, getModulePath
+from lsst.ts.wep.utils import CamType, CentroidFindType, getModulePath
class TestImgsAuxTelZWO(BaseCwfsTestCase, unittest.TestCase):
diff --git a/tests/cwfs/test_imgsLsstFam.py b/tests/cwfs/test_imgsLsstFam.py
index 56dfc16b..670fb68c 100644
--- a/tests/cwfs/test_imgsLsstFam.py
+++ b/tests/cwfs/test_imgsLsstFam.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.cwfs.baseCwfsTestCase import BaseCwfsTestCase
-from lsst.ts.wep.utility import CamType, CentroidFindType, getModulePath
+from lsst.ts.wep.utils import CamType, CentroidFindType, getModulePath
class TestImgsLsstFam(BaseCwfsTestCase, unittest.TestCase):
diff --git a/tests/cwfs/test_instrument.py b/tests/cwfs/test_instrument.py
index a860c774..14eb7829 100644
--- a/tests/cwfs/test_instrument.py
+++ b/tests/cwfs/test_instrument.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.cwfs.instrument import Instrument
-from lsst.ts.wep.utility import CamType, getConfigDir, getModulePath
+from lsst.ts.wep.utils import CamType, getConfigDir, getModulePath
class TestInstrument(unittest.TestCase):
diff --git a/tests/cwfs/test_multiImgs.py b/tests/cwfs/test_multiImgs.py
index 1c89cba0..0dcb634c 100644
--- a/tests/cwfs/test_multiImgs.py
+++ b/tests/cwfs/test_multiImgs.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.cwfs.baseCwfsTestCase import BaseCwfsTestCase
-from lsst.ts.wep.utility import CamType, CentroidFindType, getModulePath
+from lsst.ts.wep.utils import CamType, CentroidFindType, getModulePath
class TestWepWithMultiImgs(BaseCwfsTestCase, unittest.TestCase):
diff --git a/tests/deblend/test_deblendAdapt.py b/tests/deblend/test_deblendAdapt.py
index 5464f61b..d696de4b 100644
--- a/tests/deblend/test_deblendAdapt.py
+++ b/tests/deblend/test_deblendAdapt.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.deblend.deblendAdapt import DeblendAdapt
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestDeblendAdapt(unittest.TestCase):
diff --git a/tests/deblend/test_deblendDefault.py b/tests/deblend/test_deblendDefault.py
index 1ed335e7..a1e97d4d 100644
--- a/tests/deblend/test_deblendDefault.py
+++ b/tests/deblend/test_deblendDefault.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.deblend.deblendDefault import DeblendDefault
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestDeblendDefault(unittest.TestCase):
diff --git a/tests/deblend/test_deblendDonutFactory.py b/tests/deblend/test_deblendDonutFactory.py
index 0304bd10..8af36e4d 100644
--- a/tests/deblend/test_deblendDonutFactory.py
+++ b/tests/deblend/test_deblendDonutFactory.py
@@ -23,7 +23,7 @@
from lsst.ts.wep.deblend.deblendAdapt import DeblendAdapt
from lsst.ts.wep.deblend.deblendDonutFactory import DeblendDonutFactory
-from lsst.ts.wep.utility import DeblendDonutType
+from lsst.ts.wep.utils import DeblendDonutType
class TestDeblendDonutFactory(unittest.TestCase):
diff --git a/tests/task/test_calcZernikesTaskCwfs.py b/tests/task/test_calcZernikesTaskCwfs.py
index efd468c2..2708579c 100644
--- a/tests/task/test_calcZernikesTaskCwfs.py
+++ b/tests/task/test_calcZernikesTaskCwfs.py
@@ -28,7 +28,7 @@
from lsst.ts.wep.task.combineZernikesMeanTask import CombineZernikesMeanTask
from lsst.ts.wep.task.combineZernikesSigmaClipTask import CombineZernikesSigmaClipTask
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_calcZernikesTaskLatiss.py b/tests/task/test_calcZernikesTaskLatiss.py
index a3164a55..234ef442 100644
--- a/tests/task/test_calcZernikesTaskLatiss.py
+++ b/tests/task/test_calcZernikesTaskLatiss.py
@@ -29,7 +29,7 @@
from lsst.ts.wep.task.calcZernikesTask import CalcZernikesTask, CalcZernikesTaskConfig
from lsst.ts.wep.task.combineZernikesMeanTask import CombineZernikesMeanTask
from lsst.ts.wep.task.combineZernikesSigmaClipTask import CombineZernikesSigmaClipTask
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_calcZernikesTaskScienceSensor.py b/tests/task/test_calcZernikesTaskScienceSensor.py
index 1aee5357..8cc4bcaa 100644
--- a/tests/task/test_calcZernikesTaskScienceSensor.py
+++ b/tests/task/test_calcZernikesTaskScienceSensor.py
@@ -27,7 +27,7 @@
from lsst.ts.wep.task.calcZernikesTask import CalcZernikesTask, CalcZernikesTaskConfig
from lsst.ts.wep.task.combineZernikesMeanTask import CombineZernikesMeanTask
from lsst.ts.wep.task.combineZernikesSigmaClipTask import CombineZernikesSigmaClipTask
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_cutOutDonutsBase.py b/tests/task/test_cutOutDonutsBase.py
index f6d96df9..22f618a4 100644
--- a/tests/task/test_cutOutDonutsBase.py
+++ b/tests/task/test_cutOutDonutsBase.py
@@ -29,7 +29,7 @@
CutOutDonutsBaseTask,
CutOutDonutsBaseTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
CamType,
DefocalType,
getModulePath,
diff --git a/tests/task/test_cutOutDonutsCwfsTask.py b/tests/task/test_cutOutDonutsCwfsTask.py
index 389fc65e..d913df45 100644
--- a/tests/task/test_cutOutDonutsCwfsTask.py
+++ b/tests/task/test_cutOutDonutsCwfsTask.py
@@ -27,7 +27,7 @@
CutOutDonutsCwfsTask,
CutOutDonutsCwfsTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
getModulePath,
runProgram,
diff --git a/tests/task/test_cutOutDonutsLatissTask.py b/tests/task/test_cutOutDonutsLatissTask.py
index 8662a97e..c2a284dc 100644
--- a/tests/task/test_cutOutDonutsLatissTask.py
+++ b/tests/task/test_cutOutDonutsLatissTask.py
@@ -30,7 +30,7 @@
CutOutDonutsScienceSensorTask,
CutOutDonutsScienceSensorTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
getModulePath,
runProgram,
diff --git a/tests/task/test_cutOutDonutsScienceSensorTask.py b/tests/task/test_cutOutDonutsScienceSensorTask.py
index b78f4e59..3f8048a5 100644
--- a/tests/task/test_cutOutDonutsScienceSensorTask.py
+++ b/tests/task/test_cutOutDonutsScienceSensorTask.py
@@ -28,7 +28,7 @@
CutOutDonutsScienceSensorTask,
CutOutDonutsScienceSensorTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
getModulePath,
runProgram,
diff --git a/tests/task/test_donutQuickMeasurementTask.py b/tests/task/test_donutQuickMeasurementTask.py
index 995ce28d..f56a1738 100644
--- a/tests/task/test_donutQuickMeasurementTask.py
+++ b/tests/task/test_donutQuickMeasurementTask.py
@@ -30,7 +30,7 @@
DonutQuickMeasurementTask,
DonutQuickMeasurementTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
DefocalType,
DonutTemplateType,
getModulePath,
diff --git a/tests/task/test_donutSourceSelectorTask.py b/tests/task/test_donutSourceSelectorTask.py
index 43e84500..fb530a61 100644
--- a/tests/task/test_donutSourceSelectorTask.py
+++ b/tests/task/test_donutSourceSelectorTask.py
@@ -32,7 +32,7 @@
DonutSourceSelectorTask,
DonutSourceSelectorTaskConfig,
)
-from lsst.ts.wep.utility import getConfigDir, getModulePath
+from lsst.ts.wep.utils import getConfigDir, getModulePath
class TestDonutSourceSelectorTask(unittest.TestCase):
diff --git a/tests/task/test_donutStamp.py b/tests/task/test_donutStamp.py
index dea9f79a..956f4858 100644
--- a/tests/task/test_donutStamp.py
+++ b/tests/task/test_donutStamp.py
@@ -31,7 +31,7 @@
from lsst.ts.wep.cwfs.compensableImage import CompensableImage
from lsst.ts.wep.cwfs.instrument import Instrument
from lsst.ts.wep.task.donutStamp import DonutStamp
-from lsst.ts.wep.utility import CamType, DefocalType, getConfigDir
+from lsst.ts.wep.utils import CamType, DefocalType, getConfigDir
class TestDonutStamp(unittest.TestCase):
diff --git a/tests/task/test_donutStamps.py b/tests/task/test_donutStamps.py
index 653e7def..58d6ac48 100644
--- a/tests/task/test_donutStamps.py
+++ b/tests/task/test_donutStamps.py
@@ -29,7 +29,7 @@
from lsst.daf.base import PropertyList
from lsst.ts.wep.task.donutStamp import DonutStamp
from lsst.ts.wep.task.donutStamps import DonutStamps
-from lsst.ts.wep.utility import DefocalType
+from lsst.ts.wep.utils import DefocalType
class TestDonutStamps(lsst.utils.tests.TestCase):
diff --git a/tests/task/test_generateDonutCatalogOnlineTask.py b/tests/task/test_generateDonutCatalogOnlineTask.py
index 75304e5f..2d090e71 100644
--- a/tests/task/test_generateDonutCatalogOnlineTask.py
+++ b/tests/task/test_generateDonutCatalogOnlineTask.py
@@ -31,7 +31,7 @@
GenerateDonutCatalogOnlineTaskConfig,
)
from lsst.ts.wep.task.refCatalogInterface import RefCatalogInterface
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestGenerateDonutCatalogOnlineTask(unittest.TestCase):
diff --git a/tests/task/test_generateDonutCatalogUtils.py b/tests/task/test_generateDonutCatalogUtils.py
index 6ef01b94..9ac4153e 100644
--- a/tests/task/test_generateDonutCatalogUtils.py
+++ b/tests/task/test_generateDonutCatalogUtils.py
@@ -32,7 +32,7 @@
donutCatalogToDataFrame,
runSelection,
)
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestGenerateDonutCatalogUtils(unittest.TestCase):
diff --git a/tests/task/test_generateDonutCatalogWcsTask.py b/tests/task/test_generateDonutCatalogWcsTask.py
index 2340e814..1681ac0f 100644
--- a/tests/task/test_generateDonutCatalogWcsTask.py
+++ b/tests/task/test_generateDonutCatalogWcsTask.py
@@ -30,7 +30,7 @@
GenerateDonutCatalogWcsTask,
GenerateDonutCatalogWcsTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_generateDonutDirectDetectTask.py b/tests/task/test_generateDonutDirectDetectTask.py
index b05cddf2..3ba9ce6a 100644
--- a/tests/task/test_generateDonutDirectDetectTask.py
+++ b/tests/task/test_generateDonutDirectDetectTask.py
@@ -29,7 +29,7 @@
GenerateDonutDirectDetectTask,
GenerateDonutDirectDetectTaskConfig,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_generateDonutFromRefitWcsTask.py b/tests/task/test_generateDonutFromRefitWcsTask.py
index 7dba252f..18443a9d 100644
--- a/tests/task/test_generateDonutFromRefitWcsTask.py
+++ b/tests/task/test_generateDonutFromRefitWcsTask.py
@@ -34,7 +34,7 @@
GenerateDonutFromRefitWcsTaskConfig,
RefCatalogInterface,
)
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
getModulePath,
runProgram,
writeCleanUpRepoCmd,
diff --git a/tests/task/test_refCatalogInterface.py b/tests/task/test_refCatalogInterface.py
index 799b6a51..1f83f8cd 100644
--- a/tests/task/test_refCatalogInterface.py
+++ b/tests/task/test_refCatalogInterface.py
@@ -24,7 +24,7 @@
from lsst.daf import butler as dafButler
from lsst.ts.wep.task.refCatalogInterface import RefCatalogInterface
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestRefCatalogInterface(unittest.TestCase):
diff --git a/tests/test_donutDetector.py b/tests/test_donutDetector.py
index e488ac15..7b3a15f5 100644
--- a/tests/test_donutDetector.py
+++ b/tests/test_donutDetector.py
@@ -25,7 +25,7 @@
import pandas as pd
from lsst.ts.wep.cwfs.donutTemplateFactory import DonutTemplateFactory
from lsst.ts.wep.donutDetector import DonutDetector
-from lsst.ts.wep.utility import DefocalType, DonutTemplateType
+from lsst.ts.wep.utils import DefocalType, DonutTemplateType
class TestDonutDetector(unittest.TestCase):
diff --git a/tests/test_donutImageCheck.py b/tests/test_donutImageCheck.py
index d0c88d46..9e4e6a48 100644
--- a/tests/test_donutImageCheck.py
+++ b/tests/test_donutImageCheck.py
@@ -24,7 +24,7 @@
import numpy as np
from lsst.ts.wep.donutImageCheck import DonutImageCheck
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestDonutImageCheck(unittest.TestCase):
diff --git a/tests/test_paramReader.py b/tests/test_paramReader.py
index 95c8aa5f..3913ba2e 100644
--- a/tests/test_paramReader.py
+++ b/tests/test_paramReader.py
@@ -25,7 +25,7 @@
import numpy as np
from lsst.ts.wep.paramReader import ParamReader
-from lsst.ts.wep.utility import getModulePath
+from lsst.ts.wep.utils import getModulePath
class TestParamReader(unittest.TestCase):
diff --git a/tests/test_wfEstimator.py b/tests/test_wfEstimator.py
index 57bc2b3f..9bd0e830 100644
--- a/tests/test_wfEstimator.py
+++ b/tests/test_wfEstimator.py
@@ -23,7 +23,7 @@
import unittest
import numpy as np
-from lsst.ts.wep.utility import CamType, DefocalType, getConfigDir, getModulePath
+from lsst.ts.wep.utils import CamType, DefocalType, getConfigDir, getModulePath
from lsst.ts.wep.wfEstimator import WfEstimator
diff --git a/tests/test_utility.py b/tests/utils/test_enumUtils.py
similarity index 53%
rename from tests/test_utility.py
rename to tests/utils/test_enumUtils.py
index da32e144..e2196707 100644
--- a/tests/test_utility.py
+++ b/tests/utils/test_enumUtils.py
@@ -19,14 +19,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import os
import unittest
from enum import IntEnum
-import numpy as np
from lsst.afw.cameraGeom import DetectorType
-from lsst.ts.wep.task.calcZernikesTask import CalcZernikesTaskConfig
-from lsst.ts.wep.utility import (
+from lsst.ts.wep.utils import (
BscDbType,
CamType,
CentroidFindType,
@@ -34,60 +31,31 @@
DonutTemplateType,
FilterType,
ImageType,
- createInstDictFromConfig,
- getAmpImagesFromDir,
getBscDbType,
getCamNameFromCamType,
getCamType,
getCamTypeFromButlerName,
getCentroidFindType,
- getConfigDir,
getDeblendDonutType,
- getDefocalDisInMm,
getDonutTemplateType,
getFilterTypeFromBandLabel,
getImageType,
- getModulePath,
- getObsLsstCmdTaskConfigDir,
mapFilterRefToG,
- rotMatrix,
- writeCleanUpRepoCmd,
- writePipetaskCmd,
)
-class TestUtility(unittest.TestCase):
- """Test the Utility functions."""
+class TestEnumUtils(unittest.TestCase):
+ """Test the Enum utils."""
- def _writePipetaskCmd(
- self,
- repoName,
- instrument,
- collections,
- runName,
- taskName=None,
- pipelineName=None,
- ):
- # Write the part of the command that is always included
- testCmd = f"pipetask run -b {repoName} -i {collections} "
- testCmd += f"--instrument {instrument} "
- testCmd += f"--register-dataset-types --output-run {runName}"
-
- # Write with taskName
- if taskName is not None:
- testCmd += f" -t {taskName}"
-
- # Write with pipeline filename
- if pipelineName is not None:
- testCmd += f" -p {pipelineName}"
-
- return testCmd
-
- def _writeCleanUpCmd(self, repoName, runName):
- testCmd = f"butler remove-runs {repoName} {runName}"
- testCmd += " --no-confirm"
-
- return testCmd
+ def testGetFilterTypeFromBandLabel(self):
+ # Test allowable filter band labels
+ self.assertEqual(getFilterTypeFromBandLabel("u"), FilterType.LSST_U)
+ self.assertEqual(getFilterTypeFromBandLabel("g"), FilterType.LSST_G)
+ self.assertEqual(getFilterTypeFromBandLabel("r"), FilterType.LSST_R)
+ self.assertEqual(getFilterTypeFromBandLabel("i"), FilterType.LSST_I)
+ self.assertEqual(getFilterTypeFromBandLabel("z"), FilterType.LSST_Z)
+ self.assertEqual(getFilterTypeFromBandLabel("y"), FilterType.LSST_Y)
+ self.assertEqual(getFilterTypeFromBandLabel("SomeFilter"), FilterType.REF)
def testMapFilterRefToG(self):
mappedFilterType = mapFilterRefToG(FilterType.REF)
@@ -97,138 +65,6 @@ def testMapFilterRefToGForFilterU(self):
mappedFilterType = mapFilterRefToG(FilterType.LSST_U)
self.assertEqual(mappedFilterType, FilterType.LSST_U)
- def testGetConfigDir(self):
- ansConfigDir = os.path.join(getModulePath(), "policy")
- self.assertEqual(getConfigDir(), ansConfigDir)
-
- def testGetObsLsstCmdTaskConfigDir(self):
- obsLsstCmdTaskConfirDir = getObsLsstCmdTaskConfigDir()
- configNormPath = os.path.normpath(obsLsstCmdTaskConfirDir)
- configNormPathList = configNormPath.split(os.sep)
-
- self.assertEqual(configNormPathList[-1], "config")
- self.assertTrue(("obs_lsst" in configNormPathList))
-
- def testGetBscDbType(self):
- self.assertEqual(getBscDbType("localDb"), BscDbType.LocalDb)
- self.assertEqual(getBscDbType("file"), BscDbType.LocalDbForStarFile)
-
- def testGetBscDbTypeWithWrongInput(self):
- self.assertRaises(ValueError, getBscDbType, "wrongType")
-
- def testGetImageType(self):
- self.assertEqual(getImageType("amp"), ImageType.Amp)
- self.assertEqual(getImageType("eimage"), ImageType.Eimg)
-
- def testGetImageTypeWithWrongInput(self):
- self.assertRaises(ValueError, getImageType, "wrongType")
-
- def testGetCentroidFindType(self):
- self.assertEqual(getCentroidFindType("randomWalk"), CentroidFindType.RandomWalk)
- self.assertEqual(getCentroidFindType("otsu"), CentroidFindType.Otsu)
- self.assertEqual(
- getCentroidFindType("convolveTemplate"), CentroidFindType.ConvolveTemplate
- )
-
- def testGetCentroidFindTypeWithWrongInput(self):
- self.assertRaises(ValueError, getCentroidFindType, "wrongType")
-
- def testGetDeblendDonutType(self):
- self.assertEqual(getDeblendDonutType("adapt"), DeblendDonutType.Adapt)
-
- def testGetDeblendDonutTypeWithWrongInput(self):
- self.assertRaises(ValueError, getDeblendDonutType, "wrongType")
-
- def testGetDonutTemplateType(self):
- self.assertEqual(getDonutTemplateType("model"), DonutTemplateType.Model)
- self.assertEqual(getDonutTemplateType("phosim"), DonutTemplateType.Phosim)
-
- def testGetDonutTemplateTypeWithWrongInput(self):
- self.assertRaises(ValueError, getDonutTemplateType, "wrongType")
-
- def testGetAmpImagesFromDir(self):
- # path to repackaged phosim files
- # with amplifier images and e-images
- defocalImgDir = os.path.join(
- getModulePath(),
- "tests",
- "testData",
- "phosimOutput",
- "realComCam",
- "repackagedFiles",
- "extra",
- )
- # test that there are e-images in that dir
- filesInDir = os.listdir(defocalImgDir)
- self.assertTrue("MC_H_20211231_006001_R22_S11_e.fits.gz" in filesInDir)
- self.assertTrue("MC_H_20211231_006001_R22_S10_e.fits.gz" in filesInDir)
-
- # get names of amp files
- ampFiles = getAmpImagesFromDir(defocalImgDir)
-
- # assert the returned content
- self.assertIsInstance(ampFiles, list)
-
- # assert that amp images are on the returned list
- self.assertTrue("MC_H_20211231_006001_R22_S10.fits" in ampFiles)
- self.assertTrue("MC_H_20211231_006001_R22_S11.fits" in ampFiles)
-
- # assert that no other files are there
- # by checking that the length of list corresponds to
- # two files tested above
- self.assertEqual(len(ampFiles), 2)
-
- def testWritePipetaskCmd(self):
- repoName = "testRepo"
- instrument = "lsst.obs.lsst.LsstCam"
- collections = "refcats"
- runName = "run2"
-
- # Test writing with task name
- taskName = "lsst.ts.wep.testTask"
- testCmdTask = self._writePipetaskCmd(
- repoName, instrument, collections, runName, taskName=taskName
- )
-
- pipeOutTask = writePipetaskCmd(
- repoName, runName, instrument, collections, taskName=taskName
- )
- self.assertEqual(testCmdTask, pipeOutTask)
-
- # Test writing with pipeline
- pipelineYamlFile = "testPipeOut.yaml"
- testCmdYaml = self._writePipetaskCmd(
- repoName, instrument, collections, runName, pipelineName=pipelineYamlFile
- )
-
- pipeOutYaml = writePipetaskCmd(
- repoName, runName, instrument, collections, pipelineYaml=pipelineYamlFile
- )
- self.assertEqual(testCmdYaml, pipeOutYaml)
-
- assertMsg = "At least one of taskName or pipelineYaml must not be None"
- with self.assertRaises(ValueError) as context:
- writePipetaskCmd(repoName, runName, instrument, collections)
- self.assertTrue(assertMsg in str(context.exception))
-
- def testWriteCleanUpRepoCmd(self):
- repoName = "testRepo"
- runName = "run2"
-
- testCmd = self._writeCleanUpCmd(repoName, runName)
- self.assertEqual(testCmd, writeCleanUpRepoCmd(repoName, runName))
-
- def testGetDefocalDisInMm(self):
- self.assertEqual(getDefocalDisInMm("lsst"), 1.5)
- self.assertEqual(getDefocalDisInMm("lsstfam"), 1.5)
- self.assertEqual(getDefocalDisInMm("comcam"), 1.5)
- self.assertEqual(getDefocalDisInMm("auxTel"), 0.8)
- instName = "telescope"
- assertMsg = f"Instrument name ({instName}) is not supported."
- with self.assertRaises(ValueError) as context:
- getDefocalDisInMm(instName)
- self.assertTrue(assertMsg in str(context.exception))
-
def testGetCamType(self):
self.assertEqual(getCamType("lsst"), CamType.LsstCam)
self.assertEqual(getCamType("lsstfam"), CamType.LsstFamCam)
@@ -240,6 +76,25 @@ def testGetCamType(self):
getCamType(instName)
self.assertTrue(assertMsg in str(context.exception))
+ def testGetCamNameFromCamType(self):
+ # Test allowable CamType values
+ self.assertEqual(getCamNameFromCamType(CamType.LsstCam), "lsst")
+ self.assertEqual(getCamNameFromCamType(CamType.LsstFamCam), "lsstfam")
+ self.assertEqual(getCamNameFromCamType(CamType.ComCam), "comcam")
+ self.assertEqual(getCamNameFromCamType(CamType.AuxTel), "auxTel")
+ self.assertEqual(getCamNameFromCamType(CamType.AuxTelZWO), "auxTelZWO")
+
+ # Create a TestCamType that has a value greater than the last CamType
+ class TestCamType(IntEnum):
+ BadInst = len(CamType) + 1
+
+ # Test the error is raised correctly with an incorrect CamType.
+ badCamType = TestCamType.BadInst
+ errMsg = f"CamType ({badCamType}) is not supported."
+ with self.assertRaises(ValueError) as context:
+ getCamNameFromCamType(badCamType)
+ self.assertEqual(str(context.exception), errMsg)
+
def testGetCamTypeFromButlerName(self):
self.assertEqual(
getCamTypeFromButlerName("LSSTCam", DetectorType.WAVEFRONT), CamType.LsstCam
@@ -276,66 +131,44 @@ def testGetCamTypeFromButlerName(self):
getCamTypeFromButlerName(instName, detType)
self.assertTrue(detAssertMsg in str(context.exception))
- def testGetFilterTypeFromBandLabel(self):
- # Test allowable filter band labels
- self.assertEqual(getFilterTypeFromBandLabel("u"), FilterType.LSST_U)
- self.assertEqual(getFilterTypeFromBandLabel("g"), FilterType.LSST_G)
- self.assertEqual(getFilterTypeFromBandLabel("r"), FilterType.LSST_R)
- self.assertEqual(getFilterTypeFromBandLabel("i"), FilterType.LSST_I)
- self.assertEqual(getFilterTypeFromBandLabel("z"), FilterType.LSST_Z)
- self.assertEqual(getFilterTypeFromBandLabel("y"), FilterType.LSST_Y)
- self.assertEqual(getFilterTypeFromBandLabel("SomeFilter"), FilterType.REF)
+ def testGetBscDbType(self):
+ self.assertEqual(getBscDbType("localDb"), BscDbType.LocalDb)
+ self.assertEqual(getBscDbType("file"), BscDbType.LocalDbForStarFile)
- def testGetCamNameFromCamType(self):
- # Test allowable CamType values
- self.assertEqual(getCamNameFromCamType(CamType.LsstCam), "lsst")
- self.assertEqual(getCamNameFromCamType(CamType.LsstFamCam), "lsstfam")
- self.assertEqual(getCamNameFromCamType(CamType.ComCam), "comcam")
- self.assertEqual(getCamNameFromCamType(CamType.AuxTel), "auxTel")
- self.assertEqual(getCamNameFromCamType(CamType.AuxTelZWO), "auxTelZWO")
+ def testGetBscDbTypeWithWrongInput(self):
+ self.assertRaises(ValueError, getBscDbType, "wrongType")
- # Create a TestCamType that has a value greater than the last CamType
- class TestCamType(IntEnum):
- BadInst = len(CamType) + 1
+ def testGetImageType(self):
+ self.assertEqual(getImageType("amp"), ImageType.Amp)
+ self.assertEqual(getImageType("eimage"), ImageType.Eimg)
- # Test the error is raised correctly with an incorrect CamType.
- badCamType = TestCamType.BadInst
- errMsg = f"CamType ({badCamType}) is not supported."
- with self.assertRaises(ValueError) as context:
- getCamNameFromCamType(badCamType)
- self.assertEqual(str(context.exception), errMsg)
+ def testGetImageTypeWithWrongInput(self):
+ self.assertRaises(ValueError, getImageType, "wrongType")
- def testCreateInstDictFromConfig(self):
- # Test instDict creation in tasks
- testConfig = CalcZernikesTaskConfig()
- testInstDict = createInstDictFromConfig(testConfig)
- truthInstDict = {
- "obscuration": 0.61,
- "focalLength": 10.312,
- "apertureDiameter": 8.36,
- "offset": None,
- "pixelSize": 10.0e-6,
- }
+ def testGetCentroidFindType(self):
+ self.assertEqual(getCentroidFindType("randomWalk"), CentroidFindType.RandomWalk)
+ self.assertEqual(getCentroidFindType("otsu"), CentroidFindType.Otsu)
+ self.assertEqual(
+ getCentroidFindType("convolveTemplate"), CentroidFindType.ConvolveTemplate
+ )
+
+ def testGetCentroidFindTypeWithWrongInput(self):
+ self.assertRaises(ValueError, getCentroidFindType, "wrongType")
- self.assertDictEqual(truthInstDict, testInstDict)
+ def testGetDonutTemplateType(self):
+ self.assertEqual(getDonutTemplateType("model"), DonutTemplateType.Model)
+ self.assertEqual(getDonutTemplateType("phosim"), DonutTemplateType.Phosim)
- def testRotMatrix(self):
- # Test rotation with 0 degrees
- testTheta1 = 0
- rotMatrix1 = np.array([[1, 0], [0, 1]])
- np.testing.assert_array_almost_equal(rotMatrix1, rotMatrix(testTheta1))
+ def testGetDonutTemplateTypeWithWrongInput(self):
+ self.assertRaises(ValueError, getDonutTemplateType, "wrongType")
- # Test rotation with 90 degrees
- testTheta2 = 90
- rotMatrix2 = np.array([[0, -1], [1, 0]])
- np.testing.assert_array_almost_equal(rotMatrix2, rotMatrix(testTheta2))
+ def testGetDeblendDonutType(self):
+ self.assertEqual(getDeblendDonutType("adapt"), DeblendDonutType.Adapt)
- # Test rotation with 45 degrees
- testTheta3 = 45
- rotMatrix3 = np.array([[0.707107, -0.707107], [0.707107, 0.707107]])
- np.testing.assert_array_almost_equal(rotMatrix3, rotMatrix(testTheta3))
+ def testGetDeblendDonutTypeWithWrongInput(self):
+ self.assertRaises(ValueError, getDeblendDonutType, "wrongType")
if __name__ == "__main__":
- # Do the unit test
+ # Run the unit test
unittest.main()
diff --git a/tests/utils/test_ioUtils.py b/tests/utils/test_ioUtils.py
new file mode 100644
index 00000000..cca96b09
--- /dev/null
+++ b/tests/utils/test_ioUtils.py
@@ -0,0 +1,78 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import os
+import unittest
+
+from lsst.ts.wep.utils import (
+ getAmpImagesFromDir,
+ getConfigDir,
+ getModulePath,
+ getObsLsstCmdTaskConfigDir,
+)
+
+
+class TestIoUtils(unittest.TestCase):
+ """Test the IO utility functions."""
+
+ def testGetConfigDir(self):
+ ansConfigDir = os.path.join(getModulePath(), "policy")
+ self.assertEqual(getConfigDir(), ansConfigDir)
+
+ def testGetObsLsstCmdTaskConfigDir(self):
+ obsLsstCmdTaskConfirDir = getObsLsstCmdTaskConfigDir()
+ configNormPath = os.path.normpath(obsLsstCmdTaskConfirDir)
+ configNormPathList = configNormPath.split(os.sep)
+
+ self.assertEqual(configNormPathList[-1], "config")
+ self.assertTrue(("obs_lsst" in configNormPathList))
+
+ def testGetAmpImagesFromDir(self):
+ # path to repackaged phosim files
+ # with amplifier images and e-images
+ defocalImgDir = os.path.join(
+ getModulePath(),
+ "tests",
+ "testData",
+ "phosimOutput",
+ "realComCam",
+ "repackagedFiles",
+ "extra",
+ )
+ # test that there are e-images in that dir
+ filesInDir = os.listdir(defocalImgDir)
+ self.assertTrue("MC_H_20211231_006001_R22_S11_e.fits.gz" in filesInDir)
+ self.assertTrue("MC_H_20211231_006001_R22_S10_e.fits.gz" in filesInDir)
+
+ # get names of amp files
+ ampFiles = getAmpImagesFromDir(defocalImgDir)
+
+ # assert the returned content
+ self.assertIsInstance(ampFiles, list)
+
+ # assert that amp images are on the returned list
+ self.assertTrue("MC_H_20211231_006001_R22_S10.fits" in ampFiles)
+ self.assertTrue("MC_H_20211231_006001_R22_S11.fits" in ampFiles)
+
+ # assert that no other files are there
+ # by checking that the length of list corresponds to
+ # two files tested above
+ self.assertEqual(len(ampFiles), 2)
diff --git a/tests/utils/test_miscUtils.py b/tests/utils/test_miscUtils.py
new file mode 100644
index 00000000..3777e7ad
--- /dev/null
+++ b/tests/utils/test_miscUtils.py
@@ -0,0 +1,105 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import unittest
+
+import numpy as np
+from lsst.ts.wep.task.calcZernikesTask import CalcZernikesTaskConfig
+from lsst.ts.wep.utils import (
+ createInstDictFromConfig,
+ extractArray,
+ getDefocalDisInMm,
+ padArray,
+ rotMatrix,
+)
+
+
+class TestMiscUtils(unittest.TestCase):
+ """Test the miscellaneous utility functions."""
+
+ def testGetDefocalDisInMm(self):
+ self.assertEqual(getDefocalDisInMm("lsst"), 1.5)
+ self.assertEqual(getDefocalDisInMm("lsstfam"), 1.5)
+ self.assertEqual(getDefocalDisInMm("comcam"), 1.5)
+ self.assertEqual(getDefocalDisInMm("auxTel"), 0.8)
+ instName = "telescope"
+ assertMsg = f"Instrument name ({instName}) is not supported."
+ with self.assertRaises(ValueError) as context:
+ getDefocalDisInMm(instName)
+ self.assertTrue(assertMsg in str(context.exception))
+
+ def testCreateInstDictFromConfig(self):
+ # Test instDict creation in tasks
+ testConfig = CalcZernikesTaskConfig()
+ testInstDict = createInstDictFromConfig(testConfig)
+ truthInstDict = {
+ "obscuration": 0.61,
+ "focalLength": 10.312,
+ "apertureDiameter": 8.36,
+ "offset": None,
+ "pixelSize": 10.0e-6,
+ }
+
+ self.assertDictEqual(truthInstDict, testInstDict)
+
+ def testRotMatrix(self):
+ # Test rotation with 0 degrees
+ testTheta1 = 0
+ rotMatrix1 = np.array([[1, 0], [0, 1]])
+ np.testing.assert_array_almost_equal(rotMatrix1, rotMatrix(testTheta1))
+
+ # Test rotation with 90 degrees
+ testTheta2 = 90
+ rotMatrix2 = np.array([[0, -1], [1, 0]])
+ np.testing.assert_array_almost_equal(rotMatrix2, rotMatrix(testTheta2))
+
+ # Test rotation with 45 degrees
+ testTheta3 = 45
+ rotMatrix3 = np.array([[0.707107, -0.707107], [0.707107, 0.707107]])
+ np.testing.assert_array_almost_equal(rotMatrix3, rotMatrix(testTheta3))
+
+ def testPadArray(self):
+ imgDim = 10
+ padPixelSize = 20
+
+ img, imgPadded = self._padRandomImg(imgDim, padPixelSize)
+
+ self.assertEqual(imgPadded.shape[0], imgDim + padPixelSize)
+
+ def _padRandomImg(self, imgDim, padPixelSize):
+ img = np.random.rand(imgDim, imgDim)
+ imgPadded = padArray(img, imgDim + padPixelSize)
+
+ return img, imgPadded
+
+ def testExtractArray(self):
+ imgDim = 10
+ padPixelSize = 20
+ img, imgPadded = self._padRandomImg(imgDim, padPixelSize)
+
+ imgExtracted = extractArray(imgPadded, imgDim)
+
+ self.assertEqual(imgExtracted.shape[0], imgDim)
+
+
+if __name__ == "__main__":
+ # Do the unit test
+ unittest.main()
diff --git a/tests/utils/test_taskUtils.py b/tests/utils/test_taskUtils.py
new file mode 100644
index 00000000..355afb52
--- /dev/null
+++ b/tests/utils/test_taskUtils.py
@@ -0,0 +1,98 @@
+# This file is part of ts_wep.
+#
+# Developed for the LSST Telescope and Site Systems.
+# This product includes software developed by the LSST Project
+# (https://www.lsst.org).
+# See the COPYRIGHT file at the top-level directory of this distribution
+# for details of code ownership.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import unittest
+
+from lsst.ts.wep.utils import writeCleanUpRepoCmd, writePipetaskCmd
+
+
+class TestTaskUtils(unittest.TestCase):
+ """Test the task utility functions."""
+
+ def _writePipetaskCmd(
+ self,
+ repoName,
+ instrument,
+ collections,
+ runName,
+ taskName=None,
+ pipelineName=None,
+ ):
+ # Write the part of the command that is always included
+ testCmd = f"pipetask run -b {repoName} -i {collections} "
+ testCmd += f"--instrument {instrument} "
+ testCmd += f"--register-dataset-types --output-run {runName}"
+
+ # Write with taskName
+ if taskName is not None:
+ testCmd += f" -t {taskName}"
+
+ # Write with pipeline filename
+ if pipelineName is not None:
+ testCmd += f" -p {pipelineName}"
+
+ return testCmd
+
+ def _writeCleanUpCmd(self, repoName, runName):
+ testCmd = f"butler remove-runs {repoName} {runName}"
+ testCmd += " --no-confirm"
+
+ return testCmd
+
+ def testWritePipetaskCmd(self):
+ repoName = "testRepo"
+ instrument = "lsst.obs.lsst.LsstCam"
+ collections = "refcats"
+ runName = "run2"
+
+ # Test writing with task name
+ taskName = "lsst.ts.wep.testTask"
+ testCmdTask = self._writePipetaskCmd(
+ repoName, instrument, collections, runName, taskName=taskName
+ )
+
+ pipeOutTask = writePipetaskCmd(
+ repoName, runName, instrument, collections, taskName=taskName
+ )
+ self.assertEqual(testCmdTask, pipeOutTask)
+
+ # Test writing with pipeline
+ pipelineYamlFile = "testPipeOut.yaml"
+ testCmdYaml = self._writePipetaskCmd(
+ repoName, instrument, collections, runName, pipelineName=pipelineYamlFile
+ )
+
+ pipeOutYaml = writePipetaskCmd(
+ repoName, runName, instrument, collections, pipelineYaml=pipelineYamlFile
+ )
+ self.assertEqual(testCmdYaml, pipeOutYaml)
+
+ assertMsg = "At least one of taskName or pipelineYaml must not be None"
+ with self.assertRaises(ValueError) as context:
+ writePipetaskCmd(repoName, runName, instrument, collections)
+ self.assertTrue(assertMsg in str(context.exception))
+
+ def testWriteCleanUpRepoCmd(self):
+ repoName = "testRepo"
+ runName = "run2"
+
+ testCmd = self._writeCleanUpCmd(repoName, runName)
+ self.assertEqual(testCmd, writeCleanUpRepoCmd(repoName, runName))
diff --git a/tests/cwfs/test_tool.py b/tests/utils/test_zernikeUtils.py
similarity index 89%
rename from tests/cwfs/test_tool.py
rename to tests/utils/test_zernikeUtils.py
index 9423f92a..b3c55a93 100644
--- a/tests/cwfs/test_tool.py
+++ b/tests/utils/test_zernikeUtils.py
@@ -24,22 +24,20 @@
import numpy as np
from astropy.io import fits
-from lsst.ts.wep.cwfs.tool import (
+from lsst.ts.wep.utils import (
ZernikeAnnularEval,
ZernikeAnnularFit,
ZernikeAnnularGrad,
ZernikeAnnularJacobian,
ZernikeMaskedFit,
- extractArray,
- padArray,
+ getModulePath,
)
-from lsst.ts.wep.utility import getModulePath
from lsst.utils.tests import TestCase
from scipy.integrate import nquad
-class TestTool(TestCase):
- """Test the functions in Tool."""
+class TestZernikeUtils(TestCase):
+ """Test the Zernike utility functions."""
def setUp(self):
self.testDataDir = os.path.join(
@@ -222,29 +220,6 @@ def testZernikeMaskFit(self):
self.assertLess(np.sum(np.abs(zr - self.zerCoef[0:nc]) ** 2), 1e-10)
- def testPadArray(self):
- imgDim = 10
- padPixelSize = 20
-
- img, imgPadded = self._padRandomImg(imgDim, padPixelSize)
-
- self.assertEqual(imgPadded.shape[0], imgDim + padPixelSize)
-
- def _padRandomImg(self, imgDim, padPixelSize):
- img = np.random.rand(imgDim, imgDim)
- imgPadded = padArray(img, imgDim + padPixelSize)
-
- return img, imgPadded
-
- def testExtractArray(self):
- imgDim = 10
- padPixelSize = 20
- img, imgPadded = self._padRandomImg(imgDim, padPixelSize)
-
- imgExtracted = extractArray(imgPadded, imgDim)
-
- self.assertEqual(imgExtracted.shape[0], imgDim)
-
if __name__ == "__main__":
# Do the unit test