Beispiel #1
0
medDataIndex medDatabaseController::indexForImage(const QString &patientName, const QString &studyName,
                                                  const QString &seriesName,  const QString &imageName)
{
    medDataIndex index = this->indexForSeries(patientName, studyName, seriesName);
    if (!index.isValid())
        return index;

    QSqlQuery query(m_database);

    QVariant seriesId = index.seriesId();

    query.prepare("SELECT id FROM image WHERE series = :id AND name = :name");
    query.bindValue(":id",   seriesId);
    query.bindValue(":name", imageName);

    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first()) {
        QVariant imageId = query.value(0);
        index.setImageId(imageId .toInt());
        return index;
    }

    return medDataIndex();
}
Beispiel #2
0
void medDatabaseRemover::removePatient ( int patientDbId )
{
    QSqlDatabase db(d->db);
    QSqlQuery query ( db );

    QString patientName;
    QString patientBirthdate;
    QString patientId;

    query.prepare ( "SELECT thumbnail, patientId  FROM " + d->T_PATIENT + " WHERE id = :patient " );
    query.bindValue ( ":patient", patientDbId );
    EXEC_QUERY ( query );
    if ( query.next() )
    {
        QString thumbnail = query.value ( 0 ).toString();
        this->removeFile ( thumbnail );
        patientId = query.value ( 1 ).toString();
    }
    if( removeTableRow ( d->T_PATIENT, patientDbId ) )
        emit removed(medDataIndex(1, patientDbId, -1, -1, -1));

    medDatabaseController * dbi = medDatabaseController::instance();
    QDir patientDir ( medStorage::dataLocation() + "/" + dbi->stringForPath ( patientId ) );
    
    if ( patientDir.exists() )
        patientDir.rmdir ( patientDir.path() ); // only removes if empty
}
Beispiel #3
0
medDataIndex medDatabaseController::indexForStudy(const QString &patientName, const QString &studyName)
{
    medDataIndex index = this->indexForPatient(patientName);
    if (!index.isValid())
        return index;

    QSqlQuery query(m_database);

    QVariant patientId = index.patientId();
    QVariant studyId   = -1;

    query.prepare("SELECT id FROM study WHERE patient = :id AND name = :name");
    query.bindValue(":id",   patientId);
    query.bindValue(":name", studyName);

    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first()) {
        studyId = query.value(0);
        index.setStudyId(studyId.toInt());
        return index;
    }

    return medDataIndex();
}
Beispiel #4
0
medDropSite::medDropSite(QWidget *parent) : QLabel(parent), d(new medDropSitePrivate)
{
    setAlignment(Qt::AlignCenter);
    setAcceptDrops(true);
    setBackgroundRole(QPalette::Base);
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    d->index = medDataIndex();
    d->canAutomaticallyChangeAppereance = true;
}
Beispiel #5
0
void medDatabaseRemover::removeStudy ( int patientDbId, int studyDbId )
{
    QSqlDatabase db(d->db);
    QSqlQuery query ( db );

    query.prepare ( "SELECT thumbnail, name, uid FROM " + d->T_STUDY + " WHERE id = :id " );
    query.bindValue ( ":id", studyDbId );
    EXEC_QUERY ( query );
    QString thumbnail;
    if ( query.next() )
    {
        thumbnail = query.value ( 0 ).toString();
        this->removeFile ( thumbnail );
    }
    if( removeTableRow ( d->T_STUDY, studyDbId ) )
        emit removed(medDataIndex(1, patientDbId, studyDbId, -1, -1));
}
Beispiel #6
0
void medDatabaseRemover::removeSeries ( int patientDbId, int studyDbId, int seriesDbId )
{
    QSqlDatabase db(d->db);
    QSqlQuery query ( db );

    query.prepare ( "SELECT thumbnail, path, name  FROM " + d->T_SERIES + " WHERE id = :series " );
    query.bindValue ( ":series", seriesDbId );
    EXEC_QUERY ( query );

    QString thumbnail;
    if ( query.next() )
    {
        thumbnail = query.value ( 0 ).toString();
        this->removeFile ( thumbnail );
        QString path = query.value ( 1 ).toString();

        // if path is empty then it was an indexed series
        if ( !path.isNull() && !path.isEmpty() )
            this->removeDataFile ( medDataIndex::makeSeriesIndex ( d->index.dataSourceId(), patientDbId, studyDbId, seriesDbId ) , path );
    }

    if( removeTableRow ( d->T_SERIES, seriesDbId ) )
        emit removed(medDataIndex(1, patientDbId, studyDbId, seriesDbId, -1));

    // we want to remove the directory if empty
    QFileInfo seriesFi ( medStorage::dataLocation() + thumbnail );
    if ( seriesFi.dir().exists() )
    {
        bool res = seriesFi.dir().rmdir ( seriesFi.absolutePath() ); // only removes if empty

        // the serie's directory has been deleted, let's check if the patient directory is empty
        // this can happen after moving series
        if(res)
        {
            QDir parentDir = seriesFi.dir();
            res = parentDir.cdUp();

            if ( res && parentDir.exists() )
            {
                res = seriesFi.dir().rmdir ( parentDir.absolutePath() ); // only removes if empty
            }
        }
    }
}
Beispiel #7
0
/**
* Returns the index of a data given patient, study, series and image name
*/
medDataIndex medDatabaseController::indexForPatient (const QString &patientName)
{
    QSqlQuery query(m_database);
    QVariant patientId = -1;

    query.prepare("SELECT id FROM patient WHERE name = :name");
    query.bindValue(":name", patientName);
    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first()) {
        patientId = query.value(0);
        return medDataIndex::makePatientIndex(this->dataSourceId(), patientId.toInt());
    }

    return medDataIndex();
}
Beispiel #8
0
medDataIndex medDatabaseController::indexForImage(int id)
{
    QSqlQuery query(m_database);

    QVariant patientId = -1;
    QVariant   studyId = -1;
    QVariant  seriesId = -1;

    query.prepare("SELECT series FROM image WHERE id = :id");
    query.bindValue(":id", id);
    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first())
        seriesId = query.value(0);

    query.prepare("SELECT study FROM series WHERE id = :id");
    query.bindValue(":id", seriesId);
    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first())
        studyId = query.value(0);

    query.prepare("SELECT patient FROM study WHERE id = :id");
    query.bindValue(":id", studyId);
    if(!query.exec())
    {
        dtkDebug() << DTK_COLOR_FG_RED << query.lastError() << DTK_NO_COLOR;
    }

    if(query.first())
        patientId = query.value(0);

    return medDataIndex(this->dataSourceId(),patientId.toInt(), studyId.toInt(), seriesId.toInt(), id);
}
void medDatabasePreview::onSeriesClicked(const medDataIndex& id)
{
    medAbstractDbController * db =  medDataManager::instance()->controllerForDataSource(id.dataSourceId());

    d->seriesGroup->clear();

    if ( db ) {
        QList<medDataIndex> series = db->series(id);
        for (QList<medDataIndex>::const_iterator seriesIt( series.begin() ); seriesIt != series.end(); ++seriesIt ) {

            d->seriesGroup->addItem(new medDatabasePreviewItem(
                                        medDataIndex::makeSeriesIndex((*seriesIt).dataSourceId(), (*seriesIt).patientId(), (*seriesIt).studyId(), (*seriesIt).seriesId()) ) );
        }
    }

    // Image level
    int firstImageId(-1);

    d->imageGroup->clear();

    if ( db ) {
        QList<medDataIndex> images = db->images(id);
        for (QList<medDataIndex>::const_iterator imageIt( images.begin() ); imageIt != images.end(); ++imageIt ) {

            if (firstImageId < 0)
                firstImageId = (*imageIt).imageId();

            d->imageGroup->addItem(new medDatabasePreviewItem( medDataIndex(*imageIt ) ) );
        }

    }

    d->scene->setSceneRect(d->imageGroup->boundingRect());

    if(!d->level)
        onSlideUp();
    else
        moveToItem( d->imageGroup->item(firstImageId) );
}
/**
* Populates database tables and generates thumbnails.
* @param medData - a @medAbstractData object created from the original image
* @param pathToStoreThumbnails - path where the thumbnails will be stored
* @return medDataIndex the new medDataIndex associated with this imported series.
**/
medDataIndex medDatabaseNonPersistentImporter::populateDatabaseAndGenerateThumbnails ( medAbstractData* data, QString pathToStoreThumbnails )
{
    QPointer<medDatabaseNonPersistentController> npdc =
            medDatabaseNonPersistentController::instance();

    QList<medDatabaseNonPersistentItem*> items = npdc->items();

    int     patientDbId   = -1;
    QString patientName = medMetaDataKeys::PatientName.getFirstValue(data);
    QString patientId = medMetaDataKeys::PatientID.getFirstValue(data);
    QString birthdate = medMetaDataKeys::BirthDate.getFirstValue(data);

    // check if patient is already in the persistent database
    medDataIndex databaseIndex = medDatabaseController::instance()->indexForPatient ( patientName );
    medDatabaseNonPersistentItem *patientItem = NULL;

    if ( databaseIndex.isValid() )
    {
        qDebug() << "Patient exists in the database, I reuse his Id";
        patientDbId = databaseIndex.patientId();
    }
    else
    {
        // check if patient is already in the non persistent database
        for ( int i=0; i<items.count(); i++ )
            //if ( items[i]->name() ==patientName )
            if ( medMetaDataKeys::PatientName.getFirstValue(items[i]->data()) == patientName )
            {
                patientDbId = items[i]->index().patientId();
                patientItem = items[i];
                break;
            }
    }

    if ( patientDbId==-1 )
    {
        patientDbId = npdc->patientId ( true );
    }

    medDataIndex index;

    if ( patientItem == NULL )
    {
        // create an item for patient
        patientItem = new medDatabaseNonPersistentItem;
        index = medDataIndex ( npdc->dataSourceId(), patientDbId, -1, -1, -1 );

        medAbstractData *medData = new medAbstractData();
        medData->addMetaData ( medMetaDataKeys::PatientName.key(), QStringList() <<  patientName );
        medData->addMetaData ( medMetaDataKeys::BirthDate.key(), birthdate );

        patientItem->d->name = patientName;
        patientItem->d->patientId = patientId;
        patientItem->d->index = index;
        patientItem->d->birthdate = birthdate;
        patientItem->d->data = medData;

        npdc->insert ( index, patientItem );
    }


    int     studyDbId   = -1;
    QString studyName = medMetaDataKeys::StudyDescription.getFirstValue(data);
    QString studyId = medMetaDataKeys::StudyID.getFirstValue(data);
    QString studyUid = medMetaDataKeys::StudyDicomID.getFirstValue(data);

    QString seriesName = medMetaDataKeys::SeriesDescription.getFirstValue(data);


    if( studyName!="EmptyStudy" || seriesName!="EmptySerie" )
    {
        // check if study is already in the persistent database
        databaseIndex = medDatabaseController::instance()->indexForStudy ( patientName, studyName );
        medDatabaseNonPersistentItem *studyItem = NULL;

        if ( databaseIndex.isValid() )
        {
            qDebug() << "Study exists in the database, I reuse its Id";
            studyDbId = databaseIndex.studyId();
        }
        else
        {
            for ( int i=0; i<items.count(); i++ )
                if ( items[i]->name()==patientName && items[i]->studyName()==studyName )
                {
                    studyDbId = items[i]->index().studyId();
                    studyItem = items[i];
                    break;
                }
        }

        if ( studyDbId==-1 )
        {
            studyDbId = npdc->studyId ( true );
        }
        if ( studyItem == NULL )
        {
            // create an item for study
            studyItem = new medDatabaseNonPersistentItem;
            index = medDataIndex ( npdc->dataSourceId(), patientDbId, studyDbId, -1, -1 );

            medAbstractData *medData = new medAbstractData();

            medData->addMetaData ( medMetaDataKeys::PatientName.key(), QStringList() << patientName );
            medData->addMetaData ( medMetaDataKeys::BirthDate.key(), birthdate );
            medData->addMetaData ( medMetaDataKeys::StudyDescription.key(), QStringList() << studyName );
            medData->addMetaData ( medMetaDataKeys::StudyID.key(), QStringList() << studyId );
            medData->addMetaData ( medMetaDataKeys::StudyDicomID.key(), QStringList() << studyUid );

            studyItem->d->name = patientName;
            studyItem->d->patientId = patientId;
            studyItem->d->birthdate = birthdate;
            studyItem->d->studyName = studyName;
            studyItem->d->index = index;
            studyItem->d->data = medData;
            studyItem->d->studyId = studyId;
            studyItem->d->studyUid = studyUid;

            npdc->insert ( index, studyItem );
        }
    }


    if(seriesName != "EmptySerie")
    {
        index = medDataIndex ( npdc->dataSourceId(), patientDbId, studyDbId, npdc->seriesId ( true ), -1 );

        QString seriesId = medMetaDataKeys::SeriesID.getFirstValue(data);
        QString seriesUid = medMetaDataKeys::SeriesDicomID.getFirstValue(data);
        QString orientation = medMetaDataKeys::Orientation.getFirstValue(data);
        QString seriesNumber = medMetaDataKeys::SeriesNumber.getFirstValue(data);
        QString sequenceName = medMetaDataKeys::SequenceName.getFirstValue(data);
        QString sliceThickness = medMetaDataKeys::SliceThickness.getFirstValue(data);
        QString rows = medMetaDataKeys::Rows.getFirstValue(data);
        QString columns = medMetaDataKeys::Columns.getFirstValue(data);

        QFileInfo info (file() );

        medDatabaseNonPersistentItem *item = new medDatabaseNonPersistentItem;

        if ( !patientName.isEmpty() )
            item->d->name = patientName;
        else
            item->d->name = info.baseName();

        item->d->patientId = patientId;
        item->d->studyName = studyName;
        item->d->seriesName = seriesName;
        item->d->seriesId = seriesId;
        item->d->file = file();
        item->d->thumb = data->thumbnail();
        item->d->index = index;
        item->d->data = data;
        item->d->orientation = orientation;
        item->d->seriesNumber = seriesNumber;
        item->d->sequenceName = sequenceName;
        item->d->sliceThickness = sliceThickness;
        item->d->rows = rows;
        item->d->columns = columns;
        item->d->seriesUid = seriesUid;
        item->d->studyUid = studyUid;

        npdc->insert ( index, item );
    }

    return index;
}
void medAbstractDatabaseImporter::importData()
{   
    QMutexLocker locker ( &d->mutex );
     
    if ( !d->data )
    {
        emit failure ( this );
        emit dataImported(medDataIndex(), d->uuid);
        return;
    }

    populateMissingMetadata(d->data, "EmptySeries");

    if ( !d->data->hasMetaData ( medMetaDataKeys::FilePaths.key() ) )
         d->data->addMetaData ( medMetaDataKeys::FilePaths.key(), QStringList() << "data created internally" );

    // Information about the app and version of the application
    QString attachedInfoApp = QString("generated with " +
                                      QString(PROJECT_NAME) +
                                      " " +
                                      QString(MEDINRIA_VERSION));
    d->data->setMetaData(medMetaDataKeys::Description.key(), attachedInfoApp);

    QString size ="";
    if ( medAbstractImageData *imagedata = dynamic_cast<medAbstractImageData*> ( d->data.data()) )
        size = QString::number ( imagedata->zDimension() );
    d->data->setMetaData ( medMetaDataKeys::Size.key(), size );

    QString patientName = medMetaDataKeys::PatientName.getFirstValue(d->data).simplified();
    QString birthDate   = medMetaDataKeys::BirthDate.getFirstValue(d->data);
    QString seriesId    = medMetaDataKeys::SeriesID.getFirstValue(d->data);
        
    QString patientId  = getPatientID(patientName, birthDate);

    d->data->setMetaData ( medMetaDataKeys::PatientID.key(), QStringList() << patientId );
 
    bool writeSuccess = true;
    QString     thumb_dir;

    if ( !d->indexWithoutImporting )
    {
        QString subDirName = "/" + patientId;
        QString imageFileNameBase =  subDirName + "/" +  seriesId;

        QDir dir ( medStorage::dataLocation() + subDirName );
        if ( !dir.exists() )
        {
            if ( !medStorage::mkpath ( medStorage::dataLocation() + subDirName ) )
            {
                qWarning() << "Unable to create directory for images";
                emit failure ( this );
                emit dataImported(medDataIndex(), d->uuid);
                return ;
            }
        }

        QString extension  = determineFutureImageExtensionByDataType ( d->data );
        QString imageFileName = imageFileNameBase + extension;

        // writing file
        writeSuccess = tryWriteImage (  medStorage::dataLocation()+imageFileName, d->data );

        if ( !writeSuccess  )
        {
            // when creating empty patients or studies, we need to continue to populate the database

            qWarning() << "Unable to write image " + imageFileName;
            qWarning() << "Either there is nothing to write or a problem occured when writing.";
        }
        else
        {
            d->data->setMetaData ( "FileName", imageFileName );
        }
        
         QFileInfo   seriesInfo ( imageFileName );
         thumb_dir = seriesInfo.dir().path() + "/" + seriesInfo.completeBaseName() + "/";
    }
    

    // Now, populate the database
   medDataIndex index = this->populateDatabaseAndGenerateThumbnails (  d->data, thumb_dir );

    emit progress(this, 100);
    emit success(this);

    if (d->uuid == "")
        emit dataImported(index);
    else
        emit dataImported(index,d->uuid);
    
}
void medAbstractDatabaseImporter::importFile ( void )
{
    QMutexLocker locker ( &d->mutex );

    /* The idea of this algorithm can be summarized in 3 steps:
     * 1. Get a list of all the files that will (try to) be imported or indexed
     * 2. Filter files that cannot be read, or won't be possible to write afterwards, or are already in the db
     * 3. Fill files metadata, write them to the db, and populate db tables
     *
     * note that depending on the input files, they might be aggregated by volume
     */

    // 1) Obtain a list of all the files that are going to be processed
    // this flattens the tree structure (if the input is a directory)
    // and puts all the files in one single list
    QStringList fileList = getAllFilesToBeProcessed ( d->file );

    // Files that pass the filters named above are grouped
    // by volume in this map and will be written in the db after.
    // the key will be the name of the aggregated file with the volume
    QMap<QString, QStringList> imagesGroupedByVolume;
    QMap<QString, QString> imagesGroupedByPatient;
    QMap<QString, QString> imagesGroupedBySeriesId;

    int currentFileNumber = 0; // this variable will be used only for calculating progress

    // if importing, and depending on the input files, they might be aggregated
    // that is: files corresponding to the same volume will be written
    // in a single output meta file (e.g. .mha)
    // this map is used to store a unique id per volume and its volume number
    QMap<QString, int> volumeUniqueIdToVolumeNumber;
    int volumeNumber = 1;

    // 2) Select (by filtering) files to be imported
    //
    // In this first loop we read the headers of all the images to be imported
    // and check if we don't have any problem in reading the file, the header
    // or in selecting a proper format to store the new file afterwards
    // new files ARE NOT written in medInria database yet, but are stored in a map for writing in a posterior step

    QString tmpPatientId;
    QString currentPatientId = "";
    QString patientID;

    QString tmpSeriesUid;
    QString currentSeriesUid = "-1";
    QString currentSeriesId = "";

    bool atLeastOneImportSucceeded = false;

    foreach ( QString file, fileList )
    {
        if ( d->isCancelled ) // check if user cancelled the process
            break;

        emit progress ( this, ( ( qreal ) currentFileNumber/ ( qreal ) fileList.count() ) * 50.0 ); //TODO: reading and filtering represents 50% of the importing process?

        currentFileNumber++;

        QFileInfo fileInfo ( file );
        if (fileInfo.size() != 0)
        {
            dtkSmartPointer<medAbstractData> medData;

            // 2.1) Try reading file information, just the header not the whole file

            bool readOnlyImageInformation = true;
            medData = tryReadImages ( QStringList ( fileInfo.filePath() ), readOnlyImageInformation );

            if ( !medData )
            {
                qWarning() << "Reader was unable to read: " << fileInfo.filePath();
                continue;
            }

            // 2.2) Fill missing metadata
            populateMissingMetadata ( medData, medMetaDataKeys::SeriesID.getFirstValue(medData));
            QString patientName = medMetaDataKeys::PatientName.getFirstValue(medData).simplified();
            QString birthDate = medMetaDataKeys::BirthDate.getFirstValue(medData);
            tmpPatientId = patientName + birthDate;

            if(tmpPatientId != currentPatientId)
            {
                currentPatientId = tmpPatientId;

                patientID = getPatientID(patientName, birthDate);
            }

            medData->setMetaData ( medMetaDataKeys::PatientID.key(), QStringList() << patientID );

            tmpSeriesUid = medMetaDataKeys::SeriesDicomID.getFirstValue(medData);

            if (tmpSeriesUid != currentSeriesUid)
            {
                currentSeriesUid = tmpSeriesUid;
                currentSeriesId = medMetaDataKeys::SeriesID.getFirstValue(medData);
            }
            else
                medData->setMetaData ( medMetaDataKeys::SeriesID.key(), QStringList() << currentSeriesId );

            // 2.3) Generate an unique id for each volume
            // all images of the same volume should share the same id
            QString volumeId = generateUniqueVolumeId ( medData );

            // check whether the image belongs to a new volume
            if ( !volumeUniqueIdToVolumeNumber.contains ( volumeId ) )
            {
                volumeUniqueIdToVolumeNumber[volumeId] = volumeNumber;
                volumeNumber++;
            }

            // 2.3) a) Determine future file name and path based on patient/study/series/image
            // i.e.: where we will write the imported image
            QString imageFileName = determineFutureImageFileName ( medData, volumeUniqueIdToVolumeNumber[volumeId] );
#ifdef Q_OS_WIN32
            if ( (medStorage::dataLocation() + "/" + imageFileName).length() > 255 )
            {
                emit showError ( tr ( "Your database path is too long" ), 5000 );
                emit dataImported(medDataIndex(), d->uuid);
                emit failure ( this );
                return;
            }
#endif
            // 2.3) b) Find the proper extension according to the type of the data
            // i.e.: in which format we will write the file in our database
            QString futureExtension  = determineFutureImageExtensionByDataType ( medData );

            // we care whether we can write the image or not if we are importing
            if (!d->indexWithoutImporting && futureExtension.isEmpty()) {
                emit showError(tr("Could not save file due to unhandled data type: ") + medData->identifier(), 5000);
                continue;
            }

            imageFileName = imageFileName + futureExtension;

            // 2.3) c) Add the image to a map for writing them all in medInria's database in a posterior step

            // First check if patient/study/series/image path already exists in the database
            // Should we emit a message otherwise ??? TO
            if ( !checkIfExists ( medData, fileInfo.fileName() ) )
            {
                imagesGroupedByVolume[imageFileName] << fileInfo.filePath();
                imagesGroupedByPatient[imageFileName] = patientID;
                imagesGroupedBySeriesId[imageFileName] = currentSeriesId;
            }
        }
        else
        {
            QString error = QString(tr("Could not read empty file: ") + fileInfo.completeBaseName());
            qWarning() << __FUNCTION__ << error;
            emit showError(error, 5000);
        }
    }

    // some checks to see if the user cancelled or something failed
    if ( d->isCancelled )
    {
        emit showError (tr ( "User cancelled import process" ), 5000 );
        emit dataImported(medDataIndex(), d->uuid);
        emit cancelled ( this );
        return;
    }

    // from now on the process cannot be cancelled
    emit disableCancel ( this );

    // 3) Re-read selected files and re-populate them with missing metadata
    //    then write them to medInria db and populate db tables

    QMap<QString, QStringList>::const_iterator it = imagesGroupedByVolume.begin();
    QMap<QString, QString>::const_iterator  itPat = imagesGroupedByPatient.begin();
    QMap<QString, QString>::const_iterator  itSer = imagesGroupedBySeriesId.begin();

    // 3.1) first check is after the filtering we have something to import
    // maybe we had problems with all the files, or they were already in the database
    if ( it == imagesGroupedByVolume.end() )
    {
        // TODO we know if it's either one or the other error, we can make this error better...
        emit showError (tr ( "No compatible image found or all of them had been already imported." ), 5000 );
        emit dataImported(medDataIndex(), d->uuid);
        emit failure ( this );
        return;
    }
    else
        qDebug() << "Chosen directory contains " << imagesGroupedByVolume.size() << " files";

    int imagesCount = imagesGroupedByVolume.count(); // used only to calculate progress
    int currentImageIndex = 0; // used only to calculate progress

    medDataIndex index; //stores the last volume's index to be emitted on success

    // final loop: re-read, re-populate and write to db
    for ( ; it != imagesGroupedByVolume.end(); it++ )
    {
        emit progress ( this, ( ( qreal ) currentImageIndex/ ( qreal ) imagesCount ) * 50.0 + 50.0 ); // 50? I do not think that reading all the headers is half the job...

        currentImageIndex++;

        QString aggregatedFileName = it.key(); // note that this file might be aggregating more than one input files
        QStringList filesPaths = it.value();   // input files being aggregated, might be only one or many
        patientID = itPat.value();
        QString seriesID = itSer.value();

        //qDebug() << currentImageIndex << ": " << aggregatedFileName << "with " << filesPaths.size() << " files";

        dtkSmartPointer<medAbstractData> imagemedData;

        QFileInfo imagefileInfo ( filesPaths[0] );

        // 3.2) Try to read the whole image, not just the header
        bool readOnlyImageInformation = false;
        imagemedData = tryReadImages ( filesPaths, readOnlyImageInformation );

        if ( imagemedData )
        {
            // 3.3) a) re-populate missing metadata
            // if there is no SeriesDescription, we use the tag Series Instance UID (specific and required)
            populateMissingMetadata ( imagemedData, medMetaDataKeys::SeriesDicomID.getFirstValue(imagemedData));
            imagemedData->setMetaData ( medMetaDataKeys::PatientID.key(), QStringList() << patientID );
            imagemedData->setMetaData ( medMetaDataKeys::SeriesID.key(), QStringList() << seriesID );

            // 3.3) b) now we are able to add some more metadata
            addAdditionalMetaData ( imagemedData, aggregatedFileName, filesPaths );
        }
        else
        {
            qWarning() << "Could not repopulate data!";
            emit showError (tr ( "Could not read data: " ) + filesPaths[0], 5000 );
            emit dataImported(medDataIndex(), d->uuid);
            emit failure(this);
            return;
        }

        if ( !d->indexWithoutImporting )
        {
            // create location to store file
            QFileInfo fileInfo ( medStorage::dataLocation() + aggregatedFileName );
            if ( !fileInfo.dir().exists() && !medStorage::mkpath ( fileInfo.dir().path() ) )
            {
                qDebug() << "Cannot create directory: " << fileInfo.dir().path();
                continue;
            }

            // now writing file
            bool writeSuccess = tryWriteImage ( fileInfo.filePath(), imagemedData );

            if ( !writeSuccess )
            {
                emit showError (tr ( "Could not save data file: " ) + filesPaths[0], 5000 );
                continue;
            }
        }
        atLeastOneImportSucceeded = true;

        // and finally we populate the database
        QFileInfo aggregatedFileNameFileInfo ( aggregatedFileName );
        QString pathToStoreThumbnails = aggregatedFileNameFileInfo.dir().path() + "/" + aggregatedFileNameFileInfo.completeBaseName() + "/";
        index = this->populateDatabaseAndGenerateThumbnails ( imagemedData, pathToStoreThumbnails );
        
        if(!d->uuid.isNull())
        {
            emit dataImported(index, d->uuid);
        }
        else
        {
            emit dataImported(index);
        }

        itPat++;
        itSer++;
    } // end of the final loop

    if ( ! atLeastOneImportSucceeded) {
        emit progress ( this,100 );
        emit dataImported(medDataIndex(), d->uuid);
        emit failure(this);
        return;
    }

    d->index = index;
    
    emit progress ( this,100 );
    emit success ( this );
}
Beispiel #13
0
void medDropSite::clear(){
    QLabel::clear();
    d->index = medDataIndex();
}