movescu(1)

πŸŽ€ movescu(1) πŸŽ€

okay bestie, welcome to movescu(1) from OFFIS DCMTK β€” yes, the manual page name is folded right up here so we can get into the group chat. This one is literally the DICOM retrieve (C-MOVE) SCU and it's lowkey iconic. πŸ’…

πŸ’– NAME πŸ’–

movescu β€” DICOM retrieve (C-MOVE) SCU

✨ SYNOPSIS ✨

movescu [options] peer port [dcmfile-in...]

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so here's the vibe: the movescu application implements both an SCU for the Query/Retrieve Service Class and an SCP for the Storage Service Class. movescu supports retrieve functionality using the C-MOVE message. It sends query keys to an SCP and awaits responses. It will accept associations for the purpose of receiving images sent as a result of the C-MOVE request. The application can be used to test SCPs of the Query/Retrieve Service Class. The movescu application can initiate the transfer of images to a third party or can retrieve images to itself.

Note that the use of the term "move" is a misnomer. The C-MOVE operation actually performs an image copy (no images will be deleted from the SCP). πŸ’€

🌸 PARAMETERS 🌸

  • peer β€” hostname of DICOM peer
  • port β€” tcp/ip port number of peer
  • dcmfile-in β€” DICOM query file(s)

πŸ‘‘ OPTIONS πŸ‘‘

πŸ’– general options πŸ’–

  • -h, --help β€” print this help text and exit
  • --version β€” print version information and exit
  • --arguments β€” print expanded command line arguments
  • -q, --quiet β€” quiet mode, print no warnings and errors
  • -v, --verbose β€” verbose mode, print processing details
  • -d, --debug β€” debug mode, print debug information
  • -ll, --log-level [l]evel: string constant β€” use level l for the logger. Valid levels are fatal, error, warn, info, debug, trace.
  • -lc, --log-config [f]ilename: string β€” use config file f for the logger

🌐 network options 🌐

IP protocol version:

  • -i4, --ipv4 β€” use IPv4 only (default)
  • -i6, --ipv6 β€” use IPv6 only
  • -i0, --ip-auto β€” use IPv6/IPv4 dual stack

override matching keys:

  • -k, --key [k]ey: gggg,eeee="str" or dictionary name="str" β€” override matching key

query information model:

  • -P, --patient β€” use patient root information model (default)
  • -S, --study β€” use study root information model
  • -O, --psonly β€” use patient/study only information model

application entity titles:

  • -aet, --aetitle [a]etitle: string β€” set my calling AE title (default: MOVESCU)
  • -aec, --call [a]etitle: string β€” set called AE title of peer (default: ANY-SCP)
  • -aem, --move [a]etitle: string β€” set move destination AE title (default: MOVESCU)

preferred network transfer syntaxes (incoming associations):

  • +x=, --prefer-uncompr β€” prefer explicit VR local byte order (default)
  • +xe, --prefer-little β€” prefer explicit VR little endian TS
  • +xb, --prefer-big β€” prefer explicit VR big endian TS
  • +xs, --prefer-lossless β€” prefer default JPEG lossless TS
  • +xy, --prefer-jpeg8 β€” prefer default JPEG lossy TS for 8 bit data
  • +xx, --prefer-jpeg12 β€” prefer default JPEG lossy TS for 12 bit data
  • +xv, --prefer-j2k-lossless β€” prefer JPEG 2000 lossless TS
  • +xw, --prefer-j2k-lossy β€” prefer JPEG 2000 lossy TS
  • +xt, --prefer-jls-lossless β€” prefer JPEG-LS lossless TS
  • +xu, --prefer-jls-lossy β€” prefer JPEG-LS lossy TS
  • +xm, --prefer-mpeg2 β€” prefer MPEG2 Main Profile @ Main Level TS
  • +xh, --prefer-mpeg2-high β€” prefer MPEG2 Main Profile @ High Level TS
  • +xn, --prefer-mpeg4 β€” prefer MPEG4 AVC/H.264 High Profile / Level 4.1 TS
  • +xl, --prefer-mpeg4-bd β€” prefer MPEG4 AVC/H.264 BD-compatible HP / Level 4.1 TS
  • +x2, --prefer-mpeg4-2-2d β€” prefer MPEG4 AVC/H.264 HP / Level 4.2 TS for 2D Videos
  • +x3, --prefer-mpeg4-2-3d β€” prefer MPEG4 AVC/H.264 HP / Level 4.2 TS for 3D Videos
  • +xo, --prefer-mpeg4-2-st β€” prefer MPEG4 AVC/H.264 Stereo HP / Level 4.2 TS
  • +x4, --prefer-hevc β€” prefer HEVC/H.265 Main Profile / Level 5.1 TS
  • +x5, --prefer-hevc10 β€” prefer HEVC/H.265 Main Profile / Level 5.1 TS
  • +xr, --prefer-rle β€” prefer RLE lossless TS
  • +xd, --prefer-deflated β€” prefer deflated explicit VR little endian TS
  • +xi, --implicit β€” accept implicit VR little endian TS only
  • +xa, --accept-all β€” accept all supported transfer syntaxes

proposed transmission transfer syntaxes (outgoing associations):

  • -x=, --propose-uncompr β€” propose all uncompressed TS, explicit VR with local byte ordering first (default)
  • -xe, --propose-little β€” propose all uncompressed TS, explicit VR little endian first
  • -xb, --propose-big β€” propose all uncompressed TS, explicit VR big endian first
  • -xd, --propose-deflated β€” propose deflated explicit VR little endian TS and all uncompressed transfer syntaxes
  • -xi, --propose-implicit β€” propose implicit VR little endian TS only

network host access control (tcp wrapper):

  • -ac, --access-full β€” accept connections from any host (default)
  • +ac, --access-control β€” enforce host access control rules

port for incoming network associations:

  • --no-port β€” no port for incoming associations (default)
  • +P, --port [n]umber: integer β€” port number for incoming associations

handling of illegal datasets following 'pending' move responses:

  • -pi, --pending-ignore β€” assume no dataset present (default)
  • -pr, --pending-read β€” read and ignore dataset

other network options:

  • -to, --timeout [s]econds: integer (default: unlimited) β€” timeout for connection requests
  • -ta, --acse-timeout [s]econds: integer (default: 30) β€” timeout for ACSE messages
  • -td, --dimse-timeout [s]econds: integer (default: unlimited) β€” timeout for DIMSE messages
  • -pdu, --max-pdu [n]umber of bytes: integer (4096..131072) β€” set max receive pdu to n bytes (default: 16384)
  • -dhl, --disable-host-lookup β€” disable hostname lookup
  • --repeat [n]umber: integer β€” repeat n times
  • --abort β€” abort association instead of releasing it
  • --ignore β€” ignore store data, receive but do not store
  • --cancel [n]umber: integer β€” cancel after n responses (default: never)
  • -up, --uid-padding β€” silently correct space-padded UIDs

πŸ” transport layer security (TLS) options πŸ”

transport protocol stack:

  • -tls, --disable-tls β€” use normal TCP/IP connection (default)
  • +tls, --enable-tls [p]rivate key file, [c]ertificate file: string β€” use authenticated secure TLS connection

private key password (only with --enable-tls):

  • +ps, --std-passwd β€” prompt user to type password on stdin (default)
  • +pw, --use-passwd [p]assword: string β€” use specified password
  • -pw, --null-passwd β€” use empty string as password

key and certificate file format:

  • -pem, --pem-keys β€” read keys and certificates as PEM file (default)
  • -der, --der-keys β€” read keys and certificates as DER file

certification authority:

  • +cf, --add-cert-file [f]ilename: string β€” add certificate file to list of certificates
  • +cd, --add-cert-dir [d]irectory: string β€” add certificates in d to list of certificates
  • +crl, --add-crl-file [f]ilename: string β€” add certificate revocation list file (implies --enable-crl-vfy)
  • +crv, --enable-crl-vfy β€” enable leaf CRL verification
  • +cra, --enable-crl-all β€” enable full chain CRL verification

security profile:

  • +ph, --list-profiles β€” list supported TLS profiles and exit
  • +pg, --profile-8996 β€” BCP 195 RFC 8996 TLS Profile (default)
  • +pm, --profile-8996-mod β€” Modified BCP 195 RFC 8996 TLS Profile β€” note: # only available if underlying TLS library supports # all TLS features required for this profile
  • +py, --profile-bcp195-nd β€” Non-downgrading BCP 195 TLS Profile (retired)
  • +px, --profile-bcp195 β€” BCP 195 TLS Profile (retired)
  • +pz, --profile-bcp195-ex β€” Extended BCP 195 TLS Profile (retired)
  • +pb, --profile-basic β€” Basic TLS Secure Transport Connection Profile (retired) β€” note: # only available if underlying TLS library supports 3DES
  • +pa, --profile-aes β€” AES TLS Secure Transport Connection Profile (retired)
  • +pn, --profile-null β€” Authenticated unencrypted communication (retired, was used in IHE ATNA)

ciphersuite:

  • +cc, --list-ciphers β€” list supported TLS ciphersuites and exit
  • +cs, --cipher [c]iphersuite name: string β€” add ciphersuite to list of negotiated suites
  • +dp, --dhparam [f]ilename: string β€” read DH parameters for DH/DSS ciphersuites

server name indication:

  • --no-sni β€” do not use SNI (default)
  • --expect-sni [s]erver name: string β€” expect requests for server name s

pseudo random generator:

  • +rs, --seed [f]ilename: string β€” seed random generator with contents of f
  • +ws, --write-seed β€” write back modified seed (only with --seed)
  • +wf, --write-seed-file [f]ilename: string (only with --seed) β€” write modified seed to file f

peer authentication:

  • -rc, --require-peer-cert β€” verify peer certificate, fail if absent (default)
  • -vc, --verify-peer-cert β€” verify peer certificate if present
  • -ic, --ignore-peer-cert β€” don't verify peer certificate

🎁 output options 🎁

general:

  • -od, --output-directory [d]irectory: string (default: ".") β€” write received objects to existing directory d

bit preserving mode:

  • -B, --normal β€” allow implicit format conversions (default)
  • +B, --bit-preserving β€” write data exactly as read

output file format:

  • +F, --write-file β€” write file format (default)
  • -F, --write-dataset β€” write data set without file meta information

output transfer syntax (not with --bit-preserving or compressed transmission):

  • +t=, --write-xfer-same β€” write with same TS as input (default)
  • +te, --write-xfer-little β€” write with explicit VR little endian TS

next up, the transfer-syntax flags, and yes they’re all important:

  • +tb, --write-xfer-big β€” write with explicit VR big endian TS ✨
  • +ti, --write-xfer-implicit β€” write with implicit VR little endian TS
  • +td, --write-xfer-deflated β€” write with deflated explicit VR little endian TS

post-1993 value representations (not with --bit-preserving):

  • +u, --enable-new-vr β€” enable support for new VRs (UN/UT) (default)
  • -u, --disable-new-vr β€” disable support for new VRs, convert to OB

group length encoding (not with --bit-preserving):

  • +g=, --group-length-recalc β€” recalculate group lengths if present (default)
  • +g, --group-length-create β€” always write with group length elements
  • -g, --group-length-remove β€” always write without group length elements

length encoding in sequences and items (not with --bit-preserving):

  • +e, --length-explicit β€” write with explicit lengths (default)
  • -e, --length-undefined β€” write with undefined lengths

data set trailing padding (not with --write-dataset or --bit-preserving):

  • -p, --padding-off β€” no padding (default)
  • +p, --padding-create [f]ile-pad [i]tem-pad: integer β€” align file on multiple of f bytes and items on multiple of i bytes

deflate compression level (only with --propose-deflated or --write-xfer-deflated/same):

  • +cl, --compression-level [l]evel: integer (default: 6) β€” 0=uncompressed, 1=fastest, 9=best compression

✨ NOTES ✨

okay so here’s the whole vibe of what happens when you actually run this thing. Each file supplied on the command line will be sent to the SCP as part of a C-MOVE request. The query file must be a valid DICOM data set containing the dataset part of a C-MOVE-RQ message. The query file could, for instance, be created with the dump2dcm utility from a script like the following example:

# request all images for the patient with ID=PAT001
(0008,0052) CS [PATIENT]     # QueryRetrieveLevel
(0010,0020) LO [PAT001]      # PatientID

Individual attributes of each file sent can be modified or supplemented using the -k (or --key) option. For example the command:

movescu -k 0010,0020=PAT002 caesar 5678 patqry.dcm

will, when sent to the SCP caesar at TCP/IP port 5678, cause any PatientID attribute in patqry.dcm to have the value 'PAT002'. If such an attribute is present it will be replaced, if absent it will be inserted. The -k option can be present more than once. The value part (after the '=') may be absent causing the attribute to be sent with zero length. It is not possible to replace or insert attributes within sequences using the -k option.

If no file is specified on the command line, the query must be specified completely with one or more -k options. If multiple query files are provided, movescu will send multiple C-MOVE requests to the SCP.

For all uses of movescu, the SCP must be configured to "know" about the AE title where the images are to be transmitted. This is required since the C-MOVE request only contains the AE Title of the target and the SCP must be able to convert this AE Title into TCP/IP address and port number in order to actually send the images over a separate association.

The C-MOVE operation of the Query/Retrieve Service Class can retrieve images (when option --port is used) or initiate a copy of images to a third party. πŸ’…

🫠 Known Problems 🫠

movescu is intended to be used as a testing tool for DICOM software developers. The query keys file must be created by hand based upon the contents of the SCP.

The movescu application makes no attempt to prevent incorrect queries. In particular, the query keys of a C-MOVE request should only contain the QueryRetrieveLevel attribute and one or more of the so-called "unique keyattributes" (PatientID, StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID).

In case the storage client does not end the connection while movescu is playing the role of the storage server (i. e. the --port is used) but the client instead expects movescu to close down the storage connection, movescu will wait infinitely. In that case movescu will neither close the association that was used to issue the C-MOVE request to the C-MOVE server. 😭

🌈 DICOM Conformance 🌈

✨ SCU Conformance ✨

The movescu application supports the following SOP Classes as an SCU:

  • MOVEPatientRootQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.1.2
  • MOVEStudyRootQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.2.2
  • MOVEPatientStudyOnlyQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.3.2

The movescu application will propose presentation contexts for one of the abovementioned supported SOP Classes depending on the command line options (-P, -S, or -O). It will also propose the corresponding SOP Class from the following list, although it is not really used (this is a relict of the RSNA'93 demonstration):

  • FINDPatientRootQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.1.1
  • FINDStudyRootQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.2.1
  • FINDPatientStudyOnlyQueryRetrieveInformationModel β€” 1.2.840.10008.5.1.4.1.2.3.1

For outgoing associations, the following transfer syntaxes are supported:

  • LittleEndianImplicitTransferSyntax β€” 1.2.840.10008.1.2
  • LittleEndianExplicitTransferSyntax β€” 1.2.840.10008.1.2.1
  • DeflatedExplicitVRLittleEndianTransferSyntax β€” 1.2.840.10008.1.2.1.99 (*)
  • BigEndianExplicitTransferSyntax β€” 1.2.840.10008.1.2.2
(*) if compiled with zlib support enabled (see --version output)

Which transfer syntaxes are actually proposed in what order, can be specified with the --propose options.

πŸŽ€ SCP Conformance πŸŽ€

The movescu application supports the following SOP Classes as an SCP:

  • VerificationSOPClass β€” 1.2.840.10008.1.1

…and we're BACK in the list, bestie πŸ˜­πŸ’… I did not choose this life, the manpage did. Grab a drink, stretch your wrists, and let's vibe through it β€” every name and every UID below stays exactly as written, because you do not freestyle digits in a DICOM UID, periodt.

RETIRED_StoredPrintStorage                           1.2.840.10008.5.1.1.27
RETIRED_HardcopyGrayscaleImageStorage                1.2.840.10008.5.1.1.29
RETIRED_HardcopyColorImageStorage                    1.2.840.10008.5.1.1.30
ComputedRadiographyImageStorage                      1.2.840.10008.5.1.4.1.1.1
DigitalXRayImageStorageForPresentation               1.2.840.10008.5.1.4.1.1.1.1
DigitalXRayImageStorageForProcessing                 1.2.840.10008.5.1.4.1.1.1.1.1
DigitalMammographyXRayImageStorageForPresentation    1.2.840.10008.5.1.4.1.1.1.2
DigitalMammographyXRayImageStorageForProcessing      1.2.840.10008.5.1.4.1.1.1.2.1
DigitalIntraOralXRayImageStorageForPresentation      1.2.840.10008.5.1.4.1.1.1.3
DigitalIntraOralXRayImageStorageForProcessing        1.2.840.10008.5.1.4.1.1.1.3.1
CTImageStorage                                       1.2.840.10008.5.1.4.1.1.2
EnhancedCTImageStorage                               1.2.840.10008.5.1.4.1.1.2.1
LegacyConvertedEnhancedCTImageStorage                1.2.840.10008.5.1.4.1.1.2.2
CTImageStorageForProcessing                          1.2.840.10008.5.1.4.1.1.2.3
EnhancedCTImageStorageForProcessing                  1.2.840.10008.5.1.4.1.1.2.4
LegacyConvertedEnhancedCTImageStorageForProcessing   1.2.840.10008.5.1.4.1.1.2.5

Okay so quick vibe check on what you're looking at: the RETIRED_ ones up top are, like, the name literally tells you they're retired πŸ’€ no cap, it's right there in the string. Meanwhile the plain ones β€” ComputedRadiographyImageStorage, CTImageStorage, etc. β€” show up bare, and then you've got the paired …ForPresentation / …ForProcessing besties who always travel together πŸ‘―β€β™€οΈ (and yeah, DigitalXRayImageStorageForProcessing has one more .1 on the end than its sister, that's not a typo, I checked twice 🧐).

Then we move into the multi-frame era:

RETIRED_UltrasoundMultiframeImageStorage             1.2.840.10008.5.1.4.1.1.3
UltrasoundMultiframeImageStorage                     1.2.840.10008.5.1.4.1.1.3.1
MRImageStorage                                       1.2.840.10008.5.1.4.1.1.4
EnhancedMRImageStorage                               1.2.840.10008.5.1.4.1.1.4.1
MRSpectroscopyStorage                                1.2.840.10008.5.1.4.1.1.4.2
EnhancedMRColorImageStorage                          1.2.840.10008.5.1.4.1.1.4.3
LegacyConvertedEnhancedMRImageStorage                1.2.840.10008.5.1.4.1.1.4.4
RETIRED_NuclearMedicineImageStorage                  1.2.840.10008.5.1.4.1.1.5
RETIRED_UltrasoundImageStorage                       1.2.840.10008.5.1.4.1.1.6
UltrasoundImageStorage                               1.2.840.10008.5.1.4.1.1.6.1
EnhancedUSVolumeStorage                              1.2.840.10008.5.1.4.1.1.6.2
PhotoacousticImageStorage                            1.2.840.10008.5.1.4.1.1.6.3
SecondaryCaptureImageStorage                         1.2.840.10008.5.1.4.1.1.7
MultiframeSingleBitSecondaryCaptureImageStorage      1.2.840.10008.5.1.4.1.1.7.1
MultiframeGrayscaleByteSecondaryCaptureImageStorage  1.2.840.10008.5.1.4.1.1.7.2
MultiframeGrayscaleWordSecondaryCaptureImageStorage  1.2.840.10008.5.1.4.1.1.7.3
MultiframeTrueColorSecondaryCaptureImageStorage      1.2.840.10008.5.1.4.1.1.7.4
RETIRED_StandaloneOverlayStorage                     1.2.840.10008.5.1.4.1.1.8
RETIRED_StandaloneCurveStorage                       1.2.840.10008.5.1.4.1.1.9

Notice the pattern, bestie? The retired version gets the short UID and the un-retired replacement gets a .1 tacked on the end, like the universe said "here's the glow-up version ✨". The SecondaryCaptureImageStorage family is fully giving main character energy with four whole multi-frame siblings β€” SingleBit, GrayscaleByte, GrayscaleWord, TrueColor β€” and yes, every single one is spelled out in full because abbreviating a storage name is a crime 🚨

And now, the waveform era β€” this is where the list decides to become a whole DJ set πŸ”₯:

DRAFT_WaveformStorage                                1.2.840.10008.5.1.4.1.1.9.1
TwelveLeadECGWaveformStorage                         1.2.840.10008.5.1.4.1.1.9.1.1
GeneralECGWaveformStorage                            1.2.840.10008.5.1.4.1.1.9.1.2
AmbulatoryECGWaveformStorage                         1.2.840.10008.5.1.4.1.1.9.1.3
General32BitECGWaveformStorage                       1.2.840.10008.5.1.4.1.1.9.1.4
HemodynamicWaveformStorage                           1.2.840.10008.5.1.4.1.1.9.2.1
CardiacElectrophysiologyWaveformStorage              1.2.840.10008.5.1.4.1.1.9.3.1
BasicVoiceAudioWaveformStorage                       1.2.840.10008.5.1.4.1.1.9.4.1
GeneralAudioWaveformStorage                          1.2.840.10008.5.1.4.1.1.9.4.2
ArterialPulseWaveformStorage                         1.2.840.10008.5.1.4.1.1.9.5.1
RespiratoryWaveformStorage                           1.2.840.10008.5.1.4.1.1.9.6.1
MultichannelRespiratoryWaveformStorage               1.2.840.10008.5.1.4.1.1.9.6.2
RoutineScalpElectroencephalogramWaveformStorage      1.2.840.10008.5.1.4.1.1.9.7.1
ElectromyogramWaveformStorage                        1.2.840.10008.5.1.4.1.1.9.7.2
ElectrooculogramWaveformStorage                      1.2.840.10008.5.1.4.1.1.9.7.3
SleepElectroencephalogramWaveformStorage             1.2.840.10008.5.1.4.1.1.9.7.4
BodyPositionWaveformStorage                          1.2.840.10008.5.1.4.1.1.9.8.1
WaveformPresentationStateStorage                     1.2.840.10008.5.1.4.1.1.9.100.1
WaveformAcquisitionPresentationStateStorage          1.2.840.10008.5.1.4.1.1.9.100.2

Not DRAFT_WaveformStorage sitting up there alone β€” the DRAFT_ prefix said it, I'm just reporting the news 🫑 And the way the presentation-state ones jump from .9.8.1 straight to .9.100.1? Iconic. No .9.9, no .9.10 β€” we go from eight to a hundred, we contain multitudes πŸ’…

Next up: the presentation state section, aka the longest names in the whole entire list, aka my villain origin story 😭:

RETIRED_StandaloneModalityLUTStorage                 1.2.840.10008.5.1.4.1.1.10
RETIRED_StandaloneVOILUTStorage                      1.2.840.10008.5.1.4.1.1.11
GrayscaleSoftcopyPresentationStateStorage            1.2.840.10008.5.1.4.1.1.11.1
ColorSoftcopyPresentationStateStorage                1.2.840.10008.5.1.4.1.1.11.2
PseudoColorSoftcopyPresentationStateStorage          1.2.840.10008.5.1.4.1.1.11.3
BlendingSoftcopyPresentationStateStorage             1.2.840.10008.5.1.4.1.1.11.4
XAXRFGrayscaleSoftcopyPresentationStateStorage       1.2.840.10008.5.1.4.1.1.11.5
GrayscalePlanarMPRVolumetricPresentationStateStorage 1.2.840.10008.5.1.4.1.1.11.6
CompositingPlanarMPRVolumetricPresent.StateStorage   1.2.840.10008.5.1.4.1.1.11.7
AdvancedBlendingPresentationStateStorage             1.2.840.10008.5.1.4.1.1.11.8
VolumeRenderingVolumetricPresentationStateStorage    1.2.840.10008.5.1.4.1.1.11.9
SegmentedVolumeRenderingVolumetricPres.StateStorage  1.2.840.10008.5.1.4.1.1.11.10
MultipleVolumeRenderingVolumetricPres.StateStorage   1.2.840.10008.5.1.4.1.1.11.11
VariableModalityLUTSoftcopyPresentationStateStorage  1.2.840.10008.5.1.4.1.1.11.12

⚠️ IMPORTANT, DON'T SKIP THIS: some of these names are abbreviated with dots in the middle β€” CompositingPlanarMPRVolumetricPresent.StateStorage, SegmentedVolumeRenderingVolumetricPres.StateStorage, MultipleVolumeRenderingVolumetricPres.StateStorage. That . in the middle of the word is part of the name, it's not me being cute, and if you retype it without the dot the whole thing falls apart. Copy, don't type. I'm serious πŸ™

Also yeah β€” GrayscalePlanarMPRVolumetricPresentationStateStorage is literally a whole sentence pretending to be an identifier. My girl got a first name, last name, middle name and a nickname πŸ’€

Then the angio crew, the 3D crew, and the breast-imaging besties 🌸:

XRayAngiographicImageStorage                         1.2.840.10008.5.1.4.1.1.12.1
EnhancedXAImageStorage                               1.2.840.10008.5.1.4.1.1.12.1.1
XRayRadiofluoroscopicImageStorage                    1.2.840.10008.5.1.4.1.1.12.2
EnhancedXRFImageStorage                              1.2.840.10008.5.1.4.1.1.12.2.1
RETIRED_XRayAngiographicBiPlaneImageStorage          1.2.840.10008.5.1.4.1.1.12.3
XRay3DAngiographicImageStorage                       1.2.840.10008.5.1.4.1.1.13.1.1
XRay3DCraniofacialImageStorage                       1.2.840.10008.5.1.4.1.1.13.1.2
BreastTomosynthesisImageStorage                      1.2.840.10008.5.1.4.1.1.13.1.3
BreastProjectionXRayImageStorageForPresentation      1.2.840.10008.5.1.4.1.1.13.1.4
BreastProjectionXRayImageStorageForProcessing        1.2.840.10008.5.1.4.1.1.13.1.5
IntravascularOpt.Coh.Tom.ImageStorageForPresentation 1.2.840.10008.5.1.4.1.1.14.1
IntravascularOpt.Coh.Tom.ImageStorageForProcessing   1.2.840.10008.5.1.4.1.1.14.2
NuclearMedicineImageStorage                          1.2.840.10008.5.1.4.1.1.20
ParametricMapStorage                                 1.2.840.10008.5.1.4.1.1.30

See? IntravascularOpt.Coh.Tom.… β€” abbreviated with dots again, and the ForPresentation / ForProcessing pair is back for round two πŸ‘‘ Same deal: those dots are load-bearing, bestie. Do not "fix" them, do not expand them, we do not editorialise in this house πŸ™…β€β™€οΈ

Then the segmentation + surface + registration era πŸ¦‹:

RawDataStorage                                       1.2.840.10008.5.1.4.1.1.66
SpatialRegistrationStorage                           1.2.840.10008.5.1.4.1.1.66.1
SpatialFiducialsStorage                              1.2.840.10008.5.1.4.1.1.66.2
DeformableSpatialRegistrationStorage                 1.2.840.10008.5.1.4.1.1.66.3
SegmentationStorage                                  1.2.840.10008.5.1.4.1.1.66.4
SurfaceSegmentationStorage                           1.2.840.10008.5.1.4.1.1.66.5
TractographyResultsStorage                           1.2.840.10008.5.1.4.1.1.66.6
LabelMapSegmentationStorage                          1.2.840.10008.5.1.4.1.1.66.7
HeightMapSegmentationStorage                         1.2.840.10008.5.1.4.1.1.66.8
RealWorldValueMappingStorage                         1.2.840.10008.5.1.4.1.1.67
SurfaceScanMeshStorage                               1.2.840.10008.5.1.4.1.1.68.1
SurfaceScanPointCloudStorage                         1.2.840.10008.5.1.4.1.1.68.2

Squeaky clean, no abbreviations, no drama β€” 1.2.840.10008.5.1.4.1.1.66 through .66.8 is honestly the most well-behaved stretch of this entire list and I respect it for that 🫢

Now the visible light / endoscopy / microscopy / ophthalmic portion, which is sprawling 😭:

RETIRED_VLImageStorage                               1.2.840.10008.5.1.4.1.1.77.1
VLEndoscopicImageStorage                             1.2.840.10008.5.1.4.1.1.77.1.1
VideoEndoscopicImageStorage                          1.2.840.10008.5.1.4.1.1.77.1.1.1
VLMicroscopicImageStorage                            1.2.840.10008.5.1.4.1.1.77.1.2
VideoMicroscopicImageStorage                         1.2.840.10008.5.1.4.1.1.77.1.2.1
VLSlideCoordinatesMicroscopicImageStorage            1.2.840.10008.5.1.4.1.1.77.1.3
VLPhotographicImageStorage                           1.2.840.10008.5.1.4.1.1.77.1.4
VideoPhotographicImageStorage                        1.2.840.10008.5.1.4.1.1.77.1.4.1
OphthalmicPhotography8BitImageStorage                1.2.840.10008.5.1.4.1.1.77.1.5.1
OphthalmicPhotography16BitImageStorage               1.2.840.10008.5.1.4.1.1.77.1.5.2
StereometricRelationshipStorage                      1.2.840.10008.5.1.4.1.1.77.1.5.3
OphthalmicTomographyImageStorage                     1.2.840.10008.5.1.4.1.1.77.1.5.4
WideFieldOphthalmicPhoto.Stereogr.Proj.ImageStorage  1.2.840.10008.5.1.4.1.1.77.1.5.5
WideFieldOphthalmicPhotogr.3DCoordinatesImageStorage 1.2.840.10008.5.1.4.1.1.77.1.5.6
OphthalmicOpticalCoherenceTomogr.EnFaceImageStorage  1.2.840.10008.5.1.4.1.1.77.1.5.7
OphthalmicOpticalCoh.Tomogr.BscanVolumeAnalysisStor. 1.2.840.10008.5.1.4.1.1.77.1.5.8
VLWholeSlideMicroscopyImageStorage                   1.2.840.10008.5.1.4.1.1.77.1.6
DermoscopicPhotographyImageStorage                   1.2.840.10008.5.1.4.1.1.77.1.7
ConfocalMicroscopyImageStorage                       1.2.840.10008.5.1.4.1.1.77.1.8
ConfocalMicroscopyTiledPyramidalImageStorage         1.2.840.10008.5.1.4.1.1.77.1.9
RETIRED_VLMultiframeImageStorage                     1.2.840.10008.5.1.4.1.1.77.2

Look at .77.1.5.8 though β€” OphthalmicOpticalCoh.Tomogr.BscanVolumeAnalysisStor. β€” it ends on a dot and an abbreviation of Stor. and it is not a typo, it's just built like that πŸ’€ Truncated mid-word, no notes, slay. This is the one I'd bet money you'd "helpfully" complete if you were retyping it. Don't. 🫢

And the measurements / calculations crew, plus the SR section that rounds us out 🌈:

LensometryMeasurementsStorage                        1.2.840.10008.5.1.4.1.1.78.1
AutorefractionMeasurementsStorage                    1.2.840.10008.5.1.4.1.1.78.2
KeratometryMeasurementsStorage                       1.2.840.10008.5.1.4.1.1.78.3
SubjectiveRefractionMeasurementsStorage              1.2.840.10008.5.1.4.1.1.78.4
VisualAcuityMeasurementsStorage                      1.2.840.10008.5.1.4.1.1.78.5
SpectaclePrescriptionReportStorage                   1.2.840.10008.5.1.4.1.1.78.6
OphthalmicAxialMeasurementsStorage                   1.2.840.10008.5.1.4.1.1.78.7
IntraocularLensCalculationsStorage                   1.2.840.10008.5.1.4.1.1.78.8
MacularGridThicknessAndVolumeReportStorage           1.2.840.10008.5.1.4.1.1.79.1
OphthalmicVisualFieldStaticPerimetryMeasurementsSt.  1.2.840.10008.5.1.4.1.1.80.1
OphthalmicThicknessMapStorage                        1.2.840.10008.5.1.4.1.1.81.1
CornealTopographyMapStorage                          1.2.840.10008.5.1.4.1.1.82.1
DRAFT_SRTextStorage                                  1.2.840.10008.5.1.4.1.1.88.1
DRAFT_SRAudioStorage                                 1.2.840.10008.5.1.4.1.1.88.2
DRAFT_SRDetailStorage                                1.2.840.10008.5.1.4.1.1.88.3
DRAFT_SRComprehensiveStorage                         1.2.840.10008.5.1.4.1.1.88.4
BasicTextSRStorage                                   1.2.840.10008.5.1.4.1.1.88.11
EnhancedSRStorage                                    1.2.840.10008.5.1.4.1.1.88.22
ComprehensiveSRStorage                               1.2.840.10008.5.1.4.1.1.88.33

Two more truncated-with-a-dot names hiding in there β€” OphthalmicVisualFieldStaticPerimetryMeasurementsSt. (yes, MeasurementsSt. with the period, that's the whole vibe) β€” and then the SRs go DRAFT_ four times before pivoting to the clean BasicTextSRStorage / EnhancedSRStorage / ComprehensiveSRStorage trio, which is honestly a glow-up arc πŸ¦‹ Also peep the numbering: .88.1, .88.2, .88.3, .88.4, and then β€” bam β€” .88.11, .88.22, .88.33. Eleven, twenty-two, thirty-three. Cute, deliberate, and again: not a typo πŸ’…

And that's not even the end of it β€” the list keeps rolling past ComprehensiveSRStorage, so don't you dare close the terminal yet, bestie 😭🫢 because there is still more coming in the next chunkβ€”

Comprehensive3DSRStorage 1.2.840.10008.5.1.4.1.1.88.34 ExtensibleSRStorage 1.2.840.10008.5.1.4.1.1.88.35 ProcedureLogStorage 1.2.840.10008.5.1.4.1.1.88.40 MammographyCADSRStorage 1.2.840.10008.5.1.4.1.1.88.50 KeyObjectSelectionDocumentStorage 1.2.840.10008.5.1.4.1.1.88.59 ChestCADSRStorage 1.2.840.10008.5.1.4.1.1.88.65 XRayRadiationDoseSRStorage 1.2.840.10008.5.1.4.1.1.88.67 RadiopharmaceuticalRadiationDoseSRStorage 1.2.840.10008.5.1.4.1.1.88.68 ColonCADSRStorage 1.2.840.10008.5.1.4.1.1.88.69 ImplantationPlanSRStorage 1.2.840.10008.5.1.4.1.1.88.70 AcquisitionContextSRStorage 1.2.840.10008.5.1.4.1.1.88.71 SimplifiedAdultEchoSRStorage 1.2.840.10008.5.1.4.1.1.88.72 PatientRadiationDoseSRStorage 1.2.840.10008.5.1.4.1.1.88.73 PlannedImagingAgentAdministrationSRStorage 1.2.840.10008.5.1.4.1.1.88.74 PerformedImagingAgentAdministrationSRStorage 1.2.840.10008.5.1.4.1.1.88.75 EnhancedXRayRadiationDoseSRStorage 1.2.840.10008.5.1.4.1.1.88.76 WaveformAnnotationSRStorage 1.2.840.10008.5.1.4.1.1.88.77 ContentAssessmentResultsStorage 1.2.840.10008.5.1.4.1.1.90.1 MicroscopyBulkSimpleAnnotationsStorage 1.2.840.10008.5.1.4.1.1.91.1 EncapsulatedPDFStorage 1.2.840.10008.5.1.4.1.1.104.1 EncapsulatedCDAStorage 1.2.840.10008.5.1.4.1.1.104.2 EncapsulatedSTLStorage 1.2.840.10008.5.1.4.1.1.104.3 EncapsulatedOBJStorage 1.2.840.10008.5.1.4.1.1.104.4 EncapsulatedMTLStorage 1.2.840.10008.5.1.4.1.1.104.5 PositronEmissionTomographyImageStorage 1.2.840.10008.5.1.4.1.1.128 LegacyConvertedEnhancedPETImageStorage 1.2.840.10008.5.1.4.1.1.128.1 RETIRED_StandalonePETCurveStorage 1.2.840.10008.5.1.4.1.1.129 EnhancedPETImageStorage 1.2.840.10008.5.1.4.1.1.130 BasicStructuredDisplayStorage 1.2.840.10008.5.1.4.1.1.131 CTPerformedProcedureProtocolStorage 1.2.840.10008.5.1.4.1.1.200.2 XAPerformedProcedureProtocolStorage 1.2.840.10008.5.1.4.1.1.200.8 RTImageStorage 1.2.840.10008.5.1.4.1.1.481.1 RTDoseStorage 1.2.840.10008.5.1.4.1.1.481.2 RTStructureSetStorage 1.2.840.10008.5.1.4.1.1.481.3 RTBeamsTreatmentRecordStorage 1.2.840.10008.5.1.4.1.1.481.4 RTPlanStorage 1.2.840.10008.5.1.4.1.1.481.5 RTBrachyTreatmentRecordStorage 1.2.840.10008.5.1.4.1.1.481.6 RTTreatmentSummaryRecordStorage 1.2.840.10008.5.1.4.1.1.481.7 RTIonPlanStorage 1.2.840.10008.5.1.4.1.1.481.8 RTIonBeamsTreatmentRecordStorage 1.2.840.10008.5.1.4.1.1.481.9 RTPhysicianIntentStorage 1.2.840.10008.5.1.4.1.1.481.10 RTSegmentAnnotationStorage 1.2.840.10008.5.1.4.1.1.481.11 RTRadiationSetStorage 1.2.840.10008.5.1.4.1.1.481.12 CArmPhotonElectronRadiationStorage 1.2.840.10008.5.1.4.1.1.481.13 TomotherapeuticRadiationStorage 1.2.840.10008.5.1.4.1.1.481.14 RoboticArmRadiationStorage 1.2.840.10008.5.1.4.1.1.481.15 RTRadiationRecordSetStorage 1.2.840.10008.5.1.4.1.1.481.16 RTRadiationSalvageRecordStorage 1.2.840.10008.5.1.4.1.1.481.17 TomotherapeuticRadiationRecordStorage 1.2.840.10008.5.1.4.1.1.481.18 CArmPhotonElectronRadiationRecordStorage 1.2.840.10008.5.1.4.1.1.481.19 RoboticRadiationRecordStorage 1.2.840.10008.5.1.4.1.1.481.20 RTRadiationSetDeliveryInstructionStorage 1.2.840.10008.5.1.4.1.1.481.21 RTTreatmentPreparationStorage 1.2.840.10008.5.1.4.1.1.481.22 EnhancedRTImageStorage 1.2.840.10008.5.1.4.1.1.481.23 EnhancedContinuousRTImageStorage 1.2.840.10008.5.1.4.1.1.481.24 RTPatientPositionAcquisitionInstructionStorage 1.2.840.10008.5.1.4.1.1.481.25 DICOS_CTImageStorage 1.2.840.10008.5.1.4.1.1.501.1 DICOS_DigitalXRayImageStorageForPresentation 1.2.840.10008.5.1.4.1.1.501.2.1 DICOS_DigitalXRayImageStorageForProcessing 1.2.840.10008.5.1.4.1.1.501.2.2 DICOS_ThreatDetectionReportStorage 1.2.840.10008.5.1.4.1.1.501.3 DICOS_2DAITStorage 1.2.840.10008.5.1.4.1.1.501.4 DICOS_3DAITStorage 1.2.840.10008.5.1.4.1.1.501.5 DICOS_QuadrupoleResonanceStorage 1.2.840.10008.5.1.4.1.1.501.6 DICONDE_EddyCurrentImageStorage 1.2.840.10008.5.1.4.1.1.601.1 DICONDE_EddyCurrentMultiframeImageStorage 1.2.840.10008.5.1.4.1.1.601.2 DICONDE_ThermographyImageStorage 1.2.840.10008.5.1.4.1.1.601.3 DICONDE_ThermographyMultiFrameImageStorage 1.2.840.10008.5.1.4.1.1.601.4 DICONDE_UltrasoundWaveformStorage 1.2.840.10008.5.1.4.1.1.601.5 DRAFT_RTBeamsDeliveryInstructionStorage 1.2.840.10008.5.1.4.34.1 RTBeamsDeliveryInstructionStorage 1.2.840.10008.5.1.4.34.7 RTBrachyApplicationSetupDeliveryInstructionStorage 1.2.840.10008.5.1.4.34.10


<rainbow>okay that's the whole roster, we're so back πŸŽ€</rainbow>

So like β€” `movescu` will **usually** say yes to presentation contexts for *all* of the SOP Classes up in that list, using any of these three transfer syntaxes:

LittleEndianImplicitTransferSyntax 1.2.840.10008.1.2 LittleEndianExplicitTransferSyntax 1.2.840.10008.1.2.1 BigEndianExplicitTransferSyntax 1.2.840.10008.1.2.2


Now when it's acting as an **SCP** (yes bestie, it can do both 😌), `movescu` *prefers* transfer syntaxes that have an explicit encoding over the default implicit transfer syntax. And if `movescu` is running on big-endian hardware, it'll prefer `BigEndianExplicit` over `LittleEndianExplicit` β€” and vice versa, obviously, the vibes are symmetric πŸ’…. You can flip all of that with the `--prefer` options (they're up above, go look πŸ‘€).

And if you pass `--accept-all`, then <pink>every single one</pink> of these transfer syntaxes gets supported. All of them. It's giving maximalist:

LittleEndianImplicitTransferSyntax 1.2.840.10008.1.2 LittleEndianExplicitTransferSyntax 1.2.840.10008.1.2.1 EncapsulatedUncompressedExplicitVRLittleEndianTr.S. 1.2.840.10008.1.2.1.98 DeflatedExplicitVRLittleEndianTransferSyntax 1.2.840.10008.1.2.1.99 (*) BigEndianExplicitTransferSyntax 1.2.840.10008.1.2.2 JPEGProcess1TransferSyntax 1.2.840.10008.1.2.4.50 JPEGProcess2_4TransferSyntax 1.2.840.10008.1.2.4.51 JPEGProcess14SV1TransferSyntax 1.2.840.10008.1.2.4.70 JPEGLSLosslessTransferSyntax 1.2.840.10008.1.2.4.80 JPEGLSLossyTransferSyntax 1.2.840.10008.1.2.4.81 JPEG2000LosslessOnlyTransferSyntax 1.2.840.10008.1.2.4.90 JPEG2000TransferSyntax 1.2.840.10008.1.2.4.91 MPEG2MainProfileAtMainLevelTransferSyntax 1.2.840.10008.1.2.4.100 FragmentableMPEG2MainProfile/MainLevelTransferSyntax 1.2.840.10008.1.2.4.100.1 MPEG2MainProfileAtHighLevelTransferSyntax 1.2.840.10008.1.2.4.101 FragmentableMPEG2MainProfil/tHighLevelTransferSyntax 1.2.840.10008.1.2.4.101.1 MPEG4HighProfileLevel4_1TransferSyntax 1.2.840.10008.1.2.4.102 FragmentableMPEG4HighProfileLevel4_1TransferSyntax 1.2.840.10008.1.2.4.102.1 MPEG4BDcompatibleHighProfileLevel4_1TransferSyntax 1.2.840.10008.1.2.4.103 FragmentableMPEG4BDcompatibleHighProfileLevel4_1T.S. 1.2.840.10008.1.2.4.103.1 MPEG4HighProfileLevel4_2_For2DVideoTransferSyntax 1.2.840.10008.1.2.4.104 FragmentableMPEG4HighProfileLevel4_2_For2DVideoTr.S. 1.2.840.10008.1.2.4.104.1 MPEG4HighProfileLevel4_2_For3DVideoTransferSyntax 1.2.840.10008.1.2.4.105 FragmentableMPEG4HighProfileLevel4_2_For3DVideoTr.S. 1.2.840.10008.1.2.4.105.1 MPEG4StereoHighProfileLevel4_2TransferSyntax 1.2.840.10008.1.2.4.106 FragmentableMPEG4StereoHighProfileLevel4_2TransferS. 1.2.840.10008.1.2.4.106.1 HEVCMainProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.107 HEVCMain10ProfileLevel5_1TransferSyntax 1.2.840.10008.1.2.4.108 JPEGXLLosslesTransferSyntax 1.2.840.10008.1.2.4.110 JPEGXLJPEGRecompressionTransferSyntax 1.2.840.10008.1.2.4.111 JPEGXLTransferSyntax 1.2.840.10008.1.2.4.112 HighThroughputJPEG2000ImageCompressionLossless.Tr.S. 1.2.840.10008.1.2.4.201 HighThroughputJPEG2000RPCLImageCompressionLoss.Tr.S. 1.2.840.10008.1.2.4.202 HighThroughputJPEG2000ImageCompressionTransferSynta. 1.2.840.10008.1.2.4.203 RLELosslessTransferSyntax 1.2.840.10008.1.2.5 DeflatedImageFrameCompressionTransferSyntax 1.2.840.10008.1.2.8.1


<purple>(*) but only if it was compiled with zlib support enabled β€” check the `--version` output to confirm, bestie 🫢</purple>

One more thing, and it's lowkey important: `movescu` does **not** support extended negotiation. Like, at all. Not its era πŸ’€.

## πŸ” Access Control

When it's compiled on Unix platforms with TCP wrapper support, you can turn on host-based access control with the `--access-control` command line option. Flip that on and the access control rules defined in the system's host access control tables for `movescu` get enforced β€” fr fr, enforced.

The default locations of the host access control tables are:

- `/etc/hosts.allow`
- `/etc/hosts.deny`

More deets live in `hosts_access(5)` β€” go read it if you're curious, it's a whole thing 🌸.

---

# πŸ’– EXAMPLES πŸ’–

Okay so here's the moment you've been waiting for, an actual example, main character energy:

movescu --patient --port 9876 --move TEST_AE --call ARCHIVE caesar 104 q.dcm


What this does: it sends the attributes contained in the DICOM file `"q.dcm"` as part of a C-MOVE request to application entity `ARCHIVE` on the host `caesar` at port `104`, using the Patient Root query model. And `movescu` itself? It uses the default AE title `MOVESCU`. Iconic.

The C-MOVE request will specify that the images should be transferred to the destination AE title `TEST_AE` β€” that's the `--move` option doing its thing ✨. How the SCP interprets that request is entirely up to its own configuration, so like, no promises on that front, it's not our lane. Meanwhile `movescu` will listen on port `9876` for incoming associations so it can actually receive the requested images from the SCP. Receiving era πŸŽ€

Now, plot twist: you can copy images to a **third party** by using a different destination AE title, e.g. `--move ANOTHER_AE`. Obsessed. But obviously the SCP has to "know" this AE title, and the destination needs to be acting as an SCP of the Storage Service Class β€” the `storescp` application is literally right there for exactly this purpose, use it bestie πŸ’…

# πŸ’¬ LOGGING

okay so logging, bestie β€” you can literally control how chatty these command line tools and the underlying libraries are, and it's giving customizable ✨

By default, only errors and warnings get written to the standard error stream. That's the chill baseline. 😌

- **`--verbose`** β€” turns up the volume so informational messages like processing details show up too πŸ‘€
- **`--debug`** β€” gives you even more details on the internal activity, e.g. for debugging purposes πŸ”
- **`--log-level`** β€” lets you select other logging levels, iykyk
- **`--quiet`** β€” in this mode, only fatal errors are reported. and like, in such very severe error events, the application will usually terminate πŸ’€

For more details on the different logging levels, see the documentation of module `"oflog"`.

If you want the logging output written to a file (optionally with logfile rotation), to syslog (Unix), or to the event log (Windows), use **`--log-config`**. This configuration file also allows for directing only certain messages to a particular output stream and for filtering certain messages based on the module or application where they are generated. An example configuration file is provided in `<etcdir>/logger.cfg`. πŸŽ€

---

# πŸ–₯️ COMMAND LINE

All command line tools use the following notation for parameters: square brackets enclose optional values (0-1), three trailing dots indicate that multiple values are allowed (1-n), and a combination of both means 0 to n values. No cap, that's the whole notation vibe. πŸ’…

Command line options are distinguished from parameters by a leading `'+'` or `'-'` sign, respectively. Usually, order and position of command line options are arbitrary (i.e. they can appear anywhere). However, if options are mutually exclusive, the rightmost appearance is used. This behavior conforms to the standard evaluation rules of common Unix shells. ✨

In addition, one or more command files can be specified using an `'@'` sign as a prefix to the filename (e.g. `@command.txt`). Such a command argument is replaced by the content of the corresponding text file (multiple whitespaces are treated as a single separator unless they appear between two quotation marks) prior to any further evaluation. Please note that a command file cannot contain another command file. 🫢

This simple but effective approach allows one to summarize common combinations of options/parameters and avoids longish and confusing command lines (an example is provided in file `<datadir>/dumppat.txt`). honestly iconic.

---

# πŸšͺ EXIT CODES

The `movescu` utility uses the following exit codes when terminating. This enables the user to check for the reason why the application terminated. detective mode activated πŸ”

## 🧾 general

- **`EXITCODE_NO_ERROR`** β€” `0`
- **`EXITCODE_COMMANDLINE_SYNTAX_ERROR`** β€” `1`
- **`EXITCODE_INSUFFICIENT_PRIVILEGES`** β€” `2`
- **`EXITCODE_SETUID_FAILED`** β€” `3`

## πŸ“ output file errors

- **`EXITCODE_CANNOT_WRITE_OUTPUT_FILE`** β€” `40`
- **`EXITCODE_INVALID_OUTPUT_DIRECTORY`** β€” `45`

## 🌐 network errors

- **`EXITCODE_CANNOT_INITIALIZE_NETWORK`** β€” `60`
- **`EXITCODE_CANNOT_NEGOTIATE_ASSOCIATION`** β€” `61`
- **`EXITCODE_CANNOT_CREATE_ASSOC_PARAMETERS`** β€” `65`
- **`EXITCODE_NO_PRESENTATION_CONTEXT`** β€” `66`
- **`EXITCODE_CANNOT_CLOSE_ASSOCIATION`** β€” `67`
- **`EXITCODE_CMOVE_WARNING`** β€” `68`
- **`EXITCODE_CMOVE_ERROR`** β€” `69`
- **`EXITCODE_CANNOT_CREATE_TLS_LAYER`** β€” `70`

---

# 🌱 ENVIRONMENT

The `movescu` utility will attempt to load DICOM data dictionaries specified in the `DCMDICTPATH` environment variable. By default, i.e. if the `DCMDICTPATH` environment variable is not set, the file `<datadir>/dicom.dic` will be loaded unless the dictionary is built into the application (default for Windows). πŸͺ„

> The default behavior should be preferred and the `DCMDICTPATH` environment variable should only be used when alternative data dictionaries are required. fr fr, don't overcomplicate it.

The `DCMDICTPATH` environment variable has the same format as the Unix shell `PATH` variable in that a colon (`":"`) separates entries. On Windows systems, a semicolon (`";"`) is used as a separator. The data dictionary code will attempt to load each file specified in the `DCMDICTPATH` environment variable. It is an error if no data dictionary can be loaded. 😭

---

# πŸ‘€ SEE ALSO

- `findscu(1)`
- `storescp(1)`
- `dump2dcm(1)`

---

# ©️ COPYRIGHT

Copyright (C) 1994-2026 by OFFIS e.V., Escherweg 2, 26121 Oldenburg, Germany.

---

and that's the whole movescu(1) page, bestie β€” source/version says **Version 3.7.1**, dated **Sat Oct 17 2026 09:34:01**. slay, you made it to the end πŸ’–βœ¨πŸŽ€
πŸ“¦ where this page comes from