Trying to implement a DICOM Router desktop (Java) application using dcm4che (v.2) toolkit.
The DICOM Router should accept any incoming DICOM send requests, store the files locally (in a certain folder structure) and after each DICOM study send request completion it should process the files in a certain way (internal actions).
I am using the dcmrcv util/tool for implementing a DICOM receiver in the following way (getDcmRcv() is actually a dmcRcv object):
...
private final CustomStorageService storageSCP = new CustomStorageService(CUIDS);
...
public DcmRcv(String name) {
device = new Device(name);
executor = new NewThreadExecutor(name);
device.setNetworkApplicationEntity(ae);
device.setNetworkConnection(nc);
ae.setNetworkConnection(nc);
ae.setAssociationAcceptor(true);
ae.register(new VerificationService());
ae.register(storageSCP);
ae.register(stgcmtSCP);
ae.addAssociationListener(storageSCP);
}
I have somehow modified StorageService to manage an AssociationListener in the following way:
private final class CustomStorageService extends StorageService implements AssociationListener {
public CustomStorageService(final String[] sopClasses) {
super(sopClasses);
}
@Override
protected void onCStoreRQ(final Association association, final int pcid, final DicomObject dcmReqObj,
final PDVInputStream dataStream, final String transferSyntaxUID,
final DicomObject dcmRspObj)
throws DicomServiceException, IOException {
final String classUID = dcmReqObj.getString(Tag.AffectedSOPClassUID);
final String instanceUID = dcmReqObj.getString(Tag.AffectedSOPInstanceUID);
GlobalConfig config = new GlobalConfig();
final File associationDir = config.getAssocDirFile();
final String prefixedFileName = instanceUID;
final String dicomFileBaseName = prefixedFileName + DICOM_FILE_EXTENSION;
File dicomFile = new File(associationDir, dicomFileBaseName + PARTIAL_FILE_EXTENSION);
assert !dicomFile.exists();
final BasicDicomObject fileMetaDcmObj = new BasicDicomObject();
fileMetaDcmObj.initFileMetaInformation(classUID, instanceUID, transferSyntaxUID);
final DicomOutputStream outStream = new DicomOutputStream(
new BufferedOutputStream(new FileOutputStream(dicomFile), 600000));
try {
outStream.writeFileMetaInformation(fileMetaDcmObj);
dataStream.copyTo(outStream);
} finally {
outStream.close();
}
dicomFile.renameTo(new File(associationDir, dicomFileBaseName));
System.out.println("DICOM file name: " + dicomFile.getName());
}
}
In such way i can accept DICOM send requests from a client (e.g. Mayam) BUT the files are stored in a flat structure in directory "rootDirectory" (C:\XXXXXX\YYYY\Development\AssocDir).
I am trying to get information such as StudyID and SeriedID from the association object to create a folder structure like: root/StudyID/SeriesID/DicmFile from dcmReqObj or dicomFile ... However:
dcmReqObj is actually empty (only AffectedSOPClassUID & AffectedSOPInstanceUID tags are populated)
Even if i try to fetch it after: outStream.writeFileMetaInformation(fileMetaDcmObj) the StudyID tag is not yet populated (inside this method) ...
Also in this method if i try to fetch "dicomFile" inside onCStoreRQ i can only take it in a transitional phase where it is not yet a populated DICOM object ...
What i have been missing here?
You'll need to do more than just use the DcmRcv class as is.
Use it as a starting point, but you'll also want to implement the
org.dcm4che2.net.AssociationListener
interface to intercept association requests, along with the
org.dcm4che2.net.service.StorageService
class for the actual data transfer.