Example #1
0
void ctkDICOMDataset::Deserialize()
{
  Q_D(ctkDICOMDataset);
  // read attribute m_ctkDICOMDataset
  // construct a DcmDataset from it
  // calls InitializeData(DcmDataset*)

  // this method can be called both from sub-classes when they get the InitializeData signal from the persistence framework
  // and from EnsureDcmDataSetIsInitialized() when a GetElement.. or SetElement.. method is called.

  if (d->m_DICOMDataSetInitialized) return; // only need to do this once

  QString stringbuffer = this->GetStoredSerialization();
  if ( stringbuffer.isEmpty() )
  {
    d->m_DICOMDataSetInitialized = true;
    return; // TODO nicer: hold three states: newly created / loaded but not initialized / restored from DB
  }


  //std::cerr << "** " << (void*)this << " ctkDICOMDataset: Deserialize Dataset from string of size " << stringbuffer.size() << "\n" << stringbuffer.toStdString() << std::endl;

  QByteArray qtArray = QByteArray::fromBase64( stringbuffer.toAscii() );
  //std::cerr << "** " << (void*)this << " ctkDICOMDataset: Deserialize Dataset from byte array of size " << qtArray.size() << std::endl;

  DcmInputBufferStream dcmbuffer;
  dcmbuffer.setBuffer( qtArray.data(), qtArray.size() );
  //std::cerr << "** Buffer state: " << dcmbuffer.status().code() << " " <<  dcmbuffer.good() << " " << dcmbuffer.eos() << " tell " << dcmbuffer.tell() << " avail " << dcmbuffer.avail() << std::endl;

  DcmDataset dataset;
  dataset.transferInit();
  //std::cerr << "** Dataset state: " << dataset.transferState() << std::endl << std::endl;
  OFCondition condition = dataset.read( dcmbuffer, EXS_LittleEndianImplicit );
  dataset.transferEnd();

  // do this in all cases, even when reading reported an error
  this->InitializeFromDataset(&dataset);

  if ( condition.bad() )
  {
    std::cerr << "** Condition code of Dataset::read() is "
              << condition.code() << std::endl;
    std::cerr << "** Buffer state: " << dcmbuffer.status().code()
              << " " <<  dcmbuffer.good()
              << " " << dcmbuffer.eos()
              << " tell " << dcmbuffer.tell()
              << " avail " << dcmbuffer.avail() << std::endl;
    std::cerr << "** Dataset state: "
              << static_cast<int>(dataset.transferState()) << std::endl;
    std::cerr << "Could not DcmDataset::read(..): "
              << condition.text() << std::endl;
    //throw std::invalid_argument( std::string("Could not DcmDataset::read(..): ") + condition.text() );
  }
}
PACSRequestStatus::RetrieveRequestStatus RetrieveDICOMFilesFromPACS::retrieve(const QString &studyInstanceUID, const QString &seriesInstanceUID, const QString &sopInstanceUID)
{
    T_ASC_PresentationContextID presentationContextID;
    T_DIMSE_C_MoveRSP moveResponse;
    DcmDataset *statusDetail = NULL;
    m_pacsConnection = new PACSConnection(m_pacs);
    PACSRequestStatus::RetrieveRequestStatus retrieveRequestStatus;
    MoveSCPCallbackData moveSCPCallbackData;
    DcmDataset *dcmDatasetToRetrieve = getDcmDatasetOfImagesToRetrieve(studyInstanceUID, seriesInstanceUID, sopInstanceUID);
    m_numberOfImagesRetrieved = 0;

    // TODO S'hauria de comprovar que es tracti d'un PACS amb el servei de retrieve configurat
    if (!m_pacsConnection->connectToPACS(PACSConnection::RetrieveDICOMFiles))
    {
        ERROR_LOG("S'ha produit un error al intentar connectar al PACS per fer un retrieve. AE Title: " + m_pacs.getAETitle());
        return PACSRequestStatus::RetrieveCanNotConnectToPACS;
    }

    // Which presentation context should be used, It's important that the connection has MoveStudyRoot level
    T_ASC_Association *association = m_pacsConnection->getConnection();
    presentationContextID = ASC_findAcceptedPresentationContextID(association, MoveAbstractSyntax);
    if (presentationContextID == 0)
    {
        ERROR_LOG("No s'ha trobat cap presentation context valid");
        return PACSRequestStatus::RetrieveFailureOrRefused;
    }

    moveSCPCallbackData.association = association;
    moveSCPCallbackData.presentationContextId = presentationContextID;
    moveSCPCallbackData.retrieveDICOMFilesFromPACS = this;

    // Set the destination of the images to us
    T_DIMSE_C_MoveRQ moveRequest = getConfiguredMoveRequest(association);
    ASC_getAPTitles(association->params, moveRequest.MoveDestination, NULL, NULL);

    OFCondition condition = DIMSE_moveUser(association, presentationContextID, &moveRequest, dcmDatasetToRetrieve, moveCallback, &moveSCPCallbackData,
                                           DIMSE_BLOCKING, 0, m_pacsConnection->getNetwork(), subOperationCallback, this, &moveResponse, &statusDetail,
                                           NULL /*responseIdentifiers*/);

    if (condition.bad())
    {
        ERROR_LOG(QString("El metode descarrega no ha finalitzat correctament. Codi error: %1, descripcio error: %2").arg(condition.code())
                     .arg(condition.text()));
    }

    m_pacsConnection->disconnect();

    retrieveRequestStatus = getDIMSEStatusCodeAsRetrieveRequestStatus(moveResponse.DimseStatus);
    processServiceClassProviderResponseStatus(moveResponse.DimseStatus, statusDetail);
    
    // Dump status detail information if there is some
    if (statusDetail != NULL)
    {
        delete statusDetail;
    }

    delete dcmDatasetToRetrieve;

    return retrieveRequestStatus;
}