private String GetAttributeValueFromDataset(DataSet dataset, DvtkData.Dimse.Tag tag) { DicomMessage dicomMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.CSTORERQ, dataset); String attributeValue = GenerateTriggers.GetValueFromMessageUsingTag(dicomMessage, tag); return(attributeValue); }
/// <summary> /// Overridden N-ACTION-RQ message handler. Return an N-EVENT-REPORT-RQ /// after the N-ACTION-RSP. /// </summary> /// <param name="dicomMessage">N-ACTION-RQ and Dataset.</param> /// <returns>Boolean - true if dicomMessage handled here.</returns> public override bool HandleNActionRequest(DicomMessage dicomMessage) { // Validate the received message // System.String iodName = DicomThread.GetIodNameFromDefinition(dicomMessage); // DicomThread.Validate(dicomMessage, iodName); // set up the default N-ACTION-RSP with a successful status DicomMessage responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.NACTIONRSP); responseMessage.Set("0x00000900", VR.US, 0); // send the response this.Send(responseMessage); // delay before generating the N-EVENT-REPORT-RQ System.Threading.Thread.Sleep(_eventDelay); // create the N-EVENT-REPORT-RQ based in the contents of the N-ACTION-RQ DicomMessage requestMessage = GenerateTriggers.MakeStorageCommitEvent(_informationModels, dicomMessage); // send the request this.Send(requestMessage); // message handled return(true); }
/// <summary> /// Send an N-SET MPPS IN-PROGRESS message from the given mppsInProgressDcmFilename. /// Use the modalityWorklistItem to overwrite the appropriate attribute values. /// NOTE: This call should only be made after the SendModalityProcedureStepInProgress() (using default N-CREATE) /// has been made. /// </summary> /// <param name="mppsInProgressDcmFilename">DCM Filename - contains MPPS IN-PROGRESS dataset.</param> /// <param name="modalityWorklistItem">Modality Worklist Item used to update MPPS IN-PROGRESS dataset.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendNSetModalityProcedureStepInProgress(System.String mppsInProgressDcmFilename, DicomQueryItem modalityWorklistItem) { // Initialize the N-SET MPPS IN-PROGRESS InitializeModalityProcedureStepInProgress(DvtkData.Dimse.DimseCommand.NSETRQ); // Generate the N-SET MPPS IN-PROGRESS from the DCM file contents (default values) GenerateTriggers.MakeMppsInProgress(mppsInProgressDcmFilename, DefaultValueManager, _nCreateSetMppsInProgress, _mppsInstanceUid); return(TriggerModalityProcedureStepInProgress(modalityWorklistItem)); }
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); }
/// <summary> /// Send an N-CREATE MPPS IN-PROGRESS message by using the Default Value Manager. /// Use the modalityWorklistItem to overwrite the appropriate attribute values. /// </summary> /// <param name="modalityWorklistItem">Modality Worklist Item used to update MPPS IN-PROGRESS dataset.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendNCreateModalityProcedureStepInProgress(DicomQueryItem modalityWorklistItem) { // Initialize the N-CREATE MPPS IN-PROGRESS InitializeModalityProcedureStepInProgress(DvtkData.Dimse.DimseCommand.NCREATERQ); // Generate the N-CREATE MPPS IN-PROGRESS from the Default Value Manager GenerateTriggers.MakeMppsInProgress(DefaultValueManager, _nCreateSetMppsInProgress, _mppsInstanceUid); return(TriggerModalityProcedureStepInProgress(modalityWorklistItem)); }
/// <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)); }
/// <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)); }
/// <summary> /// Send an N-SET MPPS DISCONTINUED message. Take the default values from the given DCM file contents. /// </summary> /// <param name="mppsDiscontinuedDcmFilename">DCM file for default MPPS Discontinued atribute values.</param> /// <returns>Boolean indicating success or failure.</returns> public bool SendNSetModalityProcedureStepDiscontinued(System.String mppsDiscontinuedDcmFilename) { // Initialize the mpps discontinued InitializeModalityProcedureStepCompletedDiscontinued(); // Generate the mpps discontinued from the DCM file content DvtkHighLevelInterface.Dicom.Messages.DicomMessage nSetMppsDiscontinued = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.NSETRQ); GenerateTriggers.MakeNSetMppsCompletedDiscontinued(mppsDiscontinuedDcmFilename, DefaultValueManager, _storageCommitItems, nSetMppsDiscontinued, _mppsInstanceUid); return(TriggerModalityProcedureStepCompletedDiscontinued(nSetMppsDiscontinued)); }
/// <summary> /// Send an N-SET MPPS COMPLETED message. Take the default values from the Default Value Manager. /// </summary> /// <returns>Boolean indicating success or failure.</returns> public bool SendNSetModalityProcedureStepCompleted() { // Initialize the mpps completed InitializeModalityProcedureStepCompletedDiscontinued(); // Generate the mpps completed from the Default Value Manager DvtkHighLevelInterface.Dicom.Messages.DicomMessage nSetMppsCompleted = new DvtkHighLevelInterface.Dicom.Messages.DicomMessage(DvtkData.Dimse.DimseCommand.NSETRQ); GenerateTriggers.MakeNSetMppsCompletedDiscontinued(DefaultValueManager, _storageCommitItems, nSetMppsCompleted, _mppsInstanceUid, "COMPLETED"); return(TriggerModalityProcedureStepCompletedDiscontinued(nSetMppsCompleted)); }
public System.String GetValue(DvtkData.Dimse.Tag sequenceTag, DvtkData.Dimse.Tag tag) { System.String lValue = System.String.Empty; if (_dicomMessage != null) { lValue = GenerateTriggers.GetValueFromMessageUsingTag(_dicomMessage, sequenceTag, tag); } return(lValue); }
/// <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)); }
private bool SendNEventReport(QueryRetrieveInformationModels qrInfoModels, DicomMessage dicomMessage) { // create the N-EVENT-REPORT-RQ based in the contents of the N-ACTION-RQ DicomMessage requestMessage = GenerateTriggers.MakeStorageCommitEvent(qrInfoModels, dicomMessage); // send the request this.Send(requestMessage); ReceiveDicomMessage(); isEventSent = true; return(isEventSent); }
/// <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); }
private void InitializeModalityProcedureStepCompletedDiscontinued() { // Get the C-STORE-RSPs returned foreach (ActorsTransaction actorsTransaction in ActorsTransactionLog) { if (actorsTransaction.FromActorName.Type == ActorTypeEnum.ImageArchive) { BaseTransaction baseTransaction = actorsTransaction.Transaction; if (baseTransaction is DicomTransaction) { DicomTransaction dicomTransaction = (DicomTransaction)baseTransaction; DicomMessageCollection cStoreResponses = dicomTransaction.DicomMessages.CStoreResponses; GenerateTriggers.HandleCStoreResponses(_storageCommitItems, cStoreResponses); } } } }
/// <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.ImageManager: // received Storage Commitment [RAD-10] DicomMessageCollection nEventReportRequests = dicomTransaction.DicomMessages.NEventReportRequests; foreach (DvtkHighLevelInterface.Dicom.Messages.DicomMessage dicomMessage in nEventReportRequests) { // Update the storage commit items with the appropriate status - as received in the // event report request GenerateTriggers.HandleNEventReportStorageCommitment(_storageCommitItems, dicomMessage); } break; default: break; } }
/// <summary> /// Overridden N-ACTION-RQ message handler. Return an N-EVENT-REPORT-RQ /// after the N-ACTION-RSP. /// </summary> /// <param name="queryMessage">N-ACTION-RQ and Dataset.</param> /// <returns>Boolean - true if dicomMessage handled here.</returns> protected override void AfterHandlingNActionRequest(DicomMessage dicomMessage) { isEventSent = false; // set up the default N-ACTION-RSP with a successful status DicomMessage responseMessage = new DicomMessage(DvtkData.Dimse.DimseCommand.NACTIONRSP); responseMessage.Set("0x00000900", DvtkData.Dimse.VR.US, 0); // send the response this.Send(responseMessage); IsMessageHandled = true; // creating information model QueryRetrieveInformationModels qrInfoModels = CreateQueryRetrieveInformationModels(true, _dataDirectory); // delay before generating the N-EVENT-REPORT-RQ WriteInformation(string.Format("Delaying the N-EVENT-REPORT by {0} secs", _eventDelay / 1000)); isAssociated = true; int waitedTime = 0; if (WaitForPendingDataInNetworkInputBuffer(_eventDelay, ref waitedTime)) { ReleaseRq releaseRq = ReceiveReleaseRq(); if (releaseRq != null) { SendReleaseRp(); isAssociated = false; } } if (!isAssociated) { string info = "Sending the N-Event-Report asynchronously."; WriteInformation(info); SCU commitScu = new SCU(); commitScu.Initialize(this.Parent); // Set the correct settings for the overview DicomThread. // commitScu.Options.Identifier = "Storage_Commitment_SCU_association_" + storageCommitmentScuIndex.ToString(); commitScu.Options.ResultsFileNameOnlyWithoutExtension = (this.overviewThread as StoreCommitScp).startDateTime + "_Storage_Commitment_SCU_association_" + storageCommitmentScuIndex.ToString(); storageCommitmentScuIndex++; commitScu.Options.LocalAeTitle = this.Options.LocalAeTitle; commitScu.Options.RemoteAeTitle = _remoteAETitle; commitScu.Options.RemotePort = _port; commitScu.Options.RemoteHostName = _remoteHostName; commitScu.Options.RemoteRole = Dvtk.Sessions.SutRole.Requestor; commitScu.Options.ResultsDirectory = this.Options.ResultsDirectory; commitScu.Options.DataDirectory = this.Options.DataDirectory; commitScu.Options.StorageMode = Dvtk.Sessions.StorageMode.NoStorage; commitScu.Options.LogThreadStartingAndStoppingInParent = false; commitScu.Options.LogWaitingForCompletionChildThreads = false; commitScu.Options.AutoValidate = false; PresentationContext presentationContext = new PresentationContext("1.2.840.10008.1.20.1", // Abstract Syntax Name "1.2.840.10008.1.2"); // Transfer Syntax Name(s) PresentationContext[] presentationContexts = new PresentationContext[1]; presentationContexts[0] = presentationContext; // create the N-EVENT-REPORT-RQ based in the contents of the N-ACTION-RQ DicomMessage requestMessage = GenerateTriggers.MakeStorageCommitEvent(qrInfoModels, dicomMessage); if (waitedTime < _eventDelay) { Sleep(_eventDelay - waitedTime); } commitScu.Start(); isEventSent = commitScu.TriggerSendAssociationAndWait(requestMessage, presentationContexts); } else { string info = "Sending the N-Event-Report synchronously."; WriteInformation(info); if (!isEventSent) { SendNEventReport(qrInfoModels, dicomMessage); } } }
/// <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)); }
/// <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); }
/// <summary> /// Create an unscheduled worklist item by adding the given user defined tags to those /// of the Default Value Manager. This worklist item can then be used in the /// SendNCreateModalityProcedureStepInProgress() and SendModalityImagesStored() method /// calls. /// This simulates the IHE Unscheduled Use Case. /// </summary> /// <param name="userDefinedTags">User defined Tags.</param> /// <returns>Modality worklist item populated from the user defined tags and default values.</returns> public DicomQueryItem CreateUnscheduledWorklistItem(TagValueCollection userDefinedTags) { return(new DicomQueryItem(1, GenerateTriggers.MakeModalityWorklistItem(DefaultValueManager, userDefinedTags))); }
/// <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); }