class NexusSink(FileSink): """This is a sink for writing NeXus HDF5 files from a template. The template is a dictionary representing the structure of the NeXus file. Special elements in this dictionary are responsible for writing the various NeXus elements. The actual writing work is done in the NexusSinkHandler. This class just initializes the handler properly. """ parameters = { 'templateclass': Param('Python class implementing ' 'NexusTemplateProvider', type=str, mandatory=True), } parameter_overrides = { 'settypes': Override(type=setof(*(POINT,))), } handlerclass = NexusSinkHandler _handlerObj = None def doInit(self, mode): if mode == SLAVE: return # The default implementation creates gazillions of SinkHandlers. # For NeXus we do not want this, we want one keeping track of the whole # process. However, we want a handler object per file. def createHandlers(self, dataset): if self._handlerObj is None: if len(dataset.detectors) == 1: self._handlerObj = self.handlerclass(self, dataset, dataset.detectors[0]) else: self._handlerObj = self.handlerclass(self, dataset, None) else: self._handlerObj.dataset = dataset return [self._handlerObj] def end(self): self._handlerObj = None def loadTemplate(self): mod, cls = self.templateclass.rsplit('.', 1) mod = importlib.import_module(mod) class_ = getattr(mod, cls) return class_().getTemplate()
class DataSink(Device): """The base class for data sinks. Each sink represents one way of processing incoming data. This is a device to be instantiated once per setup so that it can be configured easily through NICOS setups. Actual processing is done by a `DataSinkHandler` class, of which one or more instances are created for each dataset that is processed with this sink. Usually, sinks are specific to a certain type of dataset (e.g. points or scans) and therefore override the `settypes` parameter with a default value that reflects this. .. attribute:: handlerclass This class attribute must be set by subclasses. It selects the subclass of `.DataSinkHandler` that is to be used for handling datasets with this sink. .. attribute:: activeInSimulation This is a class attribute that selects whether this sink can be used in simulation mode. This should only be true for sinks that write no data, such as a "write scan data to the console" sink. .. automethod:: isActive """ parameters = { 'detectors': Param('List of detector names to activate this sink ' '(default is always activated)', type=listof(str)), 'settypes': Param('List of dataset types to activate this sink ' '(default is for all settypes the sink supports)', type=setof(*SETTYPES)), } parameter_overrides = { 'lowlevel': Override(default=True, mandatory=False), } # Set to true in subclasses that are safe for simulation. activeInSimulation = False # Set this to the corresponding Handler class. handlerclass = None def isActive(self, dataset): """Should return True if the sink can and should process this dataset. The default implementation, which should always be called in overrides, checks for simulation mode and for a match with the settypes and the detectors selected by the respective parameters. Derived classes can add additional checks, such as the dataset producing an array that can be written to an image file. """ if session.mode == SIMULATION and not self.activeInSimulation: return False if self.settypes and dataset.settype not in self.settypes: return False if self.detectors and \ not ({d.name for d in dataset.detectors} & set(self.detectors)): return False return True def createHandlers(self, dataset): """Start processing the given dataset (a BaseDataset). Creates the corresponding DataSinkHandler instances to use for this dataset determined via `handlerclass` and returns them. """ if self.handlerclass is None: raise NotImplementedError('Must set an "handlerclass" attribute ' 'on %s' % self.__class__) # pylint: disable=not-callable if dataset.settype == POINT: dets = {d.name for d in dataset.detectors} if self.detectors: dets &= set(self.detectors) return [self.handlerclass(self, dataset, session.getDevice(det)) for det in dets] else: return [self.handlerclass(self, dataset, None)]
def test_setof(): SETTYPES = (1, 2, 3, 4) assert setof(*SETTYPES)() == frozenset() assert setof(*SETTYPES)([1]) == frozenset([1]) assert raises(ValueError, setof(*SETTYPES), [5])