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 peerportβ tcp/ip port number of peerdcmfile-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 arefatal,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 toOB
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.2MOVEStudyRootQueryRetrieveInformationModelβ1.2.840.10008.5.1.4.1.2.2.2MOVEPatientStudyOnlyQueryRetrieveInformationModelβ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.1FINDStudyRootQueryRetrieveInformationModelβ1.2.840.10008.5.1.4.1.2.2.1FINDPatientStudyOnlyQueryRetrieveInformationModelβ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.2LittleEndianExplicitTransferSyntaxβ1.2.840.10008.1.2.1DeflatedExplicitVRLittleEndianTransferSyntaxβ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
- arch rolling: dcmtk 3.7.1-1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms