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)
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
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
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
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
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
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
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
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)
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
def decode(self, encoded): raise ProgrammingError('Decoder not implemented')
def encode(self, key, entry, **params): raise ProgrammingError('Encoder not implemented')
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]
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))
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
def doSetPreset(self, **preset): raise ProgrammingError(self, 'Channel.setPreset should not be called')