Exemple #1
0
    def assignCounter(self, dataset):
        """Assign counter numbers to the dataset.

        Datasets have no numbers until one is explicitly assigned.  Assignment
        should only be requested when a file is actually written, so that
        measurements that don't write files don't increment numbers needlessly.

        This can be called multiple times on a dataset; the counter will only
        be increased and assigned once.
        """
        if dataset.counter != 0:
            return
        if session.mode == SIMULATION:
            raise ProgrammingError('assignCounter should not be called in '
                                   'simulation mode')

        new_counters = self.incrementCounters(dataset.countertype)
        for (attr, value) in new_counters:
            setattr(dataset, attr, value)

        # push special counters into parameters for display
        if dataset.settype == SCAN:
            session.experiment._setROParam('lastscan', dataset.counter)
        elif dataset.settype == POINT:
            session.experiment._setROParam('lastpoint', dataset.counter)
Exemple #2
0
    def getFilenames(self, dataset, nametemplates, *subdirs, **kwargs):
        """Determines dataset filenames from filename templates.

        Call this instead of `createDataFile` if you want to resolve the
        templates and make the filenames known in the dataset, but create (or
        copy from external) the files on your own.

        Registers the first filename in the dataset as 'the' filename.  Returns
        a short path of the first filename and a list of the absolute paths of
        all filenames.  After the counting is finished, you should create the
        datafile(s) and then call `linkFiles` to create the hardlinks.

        Keyword argument `nomeasdata` can be set to true in order to not record
        this as a measurement data file in the dataset.  (Useful for either
        temporary files or auxiliary data files.)

        A dictionary of supplementary template values can be provided using
        the `additionalinfo` keyword argument.
        """
        if dataset.counter == 0:
            raise ProgrammingError('a counter number must be assigned to the '
                                   'dataset first')
        addinfo = kwargs.pop('additionalinfo', {})
        filenames = self.expandNameTemplates(nametemplates,
                                             additionalinfo=addinfo)
        filename = filenames[0]
        filepaths = [session.experiment.getDataFilename(ln, *subdirs)
                     for ln in filenames]

        if not kwargs.get('nomeasdata'):
            shortpath = path.join(*subdirs + (filename,))
            dataset.filenames.append(shortpath)
            dataset.filepaths.append(filepaths[0])

        return filename, filepaths
Exemple #3
0
 def __init__(self,
              name,
              type='other',
              errors='none',
              unit='',
              fmtstr='%.3f'):
     if type not in ('counter', 'monitor', 'time', 'other', 'error',
                     'filename', 'info'):
         raise ProgrammingError('invalid Value type parameter')
     if errors not in ('none', 'next', 'sqrt'):
         raise ProgrammingError('invalid Value errors parameter')
     self.name = name
     self.type = type
     self.errors = errors
     self.unit = unit
     self.fmtstr = fmtstr
Exemple #4
0
    def __init__(self,
                 description,
                 devclass,
                 optional=False,
                 multiple=False,
                 missingok=False):
        def complain(multiple, test):
            raise ProgrammingError(
                'devclass %r (%s): multiple should be a '
                'bool or a list of integers, but is %r '
                '(testing for %s)' %
                (devclass.__name__, description, multiple, test))

        # first check all our parameters.
        single = False

        # Do not change the order since bool is a subclass of int
        # see: https://docs.python.org/2/library/functions.html#bool
        if isinstance(multiple, bool):
            single = not multiple
            if single:
                # map False to [1] (single), whereas true is an unlimited list
                # which could not be handled by a python list object
                multiple = [1]
        elif isinstance(multiple, int):
            multiple = [multiple]

        # allowed non-list values are converted to a list above already...
        if isinstance(multiple, list):
            if not multiple:
                complain(multiple, 'list should be non-empty')
            for item in multiple:
                try:
                    if item != int(item):
                        complain(multiple, 'list items should be int\'s')
                    if item < 0:
                        complain(multiple, 'list items should be positive')
                except (TypeError, ValueError):
                    complain(multiple, 'list items should be numbers')
        elif not (isinstance(multiple, bool) and multiple):
            complain(multiple, 'is-a-list')
        # multiple is now True or a list of integers
        if not isinstance(optional, bool):
            raise ProgrammingError('optional must be a boolean')
        # now set member values
        self.description = description
        self.devclass = devclass
        self.optional = optional
        self.multiple = multiple
        self.single = single
        self.missingok = missingok
Exemple #5
0
    def createDataFile(self, dataset, nametemplates, *subdirs, **kwargs):
        """Creates and returns a file named according to the given list of
        nametemplates in the given subdir of the datapath.

        The nametemplate can be either a string or a list of strings.  In the
        second case, the first listentry is used to create the file and the
        remaining ones will be hardlinked to this file if the os supports this.

        Filename templates should contain placeholders in ``%(key)s`` format.
        Possible placeholder keys are all counters (see `getCounters`), the
        experiment's proposal info keys (e.g. ``proposal``) as well as all
        devices and parameters as accepted by `DeviceValueDict`.

        Setting `fileclass` as keyword argument a DataFile class can be
        specified used for creating the data file (descriptor).
        If no `fileclass` has been specified this defaults to
        `nicos.core.data.DataFile`.

        Keyword argument `nomeasdata` can be set to true in order to not record
        this as a measurement data file in the dataset.  (Useful for either
        temporary files or auxiliary data files.)
        """
        fileclass = kwargs.get('fileclass', DataFile)
        if session.mode == SIMULATION:
            raise ProgrammingError('createDataFile should not be called in '
                                   'simulation mode')
        filename, filepaths = self.getFilenames(dataset, nametemplates,
                                                *subdirs, **kwargs)
        filepath = filepaths[0]
        shortpath = path.join(*subdirs + (filename,))

        self.log.debug('creating file %r using fileclass %r', filename,
                       fileclass)
        if fileclass == DataFile:
            datafile = fileclass(
                shortpath, filepath, kwargs.pop('filemode', None),
                kwargs.pop('logger', None))
        else:
            datafile = fileclass(shortpath, filepath)
        exp = session.experiment
        if exp.managerights:
            os.chmod(filepath,
                     exp.managerights.get('enableFileMode', DEFAULT_FILE_MODE))
            # XXX add chown here?

        self.linkFiles(filepath, filepaths[1:])

        return datafile
Exemple #6
0
    def __init__(self,
                 description,
                 type=float,
                 default=_notset,
                 mandatory=False,
                 settable=False,
                 volatile=False,
                 unit=None,
                 fmtstr='%r',
                 category=None,
                 preinit=False,
                 prefercache=None,
                 userparam=None,
                 internal=False,
                 chatty=False,
                 no_sim_restore=False,
                 ext_desc=''):
        self.type = fixup_conv(type)
        if default is self._notset:
            default = type()
        self.default = default
        self.mandatory = mandatory
        self.settable = settable
        self.volatile = volatile
        self.unit = unit
        self.fmtstr = fmtstr
        self.category = category
        self.description = description
        self.preinit = preinit
        self.prefercache = prefercache
        self.internal = internal
        self.chatty = chatty
        self.no_sim_restore = no_sim_restore
        self.ext_desc = ext_desc
        self.classname = None  # filled by DeviceMeta

        if internal and mandatory:
            raise ProgrammingError("Ambiguous parameter settings detected. "
                                   "'internal' and 'mandatory' must be used "
                                   "exclusively.")

        if userparam is None:  # implicit settings
            self.userparam = not self.internal
        else:
            self.userparam = userparam
Exemple #7
0
    def _generateSequence(self, target):
        seq = []

        if target == '+':
            seq.append((SeqDev(self._attached_pom,
                               0.8), SeqDev(self._attached_pmag, -2.5)))
            seq.append(SeqSleep(4.))
            seq.append(SeqDev(self._attached_pmag, .15))
        elif target == '-':
            seq.append((SeqDev(self._attached_pom,
                               0.8), SeqDev(self._attached_pmag, 2.5)))
            seq.append(SeqSleep(4.))
            seq.append(SeqDev(self._attached_pmag, 1.))
        elif target == '0':
            seq.append((SeqDev(self._attached_pom,
                               3), SeqDev(self._attached_pmag, 0)))
        else:
            raise ProgrammingError('Invalid value requested')

        return seq
Exemple #8
0
    def _initObject(self):
        if not self._orb:
            raise ProgrammingError(self, 'Programmer forgot to call _initORB')

        obj = self._orb.resolve_initial_references('NameService')
        _root_context = obj._narrow(CosNaming.NamingContext)

        if not _root_context:
            raise CommunicationError(
                self, 'Failed to narrow the root naming'
                ' context')
        if self._is_corba_device():
            try:
                tmp = self.objname.split('.') if self.objname else \
                    self.config.split()[2].split('.')
                if len(tmp) < 2:
                    tmp.append('caress_object')
                self.log.debug('%r', tmp)
                obj = _root_context.resolve(
                    [CosNaming.NameComponent(tmp[0], tmp[1])])
            except CosNaming.NamingContext.NotFound as ex:
                raise ConfigurationError(self,
                                         'Name not found: %s' % (ex, )) from ex
            self._caressObject = obj._narrow(CARESS.CORBADevice)
        else:
            try:
                self._caressObject = \
                    self._orb.string_to_object('corbaname::%s#%s.context/'
                                               'caress.context/'
                                               'server.context/absdev.object' %
                                               (self.nameserver, self.objname))
            except CORBA.BAD_PARAM as ex:
                raise ConfigurationError(self,
                                         'Name not found: %s' % (ex, )) from ex

        if CORBA.is_nil(self._caressObject):
            raise CommunicationError(self, 'Could not create a CARESS device')

        if hasattr(self._caressObject, 'init_module_orb'):
            self._caressObject.init_module = self._caressObject.init_module_orb
Exemple #9
0
    def _assignCounter(self):
        # Adapted from DataManager.assignCounter function
        if self.dataset.counter != 0:
            return

        exp = session.experiment
        if not path.isfile(path.join(exp.dataroot, exp.counterfile)):
            session.log.warning('creating new empty file counter file at %s',
                                path.join(exp.dataroot, exp.counterfile))

        if session.mode == SIMULATION:
            raise ProgrammingError('assignCounter should not be called in '
                                   'simulation mode')

        # Read the counter from SICS file
        counter = exp.sicscounter + 1

        # Keep track of which files we have already updated, since the proposal
        # and the sample specific counter might be the same file.
        seen = set()
        for directory, attr in [(exp.dataroot, 'counter'),
                                (exp.proposalpath, 'propcounter'),
                                (exp.samplepath, 'samplecounter')]:
            counterpath = path.normpath(path.join(directory, exp.counterfile))
            readFileCounter(counterpath, self.dataset.countertype)
            if counterpath not in seen:
                updateFileCounter(counterpath, self.dataset.countertype,
                                  counter)
                seen.add(counterpath)

            setattr(self.dataset, attr, counter)

        # Update the counter in SICS file
        exp.updateSicsCounterFile(counter)

        session.experiment._setROParam('lastpoint', self.dataset.counter)
Exemple #10
0
 def __init__(self, shortpath, filepath):
     if path.isfile(filepath):
         raise ProgrammingError('Data file named %r already exists! '
                                'Check filename templates!' % filepath)
     self.shortpath = shortpath
     self.filepath = filepath
Exemple #11
0
 def decode(self, encoded):
     raise ProgrammingError('Decoder not implemented')
Exemple #12
0
 def encode(self, key, entry, **params):
     raise ProgrammingError('Encoder not implemented')
Exemple #13
0
 def __init__(self, *types):
     if not types:
         raise ProgrammingError('tupleof() needs some types as arguments')
     self.__doc__ = 'a tuple of (' + ', '.join(map(convdoc, types)) + ')'
     self.types = [fixup_conv(typeconv) for typeconv in types]
Exemple #14
0
 def complain(multiple, test):
     raise ProgrammingError(
         'devclass %r (%s): multiple should be a '
         'bool or a list of integers, but is %r '
         '(testing for %s)' %
         (devclass.__name__, description, multiple, test))
Exemple #15
0
 def metainfo(self):
     # The metainfo is the same as for the first datapoint / subscan.
     if not self.subsets:
         raise ProgrammingError('metainfo is not available without points')
     return self.subsets[0].metainfo
Exemple #16
0
 def doSetPreset(self, **preset):
     raise ProgrammingError(self, 'Channel.setPreset should not be called')