示例#1
0
        /// <summary>
        /// Trigger the Client to send a Verification (DICOM C-ECHO-RQ).
        /// </summary>
        /// <param name="actorName">Destination Actor Name.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool TriggerClientVerification(ActorName actorName)
        {
            // Set up a Verification SOP Class - C-ECHO-RQ trigger
            DicomTrigger dicomTrigger = new DicomTrigger(Dvtk.IheActors.Bases.TransactionNameEnum.RAD_UNKNOWN);

            dicomTrigger.AddItem(new DicomMessage(DvtkData.Dimse.DimseCommand.CECHORQ),
                                 HliScp.VERIFICATION_SOP_CLASS_UID,
                                 HliScp.IMPLICIT_VR_LITTLE_ENDIAN);
            DicomTriggerItem dicomTriggerItem = dicomTrigger.TriggerItems[0];

            // thread must wait for association completion
            _scu.SignalCompletion = true;

            // set up the presentation context from the trigger
            PresentationContext[] presentationContexts = new PresentationContext[1];
            presentationContexts[0] = new PresentationContext(dicomTriggerItem.SopClassUid,
                                                              dicomTriggerItem.TransferSyntaxes);
            _scu.TriggerSendAssociation(dicomTriggerItem.Message, presentationContexts);

            // wait for association completion
            // - timeout of 0 means "no timeout".
            _semaphore.Wait(0);

            // return a boolean indicating if the trigger was processed successfully or not
            return(_scu.ProcessTriggerResult);
        }
示例#2
0
        private DicomTrigger GenerateTrigger(DicomMessage dicomMessage)
        {
            DicomTrigger storageCommitTrigger = new DicomTrigger(TransactionNameEnum.RAD_10);

            storageCommitTrigger.AddItem(GenerateTriggers.MakeStorageCommitEvent(_informationModels, dicomMessage),
                                         "1.2.840.10008.1.20.1",
                                         "1.2.840.10008.1.2");

            return(storageCommitTrigger);
        }
示例#3
0
        private DicomTrigger GenerateTrigger(DicomMessage dicomMessage)
        {
            DicomTrigger storageCommitTrigger = new DicomTrigger(TransactionNameEnum.RAD_10);
            storageCommitTrigger.AddItem(GenerateTriggers.MakeStorageCommitEvent(_informationModels, dicomMessage),
                                        "1.2.840.10008.1.20.1",
                                        "1.2.840.10008.1.2");

            return storageCommitTrigger;
        }
示例#4
0
        /// <summary>
        /// Handle a Dicom Transaction from the given Actor Name.
        /// </summary>
        /// <param name="actorName">Source Actor Name.</param>
        /// <param name="dicomTransaction">Dicom Transaction.</param>
        protected override void HandleTransactionFrom(ActorName actorName, DicomTransaction dicomTransaction)
        {
            switch (actorName.Type)
            {
                case ActorTypeEnum.AcquisitionModality:
                    // received Modality Procedure Step In Progress [RAD-6] or
                    // received Modality Procedur Step Completed [RAD-7]
                case ActorTypeEnum.EvidenceCreator:
                {

                    // received Creator Procedure Step In Progress [RAD-20] or
                    // received Creator Procedure Step Completed [RAD-21]
                    TransactionNameEnum transactionName = dicomTransaction.TransactionName;
                    DicomMessage dicomMessage = (DicomMessage)dicomTransaction.DicomMessages[0];

                    // ignore the C-ECHO-RQ used in the Verification SOP Class
                    // - no need to forward this
                    if (dicomMessage.CommandSet.DimseCommand != DvtkData.Dimse.DimseCommand.CECHORQ)
                    {
                        // make a trigger from the transaction message
                        DicomTrigger dicomTrigger = new DicomTrigger(transactionName);
                        dicomTrigger.AddItem(dicomMessage,
                            "1.2.840.10008.3.1.2.3.3",
                            "1.2.840.10008.1.2");

                        // trigger the following actors
                        bool triggerResult = TriggerActorInstances(ActorTypeEnum.DssOrderFiller, dicomTrigger, false);
                        if (triggerResult == true)
                        {
                            triggerResult = TriggerActorInstances(ActorTypeEnum.ImageManager, dicomTrigger, false);
                        }
                    }
                    break;
                }
                default:
                    break;
            }
        }
示例#5
0
        /// <summary>
        /// Send a C-MOVE-RQ Information Model Retrieve.
        /// Retrieve based on the informationModel provided and the query/retrieve level. Take
        /// the retrieve tags from the retrieveTags provided. The retrieve is done to the move
        /// destination.
        /// 
        /// The C-MOVE-RSP messages returned are stored in a DicomQueryItemCollection named RetrieveItems.
        /// </summary>
        /// <param name="informationModel">Q/R Information Model to be used in the retrieve operation.</param>
        /// <param name="level">Query / retrieve level.</param>
        /// <param name="moveDestination">AE Title of the "move" destination.</param>
        /// <param name="retrieveTags">List of Retrieve Tags.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool SendRetrieveImages(QueryRetrieveInformationModelEnum informationModel, QueryRetrieveLevelEnum level, System.String moveDestination, TagValueCollection retrieveTags)
        {
            System.String queryRetrieveLevel = System.String.Empty;
            switch(level)
            {
                case QueryRetrieveLevelEnum.PatientQueryRetrieveLevel:
                    queryRetrieveLevel = "PATIENT";
                    break;
                case QueryRetrieveLevelEnum.StudyQueryRetrieveLevel:
                    queryRetrieveLevel = "STUDY";
                    break;
                case QueryRetrieveLevelEnum.SeriesQueryRetrieveLevel:
                    queryRetrieveLevel = "SERIES";
                    break;
                case QueryRetrieveLevelEnum.InstanceQueryRetrieveLevel:
                    queryRetrieveLevel = "IMAGE";
                    break;
                default:
                    return false;
            }
            if (retrieveTags.Find(Tag.QUERY_RETRIEVE_LEVEL) == null)
            {
                retrieveTags.Add(new DicomTagValue(Tag.QUERY_RETRIEVE_LEVEL, queryRetrieveLevel));
            }
            _retrieveItems = new DicomQueryItemCollection();

            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_16);
            System.String sopClassUid = System.String.Empty;
            switch(informationModel)
            {
                case QueryRetrieveInformationModelEnum.PatientRootQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.1.2";
                    break;
                case QueryRetrieveInformationModelEnum.StudyRootQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.2.2";
                    break;
                case QueryRetrieveInformationModelEnum.PatientStudyOnlyQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.3.2";
                    break;
                default:
                    return false;
            }
            trigger.AddItem(GenerateTriggers.MakeCMoveRetrieve(informationModel, moveDestination, retrieveTags),
                            sopClassUid,
                            "1.2.840.10008.1.2");

            // RAD-16 - trigger the ImageArchive
            bool triggerResult = TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true);

            // Get the retrieve items returned
            if (triggerResult == true)
            {
                foreach (ActorsTransaction actorsTransaction in ActorsTransactionLog)
                {
                    if (actorsTransaction.FromActorName.Type == ActorTypeEnum.ImageArchive)
                    {
                        BaseTransaction baseTransaction = actorsTransaction.Transaction;
                        if (baseTransaction is DicomTransaction)
                        {
                            DicomTransaction dicomTransaction = (DicomTransaction)baseTransaction;
                            if (dicomTransaction.Processed == false)
                            {
                                DicomMessageCollection cMoveResponses = dicomTransaction.DicomMessages.CMoveResponses;
                                int index = 0;
                                foreach (DvtkHighLevelInterface.Dicom.Messages.DicomMessage dicomMessage in cMoveResponses)
                                {
                                    // store all C-MOVE-RSP messages
                                    // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_COMPLETED_SUBOPERATIONS) to get completed count
                                    // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_FAILED_SUBOPERATIONS) to get failed count
                                    // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_REMAINING_SUBOPERATIONS) to get remaining count
                                    // - use DicomQueryItem.GetValue(Tag.NUMBER_OF_WARNING_SUBOPERATIONS) to get warning count
                                    DicomQueryItem dicomRetriveItem = new DicomQueryItem(index++, dicomMessage);
                                    _retrieveItems.Add(dicomRetriveItem);
                                }
                                dicomTransaction.Processed = true;
                            }
                        }
                    }
                }
            }

            return triggerResult;
        }
示例#6
0
        /// <summary>
        /// Send a C-FIND-RQ Information Model Query.
        /// Query based on the informationModel provided and the query/retrieve level. Take
        /// the query tags from the queryTags provided.
        /// 
        /// The C-FIND-RSP messages returned are stored in a DicomQueryItemCollection named QueryItems.
        /// </summary>
        /// <param name="informationModel">Q/R Information Model to be used in the query operation.</param>
        /// <param name="level">Query / retrieve level.</param>
        /// <param name="queryTags">List of Query Tags.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool SendQueryImages(QueryRetrieveInformationModelEnum informationModel, QueryRetrieveLevelEnum level, TagValueCollection queryTags)
        {
            System.String queryRetrieveLevel = System.String.Empty;
            switch(level)
            {
                case QueryRetrieveLevelEnum.PatientQueryRetrieveLevel:
                    _patientLevelQueryItems = new DicomQueryItemCollection();
                    queryRetrieveLevel = "PATIENT";
                    break;
                case QueryRetrieveLevelEnum.StudyQueryRetrieveLevel:
                    _studyLevelQueryItems = new DicomQueryItemCollection();
                    queryRetrieveLevel = "STUDY";
                    break;
                case QueryRetrieveLevelEnum.SeriesQueryRetrieveLevel:
                    _seriesLevelQueryItems = new DicomQueryItemCollection();
                    queryRetrieveLevel = "SERIES";
                    break;
                case QueryRetrieveLevelEnum.InstanceQueryRetrieveLevel:
                    _instanceLevelQueryItems = new DicomQueryItemCollection();
                    queryRetrieveLevel = "IMAGE";
                    break;
                default:
                    return false;
            }
            if (queryTags.Find(Tag.QUERY_RETRIEVE_LEVEL) == null)
            {
                queryTags.Add(new DicomTagValue(Tag.QUERY_RETRIEVE_LEVEL, queryRetrieveLevel));
            }

            DicomQueryItemCollection queryItems = QueryItems(level);

            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_14);
            System.String sopClassUid = System.String.Empty;
            switch(informationModel)
            {
                case QueryRetrieveInformationModelEnum.PatientRootQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.1.1";
                    break;
                case QueryRetrieveInformationModelEnum.StudyRootQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.2.1";
                    break;
                case QueryRetrieveInformationModelEnum.PatientStudyOnlyQueryRetrieveInformationModel:
                    sopClassUid = "1.2.840.10008.5.1.4.1.2.3.1";
                    break;
                default:
                    return false;
            }
            trigger.AddItem(GenerateTriggers.MakeCFindQuery(informationModel, queryTags),
                            sopClassUid,
                            "1.2.840.10008.1.2");

            // RAD-14 - trigger the ImageArchive
            bool triggerResult = TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true);

            // Get the query items returned
            if (triggerResult == true)
            {
                foreach (ActorsTransaction actorsTransaction in ActorsTransactionLog)
                {
                    if (actorsTransaction.FromActorName.Type == ActorTypeEnum.ImageArchive)
                    {
                        BaseTransaction baseTransaction = actorsTransaction.Transaction;
                        if (baseTransaction is DicomTransaction)
                        {
                            DicomTransaction dicomTransaction = (DicomTransaction)baseTransaction;
                            if (dicomTransaction.Processed == false)
                            {
                                DicomMessageCollection cFindResponses = dicomTransaction.DicomMessages.CFindResponses;
                                int index = 0;
                                foreach (DvtkHighLevelInterface.Dicom.Messages.DicomMessage dicomMessage in cFindResponses)
                                {
                                    if (dicomMessage.DataSet.Count != 0)
                                    {
                                        DicomQueryItem dicomQueryItem = new DicomQueryItem(index++, dicomMessage);
                                        queryItems.Add(dicomQueryItem);
                                    }
                                }
                                dicomTransaction.Processed = true;
                            }
                        }
                    }
                }
            }

            return triggerResult;
        }
示例#7
0
        private bool TriggerModalityProcedureStepInProgress(DicomQueryItem modalityWorklistItem)
        {
            // Use modality Worklist Item to help construct the MPPS InProgress Message
            // Get the attribute values to copy
            DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator");
            DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage);

            DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator");
            mppsInProgressComparator.PopulateDicomMessage(_nCreateSetMppsInProgress, dicomWorklistItemComparator);

            // Trigger the N-CREATE-RQ MPPS InProgress
            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_6);
            trigger.AddItem(_nCreateSetMppsInProgress,
                "1.2.840.10008.3.1.2.3.3",
                "1.2.840.10008.1.2");

            // Update the default PerformedProcedureStepEntity values for the next MPPS In-Progress
            DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.PerformedProcedureStepEntity);

            // RAD-6 - trigger the PerformedProcedureStepManager
            return TriggerActorInstances(ActorTypeEnum.PerformedProcedureStepManager, trigger, true);
        }
示例#8
0
        private bool TriggerModalityProcedureStepCompletedDiscontinued(DvtkHighLevelInterface.Dicom.Messages.DicomMessage nSetMppsCompletedDiscontinued)
        {
            // Trigger the N-SET-RQ MPPS Completed/Discontinued
            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_7);
            trigger.AddItem(nSetMppsCompletedDiscontinued,
                            "1.2.840.10008.3.1.2.3.3",
                            "1.2.840.10008.1.2");

            // RAD-7 - trigger the PerformedProcedureStepManager
            return TriggerActorInstances(ActorTypeEnum.PerformedProcedureStepManager, trigger, true);
        }
示例#9
0
        /// <summary>
        /// Send the Storage Commitment message - use the storage commitment details
        /// built up during any previous SendModalityImagesStored() operations.
        /// The N-ACTION-RQ will be sent to the Image Manager.
        /// 
        /// If the configured ActorOption1 for the DicomPeerToPeerConfiguration from the
        /// AcquisitionModalityActor to the ImageManagerActor is set to the string
        /// "DO_STORAGE_COMMITMENT_ON_SINGLE_ASSOCIATION" then the framework expects the
        /// Image Manager to return the N-EVENT-REPORT details over the same association
        /// as the N-ACTION details were sent. If the ActorOption1 configuration parameter
        /// is not set as above then the framework will expect the Image Manger to return
        /// the N-EVENT-REPORT details over a different association than the one used for the
        /// N-ACTION details.
        /// </summary>
        /// <param name="awaitNEventReport">Boolean indicating whether to wait for the
        /// N-EVENT-REPORT - either over the same or different association before returning
        /// to the caller.</param>
        /// <param name="timeOut">Time (in Seconds) to wait for the N-EVENT-REPORT to be sent
        /// from the Image Manager - only used if "awaitNEventReport" is set true.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool SendStorageCommitment(bool awaitNEventReport, int timeOut)
        {
            // Check if we need to wait for the Event Report
            if (awaitNEventReport == true)
            {
                // Subscribe to the event
                SubscribeStorageCommitmentNEventReportResponseEvent();
            }

            // Generate a new Storage Commitment Transaction UID
            InBuiltDefaultTagValues inbuiltDefaultTagValues = new InBuiltDefaultTagValues();
            System.String uidRoot = inbuiltDefaultTagValues.UidRoot;
            DicomTagValueAutoSetUid tagValueUid = new DicomTagValueAutoSetUid(AffectedEntityEnum.AnyEntity,
                Tag.TRANSACTION_UID, uidRoot, 1);
            _storageCommitTransactionUid = tagValueUid.Value;

            DvtkHighLevelInterface.Dicom.Messages.DicomMessage nActionStorageCommitment = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.NACTIONRQ);
            GenerateTriggers.MakeNActionStorageCommitment(_storageCommitItems, nActionStorageCommitment, _storageCommitTransactionUid, _mppsInstanceUid);

            // Trigger the N-ACTION-RQ Storage Commitment
            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_10);
            trigger.AddItem(nActionStorageCommitment,
                            "1.2.840.10008.1.20.1",
                            "1.2.840.10008.1.2");

            // RAD-10 - trigger the ImageManager
            bool result = TriggerActorInstances(ActorTypeEnum.ImageManager, trigger, true);
            if (result == true)
            {
                // Check if we need to wait for the Event Report
                if (awaitNEventReport == true)
                {
                    // Wait for the N-Event-Report response
                    // for the given timeout
                    result = WaitStorageCommitmentNEventReportResponse(timeOut);

                    // Unsubscribe to the event
                    UnsubscribeStorageCommitmentNEventReportResponseEvent();
                }
            }
            return result;
        }
示例#10
0
 /// <summary>
 /// Send a CFind Modality Worklist Query trigger by reading the query
 /// dataset from the given mwlQueryDcmFilename. If the scheduledProcedureStepStartDate
 /// is defined (not string empty) then if a value for this attribute is present in the
 /// read datset it will be overwritten by the scheduledProcedureStepStartDate value.
 /// </summary>
 /// <param name="mwlQueryDcmFilename">DCM file containing the MWL Query Dataset.</param>
 /// <param name="scheduledProcedureStepStartDate">Optional (not sting empty) start date to overwrite dataset value.</param>
 /// <returns>Boolean indicating success or failure.</returns>
 public bool SendQueryModalityWorklist(System.String mwlQueryDcmFilename, System.String scheduledProcedureStepStartDate)
 {
     // Generate trigger using the mwl dcm file contents and the given scheduledProcedureStepStartDate
     DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_5);
     trigger.AddItem(GenerateTriggers.MakeCFindModalityWorklist(mwlQueryDcmFilename, scheduledProcedureStepStartDate),
         "1.2.840.10008.5.1.4.31",
         "1.2.840.10008.1.2");
     return TriggerModalityWorklistQuery(trigger);
 }
示例#11
0
 /// <summary>
 /// Send a CFind Modality Worklist Query trigger from the given queryTags.
 /// All other return keys are taken from the supported return key attributes
 /// in the Worklist Information Model.
 /// </summary>
 /// <param name="queryTags">List of Query Tags.</param>
 /// <returns>Boolean indicating success or failure.</returns>
 public bool SendQueryModalityWorklist(TagValueCollection queryTags)
 {
     // Generate trigger using the query tags
     DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_5);
     trigger.AddItem(GenerateTriggers.MakeCFindModalityWorklist(queryTags),
                     "1.2.840.10008.5.1.4.31",
                     "1.2.840.10008.1.2");
     return TriggerModalityWorklistQuery(trigger);
 }
示例#12
0
        /// <summary>
        /// Send all the images found in the given storage directory.
        /// </summary>
        /// <param name="storageDirectory">Given storage directory - containing storage DCM files.</param>
        /// <param name="modalityWorklistItem">Worklist Item used to provide overruling values for
        /// the Image headers.</param>
        /// <param name="withSingleAssociation">Boolean indicating whether the images should be sent in a single
        /// association or not.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool SendModalityImagesStored(System.String storageDirectory, DicomQueryItem modalityWorklistItem, bool withSingleAssociation)
        {
            if ((storageDirectory.Length == 0) ||
                (modalityWorklistItem == null)) return false;

            // Use a hash table to store the instance uid mappings
            // - the instance uids for the study, series and sop are going to be updated for all the datasets
            // read from the storageDirectory
            Hashtable instanceMapper = new Hashtable();

            // Get the directory info for the storage directory - and make sure that it exists
            DirectoryInfo directoryInfo = new DirectoryInfo(storageDirectory);
            if (directoryInfo.Exists == false)
            {
                System.String message = System.String.Format("storageDirectory:\"{0}\" - does not exist.", storageDirectory);
                throw new System.Exception(message);
            }

            // Get a trigger
            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_8);
            trigger.HandleInSingleAssociation = withSingleAssociation;

            // Interate over all the DCM files found in the storage directory
            // - update the instances found with the worklist item contents and
            // set up the triggers for the Image Archive
            foreach(FileInfo fileInfo in directoryInfo.GetFiles())
            {
                if ((fileInfo.Extension.ToLower().Equals(".dcm")) ||
                    (fileInfo.Extension == System.String.Empty))
                {
                    // Read the file meta information - it must be present for this actor
                    DvtkData.Media.FileMetaInformation fileMetaInformation = Dvtk.DvtkDataHelper.ReadFMIFromFile(fileInfo.FullName);
                    if (fileMetaInformation == null) continue;

                    // Try to get the transfer syntax uid
                    // - start with Implicit VR Little Endian
                    System.String transferSyntaxUid = "1.2.840.10008.1.2";
                    DvtkData.Dimse.Attribute attribute = fileMetaInformation.GetAttribute(DvtkData.Dimse.Tag.TRANSFER_SYNTAX_UID);
                    if (attribute != null)
                    {
                        UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)attribute.DicomValue;
                        if (uniqueIdentifier.Values.Count > 0)
                        {
                            transferSyntaxUid = uniqueIdentifier.Values[0];
                        }
                    }

                    // Read the dataset from the DCM file
                    DvtkData.Dimse.DataSet dataset = Dvtk.DvtkDataHelper.ReadDataSetFromFile(fileInfo.FullName);
                    if (dataset == null) continue;

                    // Remove any Group Lengths from the dataset
                    dataset.RemoveGroupLengthAttributes();

                    // Try to get the series instance uid
                    System.String oldSeriesInstanceUid = System.String.Empty;
                    DvtkData.Dimse.Attribute seriesInstanceUidAttribute = dataset.GetAttribute(Tag.SERIES_INSTANCE_UID);
                    if (seriesInstanceUidAttribute != null)
                    {
                        UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)seriesInstanceUidAttribute.DicomValue;
                        if (uniqueIdentifier.Values.Count > 0)
                        {
                            oldSeriesInstanceUid = uniqueIdentifier.Values[0];
                        }

                        // Remove the old series instance from the dataset
                        dataset.Remove(seriesInstanceUidAttribute);
                    }

                    // See if a mapping exists
                    System.String newSeriesInstanceUid = (System.String) instanceMapper[oldSeriesInstanceUid];
                    if (newSeriesInstanceUid == null)
                    {
                        // Add a mapping
                        DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.SeriesEntity);
                        newSeriesInstanceUid = DefaultValueManager.GetInstantiatedValue(Tag.SERIES_INSTANCE_UID);
                        instanceMapper.Add(oldSeriesInstanceUid, newSeriesInstanceUid);
                    }

                    // Add the new series instance uid to the dataset
                    dataset.AddAttribute(Tag.SERIES_INSTANCE_UID.GroupNumber, Tag.SERIES_INSTANCE_UID.ElementNumber, VR.UI, newSeriesInstanceUid);

                    // Try to get the sop instance uid
                    System.String oldSopInstanceUid = System.String.Empty;
                    DvtkData.Dimse.Attribute sopInstanceUidAttribute = dataset.GetAttribute(Tag.SOP_INSTANCE_UID);
                    if (sopInstanceUidAttribute != null)
                    {
                        UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)sopInstanceUidAttribute.DicomValue;
                        if (uniqueIdentifier.Values.Count > 0)
                        {
                            oldSopInstanceUid = uniqueIdentifier.Values[0];
                        }

                        // Remove the old sop instance from the dataset
                        dataset.Remove(sopInstanceUidAttribute);
                    }

                    // See if a mapping exists
                    System.String newSopInstanceUid = (System.String) instanceMapper[oldSopInstanceUid];
                    if (newSopInstanceUid == null)
                    {
                        // Add a mapping
                        DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.InstanceEntity);
                        newSopInstanceUid = DefaultValueManager.GetInstantiatedValue(Tag.SOP_INSTANCE_UID);
                        instanceMapper.Add(oldSopInstanceUid, newSopInstanceUid);
                    }

                    // Add the new sop instance uid to the dataset
                    dataset.AddAttribute(Tag.SOP_INSTANCE_UID.GroupNumber, Tag.SOP_INSTANCE_UID.ElementNumber, VR.UI, newSopInstanceUid);

                    // Use modality Worklist Item to help construct the Storage Message
                    // Get the attribute values to copy
                    DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator");
                    DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage);

                    // Also try to use the MPPS InProgress Message to help construct the Storage Message
                    DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator");
                    DicomComparator dicomMppsInProgressComparator = null;
                    if (_nCreateSetMppsInProgress != null)
                    {
                        dicomMppsInProgressComparator = mppsInProgressComparator.InitializeDicomComparator(_nCreateSetMppsInProgress);
                    }

                    // Create the Storage message
                    DvtkHighLevelInterface.Comparator.Comparator storageComparator = new DvtkHighLevelInterface.Comparator.Comparator("StorageComparator");
                    DvtkHighLevelInterface.Dicom.Messages.DicomMessage cStoreInstance = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ);
                    GenerateTriggers.MakeCStoreInstance(DefaultValueManager, cStoreInstance, dataset);
                    storageComparator.PopulateDicomMessage(cStoreInstance, dicomWorklistItemComparator);
                    if (dicomMppsInProgressComparator != null)
                    {
                        storageComparator.PopulateDicomMessage(cStoreInstance, dicomMppsInProgressComparator);
                    }

                    // Try to get the sop class uid
                    System.String sopClassUid = System.String.Empty;
                    DvtkData.Dimse.Attribute sopClassUidAttribute = dataset.GetAttribute(Tag.SOP_CLASS_UID);
                    if (sopClassUidAttribute != null)
                    {
                        UniqueIdentifier uniqueIdentifier = (UniqueIdentifier)sopClassUidAttribute.DicomValue;
                        if (uniqueIdentifier.Values.Count > 0)
                        {
                            sopClassUid = uniqueIdentifier.Values[0];
                        }
                    }

                    // Add trigger item to the trigger
                    trigger.AddItem(cStoreInstance,
                                    sopClassUid,
                                    transferSyntaxUid);
                }
            }

            // RAD-8 - trigger the ImageArchive
            return TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true);
        }
示例#13
0
        /// <summary>
        /// Send a single image generated from the Default Value Manager and
        /// the given Modality Worklist Item.
        /// </summary>
        /// <param name="startNewSeries">Boolean indicating if this image is part of a new
        /// Series or not.</param>
        /// <param name="modalityWorklistItem">Worklist Item used to provide overruling values for
        /// the Image header.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool SendModalityImagesStored(bool startNewSeries, DicomQueryItem modalityWorklistItem)
        {
            if (modalityWorklistItem == null) return false;

            // Update the default SeriesEntity values for the next Storage Message
            if (startNewSeries == true)
            {
                DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.SeriesEntity);
            }

            // Use modality Worklist Item to help construct the Storage Message
            // Get the attribute values to copy
            DvtkHighLevelInterface.Comparator.Comparator worklistItemComparator = new DvtkHighLevelInterface.Comparator.Comparator("WorklistItemComparator");
            DicomComparator dicomWorklistItemComparator = worklistItemComparator.InitializeDicomComparator(modalityWorklistItem.DicomMessage);

            // Also try to use the MPPS InProgress Message to help construct the Storage Message
            DvtkHighLevelInterface.Comparator.Comparator mppsInProgressComparator = new DvtkHighLevelInterface.Comparator.Comparator("MppsInProgressComparator");
            DicomComparator dicomMppsInProgressComparator = null;
            if (_nCreateSetMppsInProgress != null)
            {
                dicomMppsInProgressComparator = mppsInProgressComparator.InitializeDicomComparator(_nCreateSetMppsInProgress);
            }

            // Create the Storage message
            DvtkHighLevelInterface.Comparator.Comparator storageComparator = new DvtkHighLevelInterface.Comparator.Comparator("StorageComparator");
            DvtkHighLevelInterface.Dicom.Messages.DicomMessage cStoreInstance = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ);
            GenerateTriggers.MakeCStoreInstance(DefaultValueManager, cStoreInstance);
            storageComparator.PopulateDicomMessage(cStoreInstance, dicomWorklistItemComparator);
            if (dicomMppsInProgressComparator != null)
            {
                storageComparator.PopulateDicomMessage(cStoreInstance, dicomMppsInProgressComparator);
            }

            // Trigger the C-STORE-RQ Instance
            DicomTrigger trigger = new DicomTrigger(TransactionNameEnum.RAD_8);
            trigger.HandleInSingleAssociation = true;
            trigger.AddItem(cStoreInstance,
                            "1.2.840.10008.5.1.4.1.1.7",
                            "1.2.840.10008.1.2");

            // Update the default InstanceEntity values for the next Storage Message
            DefaultValueManager.UpdateInstantiatedDefaultTagValues(AffectedEntityEnum.InstanceEntity);

            // RAD-8 - trigger the ImageArchive
            return TriggerActorInstances(ActorTypeEnum.ImageArchive, trigger, true);
        }
示例#14
0
        /// <summary>
        /// Trigger the Client to send a Verification (DICOM C-ECHO-RQ).
        /// </summary>
        /// <param name="actorName">Destination Actor Name.</param>
        /// <returns>Boolean indicating success or failure.</returns>
        public bool TriggerClientVerification(ActorName actorName)
        {
            // Set up a Verification SOP Class - C-ECHO-RQ trigger
            DicomTrigger dicomTrigger = new DicomTrigger(Dvtk.IheActors.Bases.TransactionNameEnum.RAD_UNKNOWN);
            dicomTrigger.AddItem(new DicomMessage(DvtkData.Dimse.DimseCommand.CECHORQ),
                                HliScp.VERIFICATION_SOP_CLASS_UID,
                                HliScp.IMPLICIT_VR_LITTLE_ENDIAN);
            DicomTriggerItem dicomTriggerItem = dicomTrigger.TriggerItems[0];

            // thread must wait for association completion
            _scu.SignalCompletion = true;

            // set up the presentation context from the trigger
            PresentationContext[] presentationContexts = new PresentationContext[1];
            presentationContexts[0] = new PresentationContext(dicomTriggerItem.SopClassUid,
                    dicomTriggerItem.TransferSyntaxes);
            _scu.TriggerSendAssociation(dicomTriggerItem.Message, presentationContexts);

            // wait for association completion
            // - timeout of 0 means "no timeout".
            _semaphore.Wait(0);

            // return a boolean indicating if the trigger was processed successfully or not
            return _scu.ProcessTriggerResult;
        }