예제 #1
0
def register(experiment_id, acquisition_id):
    """
    .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/register

        Register a single directory (passed as parameter `path` in the
        JSON request) as the directory containing all the files for
        the given acquisition.

        Calling this method twice with different `path` parameters
        will result in an error (so you cannot combine the contents of
        two directories by 'registering' them).  On the other hand,
        the *same* directory can be registered over and over again
        without adverse side-effects; the method is idempotent in this
        sense.

        **Example request**:

        .. sourcecode:: http

            Content-Type: application/json

            {
                "path": "/fullpath/to/serversidedata"
            }

        **Example response**:

        .. sourcecode:: http

            HTTP/1.1 200 OK
            Content-Type: application/json

            {
                "data": "/fullpath/to/serversidedata"
            }

        :reqheader Authorization: JWT token issued by the server
        :statuscode 200: no error
        :statuscode 500: server error
    """
    data = request.get_json()
    path = data['path']
    logger.info('Registering microscope files from path `%s` ...', path)

    try:
        filenames = [
            f for f in os.listdir(path)
            if (not f.startswith('.')
                and not os.path.isdir(os.path.join(path, f)))
        ]
    except OSError as err:
        logger.error("Cannot list directory `%s`: %s", path, err)
        raise

    with tm.utils.ExperimentSession(experiment_id) as session:
        experiment = session.query(tm.Experiment).one()
        microscope_type = experiment.microscope_type
        img_regex, metadata_regex = get_microscope_type_regex(microscope_type)
        acquisition = session.query(tm.Acquisition).get(acquisition_id)
        plate = session.query(tm.Plate).get(acquisition.plate_id)

        # check for image files already registered
        img_filenames = [f.name for f in acquisition.microscope_image_files]
        img_files = [
            tm.MicroscopeImageFile(
                name=f, acquisition_id=acquisition.id
            )
            for f in filenames
            if img_regex.search(f) and
            f not in img_filenames
        ]
        # check for metadata already registered
        meta_filenames = [f.name for f in acquisition.microscope_metadata_files]
        meta_files = [
            tm.MicroscopeMetadataFile(
                name=secure_filename(f), acquisition_id=acquisition.id
            )
            for f in filenames
            if metadata_regex.search(f) and
            f not in meta_filenames
        ]

        session.bulk_save_objects(img_files + meta_files)

        # trigger creation of directories
        acquisition.location
        acquisition.microscope_metadata_location

        # link root directory
        path_to_link = os.path.join(
            LibraryConfig().storage_home,
            ('experiment_{}'
             '/plates/plate_{}'
             '/acquisitions/acquisition_{}'
             '/microscope_images'
            .format(experiment.id, plate.id, acquisition.id)))
        if not os.path.exists(path_to_link):
            try:
                os.symlink(path, path_to_link)
            except Exception as err:
                logger.debug(
                    "Error linking source directory `%s` to TM directory `%s`: %s",
                    path, path_to_link, err)
                raise
        else:
            # path exists, check if it is correct
            p1 = os.path.realpath(path)
            p2 = os.path.realpath(path_to_link)
            if p1 != p2:
                raise ValueError(
                    "Acquisition {a} of plate {p} of experiment {e}"
                    " is already linked to directory `{d}`"
                    .format(
                        a=acquisition.id,
                        p=plate.id,
                        e=epxeriment.id,
                        d=p1))

        microscope_files = session.query(tm.MicroscopeImageFile).filter_by(acquisition_id=acquisition.id).all()
        for microscope_file in microscope_files:
            microscope_file.location
            microscope_file.status = 'COMPLETE'

    return jsonify(message='ok')
예제 #2
0
def register_upload(experiment_id, acquisition_id):
    """
    .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/upload/register

        Notify the server that an upload for this acquisition is imminent.
        The client has to wait for this response before uploading files.

        **Example request**:

        .. sourcecode:: http

            Content-Type: application/json

            {
                "files": ["file1.png", "file2.png", ...]
            }

        **Example response**:

        .. sourcecode:: http

            HTTP/1.1 200 OK
            Content-Type: application/json

            {
                "data": ["file1.png", "file2.png", ...]
            }

        :reqheader Authorization: JWT token issued by the server
        :statuscode 200: no error
        :statuscode 500: server error

    """
    logger.info('register microscope files for upload')
    data = request.get_json()
    files = data['files']

    if len(files) == 0:
        raise MalformedRequestError(
            'No files supplied. Cannot register upload.'
        )

    with tm.utils.ExperimentSession(experiment_id) as session:
        experiment = session.query(tm.Experiment).one()
        microscope_type = experiment.microscope_type
        img_regex, metadata_regex = get_microscope_type_regex(microscope_type)
        acquisition = session.query(tm.Acquisition).get(acquisition_id)
        img_filenames = [f.name for f in acquisition.microscope_image_files]
        img_files = [
            tm.MicroscopeImageFile(
                name=secure_filename(f), acquisition_id=acquisition.id
            )
            for f in files
            if img_regex.search(f) and
            secure_filename(f) not in img_filenames
        ]
        meta_filenames = [f.name for f in acquisition.microscope_metadata_files]
        meta_files = [
            tm.MicroscopeMetadataFile(
                name=secure_filename(f), acquisition_id=acquisition.id
            )
            for f in files
            if metadata_regex.search(f) and
            secure_filename(f) not in meta_filenames
        ]

        session.bulk_save_objects(img_files + meta_files)

        # Trigger creation of directories
        acquisition.location
        acquisition.microscope_images_location
        acquisition.microscope_metadata_location

    with tm.utils.ExperimentSession(experiment_id) as session:
        image_filenames = session.query(tm.MicroscopeImageFile.name).\
            filter(tm.MicroscopeImageFile.status != FileUploadStatus.COMPLETE).\
            all()
        metadata_filenames = session.query(tm.MicroscopeMetadataFile.name).\
            filter(tm.MicroscopeMetadataFile.status != FileUploadStatus.COMPLETE).\
            all()
        all_filenames = image_filenames + metadata_filenames
        logger.info('registered %d files', len(all_filenames))
        return jsonify(data=[f.name for f in all_filenames])
예제 #3
0
def register(experiment_id, acquisition_id):
    """
    .. http:post:: /api/experiments/(string:experiment_id)/acquisitions/(string:acquisition_id)/register

        Pass the NFS path to the data to the server.
        The client has to wait for this response before uploading files.

        **Example request**:

        .. sourcecode:: http

            Content-Type: application/json

            {
                "path": "/fullpath/to/serversidedata"
            }

        **Example response**:

        .. sourcecode:: http

            HTTP/1.1 200 OK
            Content-Type: application/json

            {
                "data": "/fullpath/to/serversidedata"
            }

        :reqheader Authorization: JWT token issued by the server
        :statuscode 200: no error
        :statuscode 500: server error

    """
    logger.info('register microscope files')
    data = request.get_json()
    path = data['path']
    logger.info('path given by the client: %s', path)

    # Parse storage_home variable from tissuemaps.cfg file
    parser = SafeConfigParser()
    parser.read('/home/tissuemaps/.tmaps/tissuemaps.cfg')
    storage_home_path = parser.get('tmlib', 'storage_home')

    path_to_link = os.path.join(
        storage_home_path,
        'experiment_{}/plates/plate_{}/acquisitions/acquisition_{}/microscope_images'
    )

    filenames = [
        f for f in os.listdir(path)
        if (not f.startswith('.') and not os.path.isdir(os.path.join(path, f)))
    ]

    with tm.utils.ExperimentSession(experiment_id) as session:
        experiment = session.query(tm.Experiment).one()
        microscope_type = experiment.microscope_type
        img_regex, metadata_regex = get_microscope_type_regex(microscope_type)
        acquisition = session.query(tm.Acquisition).get(acquisition_id)
        # single plate only
        plate = session.query(tm.Plate).one()

        logger.info(
            'path to link: %s',
            path_to_link.format(experiment.id, plate.id, acquisition.id))
        logger.info('experiment %s', experiment.id)
        logger.info('acquisition %s', acquisition)
        logger.info('plate %s', plate)

        # check for image files already registered
        img_filenames = [f.name for f in acquisition.microscope_image_files]
        logger.debug('img_filenames %s', img_filenames)
        img_files = [
            tm.MicroscopeImageFile(name=f, acquisition_id=acquisition.id)
            for f in filenames
            if img_regex.search(f) and f not in img_filenames
        ]
        # check for metadata already registered
        meta_filenames = [
            f.name for f in acquisition.microscope_metadata_files
        ]
        meta_files = [
            tm.MicroscopeMetadataFile(name=secure_filename(f),
                                      acquisition_id=acquisition.id)
            for f in filenames
            if metadata_regex.search(f) and f not in meta_filenames
        ]

        session.bulk_save_objects(img_files + meta_files)

        # Trigger creation of directories
        acquisition.location
        #acquisition.microscope_images_location
        acquisition.microscope_metadata_location

        os.symlink(
            path, path_to_link.format(experiment.id, plate.id, acquisition.id))

        microscope_files = session.query(tm.MicroscopeImageFile).filter_by(
            acquisition_id=acquisition.id).all()

        for microscope_file in microscope_files:
            microscope_file.location
            microscope_file.status = 'COMPLETE'

    return jsonify(message='ok')