diff --git a/app/Services/Pacs/Sync/StudiesSync.php b/app/Services/Pacs/Sync/StudiesSync.php index 022fdf1..60198d9 100644 --- a/app/Services/Pacs/Sync/StudiesSync.php +++ b/app/Services/Pacs/Sync/StudiesSync.php @@ -8,7 +8,7 @@ use App\Services\Pacs\DicomUtils; use App\Services\Pacs\OrthancRestClient; use App\Services\StudyRouter\DicomStudyRouter; -use App\Services\StudyRouter\RawDicomTag; +use App\Services\StudyRouter\RawDicomTags; use Carbon\Carbon; use Exception; use Illuminate\Pipeline\Pipeline; @@ -27,7 +27,7 @@ class StudiesSync private OrthancRestClient $client; - public function __construct(private readonly DicomServer $dicomServer, ?OrthancRestClient $client = null) + public function __construct(private readonly DicomServer $dicomServer, ?OrthancRestClient $client = null, private readonly int $maxInstances = 5) { $this->study_ids = collect(); $this->client = $client ?? new OrthancRestClient($dicomServer); @@ -106,28 +106,39 @@ public function fetchStudyDetails(string $orthanc_uuid): ?array return $study; } + public function fetchInstancesList(string $orthanc_uuid): ?array + { + return $this->client->getStudyInstancesList($orthanc_uuid); + } + + public function fetchInstancesTags(string $orthanc_uuid): ?array + { + return $this->client->getInstanceDetails($orthanc_uuid, true); + } + public function matchRouting(mixed $orthanc_src) { + /* $dicomData = [ - RawDicomTag::PatientName->value => data_get($orthanc_src, 'PatientMainDicomTags.PatientName'), - RawDicomTag::PatientID->value => data_get($orthanc_src, 'PatientMainDicomTags.PatientID'), - RawDicomTag::Modality->value => data_get($orthanc_src, 'RequestedTags.Modality'), - RawDicomTag::StudyDescription->value => $this->getStudyDescription($orthanc_src), - RawDicomTag::BodyPartExamined->value => data_get($orthanc_src, 'RequestedTags.BodyPartExamined'), - RawDicomTag::ReferringPhysicianName->value => data_get($orthanc_src, 'MainDicomTags.ReferringPhysicianName'), - RawDicomTag::AccessionNumber->value => data_get($orthanc_src, 'MainDicomTags.AccessionNumber'), - RawDicomTag::InstitutionName->value => data_get($orthanc_src, 'MainDicomTags.InstitutionName'), - RawDicomTag::InstitutionAddress->value => data_get($orthanc_src, 'RequestedTags.InstitutionAddress'), - RawDicomTag::OperatorsName->value => data_get($orthanc_src, 'RequestedTags.OperatorsName'), - RawDicomTag::StationName->value => data_get($orthanc_src, 'RequestedTags.StationName'), - RawDicomTag::Manufacturer->value => data_get($orthanc_src, 'RequestedTags.Manufacturer'), - RawDicomTag::ManufacturerModelName->value => data_get($orthanc_src, 'RequestedTags.ManufacturerModelName'), - RawDicomTag::SoftwareVersions->value => data_get($orthanc_src, 'RequestedTags.SoftwareVersions'), - RawDicomTag::ProtocolName->value => data_get($orthanc_src, 'xxx'), + RawDicomTags::PatientName->value => data_get($orthanc_src, 'PatientMainDicomTags.PatientName'), + RawDicomTags::PatientID->value => data_get($orthanc_src, 'PatientMainDicomTags.PatientID'), + RawDicomTags::Modality->value => data_get($orthanc_src, 'RequestedTags.Modality'), + RawDicomTags::StudyDescription->value => $this->getStudyDescription($orthanc_src), + RawDicomTags::BodyPartExamined->value => data_get($orthanc_src, 'RequestedTags.BodyPartExamined'), + RawDicomTags::ReferringPhysicianName->value => data_get($orthanc_src, 'MainDicomTags.ReferringPhysicianName'), + RawDicomTags::AccessionNumber->value => data_get($orthanc_src, 'MainDicomTags.AccessionNumber'), + RawDicomTags::InstitutionName->value => data_get($orthanc_src, 'MainDicomTags.InstitutionName'), + RawDicomTags::InstitutionAddress->value => data_get($orthanc_src, 'RequestedTags.InstitutionAddress'), + RawDicomTags::OperatorsName->value => data_get($orthanc_src, 'RequestedTags.OperatorsName'), + RawDicomTags::StationName->value => data_get($orthanc_src, 'RequestedTags.StationName'), + RawDicomTags::Manufacturer->value => data_get($orthanc_src, 'RequestedTags.Manufacturer'), + RawDicomTags::ManufacturerModelName->value => data_get($orthanc_src, 'RequestedTags.ManufacturerModelName'), + RawDicomTags::SoftwareVersions->value => data_get($orthanc_src, 'RequestedTags.SoftwareVersions'), + RawDicomTags::ProtocolName->value => data_get($orthanc_src, 'xxx'), ]; $dicomData = array_purge($dicomData); - - return DicomStudyRouter::matchStudy($dicomData); + */ + return DicomStudyRouter::matchStudy($orthanc_src); } public function getStudyDescription(mixed $orthanc_src): ?string @@ -148,14 +159,18 @@ public function getStudyDescription(mixed $orthanc_src): ?string public function transformData(mixed $orthanc_src): array { $inst_name = data_get($orthanc_src, 'MainDicomTags.InstitutionName'); - $routing = $this->matchRouting($orthanc_src); + $orthanc_uuid = strtolower($orthanc_src['ID']); + + $dicom_tags = $this->getStudyDicomTags($orthanc_uuid); + $routing = $this->matchRouting($dicom_tags); + // dd($routing); $patient_name = data_get($orthanc_src, 'PatientMainDicomTags.PatientName'); $descr = $this->getStudyDescription($orthanc_src); $study = [ 'dicom_server_id' => $this->dicomServer->id, - 'orthanc_uuid' => strtolower($orthanc_src['ID']), + 'orthanc_uuid' => $orthanc_uuid, 'institution_name' => $inst_name, 'organization_id' => $routing['organization_id'], 'department_id' => $routing['department_id'], @@ -280,6 +295,32 @@ public function transformData(mixed $orthanc_src): array return compact('study', 'details'); } + private function getStudyDicomTags(string $study_uuid): array + { + $instances = $this->fetchInstancesList($study_uuid); + if (empty($instances)) { + return []; + } + + // randomly sample few instances for tags collection + $selectedInstances = count($instances) <= $this->maxInstances ? $instances : array_rand(array_flip($instances), $this->maxInstances); + + $tags = []; + foreach ($selectedInstances as $instance) { + foreach ($this->fetchInstancesTags($instance) as $key => $value) { + if ($key == 'MainDicomTags' || $key == 'RequestedTags') { + foreach ($value as $tag => $val) { + if (! isset($tags[$tag]) || $tags[$tag] !== $val) { + $tags[$tag] = $val; + } + } + } + } + } + + return $tags; + } + private function setValue(array &$array, string $key, mixed $value): void { if (filled($value)) {