private void LoadAdditionalEntities() { Debug.Assert(ServerPartition != null); Debug.Assert(StorageLocation != null); using (ServerExecutionContext context = new ServerExecutionContext()) { if (_filesystem != null) _filesystem = FilesystemMonitor.Instance.GetFilesystemInfo(StorageLocation.FilesystemKey); _study = StorageLocation.LoadStudy(context.ReadContext); _patient = Patient.Load(context.ReadContext, _study.PatientKey); } }
/// <summary> /// Constructor. /// </summary> /// <param name="thePartition"></param> /// <param name="location"></param> /// <param name="thePatient"></param> /// <param name="theStudy"></param> public StudyEditor(ServerPartition thePartition, StudyStorageLocation location, Patient thePatient, Study theStudy, WorkQueue workQueue) { FailureReason = string.Empty; Platform.CheckForNullReference(thePartition, "thePartition"); Platform.CheckForNullReference(location, "location"); Platform.CheckForNullReference(thePatient, "thePatient"); Platform.CheckForNullReference(theStudy, "theStudy"); ServerPartition = thePartition; StorageLocation = location; Patient = thePatient; Study = theStudy; _workQueue = workQueue; // Scrub for invalid characters that may cause a failure when the Xml is generated for the history Patient.PatientId = XmlUtils.XmlCharacterScrub(Patient.PatientId); Patient.PatientsName = XmlUtils.XmlCharacterScrub(Patient.PatientsName); Study.StudyDescription = XmlUtils.XmlCharacterScrub(Study.StudyDescription); Study.ReferringPhysiciansName = XmlUtils.XmlCharacterScrub(Study.ReferringPhysiciansName); Study.PatientId = XmlUtils.XmlCharacterScrub(Study.PatientId); Study.PatientsName = XmlUtils.XmlCharacterScrub(Study.PatientsName); }
public Patient LoadPatient(IPersistenceContext context) { if (_patient==null) { lock (SyncRoot) { if (_patient == null) { _patient = Patient.Load(context, PatientKey); } } } return _patient; }
/// <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(); } } }
private void TransferStudy(ServerEntityKey studyKey, PatientInfo oldPatient, Patient newPatient) { Platform.Log(LogLevel.Info, "Transferring study from {0} [ID={1}] to {2} [ID={3}]", oldPatient.Name, oldPatient.PatientId, newPatient.PatientsName, newPatient.PatientId); IAttachStudyToPatient attachStudyToPatientBroker = UpdateContext.GetBroker<IAttachStudyToPatient>(); AttachStudyToPatientParamaters parms = new AttachStudyToPatientParamaters { StudyKey = studyKey, NewPatientKey = newPatient.GetKey() }; attachStudyToPatientBroker.Execute(parms); }
private void UpdateDatabase() { // Reload the StudyStorage and Study tables. LoadEntities(); UpdateEntity(_study); UpdateEntity(_curPatient); UpdateEntity(_storage); SetStudyEncoding(_study); // Update the Study table IStudyEntityBroker studyUpdateBroker = UpdateContext.GetBroker<IStudyEntityBroker>(); studyUpdateBroker.Update(_study); // Update the StudyStorage table IStudyStorageEntityBroker storageUpdateBroker = UpdateContext.GetBroker<IStudyStorageEntityBroker>(); storageUpdateBroker.Update(_storage); // Update Patient level info. Different cases can occur here: // A) Patient demographic info is not changed ==> update the current patient // B) New patient demographics matches (another) existing patient in the datbase // ==> Transfer the study to that patient. This means the study count on both patients must be updated. // The current patient should also be deleted if there's no more study attached to it after the transfer. // C) New patient demographics doesn't match any patient in the database // ==> A new patient should be created for this study. The study count on the current patient should be updated // and the patient should also be deleted if this is the only study attached to it. if (_patientInfoIsNotChanged) { UpdateCurrentPatient(); UpdatePatientEncoding(_curPatient); } else if (_newPatient == null) { // No matching patient in the database. We should create a new patient for this study _newPatient = CreateNewPatient(_newPatientInfo); UpdatePatientEncoding(_newPatient); } else { // There's already patient in the database with the new patient demographics // The study should be attached to that patient. TransferStudy(_study.Key, _oldPatientInfo, _newPatient); UpdatePatientEncoding(_newPatient); } }
private void UpdatePatientEncoding(Patient patient) { // Note: patient can be an existing one or a new one // set the SpecificCharacterSet of the patient and study record. This will update the database // and force Patient/Study/Series level query response to be encoded in UTF8. Image level responses // will be encoded using the character set in the image (see QueryScpExtension) // if (atLeastOneFileUpdatedToUTF8) { // Only update the db if necessary if (!IsUTF8(patient.SpecificCharacterSet)) { Platform.Log(LogLevel.Info, "Updating encoding for patient information in the database to UTF8 [ Name={0}, ID={1} ]", patient.Name, patient.PatientId); // update to UTF8 patient.SpecificCharacterSet = UTF8; // This method is called at the very end of UpdateDatabase(), update the database now IPatientEntityBroker broker = UpdateContext.GetBroker<IPatientEntityBroker>(); PatientUpdateColumns columns = new PatientUpdateColumns() { SpecificCharacterSet = UTF8 }; broker.Update(patient.Key, columns); } } }
private void Initialize() { _backupDir = ProcessorContext.BackupDirectory; _oldStudyPath = _oldStudyLocation.GetStudyPath(); _oldStudyInstanceUid = _oldStudyLocation.StudyInstanceUid; _oldStudyFolder = _oldStudyLocation.StudyFolder; _newStudyInstanceUid = _oldStudyInstanceUid; _study = _oldStudyLocation.LoadStudy(ServerExecutionContext.Current.ReadContext); _totalSopCount = _study.NumberOfStudyRelatedInstances; _curPatient = _study.LoadPatient(ServerExecutionContext.Current.ReadContext); _oldPatientInfo = new PatientInfo { Name = _curPatient.PatientsName, PatientId = _curPatient.PatientId, IssuerOfPatientId = _curPatient.IssuerOfPatientId }; _newPatientInfo = new PatientInfo(_oldPatientInfo); Debug.Assert(_newPatientInfo.Equals(_oldPatientInfo)); foreach (BaseImageLevelUpdateCommand command in _commands) { ImageLevelUpdateEntry imageLevelUpdate = command.UpdateEntry; if (imageLevelUpdate == null) continue; if (imageLevelUpdate.TagPath.Tag.TagValue == DicomTags.StudyInstanceUid) { _newStudyInstanceUid = imageLevelUpdate.GetStringValue(); } else if (imageLevelUpdate.TagPath.Tag.TagValue == DicomTags.PatientId) { _newPatientInfo.PatientId = imageLevelUpdate.GetStringValue(); } else if (imageLevelUpdate.TagPath.Tag.TagValue == DicomTags.IssuerOfPatientId) { _newPatientInfo.IssuerOfPatientId = imageLevelUpdate.GetStringValue(); } else if (imageLevelUpdate.TagPath.Tag.TagValue == DicomTags.PatientsName) { _newPatientInfo.Name = imageLevelUpdate.GetStringValue(); } } Platform.CheckForNullReference(_newStudyInstanceUid, "_newStudyInstanceUid"); NewStudyPath = Path.Combine(_oldStudyLocation.FilesystemPath, _partition.PartitionFolder); NewStudyPath = Path.Combine(NewStudyPath, _oldStudyFolder); NewStudyPath = Path.Combine(NewStudyPath, _newStudyInstanceUid); _newPatient = FindPatient(_newPatientInfo, ServerExecutionContext.Current.ReadContext); _patientInfoIsNotChanged = _newPatientInfo.Equals(_oldPatientInfo); Statistics.InstanceCount = _study.NumberOfStudyRelatedInstances; Statistics.StudySize = (ulong) _oldStudyLocation.LoadStudyXml().GetStudySize(); // The study path will be changed. We will need to delete the original folder at the end. // May be too simple to test if two paths are the same. But let's assume it is good enough for 99% of the time. _deleteOriginalFolder = NewStudyPath != _oldStudyPath; _initialized = true; }
private void Initialize() { _study = Study.Find(ServerExecutionContext.Current.ReadContext,_studyLocation.StudyInstanceUid, _partition); _curPatient = _study.LoadPatient(ServerExecutionContext.Current.ReadContext); _oldPatientInfo = new PatientInfo { PatientsName = _curPatient.PatientsName, PatientId = _curPatient.PatientId, IssuerOfPatientId = _curPatient.IssuerOfPatientId }; _seriesInstanceUid = _file.DataSet[DicomTags.SeriesInstanceUid].ToString(); var broker = ServerExecutionContext.Current.ReadContext.GetBroker<ISeriesEntityBroker>(); var select = new SeriesSelectCriteria(); select.SeriesInstanceUid.EqualTo(_seriesInstanceUid); select.ServerPartitionKey.EqualTo(_partition.Key); _curSeries = broker.FindOne(select); _newPatientInfo = new PatientInfo(_oldPatientInfo); _file.DataSet.LoadDicomFields(_newPatientInfo); _newPatient = FindPatient(_newPatientInfo, ServerExecutionContext.Current.ReadContext); _patientInfoIsNotChanged = _newPatientInfo.Equals(_oldPatientInfo); }
private void UpdateDatabase() { var patientUpdate = new PatientUpdateColumns(); var seriesUpdate = new SeriesUpdateColumns(); var studyUpdate = new StudyUpdateColumns(); // Update Patient level info. Different cases can occur here: // A) Patient demographic info is not changed ==> update the current patient // B) New patient demographics matches (another) existing patient in the datbase // ==> Transfer the study to that patient. This means the study count on both patients must be updated. // The current patient should also be deleted if there's no more study attached to it after the transfer. // C) New patient demographics doesn't match any patient in the database // ==> A new patient should be created for this study. The study count on the current patient should be updated // and the patient should also be deleted if this is the only study attached to it. if (_patientInfoIsNotChanged) { _newPatient = _curPatient; } else if (_newPatient == null) { // No matching patient in the database. We should create a new patient for this study _newPatient = CreateNewPatient(_newPatientInfo); } else { // There's already patient in the database with the new patient demographics // The study should be attached to that patient. TransferStudy(_study.Key, _oldPatientInfo, _newPatient); } // Copy the existing valus over into the study & series objects // Note, this sets up an update statement that will update the key columns for // Study Instance UID, Series Instance UID, however, note that the columns will not // actually change value. Its alittle ugly, but it will make it so if we add new // columns in the future, it just "works". _file.DataSet.LoadDicomFields(patientUpdate); _file.DataSet.LoadDicomFields(studyUpdate); _file.DataSet.LoadDicomFields(seriesUpdate); // Get any extensions that exist and process them var ep = new ProcessorInsertExtensionPoint(); var extensions = ep.CreateExtensions(); foreach (IInsertExtension e in extensions) e.UpdateExtension(_partition.Key, patientUpdate,studyUpdate,seriesUpdate, _file); UpdatePatientEncoding(_newPatient, patientUpdate); SetStudyEncoding(_study, studyUpdate); // Update the Study table var patientUpdateBroker = UpdateContext.GetBroker<IPatientEntityBroker>(); patientUpdateBroker.Update(_newPatient.Key, patientUpdate); // Update the Study table var studyUpdateBroker = UpdateContext.GetBroker<IStudyEntityBroker>(); studyUpdateBroker.Update(_study.Key, studyUpdate); // Update the Series table var seriesUpdateBroker = UpdateContext.GetBroker<ISeriesEntityBroker>(); seriesUpdateBroker.Update(_curSeries.Key, seriesUpdate); // If the Request Attributes Sequence is in the dataset, do an insert. // Small hole in this that if the value of this sequence has changed, both the old and // the new values will stay in the database, not much to do about it, except // reprocess the whole series, which doesn't seem worth it. if (_file.DataSet.Contains(DicomTags.RequestAttributesSequence)) { var attribute = _file.DataSet[DicomTags.RequestAttributesSequence] as DicomAttributeSQ; if (attribute != null && !attribute.IsEmpty) { foreach (DicomSequenceItem sequenceItem in (DicomSequenceItem[])attribute.Values) { var requestParms = new RequestAttributesInsertParameters(); sequenceItem.LoadDicomFields(requestParms); requestParms.SeriesKey = _curSeries.Key; var insertRequest = UpdateContext.GetBroker<IInsertRequestAttributes>(); insertRequest.Execute(requestParms); } } } }
private void UpdatePatientEncoding(Patient patient, PatientUpdateColumns update) { // set the SpecificCharacterSet of the patient and study record. This will update the database // and force Patient/Study/Series level query response to be encoded in UTF8. Image level responses // will be encoded using the character set in the image (see QueryScpExtension) // // Only update the db if necessary if (IsUTF8(patient.SpecificCharacterSet)) { update.SpecificCharacterSet = UTF8; } }
static public Patient Insert(IUpdateContext update, Patient entity) { var broker = update.GetBroker<IPatientEntityBroker>(); var updateColumns = new PatientUpdateColumns(); updateColumns.ServerPartitionKey = entity.ServerPartitionKey; updateColumns.NumberOfPatientRelatedStudies = entity.NumberOfPatientRelatedStudies; updateColumns.NumberOfPatientRelatedSeries = entity.NumberOfPatientRelatedSeries; updateColumns.NumberOfPatientRelatedInstances = entity.NumberOfPatientRelatedInstances; updateColumns.SpecificCharacterSet = entity.SpecificCharacterSet; updateColumns.PatientsName = entity.PatientsName; updateColumns.PatientId = entity.PatientId; updateColumns.IssuerOfPatientId = entity.IssuerOfPatientId; Patient newEntity = broker.Insert(updateColumns); return newEntity; }
static public Patient Insert(Patient entity) { using (var update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { Patient newEntity = Insert(update, entity); update.Commit(); return newEntity; } }