7. Execution results¶
7.1. Result frames¶
- class cpl.Result¶
Calling cpl.Recipe.__call__() returns an object that contains all result (‘production’) frames in attributes. All results for one tag are summarized in one attribute of the same name. So, the muse_bias recipe returns a frame with the tag MASTER_BIAS in the according attribute:
res = muse_bias(...) res.MASTER_BIAS.writeto('master_bias')
The attribute content is either a astropy.io.fits.HDUList or a list() of HDU lists, depending on the recipe and the call: If the recipe produces one out put frame of a tag per input file, the attribute contains a list if the recipe was called with a list, and if the recipe was called with a single input frame, the result attribute will also contain a single input frame. If the recipe combines all input frames to one output frame, a single astropy.io.fits.HDUList es returned, independent of the input parameters. The following examples will illustrate this:
muse_scibasic = cpl.Recipe('muse_scibasic') ... # Only single input frame, so we get one output frame res = muse_scibasic('raw.fits') res.PIXTABLE_OBJ.writeto('pixtable.fits') # List of input frames results in a list of output frames res = muse_scibasic([ 'raw1.fits', 'raw2.fits', 'raw3.fits' ]) for i, h in res.PIXTABLE_OBJ: h.writeto('pixtable%i.fits' % (i+1)) # If we call the recipe with a list containing a single frame, we get a list # with a single frame back res = muse_scibasic([ 'raw1.fits' ]) res.PIXTABLE_OBJ[0].writeto('pixtable1.fits') # The bias recipe always returns one MASTER BIAS, regardless of number of # input frames. So we always get a single frame back. muse_bias = cpl.Recipe('muse_bias') ... res = muse_bias([ 'bias1.fits', 'bias2.fits', 'bias3.fits' ]) res.MASTER_BIAS.writeto('master_bias.fits')
Note
This works well only for MUSE recipes. Other recipes dont provide the necessary information about the recipe.
7.2. Run statistics¶
In Addition to the result frames the cpl.Result object provides the attribute cpl.Result.stat which contains several statistics of the recipe execution:
- cpl.Result.return_code¶
The return code of the recipe. Since an exception is thrown if the return code indicates an error, this attribute is always set to 0.
- cpl.Result.stat.user_time¶
CPU time in user mode, in seconds.
- cpl.Result.stat.sys_time¶
CPU time in system mode, in seconds.
7.3. Execution log¶
- cpl.Result.log¶
List of log messages for the recipe.
See also
- cpl.Result.error¶
If one or more error was set during the recipe run, the first error is stored in this attribute. The following errors are chained and can be accessed with the cpl.CplError.next attribute.
Note
An error here does not indicate a failed recipe execution, since a failed execution would result in a non-zero return code, and an exception would be thrown.
See also
7.4. Thread control¶
If the recipe was called in the background (see Parallel execution), the result object is returned immediately and is dervived from threading.Thread. Its interface can be used to control the thread execution:
- cpl.Result.isAlive()¶
Returns whether the recipe is still running
- cpl.Result.join(timeout = None)¶
Wait until the recipe terminates. This blocks the calling thread until the recipe terminates – either normally or through an unhandled exception – or until the optional timeout occurs.
When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call isAlive() after join() to decide whether a timeout happened – if the recipe is still running, the join() call timed out.
When the timeout argument is not present or None, the operation will block until the recipe terminates.
A thread can be cpl.Result.join() ed many times.
Like in the foreground execution, the output frames may be retrieved as attributes of the cpl.Result frame. If any of the attributes is accessed, the calling thread will block until the recipe is terminated. If the recipe execution raised an exception, this exception will be raised whenever an attribute is accessed.
7.5. CPL Exceptions¶
- exception cpl.CplError(retval, res, logger=None)¶
Error message from the recipe.
If the CPL recipe invocation returns an error, it is converted into a cpl.CplError exception and no frames are returned. Also, the error is notified in the log file.
The exception is raised on recipe invocation, or when accessing the result frames if the recipe was started in background (cpl.Recipe.threaded set to True).
Attributes:
- code¶
The CPL error code returned from the recipe.
- msg¶
The supplied error message.
- filename¶
The source file name where the error occurred.
- line¶
The line number where the error occurred.
- log¶
Log lines of the recipe that lead to this exception.
See also
- exception cpl.RecipeCrash(bt_file)¶
Recipe crash exception
If the CPL recipe crashes with a SIGSEV or a SIGBUS, the C stack trace is tried to conserved in this exception. The stack trace is obtained with the GNU debugger gdb. If the debugger is not available, or if the debugger cannot be attached to the crashed recipe, the Exception remains empty.
When converted to a string, the Exception will return a stack trace similar to the Python stack trace.
The exception is raised on recipe invocation, or when accessing the result frames if the recipe was started in background (cpl.Recipe.threaded set to True).
Attributes:
- elements¶
List of stack elements, with the most recent element (the one that caused the crash) at the end. Each stack element is a collections.namedtuple() with the following attributes:
- filename¶
Source file name, including full path, if available.
- line¶
Line number, if available
- func¶
Function name, if available
- params¶
Dictionary parameters the function was called with. The key here is the parameter name, the value is a string describing the value set.
- localvars¶
Dictionary of local variables of the function, if available. The key here is the parameter name, the value is a string describing the value set.
- signal¶
Signal that caused the crash.