Source code for tuna.tools.continuum
# -*- coding: utf-8 -*-
"""
This module's scope are operations to calculate the continuum in a data cube.
Example::
>>> import tuna
>>> raw = tuna.io.read ( "tuna/test/unit/unit_io/adhoc.ad3" )
>>> continuum_detector = tuna.tools.continuum_detector ( raw = raw )
>>> continuum_detector.array [ 100 ] [ 100 ]
3.0
"""
import logging
import math
import numpy
import threading
import time
import tuna
[docs]class detector ( threading.Thread ):
"""
This class is responsible for detecting the continuum at each pixel, for a given input data cube.
It inherits from the :ref:`threading_label`.Thread class, and it auto-starts its thread execution. Clients are expected to use its .join ( ) method before using its results.
Its constructor expects the following parameters:
* can : :ref:`tuna_io_can_label`
Containing data from a spectrograph.
* continuum_to_FSR_ratio : float
Encoding the ratio below which values are to be ignored.
"""
def __init__ ( self,
can : tuna.io.can,
continuum_to_FSR_ratio : float = 0.25 ) -> None:
super ( self.__class__, self ).__init__ ( )
self.__version__ = "0.1.0"
self.changelog = {
"0.1.0" : "Tuna 0.15.0 : Added changelog. Moved to tuna.tools.continuum. Refactored as a plugin."
}
self.log = logging.getLogger ( __name__ )
self.can = can
self.continuum_to_FSR_ratio = continuum_to_FSR_ratio
self.continuum = None
self.start ( )
[docs] def run ( self ):
"""
Method required by :ref:`threading_label`, which allows parallel exection in a separate thread.
"""
start = time.time ( )
continuum_array = numpy.zeros ( shape = ( self.can.array.shape [ 1 ],
self.can.array.shape [ 2 ] ) )
self.log.debug ( "Continuum array 0% created." )
last_percentage_logged = 0
for row in range ( self.can.array.shape [ 1 ] ):
percentage = 10 * int ( row / self.can.array.shape [ 1 ] * 10 )
if ( percentage > last_percentage_logged ):
last_percentage_logged = percentage
self.log.debug ( "Continuum array %d%% created." % ( percentage ) )
for col in range ( self.can.array.shape [ 2 ] ):
continuum_array [ row ] [ col ] = median_of_lowest_channels ( spectrum = self.can.array [ :, row, col ],
continuum_to_FSR_ratio = self.continuum_to_FSR_ratio )
self.log.info ( "Continuum array created." )
self.continuum = tuna.io.can ( array = continuum_array )
self.log.debug ( "detect_continuum() took %ds." % ( time.time ( ) - start ) )
[docs]def suppress_channel ( replacement,
array = numpy.ndarray,
channels = list ):
"""
This function creates a copy of the input array, substituting the input channels list with the channels from the input replacement.
Parameters:
* replacement: numpy.ndarray
Contains the signal where channels are going to be replaced from.
* array : numpy.ndarray
The data that is going to be copied, and the original data is from.
* channels : list
Lists the indexes of the channels to be substituted.
"""
result = numpy.copy ( array )
for channel in channels:
result [ channel ] = numpy.copy ( replacement.array [ channel ] )
return result
[docs]def continuum_detector ( raw : tuna.io.can,
continuum_to_FSR_ratio : float = 0.25 ) -> tuna.io.can:
"""
This function's goal is to conveniently return a Tuna can containing the continuum data for the given input.
Parameters:
* raw : :ref:`tuna_io_can_label`
Containing data from a spectrograph.
* continuum_to_FSR_ratio : float
Encoding the ratio below which values are to be ignored.
"""
continuum_detector_object = detector ( can = raw,
continuum_to_FSR_ratio = continuum_to_FSR_ratio )
continuum_detector_object.join ( )
return continuum_detector_object.continuum