예제 #1
0
 def test_InheritFrom(self):
     from niprov.inheriting import inheritFrom
     parentProv = {
         'acquired': datetime.now(),
         'subject': 'JD',
         'protocol': 'X',
         'technique': 'abc',
         'repetition-time': 1.0,
         'epi-factor': 1.0,
         'magnetization-transfer-contrast': True,
         'diffusion': True,
         'echo-time': 123,
         'flip-angle': 892,
         'inversion-time': 123
     }
     prov = inheritFrom({'a': 1}, parentProv)
     self.assertEqual(prov['acquired'], parentProv['acquired'])
     self.assertEqual(prov['subject'], parentProv['subject'])
     self.assertEqual(prov['protocol'], parentProv['protocol'])
     self.assertEqual(prov['technique'], parentProv['technique'])
     self.assertEqual(prov['repetition-time'],
                      parentProv['repetition-time'])
     self.assertEqual(prov['epi-factor'], parentProv['epi-factor'])
     self.assertEqual(prov['magnetization-transfer-contrast'],
                      parentProv['magnetization-transfer-contrast'])
     self.assertEqual(prov['diffusion'], parentProv['diffusion'])
     self.assertEqual(prov['echo-time'], parentProv['echo-time'])
     self.assertEqual(prov['flip-angle'], parentProv['flip-angle'])
     self.assertEqual(prov['inversion-time'], parentProv['inversion-time'])
예제 #2
0
 def test_InheritFrom(self):
     from niprov.inheriting import inheritFrom
     parentProv = {'acquired':datetime.now(),
         'subject':'JD', 
         'protocol':'X',
         'technique':'abc',
         'repetition-time':1.0,
         'epi-factor':1.0,
         'magnetization-transfer-contrast':True,
         'diffusion':True,
         'echo-time':123,
         'flip-angle':892,
         'inversion-time':123}
     prov = inheritFrom({'a':1}, parentProv)
     self.assertEqual(prov['acquired'], parentProv['acquired'])
     self.assertEqual(prov['subject'], parentProv['subject'])
     self.assertEqual(prov['protocol'], parentProv['protocol'])
     self.assertEqual(prov['technique'], parentProv['technique'])
     self.assertEqual(prov['repetition-time'], parentProv['repetition-time'])
     self.assertEqual(prov['epi-factor'], parentProv['epi-factor'])
     self.assertEqual(prov['magnetization-transfer-contrast'], 
         parentProv['magnetization-transfer-contrast'])
     self.assertEqual(prov['diffusion'], parentProv['diffusion'])
     self.assertEqual(prov['echo-time'], parentProv['echo-time'])
     self.assertEqual(prov['flip-angle'], parentProv['flip-angle'])
     self.assertEqual(prov['inversion-time'], parentProv['inversion-time'])
예제 #3
0
 def test_Doesnt_complain_if_parent_is_missing_basic_fields(self):
     from niprov.inheriting import inheritFrom
     prov = inheritFrom({'a':1}, {'b':2})
예제 #4
0
파일: adding.py 프로젝트: ilogue/niprov
def add(filepath, transient=False, provenance=None, 
    dependencies=Dependencies()):
    """
    Simply register the file.

    Inspects the file and makes it known to the provenance data, such that 
    image files can be logged that have been created using this file. 
    Useful also for temporary files.
    
    Example:
        (provenance, status) = niprov.add('/path/to/my.nii')

    Args:
        filepath (str): Path to the newly created file.
        transient (bool, optional): Set this to True to indicate that the file 
            is only temporary and future checks should not expect it to be 
            physically present. Defaults to False, assuming that the file 
            remains.
        provenance (dict, optional): Add the key-value pairs in this dictionary 
            to the provenance record for the new file.

    Returns:
        tuple: Tuple of new provenance and status. Status is a string with one 
            of the following values:
            'new': File was not known yet and has been added.
            'series': The file was deemed part of a series and has been added.
            'failed': There was an error inspecting the file.
            'known': The file was already known to niprov, nothing happened.
            'dryrun': Function called with config.dryrun, database not touched.
    """
    config = dependencies.getConfiguration()
    file = dependencies.getFileFactory()
    repository = dependencies.getRepository()
    listener = dependencies.getListener()
    filesys = dependencies.getFilesystem()
    query = dependencies.getQuery()

    if provenance is None:
        provenance = {}
    provenance['transient'] = transient
    provenance['added'] = datetime.now()
    provenance['id'] = shortuuid.uuid()[:6]
    vparts = pkg_resources.get_distribution("niprov").version.split('.')
    provenance['version-added'] = float(vparts[0] + '.' + ''.join(vparts[1:]))

    img = file.locatedAt(filepath, provenance=provenance)
    if config.dryrun:
        return img

    if not transient:
        if not filesys.fileExists(img.location.path):
            raise IOError(errno.ENOENT, 'File not found', img.location.path)
        try:
            img.inspect()
        except:
            img.status = 'failed'
            listener.fileError(img.path)
            return img
        if config.attach:
            img.attach(config.attach_format)

    if not provenance.get('parents', []):
        for copy in query.copiesOf(img):
            if not copy.location == img.location:
                inheritFrom(img.provenance, copy.provenance)
                img.provenance['parents'] = [copy.location.toString()]
                img.provenance['copy-as-parent'] = True
                listener.usingCopyAsParent(copy)
                break

    previousVersion = repository.byLocation(img.location.toString())
    series = repository.getSeries(img)
    if previousVersion:
        img.keepVersionsFromPrevious(previousVersion)
    elif series:
        if series.hasFile(img):
            img.keepVersionsFromPrevious(series)
        else:
            img = series.mergeWith(img)

    if not previousVersion and not series:
        repository.add(img)
    else:
        repository.update(img)

    listener.fileAdded(img)
    return img
예제 #5
0
파일: plogging.py 프로젝트: ilogue/niprov
def log(new, transformation, parents, code=None, logtext=None, transient=False,
        script=None, user=None, provenance=None, opts=None,
        dependencies=Dependencies()):
    """
    Register a transformation that creates a new image (or several).

    This will retrieve the primary parent's provenance. if no provenance is 
    availale for the primary parent, calls listener.unknownFile. Otherwise,
    some fields are copied from the primary parent, subject to availability. 
    For instance, if the parent has no 'subject' field, the new file's 
    provenance won't either.

    Args:
        new (str or list): Path(s) to the newly created file(s).
        transformation (str): Name of the operation that has been used.
        parents (str or list): Path(s) to the file(s) that were used as the 
            basis of the transformation. Assumes that the first file in the 
            list is the primary parent for which basic provenance is known.
        code (str, optional): Code that was used to generate the new file
        logtext (str, optional): Any information about the transformation that 
            was logged.
        script (str, optional): Path to the code file that contains the 
            transformation code.
        transient (bool, optional): Set this to True to indicate that the file 
            is only temporary and future checks should not expect it to be 
            physically present. Defaults to False, assuming that the file 
            remains.
        user (string, optional): Name of the user logging provenance.
        provenance (dict, optional): Add the key-value pairs in this dictionary 
            to the provenance record for the new files.
        opts (Configuration): General settings for niprov. 
            See :py:mod:`niprov.config`

    Raises:
      IOError: '[Errno 2] File not found' is raised if the new file does not
        exist on the filesystem and is not marked as transient.

    Returns:
        BaseFile: New provenance, if multiple files were created, this is 
            a list of images, otherwise, it is a single object.
    """
    repository = dependencies.getRepository()
    listener = dependencies.getListener()
    factory = dependencies.getFileFactory()
    filesys = dependencies.getFilesystem()
    opts = dependencies.reconfigureOrGetConfiguration(opts)
    location = dependencies.getLocationFactory()
    users = dependencies.getUsers()

    if isinstance(new, basestring):
        new = [new]
    if isinstance(parents, basestring):
        parents = [parents]
    if provenance is None:
        provenance = {}

    #gather provenance common to all new files
    parents = [location.completeString(p) for p in parents]
    commonProvenance = provenance
    commonProvenance['parents'] = parents
    commonProvenance['transformation'] = transformation
    commonProvenance['script'] = script
    commonProvenance['user'] = users.determineUser(user)
    if code:
        commonProvenance['code'] = code
    if logtext:
        commonProvenance['logtext'] = logtext
    parent = repository.byLocation(parents[0])
    if parent is None:
        parent = add(parents[0], dependencies=dependencies)
        listener.addUnknownParent(parents[0])

    inheritFrom(commonProvenance, parent.provenance)

    # do things specific to each new file
    newImages = []
    for newfile in new:
        singleProvenance = copy.deepcopy(commonProvenance)
        image = add(newfile, transient=transient, provenance=singleProvenance, 
            dependencies=dependencies)
        newImages.append(image)

    # only return one image if only one file was created
    if len(new) == 1:
        return image

    return newImages
예제 #6
0
 def test_Doesnt_complain_if_parent_is_missing_basic_fields(self):
     from niprov.inheriting import inheritFrom
     prov = inheritFrom({'a': 1}, {'b': 2})
예제 #7
0
def log(new,
        transformation,
        parents,
        code=None,
        logtext=None,
        transient=False,
        script=None,
        user=None,
        provenance=None,
        opts=None,
        dependencies=Dependencies()):
    """
    Register a transformation that creates a new image (or several).

    This will retrieve the primary parent's provenance. if no provenance is 
    availale for the primary parent, calls listener.unknownFile. Otherwise,
    some fields are copied from the primary parent, subject to availability. 
    For instance, if the parent has no 'subject' field, the new file's 
    provenance won't either.

    Args:
        new (str or list): Path(s) to the newly created file(s).
        transformation (str): Name of the operation that has been used.
        parents (str or list): Path(s) to the file(s) that were used as the 
            basis of the transformation. Assumes that the first file in the 
            list is the primary parent for which basic provenance is known.
        code (str, optional): Code that was used to generate the new file
        logtext (str, optional): Any information about the transformation that 
            was logged.
        script (str, optional): Path to the code file that contains the 
            transformation code.
        transient (bool, optional): Set this to True to indicate that the file 
            is only temporary and future checks should not expect it to be 
            physically present. Defaults to False, assuming that the file 
            remains.
        user (string, optional): Name of the user logging provenance.
        provenance (dict, optional): Add the key-value pairs in this dictionary 
            to the provenance record for the new files.
        opts (Configuration): General settings for niprov. 
            See :py:mod:`niprov.config`

    Raises:
      IOError: '[Errno 2] File not found' is raised if the new file does not
        exist on the filesystem and is not marked as transient.

    Returns:
        BaseFile: New provenance, if multiple files were created, this is 
            a list of images, otherwise, it is a single object.
    """
    repository = dependencies.getRepository()
    listener = dependencies.getListener()
    factory = dependencies.getFileFactory()
    filesys = dependencies.getFilesystem()
    opts = dependencies.reconfigureOrGetConfiguration(opts)
    location = dependencies.getLocationFactory()
    users = dependencies.getUsers()

    if isinstance(new, basestring):
        new = [new]
    if isinstance(parents, basestring):
        parents = [parents]
    if provenance is None:
        provenance = {}

    #gather provenance common to all new files
    parents = [location.completeString(p) for p in parents]
    commonProvenance = provenance
    commonProvenance['parents'] = parents
    commonProvenance['transformation'] = transformation
    commonProvenance['script'] = script
    commonProvenance['user'] = users.determineUser(user)
    if code:
        commonProvenance['code'] = code
    if logtext:
        commonProvenance['logtext'] = logtext
    parent = repository.byLocation(parents[0])
    if parent is None:
        parent = add(parents[0], dependencies=dependencies)
        listener.addUnknownParent(parents[0])

    inheritFrom(commonProvenance, parent.provenance)

    # do things specific to each new file
    newImages = []
    for newfile in new:
        singleProvenance = copy.deepcopy(commonProvenance)
        image = add(newfile,
                    transient=transient,
                    provenance=singleProvenance,
                    dependencies=dependencies)
        newImages.append(image)

    # only return one image if only one file was created
    if len(new) == 1:
        return image

    return newImages