Questions while reading astrometry.py

I have problems reading the following code AstrometryTask
like scheme, the description about lsst.afw.table.Schema is too little that I can’t understand what were transfer to the __init__ function of AstrometryTask.

I try to instance the Scheme class to know what the followling code’role is

self.usedKey = schema.addField("calib_astrometry_used", type="Flag",
                                           doc="set if source was used in astrometric calibration")

but it can’t be instanced

from lsst.afw.table import Schema
a = Scheme()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_6334/1266743854.py in <module>
      1 from lsst.afw.table import Schema
----> 2 a = Scheme()

TypeError: 'str' object is not callable

The following can’t excute too,

Schema.addField("calib_astrometry_used", type="Flag",doc="set if source was used in astrometric calibration")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_6334/1164436723.py in <module>
----> 1 Schema.addField("calib_astrometry_used", type="Flag",doc="set if source was used in astrometric calibration")

TypeError: addField() missing 1 required positional argument: 'field'

So, can you give me some introduction about what scheme is?

I have question reading the __init__ function of Task too,

def __init__(self, config=None, name=None, parentTask=None, log=None):
        self.metadata = dafBase.PropertyList()
        self.__parentTask: Optional[weakref.ReferenceType]
        self.__parentTask = parentTask if parentTask is None else weakref.ref(pa                                                                                                             rentTask)

        if parentTask is not None:
            if name is None:
                raise RuntimeError("name is required for a subtask")
            self._name = name
            self._fullName = parentTask._computeFullName(name)
            if config is None:
                config = getattr(parentTask.config, name)
            self._taskDict = parentTask._taskDict
            loggerName = parentTask.log.getChild(name).name
        else:
            if name is None:
                name = getattr(self, "_DefaultName", None)
                if name is None:
                    raise RuntimeError("name is required for a task unless it ha                                                                                                             s attribute _DefaultName")
                name = self._DefaultName
            self._name = name
            self._fullName = self._name
            if config is None:
                config = self.ConfigClass()
            self._taskDict = dict()
            loggerName = self._fullName
            if log is not None and log.name:
                loggerName = log.getChild(loggerName).name
            elif self._add_module_logger_prefix:
                # Prefix the logger name with the root module name.
                # We want all Task loggers to have this prefix to make
                # it easier to control them. This can be disabled by
                # a Task setting the class property _add_module_logger_prefix
                # to False -- in which case the logger name will not be
                # modified.
                module_name = self.__module__
                module_root = module_name.split(".")[0] + "."
                if not loggerName.startswith(module_root):
                    loggerName = module_root + loggerName

        # Get a logger (that might be a subclass of logging.Logger).
        self.log = lsst.utils.logging.getLogger(loggerName)
        self.config = config
        if lsstDebug:
            self._display = lsstDebug.Info(self.__module__).display
        else:
            self._display = None
        self._taskDict[self._fullName] = weakref.ref(self)

though I know the meaning of the following code:

config=None, name=None, parentTask=None, log=None,

But there are no examples tell me what is really tranfer to the function.
And I find no footprints that make a variable named parenTask in it’s parent-task like RefMatchTask or Astrometry task. So, How the variable like parentTask be created?

You might want to check for simple errors (like typing Scheme instead of Schema or calling instance methods on a class) before posting here.

The best documentation for lsst.afw.table is not in pipelines.lsst.io, unfortunately, partly because it is primarily implemented in C++. Our Doxygen documentation at LSST Applications: Tables is a better place to start, but it is already at a fairly advanced level.

1 Like

Thank you very much !

Sorry I was confused by the schema parameter transfer to the __init__ function of AstrometryTask and the Class Schema

    def __init__(self, refObjLoader, schema=None, **kwargs):
        RefMatchTask.__init__(self, refObjLoader, **kwargs)

        if schema is not None:
            self.usedKey = schema.addField("calib_astrometry_used", type="Flag",
                                           doc="set if source was used in astrometric calibration")

I have some concepts about what schema is after making an instance,
Sorry for asking such a question.
Thank you!

Hello,

I am now reading the Class ReferenceObjectLoader. I want to know the parameters that passed into the __init__ function. And try to excute the class methods that RefMatchTask calls.

I use the rc2_subset dataset.

So, Like I can get an raw Exposure by

butler.get('raw',expsure=23718, detector=58, collections=collection,instrument='HSC')

How can I get a refObjLoader that can used on this raw image? what parameters should be passed to the ReferenceObjLoader's __init__?

 def __init__(self, dataIds, refCats, log=None, **kwargs):
        super().__init__(**kwargs)
        self.dataIds = dataIds
        self.refCats = refCats
        self.log = log or logging.getLogger(__name__).getChild("ReferenceObjectLoader")

As for my version of pipeline the parameters are:

def __init__(self, dataIds, refCats, config, log=None):

Thank you!

Hi Yuanyu -

I do not understand what you are actually trying to do, so a more specific code example might be helpful. However, the refObjLoader is used by many pieces of pipeline code, so a search in the main https://github.com/lsst organization for “refObjLoader” will return many examples of how this is used in Science Pipelines code (here is an example).

There are two “tutorial” notebooks demonstrating the loading of refcats into Jupyter notebooks, but they have not been reviewed yet. They are here and here, but because they are still being reviewed, they may change before being merged to the main repository (and these links will probably stop working once that happens).

Best of luck in understanding the pipelines code, and let us know if you have further questions.