Ejemplo n.º 1
0
        /// <summary>
        /// Load the values for the sequence <see cref="DicomTags.RequestAttributesSequence"/>
        /// into a response message for a specific series.
        /// </summary>
        /// <param name="read">The connection to use to read the values.</param>
        /// <param name="response">The message to add the values into.</param>
        /// <param name="row">The <see cref="Series"/> entity to load the related <see cref="RequestAttributes"/> entity for.</param>
        private static void LoadRequestAttributes(IPersistenceContext read, DicomMessageBase response, Series row)
        {
            var select = read.GetBroker<IRequestAttributesEntityBroker>();

            var criteria = new RequestAttributesSelectCriteria();

            criteria.SeriesKey.EqualTo(row.GetKey());

            IList<RequestAttributes> list = select.Find(criteria);

            if (list.Count == 0)
            {
                response.DataSet[DicomTags.RequestAttributesSequence].SetNullValue();
                return;
            }

            foreach (RequestAttributes request in list)
            {
                var item = new DicomSequenceItem();
                item[DicomTags.ScheduledProcedureStepId].SetStringValue(request.ScheduledProcedureStepId);
                item[DicomTags.RequestedProcedureId].SetStringValue(request.RequestedProcedureId);

                response.DataSet[DicomTags.RequestAttributesSequence].AddSequenceItem(item);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Validates the contents in the <see cref="DicomMessageBase"/> object.
        /// </summary>
        /// <param name="message"></param>
        /// <exception cref="DicomDataException"/> is thrown if the DICOM object fails the validation.
        public void Validate(DicomMessageBase message)
        {
            String studyInstanceUid = message.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty);
            String seriesInstanceUid = message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty);
            String sopInstanceUid = message.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty);

            if (String.IsNullOrEmpty(studyInstanceUid))
            {
                throw new DicomDataException("Study Instance UID is missing or empty");
            }

            if (studyInstanceUid.Length > 64 || seriesInstanceUid.Length > 64 || sopInstanceUid.Length > 64)
            {
            	if (studyInstanceUid.Length > 64)
                    throw new DicomDataException(string.Format("Study Instance UID is > 64 bytes in the SOP Instance : {0}", studyInstanceUid));

            	if (seriesInstanceUid.Length > 64)
            		throw new DicomDataException(string.Format("Series Instance UID is > 64 bytes in the SOP Instance : {0}", seriesInstanceUid));

            	throw new DicomDataException(string.Format("SOP Instance UID is > 64 bytes in the SOP Instance : {0}", sopInstanceUid));
            }

			if (studyInstanceUid.EndsWith("."))
				throw new DicomDataException(string.Format("Study Instance UID ends with period : {0}", studyInstanceUid));

			if (seriesInstanceUid.EndsWith("."))
				throw new DicomDataException(string.Format("Series Instance UID ends with period : {0}", seriesInstanceUid));

			if (sopInstanceUid.EndsWith("."))
				throw new DicomDataException(string.Format("SOP Instance UID ends with period : {0}", sopInstanceUid));
		}
Ejemplo n.º 3
0
        private IWorkItemProcessor InsertStudyDelete(DicomMessageBase msg, WorkItemPriorityEnum priority, WorkItemStatusEnum status)
        {
            var rq = new WorkItemInsertRequest
                         {
                             Request = new DeleteStudyRequest
                                           {
                                               Patient = new WorkItemPatient(msg.DataSet),
                                               Study = new WorkItemStudy(msg.DataSet),
                                               Priority = priority
                                           }
                         };
            var rsp = WorkItemService.Instance.Insert(rq);

            var updateRequest = new WorkItemUpdateRequest
            {
                Status = status,
                Identifier = rsp.Item.Identifier
            };

            WorkItemService.Instance.Update(updateRequest);

            using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex))
            {
                var broker = context.GetWorkItemBroker();

                var d = new DeleteStudyItemProcessor();
                d.Initialize(new WorkItemStatusProxy(broker.GetWorkItem(rsp.Item.Identifier)));
                return d;
            }
        }
Ejemplo n.º 4
0
 public ServerActionContext(DicomMessageBase msg, ServerEntityKey filesystemKey,
                            ServerPartition partition, ServerEntityKey studyLocationKey)
 {
     Message = msg;
     ServerPartitionKey = partition.Key;
     StudyLocationKey = studyLocationKey;
     FilesystemKey = filesystemKey;
 	ServerPartition = partition;
 }
		public DicomCompressedPixelData(DicomMessageBase msg, byte[] frameData) : base(msg)
		{
			_sq = new DicomFragmentSequence(DicomTags.PixelData);
			AddFrameFragment(frameData);
			//ByteBuffer buffer = new ByteBuffer(frameData);
			//DicomFragment fragment = new DicomFragment(buffer);
			//_sq.AddFragment(fragment);
			NumberOfFrames = 1;
		}
Ejemplo n.º 6
0
 public UpdateWorkQueueCommand(DicomMessageBase message, StudyStorageLocation location, bool duplicate, string extension, string uidGroupId)
     : base("Update/Insert a WorkQueue Entry")
 {
     Platform.CheckForNullReference(message, "Dicom Message object");
     Platform.CheckForNullReference(location, "Study Storage Location");
     
     _message = message;
     _storageLocation = location;
     _duplicate = duplicate;
     _extension = extension;
     _uidGroupId = uidGroupId;
 }
        public UpdateWorkQueueCommand(DicomMessageBase message, StudyStorageLocation location, bool duplicate, WorkQueueData data=null, WorkQueueUidData uidData=null, ExternalRequestQueue request=null, WorkQueuePriorityEnum priority=null)
            : base("Update/Insert a WorkQueue Entry")
        {
            Platform.CheckForNullReference(message, "Dicom Message object");
            Platform.CheckForNullReference(location, "Study Storage Location");
            
            _message = message;
            _storageLocation = location;
            _duplicate = duplicate;
            _data = data;
            _request = request;
            _uidData = uidData;
	        _priority = priority;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Load the values for the tag <see cref="DicomTags.ModalitiesInStudy"/> into a response
        /// message for a specific <see cref="Study"/>.
        /// </summary>
        /// <param name="read">The connection to use to read the values.</param>
        /// <param name="response">The message to add the value into.</param>
        /// <param name="key">The <see cref="ServerEntityKey"/> for the <see cref="Study"/>.</param>
        private static void LoadModalitiesInStudy(IPersistenceContext read, DicomMessageBase response, ServerEntityKey key)
        {
            var select = read.GetBroker<IQueryModalitiesInStudy>();

            var parms = new ModalitiesInStudyQueryParameters { StudyKey = key };

            IList<Series> list = select.Find(parms);

            string value = "";
            foreach (Series series in list)
            {
                value = value.Length == 0
                    ? series.Modality
                    : String.Format("{0}\\{1}", value, series.Modality);
            }
            response.DataSet[DicomTags.ModalitiesInStudy].SetStringValue(value);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Create a list of SOP Instances to move based on a Patient level C-MOVE-RQ.
        /// </summary>
        /// <param name="read"></param>
        /// <param name="msg"></param>
        /// <param name="errorComment"> </param>
        /// <returns></returns>
        private bool GetSopListForPatient(IPersistenceContext read, DicomMessageBase msg, out string errorComment)
        {
            errorComment = string.Empty;
            string patientId = msg.DataSet[DicomTags.PatientId].GetString(0, "");

            var select = read.GetBroker<IStudyEntityBroker>();

            var criteria = new StudySelectCriteria();
            criteria.PatientId.EqualTo(patientId);
			criteria.ServerPartitionKey.EqualTo(Partition.Key);

            IList<Study> studyList = select.Find(criteria);

        	bool bOfflineFound = false;
            foreach (Study study in studyList)
            {
                StudyStorageLocation location;

				try
				{
					FilesystemMonitor.Instance.GetReadableStudyStorageLocation(Partition.Key, study.StudyInstanceUid,
					                                                           StudyRestore.True, StudyCache.True, out location);
				}
                catch (StudyIsNearlineException e)
                {
                    errorComment = string.Format(e.RestoreRequested ? "Study is nearline, inserted restore request: {0}" : "Study is nearline: {0}", study.StudyInstanceUid);

                    bOfflineFound = true;
                    continue;				        
                }
				catch (Exception e)
				{
				    errorComment = string.Format("Exception occurred when determining study location: {0}", e.Message);
					bOfflineFound = true;
					continue;
				}

            	StudyXml theStream = LoadStudyXml(location);

                _theScu.LoadStudyFromStudyXml(location.GetStudyPath(), theStream);
            }

            return !bOfflineFound;
        }
		/// <summary>
		/// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
		/// </summary>
		/// <param name="context">The processing context</param>
		/// <param name="message">A subset of the message stored in <paramref name="sourceFilename"/></param>
		/// <param name="sourceFilename">The location of the filename that is a duplicate</param>
		/// <param name="data">The data</param>
		/// <param name="duplicate">How the processor should handle the duplicate</param>
		public static void ProcessStoredDuplicateFile(SopInstanceProcessorContext context,
													  string sourceFilename,
													  DicomMessageBase message,
													  StudyProcessWorkQueueData data,
													  DuplicateProcessingEnum duplicate)
		{
			SaveDuplicateFile(context, message.DataSet[DicomTags.SopInstanceUid].ToString(), sourceFilename);
			var uidData = new WorkQueueUidData
			{
				Extension = ServerPlatform.DuplicateFileExtension,
				GroupId = context.Group,
				DuplicateProcessing = duplicate
			};

			if (context.Request != null)
				uidData.OperationToken = context.Request.OperationToken;

			context.CommandProcessor.AddCommand(
				new UpdateWorkQueueCommand(message, context.StudyLocation, true, data, uidData, context.Request));
		}
		private void SetSourceMessage(DicomMessageBase sourceMessage)
		{
			_sourceMessage = sourceMessage;
			_loaded = !_sourceMessage.DataSet.IsEmpty();
		}
		/// <summary>
		/// Constructs a new <see cref="DicomMessageSopDataSource"/>.
		/// </summary>
		/// <param name="sourceMessage">The source <see cref="DicomMessageBase"/> which provides all the SOP instance data.</param>
		protected DicomMessageSopDataSource(DicomMessageBase sourceMessage)
		{
			_dummy = new DicomAttributeCollection();
			SetSourceMessage(sourceMessage);
		}
Ejemplo n.º 13
0
 /// <summary>
 /// Updat ethe pixel data related tags in a DICOM message.
 /// </summary>
 /// <param name="message"></param>
 public abstract void UpdateMessage(DicomMessageBase message);
Ejemplo n.º 14
0
        /// <summary>
        /// Populate at the IMAGE level a response message.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
        /// <param name="theInstanceStream"></param>
        private void PopulateInstance(DicomMessageBase request, DicomMessageBase response, IEnumerable<DicomTag> tagList,
                                      InstanceXml theInstanceStream)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            DicomAttributeCollection sourceDataSet = theInstanceStream.Collection;

            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }
            else if (sourceDataSet.Contains(DicomTags.SpecificCharacterSet))
			{
				dataSet[DicomTags.SpecificCharacterSet].SetStringValue(sourceDataSet[DicomTags.SpecificCharacterSet].ToString());
				dataSet.SpecificCharacterSet = sourceDataSet[DicomTags.SpecificCharacterSet].ToString(); // this will ensure the data is encoded using the specified character set
			}

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(request.DataSet[DicomTags.PatientId].ToString());
                            break;
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.StudyInstanceUid].ToString());
                            break;
                        case DicomTags.SeriesInstanceUid:
                            dataSet[DicomTags.SeriesInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.SeriesInstanceUid].ToString());
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("IMAGE");
                            break;
                        default:
                            if (sourceDataSet.Contains(tag))
                                dataSet[tag] = sourceDataSet[tag].Copy();
                            else if (!tag.IsPrivate)                           
                                dataSet[tag].SetNullValue();
                            break;
						// Meta tags that should have not been in the RQ, but we've already set
						case DicomTags.RetrieveAeTitle:
						case DicomTags.InstanceAvailability:
						case DicomTags.SpecificCharacterSet:
							break;
					}
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="message"></param>
 protected DicomPixelData(DicomMessageBase message)
     : this(message.DataSet)
 {
     _transferSyntax = message.TransferSyntax;
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Create a Study Directory Record
        /// </summary>
        /// <param name="dicomFile">The dicom file.</param>
        private static DirectoryRecordSequenceItem CreateStudyItem(DicomMessageBase dicomFile)
        {
            IDictionary<uint, object> dicomTags = new Dictionary<uint, object>();
            dicomTags.Add(DicomTags.StudyInstanceUid, null);
            dicomTags.Add(DicomTags.StudyId, null);
            dicomTags.Add(DicomTags.StudyDate, null);
            dicomTags.Add(DicomTags.StudyTime, null);
            dicomTags.Add(DicomTags.AccessionNumber, null);
            dicomTags.Add(DicomTags.StudyDescription, null);

            return AddSequenceItem(DirectoryRecordType.Study, dicomFile.DataSet, dicomTags);
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Traverse at the Patient level to check if a Patient exists or create a Patient if it doesn't exist.
 /// </summary>
 /// <param name="patients"></param>
 /// <param name="file"></param>
 /// <returns></returns>
 private static DirectoryRecordSequenceItem GetExistingOrCreateNewPatient(DirectoryRecordSequenceItem patients, DicomMessageBase file)
 {
     DirectoryRecordSequenceItem currentPatient = patients;
     while (currentPatient != null)
     {
         if (currentPatient[DicomTags.PatientId].Equals(file.DataSet[DicomTags.PatientId])
             && currentPatient[DicomTags.PatientsName].Equals(file.DataSet[DicomTags.PatientsName]))
         {
             return currentPatient;
         }
         if (currentPatient.NextDirectoryRecord == null)
         {
             currentPatient.NextDirectoryRecord = CreatePatientItem(file);
             return currentPatient.NextDirectoryRecord;
         }
         currentPatient = currentPatient.NextDirectoryRecord;
     }
     return null;
 }
		/// <summary>
		/// Update a <see cref="DicomMessageBase"/> with the pixel data contained
		/// within this object and also update pixel data related tags.
		/// </summary>
		/// <param name="message"></param>
		public override void UpdateMessage(DicomMessageBase message)
		{
			UpdateAttributeCollection(message.DataSet);
			DicomFile file = message as DicomFile;
			if (file != null)
				file.TransferSyntax = TransferSyntax;
		}
		/// <summary>
		/// Returns a value indicating whether the Dicom image must be reconciled.
		/// </summary>
		/// <param name="storageLocation"></param>
		/// <param name="message">The Dicom message</param>
		/// <returns></returns>
		private bool ShouldReconcile(StudyStorageLocation storageLocation, DicomMessageBase message)
		{
			Platform.CheckForNullReference(_context, "_context");
			Platform.CheckForNullReference(message, "message");

			if (_context.Study == null)
			{
				// the study doesn't exist in the database
				return false;
			}

		    StudyComparer comparer = new StudyComparer();
            DifferenceCollection list = comparer.Compare(message, storageLocation.Study, storageLocation.ServerPartition.GetComparisonOptions());

		    if (list != null && list.Count > 0)
		    {
		        LogDifferences(message, list);
		        return true;
		    }
		    return false;
		}
Ejemplo n.º 20
0
        private static ReconcileStudyQueueDescription GetQueueEntryDescription(StudyStorageLocation existingStorage, DicomMessageBase file)
        {
            ReconcileStudyQueueDescription desc = new ReconcileStudyQueueDescription
                                                  	{
                                                  		ExistingPatientId = existingStorage.Study.PatientId,
                                                  		ExistingPatientName = existingStorage.Study.PatientsName,
                                                  		ExistingAccessionNumber = existingStorage.Study.AccessionNumber,
                                                  		ConflictingPatientName =
                                                  			file.DataSet[DicomTags.PatientsName].GetString(0, String.Empty),
                                                  		ConflictingPatientId =
                                                  			file.DataSet[DicomTags.PatientId].GetString(0, String.Empty),
                                                  		ConflictingAccessionNumber =
                                                  			file.DataSet[DicomTags.AccessionNumber].GetString(0, String.Empty)
                                                  	};

        	return desc;
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Traverse at the Series level to check if a Series exists, or create a Series if it doesn't exist.
 /// </summary>
 /// <param name="series"></param>
 /// <param name="file"></param>
 /// <returns></returns>
 private static DirectoryRecordSequenceItem GetExistingOrCreateNewSeries(DirectoryRecordSequenceItem series, DicomMessageBase file)
 {
     DirectoryRecordSequenceItem currentSeries = series;
     while (currentSeries != null)
     {
         if (currentSeries[DicomTags.SeriesInstanceUid].Equals(file.DataSet[DicomTags.SeriesInstanceUid]))
         {
             return currentSeries;
         }
         if (currentSeries.NextDirectoryRecord == null)
         {
             currentSeries.NextDirectoryRecord = CreateSeriesItem(file);
             return currentSeries.NextDirectoryRecord;
         }
         currentSeries = currentSeries.NextDirectoryRecord;
     }
     return null;
 }
        /// <summary>
        /// Checks the data in the message and generates warning logs/alerts if
        /// any of them exceeeds the max size allowed in the database
        /// </summary>
        /// <param name="file"></param>
        private void CheckDataLength(DicomMessageBase file)
        {
            //TODO: Maybe this should be part of the model?

            String studyInstanceUid = file.DataSet[DicomTags.StudyInstanceUid].GetString(0, String.Empty);
            
            String patientId = file.DataSet[DicomTags.PatientId].GetString(0, String.Empty);
            String issuerOfPatientId = file.DataSet[DicomTags.IssuerOfPatientId].GetString(0, String.Empty);
            String patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, String.Empty);
            String patientsBirthDate = file.DataSet[DicomTags.PatientsBirthDate].GetString(0, String.Empty);
            String patientsSex = file.DataSet[DicomTags.PatientsSex].GetString(0, String.Empty);
            String accessionNumber = file.DataSet[DicomTags.AccessionNumber].GetString(0, String.Empty);

            bool alert = false;
            if (!string.IsNullOrEmpty(patientId) && patientId.Length>64)
            {
                alert = true;
                Platform.Log(LogLevel.Warn, "Patient ID ({0}) in the dicom message exceeeds 64 characters", patientId);
            }

            if (!string.IsNullOrEmpty(issuerOfPatientId) && issuerOfPatientId.Length > 64)
            {
                alert = true; 
                Platform.Log(LogLevel.Warn, "Issuer Of Patient ID ({0}) in the dicom message exceeeds 64 characters", issuerOfPatientId);
            }
            if (!string.IsNullOrEmpty(patientsName) && patientsName.Length > 64)
            {
                alert = true; 
                Platform.Log(LogLevel.Warn, "Patient's Name ({0}) in the dicom message exceeeds 64 characters", patientsName);
            }
            if (!string.IsNullOrEmpty(patientsBirthDate) && patientsBirthDate.Length > 8)
            {
                alert = true;
                Platform.Log(LogLevel.Warn, "Patient's Birth Date ({0}) in the dicom message exceeeds 8 characters", patientsBirthDate);
            }
            if (!string.IsNullOrEmpty(patientsSex) && patientsSex.Length > 2)
            {
                alert = true; 
                Platform.Log(LogLevel.Warn, "Patient's Sex ({0}) in the dicom message exceeeds 2 characters", patientsSex);
            }
            if (!string.IsNullOrEmpty(accessionNumber) && accessionNumber.Length > 16)
            {
                alert = true; 
                Platform.Log(LogLevel.Warn, "Accession Number ({0}) in the dicom message exceeeds 16 characters", accessionNumber);
            }

            if (alert)
            {
                StudyAlertGenerator.Generate(
                    new StudyAlert("Study Process", _context.Partition.AeTitle, studyInstanceUid, StudyAlertType.BadDicomData, 
                        String.Format("Study {0} contains some bad data which may have been truncated. It may not appear when queried by remote devices.", 
                        studyInstanceUid)));
            }
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Initializes a <see cref="DicomUncompressedPixelData"/> from the attributes in a DICOM file/message.
 /// </summary>
 /// <param name="dicomMessage">A DICOM file/message from which to initialize the properties of the <see cref="DicomUncompressedPixelData"/>.</param>
 public DicomUncompressedPixelData(DicomMessageBase dicomMessage)
     : base(dicomMessage)
 {
     _pd = dicomMessage.DataSet[DicomTags.PixelData];
     InitializeFrameData(this, _pd);
 }
		private static void LogDifferences(DicomMessageBase message, DifferenceCollection list)
		{
			string sopInstanceUid = message.DataSet[DicomTags.SopInstanceUid].GetString(0, String.Empty);
			StringBuilder sb = new StringBuilder();
			sb.AppendFormat("Found {0} issue(s) in SOP {1}\n", list.Count, sopInstanceUid);
			sb.Append(list.ToString());
			Platform.Log(LogLevel.Warn, sb.ToString());
		}
Ejemplo n.º 25
0
        static private DicomFile ConvertToDicomFile(DicomMessageBase message, string filename, string sourceAe)
        {
            // This routine sets some of the group 0x0002 elements.
            DicomFile file;
            if (message is DicomFile)
            {
                file = message as DicomFile;
            }
            else if (message is DicomMessage)
            {
                file = new DicomFile(message as DicomMessage, filename);
            }
            else
            {
                throw new NotSupportedException(String.Format("Cannot convert {0} to DicomFile", message.GetType()));
            }

            file.SourceApplicationEntityTitle = sourceAe;
            file.TransferSyntax = message.TransferSyntax;

            return file;
        }
		/// <summary>
		/// Initializes a <see cref="DicomUncompressedPixelData"/> from the attributes in a DICOM file/message.
		/// </summary>
		/// <param name="dicomMessage">A DICOM file/message from which to initialize the properties of the <see cref="DicomUncompressedPixelData"/>.</param>
		public DicomUncompressedPixelData(DicomMessageBase dicomMessage)
			: base(dicomMessage)
		{
			_pd = dicomMessage.DataSet[DicomTags.PixelData];
			InitializeFrameData(this, _pd);
		}
Ejemplo n.º 27
0
        /// <summary>
        /// Compare at the IMAGE level if a query matches the data in an <see cref="InstanceXml"/> file.
        /// </summary>
        /// <param name="queryMessage"></param>
        /// <param name="matchTagList"></param>
        /// <param name="instanceStream"></param>
        /// <returns></returns>
        private static bool CompareInstanceMatch(DicomMessageBase queryMessage, IEnumerable<uint> matchTagList,
                                                 InstanceXml instanceStream)
        {
            foreach (uint tag in matchTagList)
            {
                if (!instanceStream.Collection.Contains(tag))
                    continue;

                DicomAttribute sourceAttrib = queryMessage.DataSet[tag];
                DicomAttribute matchAttrib = instanceStream.Collection[tag];

                if (sourceAttrib.Tag.VR.Equals(DicomVr.SQvr))
                    continue; // TODO

                if (sourceAttrib.IsNull)
                    continue;

                string sourceString = sourceAttrib.ToString();
                if (sourceString.Contains("*") || sourceString.Contains("?"))
                {
                    sourceString = sourceString.Replace("*", "[\x21-\x7E]");
                    sourceString = sourceString.Replace("?", ".");
                    if (!Regex.IsMatch(matchAttrib.ToString(), sourceString))
                        return false;
                }
                else if (!sourceAttrib.Equals(matchAttrib))
                    return false;
            }

            return true;
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Traverse at the Study level to check if a Study exists or create a Study if it doesn't exist.
 /// </summary>
 /// <param name="studies"></param>
 /// <param name="file"></param>
 /// <returns></returns>
 private static DirectoryRecordSequenceItem GetExistingOrCreateNewStudy(DirectoryRecordSequenceItem studies, DicomMessageBase file)
 {
     DirectoryRecordSequenceItem currentStudy = studies;
     while (currentStudy != null)
     {
         if (currentStudy[DicomTags.StudyInstanceUid].Equals(file.DataSet[DicomTags.StudyInstanceUid]))
         {
             return currentStudy;
         }
         if (currentStudy.NextDirectoryRecord == null)
         {
             currentStudy.NextDirectoryRecord = CreateStudyItem(file);
             return currentStudy.NextDirectoryRecord;
         }
         currentStudy = currentStudy.NextDirectoryRecord;
     }
     return null;
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Populate data from a <see cref="Patient"/> entity into a DICOM C-FIND-RSP message.
        /// </summary>
        /// <param name="response">The response message to populate with results.</param>
        /// <param name="tagList">The list of tags to populate.</param>
        /// <param name="row">The <see cref="Patient"/> table to populate from.</param>
        private void PopulatePatient(DicomMessageBase response, IEnumerable<DicomTag> tagList, Patient row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
            //dataSet[DicomTags.InstanceAvailability].SetStringValue("ONLINE");

            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet; 
            }
            else if (false == String.IsNullOrEmpty(row.SpecificCharacterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(row.SpecificCharacterSet);
                dataSet.SpecificCharacterSet = row.SpecificCharacterSet; // this will ensure the data is encoded using the specified character set
            }

        	IList<Study> relatedStudies = row.LoadRelatedStudies();
        	Study study = null;
			if (relatedStudies.Count > 0)
				study = CollectionUtils.FirstElement(relatedStudies);

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientsName:
                            dataSet[DicomTags.PatientsName].SetStringValue(row.PatientsName);
                            break;
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(row.PatientId);
                            break;
                        case DicomTags.IssuerOfPatientId:
                            dataSet[DicomTags.IssuerOfPatientId].SetStringValue(row.IssuerOfPatientId);
                            break;
                        case DicomTags.NumberOfPatientRelatedStudies:
                            dataSet[DicomTags.NumberOfPatientRelatedStudies].AppendInt32(row.NumberOfPatientRelatedStudies);
                            break;
                        case DicomTags.NumberOfPatientRelatedSeries:
                            dataSet[DicomTags.NumberOfPatientRelatedSeries].AppendInt32(row.NumberOfPatientRelatedSeries);
                            break;
                        case DicomTags.NumberOfPatientRelatedInstances:
                            dataSet[DicomTags.NumberOfPatientRelatedInstances].AppendInt32(
                                row.NumberOfPatientRelatedInstances);
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("PATIENT");
                            break;
						case DicomTags.PatientsSex:
							if (study == null)
								dataSet[DicomTags.PatientsSex].SetNullValue();
							else
								dataSet[DicomTags.PatientsSex].SetStringValue(study.PatientsSex);
                    		break;
						case DicomTags.PatientsBirthDate:
							if (study == null)
								dataSet[DicomTags.PatientsBirthDate].SetNullValue();
							else
								dataSet[DicomTags.PatientsBirthDate].SetStringValue(study.PatientsBirthDate);
							break;
                    
						// Meta tags that should have not been in the RQ, but we've already set
						case DicomTags.RetrieveAeTitle:
						case DicomTags.InstanceAvailability:
						case DicomTags.SpecificCharacterSet:
                    		break;

                        default:
                            if (!tag.IsPrivate)
                                dataSet[tag].SetNullValue();

                            foreach (var q in _queryExtensions)
                                q.PopulatePatient(response, tag, row, study);

                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Create a Patient Directory Record
        /// </summary>
        /// <param name="dicomFile">The dicom file or message.</param>
        private static DirectoryRecordSequenceItem CreatePatientItem(DicomMessageBase dicomFile)
        {
            if (dicomFile == null)
                throw new ArgumentNullException("dicomFile");

            IDictionary<uint, object> dicomTags = new Dictionary<uint, object>();
            dicomTags.Add(DicomTags.PatientsName, null);
            dicomTags.Add(DicomTags.PatientId, null);
            dicomTags.Add(DicomTags.PatientsBirthDate, null);
            dicomTags.Add(DicomTags.PatientsSex, null);

            return AddSequenceItem(DirectoryRecordType.Patient, dicomFile.DataSet, dicomTags);
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Populate the data from a <see cref="Study"/> entity into a DICOM C-FIND-RSP message.
        /// </summary>
		/// <param name="read">The connection to use to read the values.</param>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
	    /// <param name="row">The <see cref="Study"/> table to populate the response from.</param>
	    /// <param name="availability">Instance availability string.</param>
        private void PopulateStudy(IPersistenceContext read, DicomMessageBase response, IEnumerable<DicomTag> tagList, Study row, string availability)
        {
            DicomAttributeCollection dataSet = response.DataSet;

            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);

			dataSet[DicomTags.InstanceAvailability].SetStringValue(availability);

            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }
            else if (false == String.IsNullOrEmpty(row.SpecificCharacterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(row.SpecificCharacterSet);
                dataSet.SpecificCharacterSet = row.SpecificCharacterSet; // this will ensure the data is encoded using the specified character set
            }
            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(row.StudyInstanceUid);
                            break;
                        case DicomTags.PatientsName:
                            dataSet[DicomTags.PatientsName].SetStringValue(row.PatientsName);
                            break;
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(row.PatientId);
                            break;
                        case DicomTags.PatientsBirthDate:
                            dataSet[DicomTags.PatientsBirthDate].SetStringValue(row.PatientsBirthDate);
                            break;
						case DicomTags.PatientsAge:
							dataSet[DicomTags.PatientsAge].SetStringValue(row.PatientsAge);
							break;
						case DicomTags.PatientsSex:
                            dataSet[DicomTags.PatientsSex].SetStringValue(row.PatientsSex);
                            break;
                        case DicomTags.StudyDate:
                            dataSet[DicomTags.StudyDate].SetStringValue(row.StudyDate);
                            break;
                        case DicomTags.StudyTime:
                            dataSet[DicomTags.StudyTime].SetStringValue(row.StudyTime);
                            break;
                        case DicomTags.AccessionNumber:
                            dataSet[DicomTags.AccessionNumber].SetStringValue(row.AccessionNumber);
                            break;
                        case DicomTags.StudyId:
                            dataSet[DicomTags.StudyId].SetStringValue(row.StudyId);
                            break;
                        case DicomTags.StudyDescription:
                            dataSet[DicomTags.StudyDescription].SetStringValue(row.StudyDescription);
                            break;
                        case DicomTags.ReferringPhysiciansName:
                            dataSet[DicomTags.ReferringPhysiciansName].SetStringValue(row.ReferringPhysiciansName);
                            break;
                        case DicomTags.NumberOfStudyRelatedSeries:
                            dataSet[DicomTags.NumberOfStudyRelatedSeries].AppendInt32(row.NumberOfStudyRelatedSeries);
                            break;
                        case DicomTags.NumberOfStudyRelatedInstances:
                            dataSet[DicomTags.NumberOfStudyRelatedInstances].AppendInt32(
                                row.NumberOfStudyRelatedInstances);
                            break;
                        case DicomTags.ModalitiesInStudy:
                            LoadModalitiesInStudy(read, response, row.Key);
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("STUDY");
                            break;
						// Meta tags that should have not been in the RQ, but we've already set
						case DicomTags.RetrieveAeTitle:
						case DicomTags.InstanceAvailability:
						case DicomTags.SpecificCharacterSet:
							break;
                        default:
                            if (!tag.IsPrivate)
                                dataSet[tag].SetNullValue();

                            foreach (var q in _queryExtensions)
                                q.PopulateStudy(response, tag, row);
                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Create a Series Directory Record
        /// </summary>
        /// <param name="dicomFile">The dicom file.</param>
        private static DirectoryRecordSequenceItem CreateSeriesItem(DicomMessageBase dicomFile)
        {
            IDictionary<uint, object> dicomTags = new Dictionary<uint, object>();
            dicomTags.Add(DicomTags.SeriesInstanceUid, null);
            dicomTags.Add(DicomTags.Modality, null);
            dicomTags.Add(DicomTags.SeriesDate, null);
            dicomTags.Add(DicomTags.SeriesTime, null);
            dicomTags.Add(DicomTags.SeriesNumber, null);
            dicomTags.Add(DicomTags.SeriesDescription, null);
            //dicomTags.Add(DicomTags.SeriesDescription, dicomFile.DataSet[DicomTags.SeriesDescription].GetString(0, String.Empty));

            return AddSequenceItem(DirectoryRecordType.Series, dicomFile.DataSet, dicomTags);
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Populate the data from a <see cref="Series"/> entity into a DICOM C-FIND-RSP message.
        /// </summary>
		/// <param name="read">The connection to use to read the values.</param>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <param name="tagList"></param>
        /// <param name="row">The <see cref="Series"/> table to populate the row from.</param>
        private void PopulateSeries(IPersistenceContext read, DicomMessageBase request, DicomMessageBase response, IEnumerable<DicomTag> tagList,
                                    Series row)
        {
            DicomAttributeCollection dataSet = response.DataSet;

        	Study theStudy = Study.Load(read, row.StudyKey);
        	StudyStorage storage = StudyStorage.Load(read, theStudy.ServerPartitionKey, theStudy.StudyInstanceUid);
            dataSet[DicomTags.RetrieveAeTitle].SetStringValue(Partition.AeTitle);
            dataSet[DicomTags.InstanceAvailability].SetStringValue(storage.StudyStatusEnum == StudyStatusEnum.Nearline
                                                                       ? "NEARLINE"
                                                                       : "ONLINE");

            var characterSet = GetPreferredCharacterSet();
            if (!string.IsNullOrEmpty(characterSet))
            {
                dataSet[DicomTags.SpecificCharacterSet].SetStringValue(characterSet);
                dataSet.SpecificCharacterSet = characterSet;
            }
            else if (false == String.IsNullOrEmpty(theStudy.SpecificCharacterSet))
			{
				dataSet[DicomTags.SpecificCharacterSet].SetStringValue(theStudy.SpecificCharacterSet);
				dataSet.SpecificCharacterSet = theStudy.SpecificCharacterSet; // this will ensure the data is encoded using the specified character set
			}

            foreach (DicomTag tag in tagList)
            {
                try
                {
                    switch (tag.TagValue)
                    {
                        case DicomTags.PatientId:
                            dataSet[DicomTags.PatientId].SetStringValue(request.DataSet[DicomTags.PatientId].ToString());
                            break;
                        case DicomTags.StudyInstanceUid:
                            dataSet[DicomTags.StudyInstanceUid].SetStringValue(
                                request.DataSet[DicomTags.StudyInstanceUid].ToString());
                            break;
                        case DicomTags.SeriesInstanceUid:
                            dataSet[DicomTags.SeriesInstanceUid].SetStringValue(row.SeriesInstanceUid);
                            break;
                        case DicomTags.Modality:
                            dataSet[DicomTags.Modality].SetStringValue(row.Modality);
                            break;
                        case DicomTags.SeriesNumber:
                            dataSet[DicomTags.SeriesNumber].SetStringValue(row.SeriesNumber);
                            break;
                        case DicomTags.SeriesDescription:
                            dataSet[DicomTags.SeriesDescription].SetStringValue(row.SeriesDescription);
                            break;
                        case DicomTags.PerformedProcedureStepStartDate:
                            dataSet[DicomTags.PerformedProcedureStepStartDate].SetStringValue(
                                row.PerformedProcedureStepStartDate);
                            break;
                        case DicomTags.PerformedProcedureStepStartTime:
                            dataSet[DicomTags.PerformedProcedureStepStartTime].SetStringValue(
                                row.PerformedProcedureStepStartTime);
                            break;
                        case DicomTags.NumberOfSeriesRelatedInstances:
                            dataSet[DicomTags.NumberOfSeriesRelatedInstances].AppendInt32(row.NumberOfSeriesRelatedInstances);
                            break;
                        case DicomTags.RequestAttributesSequence:
                            LoadRequestAttributes(read, response, row);
                            break;
                        case DicomTags.QueryRetrieveLevel:
                            dataSet[DicomTags.QueryRetrieveLevel].SetStringValue("SERIES");
                            break;
						// Meta tags that should have not been in the RQ, but we've already set
						case DicomTags.RetrieveAeTitle:
						case DicomTags.InstanceAvailability:
						case DicomTags.SpecificCharacterSet:
							break;
                        default:
                            if (!tag.IsPrivate)
                                dataSet[tag].SetNullValue();

                            foreach (var q in _queryExtensions)
                                q.PopulateSeries(response, tag, row);

                            break;
                    }
                }
                catch (Exception e)
                {
                    Platform.Log(LogLevel.Warn, e, "Unexpected error setting tag {0} in C-FIND-RSP",
                                 dataSet[tag].Tag.ToString());
                    if (!tag.IsPrivate)
                        dataSet[tag].SetNullValue();
                }
            }
        }