Sunday, August 1, 2021

MODALIZER+ V6

Well, I guess it's time to celebrate. MODALIZER+ V6 is being released today. Seriously, it's been a long journey. We started working on this version more than two years ago. This been a team work of many people. Evgenia that was in charge of the DICOMIZER-MODALIZER product line since its beginning, Bezalel that designed the new UI, Bar that finished the work and added the latest features, and also David and Rotem that helped allong the way. Additionally, this release completes the work on all HRZ V6 products: MODAIZER-SDK DICOM Library, ZiKiT PACS Server and now MODALIZER+.

So, what's new in MODALIZER+ V6? The first thing you will notice is of course the new graphic design.

MODALIZER+ V6 Home Screen

The new MODALIZER+ is colorful. You will also notice the colors are following into the different workflows, allowing the user to distinguish between them, as we realized that some of the screens look very similar to one another. Also, there's usability, you will notice larger fonts and wider spaces.

Monday, January 18, 2021

Move all studies of patients with ID in CSV file from PACS-A to PACS-B

OK, so here's another PowerShell DICOM script that came handy recently. So my friend, lets call him Benny, got a request from his manager to export all the studies of patients in a list provided as excel sheet and deliver them to a research group (after de-identification and everything of course) but when he called me he just needed to get them out quickly from the PACS. The list was long and there was no chance to do this one by one. So we wrote together this little PowerShell script that reads the patient id's from the excel (after saving it as csv) and use MODALIZER-SDK to do the DICOM work. here it is. I think it explains itself pretty well. We've set the destination PACS-B to be our lightweight PACS server with no plugin so the DICOM files were saved on the disk and from there he picked them up.

$my_ae_title="MY-AE-TITLE"


$pacs_a_ae_title="PACS-A"

$pacs_a_ip_address="10.0.0.10"

$pacs_a_dicom_port=104


$pacs_b_ae_title="PACS-B"


function MoveStudyByPatientID

param($pat)

$r = New-Object -ComObject rzdcx.DCXREQ

    

    # Lets echo to be sure

$r.Echo($my_ae_title, $pacs_a_ae_title, $pacs_a_ip_address, $pacs_a_dicom_port)

$o = New-Object -ComObject rzdcx.DCXOBJ

$e = New-Object -ComObject rzdcx.DCXELM

# Query Level - STUDY

$e.Init(0x00080052)

$e.Value = "STUDY"

$o.insertElement($e)

# Patient ID

$e.Init(0x00100020)

$e.Value = $pat

$o.insertElement($e)

# Study Instance UID

$e.Init(0x0020000d)

    $e.Value = ""

$o.insertElement($e)

$i = $r.Query($my_ae_title, $pacs_a_ae_title, $pacs_a_ip_address, $pacs_a_dicom_port, "1.2.840.10008.5.1.4.1.2.1.1", $o)

    if ($i.AtEnd()) {

        "No Studies for patient id: " + $pat

    }

    else

    {

        while ($i.AtEnd() -ne $true)

        {

            $res = $i.Get()

    "LOG: Study Instance UID: " + $res.GetElement(0x0020000d).Value

    $o.insertElement($res.GetElement(0x0020000d))

    $r.Move($my_ae_title, $pacs_a_ae_title, $pacs_a_ip_address, $pacs_a_dicom_port, 104, $pacs_b_ae_title, $o)

            $i.Next();

    } 

    }

}


# A log never hurts

$a = New-Object -ComObject rzdcx.DCXAPP

$a.StartLogging("log.log")

$a.LogLevel = 5


$patients = Import-Csv -Path .\patients.csv

foreach ($pat in $patients.patient_id) 

{

    "LOG: Patient ID: " + $pat

MoveStudyByPatientID $pat

}


$a.StopLogging()


# That's it for now 




Thursday, August 27, 2020

Sending DICOM files indexed in a DICOMDIR on a DICOM CD to PACS using PowerShell and MODALIZER-SDK

 I'm posting this PowerShell script in response to a question I got about sending DICOM files on a CD to PACS. 

This functionality is available in MODALIZER+ from the View menu simply by right clicking the Study item at the top study panel and selecting "Send to". The PACS AE title has to be configured first in the settings.

But, for the automation enthusiasts, here's a PowerShell script that do the same. Recalling on DICOMDIR, a DICOM CD or DVD has a file called DICOMDIR in the root path that references all DICOM files on the media. This script iterates through the DICOMDIR records to collect all referenced files, then it send them using DCXREQ.Send command to the PACS.

Here it is. Enjoy!

 # Send DICOMDIR Patients to PACS


param($rootFolder);

Wednesday, May 8, 2019

More PowerShell DICOM

# PowerShell DICOM

# This little script becomes handy for example for a daily test of your PACS
# It generates a 1000x1000 image with date and key attributes (Study, Series and Instance UID) burned in
# This script uses HRZ's RZDCX.DLL.

# Create DICOM Object
$DCM = New-Object -com rzdcx.DCXOBJ

# UID Generator
$UID = New-Object -com rzdcx.DCXUID

# Create new Key UID's
$studyInstanceUID = $UID.CreateUID(1)
$seriesInstanceUID = $UID.CreateUID(2)
$sopInstanceUID = $UID.CreateUID(3)

# Add minimal elements to the dataset
$tagValues = @(
0x00080016, "1.2.840.10008.5.1.4.1.1.7", 
0x00080018, $sopInstanceUID,
0x00080020, ($studyDate = Get-Date -UFormat "%Y%m%d"),
0x00080030, "",
0x00080050, "ACCNUMHRZTEST",
0x00080060, "SC",
0x00080064, "WSD",
0x00080090, "HRZ",
0x00100010, "HRZ^TEST",
0x00100020, "HRZTEST",
0x00100030, "20100101",
0x00100040, "O",
0x0020000d, $studyInstanceUID,
0x0020000e, $seriesInstanceUID,
0x00200010, "123",
0x00200011, "1",
0x00200013, "1")

$E = New-Object -com rzdcx.DCXELM
for (($i=0); ($i -lt $tagValues.Count); ($i+=2))
{
    $E.Init($tagValues[$i])
    $E.Value = $tagValues[$i+1]
    $DCM.insertElement($E)
}

# Create 1000x1000 Image with text printed on it
$rows = 1000
$cols = 1000

# jpeg image
Add-Type -AssemblyName System.Drawing
$imageFormat = "System.Drawing.Imaging.ImageFormat" -as [type]
$format = $imageFormat::jpeg


$uidType = "rzdcx.UID_TYPE" -as [type]

$createDate = Get-Date
$bmp = new-object System.Drawing.Bitmap $cols,$rows
$font = new-object System.Drawing.Font Consolas,24 
$brushBg = [System.Drawing.Brushes]::Yellow 
$brushFg = [System.Drawing.Brushes]::Black 
$graphics = [System.Drawing.Graphics]::FromImage($bmp
$graphics.FillRectangle($brushBg,0,0,$bmp.Width,$bmp.Height) 
$graphics.DrawString($createDate, $font,$brushFg,10,10
$font = new-object System.Drawing.Font Consolas,8 
$graphics.DrawString("StudyInstance UID: " + $studyInstanceUID, $font,$brushFg, 10,110)  
$graphics.DrawString("Series Instance UID: " + $studyInstanceUID, $font,$brushFg,10,210)  
$graphics.DrawString("SOP Instance UID: " + $studyInstanceUID, $font,$brushFg,10,310)  
$graphics.DrawString("TARGET AET: " + "PACS-A", $font, $brushFg, 10, 410)  

$graphics.Dispose() 

# Save the JPEG image
$filename = "$home\HRZTEST.jpg"
$bmp.Save($filename, $format

# Insert it to the DICOM object
$DCM.SetJpegFrames($filename);

# Save the DICOM file
$dcmfile = $filename + ".dcm"
$DCM.saveFile($dcmfile)

# Send it to the PACS
$REQ = New-Object -com rzdcx.DCXREQ

$succeeded = ""
$failed = ""

# Start logging for network comunication and save to log file

$APP = New-Object -com rzdcx.DCXAPP
$APP.LogLevel = 5 # Debug

$logFile = "$home\SendTestImage.log"

$APP.StartLogging($logFile)

$REQ.Echo("HRZ-TEST", "PACS-A", "localhost", 104)
$REQ.Send("HRZ-TEST", "PACS-A", "localhost", 104, $dcmfile, [ref] $succeeded, [ref] $failed)

# Print results
$filename
$dcmfile
"Succeeded: " + $succeeded
"Failed: " + $failed

# Stop logging
$App.StopLogging()

"Done!"






Tuesday, January 15, 2019

PowerShell DICOM Scripting

Disclosure: This post is purely technical!
Assumption: you know your way around PowerShell or how to get there and a bit of DICOM and our RZDCX API.

If your system is x64 (probably) than make sure to regsvr32 radix.dll the x64 version.

Let's PowerShell!!!

# download rzdcx
Invoke-WebRequest -Uri http://downloads.roniza.com/rzdcx/2.0.8.7/RZDCX_2087.zip -OutFile ./rzdcx.zip

# unzip it
Expand-Archive ./rzdcx.zip -DestinationPath ./rzdcx

# regsvr32 win32 version
$rzdcx32 = Resolve-Path .\rzdcx\win32\rzdcx.dll
Start-Process regsvr32 -verb runAs -argumentlist $rzdcx32

$rzdcx64 = Resolve-Path .\rzdcx\x64\rzdcx.dll
Start-Process regsvr32 -verb runAs -argumentlist $rzdcx64

# Create DICOM Object
$DCM = New-Object -com rzdcx.DCXOBJ

# I assume you have a directory called DICOM with DICOM files in it
$files = @(Get-ChildItem ".\DICOM\*")

# Write headers
"filename, Patient Name, Patient ID"

# For each file extract and print patient name and patient id
foreach ($file in $files) {
  $DCM.openFile($file)
  $patname = $DCM.GetElement([int32]::Parse(00100010,'HexNumber')).Value
  $patid   = $DCM.GetElement([int32]::Parse(00100020,'HexNumber')).Value
  Write-Host $file "," $patname "," $patid
}

Try it!


Thursday, November 1, 2018

HL7Kit 2018 - Integrated DICOM and HL7 Solution

Yo! It's been a while ... no posts since June 2016 :-§

Maybe its because when you do there's less time to talk, ah? Anyway, I finally got some time for it and that's because HRZ have finally officially released HL7Kit 2018. Yeah! Check this beautiful little web site we've published for the occasion. Let me tell you about this product that my team and I worked so hard to push through the door.

For those of you that worked with the kit before, the first thing you will notice is the new UX. We've invested in usability and graphic design to make the kit nicer and simpler to use.

HL7Kit desktop applications shortcuts and the control panel


Another improvement is that now the installation and evaluation is much simpler because after installation (which is just a series of next-next-nexts) everything works with an internal SQLite database and by everything I mean everything! DICOM Storage, Q/R, Modality Worklist MPPS, and HL7 Orders ORM^O01 and Schedules SIU^S12 that are automatically mapped to Modality Worklist entries. Apart for the fact that it makes evaluation a snap, it also makes it really attractive for