Come già osservato, BasicDicomObject è cronologico, insieme a molti altri.
Il nuovo "oggetto Dicom" è Attributi - un oggetto è una raccolta di attributi.
Pertanto, si creano Attributi, si compilano con i tag necessari per RQ-comportamento (C-FIND, ecc.) E ciò che si ottiene in cambio è un altro oggetto Attributi da cui si estraggono i tag desiderati.
A mio parere, dcm4che 2.x era vago sul tema della gestione delle rappresentazioni dei valori individuali. dcm4che 3.x è abbastanza più chiaro.
La migrazione richiede una riscrittura del codice per quanto riguarda la query e il trattamento dei singoli tag. D'altra parte, dcm4che 3.x rende il nuovo codice meno complicato.
Un esempio abbastanza completo, recupero degli studi da un PACS dati i numeri di accesso; impostazione della query e gestione del risultato:
String modality = null;
String accessionNumber = "1234567890";
//--------------------------------------------------------
// HERE follows setup of a query, using an Attributes object
//--------------------------------------------------------
Attributes query = new Attributes();
// Indicate character set
{
int tag = Tag.SpecificCharacterSet;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, "ISO_IR 100");
}
// Study level query
{
int tag = Tag.QueryRetrieveLevel;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, "STUDY");
}
// Accession number
{
int tag = Tag.AccessionNumber;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setString(tag, vr, accessionNumber);
}
// Optionally filter on modality in study if 'modality' is provided,
// otherwise retrieve modality
{
int tag = Tag.ModalitiesInStudy;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
if (null != modality && modality.length() > 0) {
query.setString(tag, vr, modality);
} else {
query.setNull(tag, vr);
}
}
// We are interested in study instance UID
{
int tag = Tag.StudyInstanceUID;
VR vr = ElementDictionary.vrOf(tag, query.getPrivateCreator(tag));
query.setNull(tag, vr);
}
// Do the actual query, needing an AppliationEntity (ae),
// a local (local) and remote (remote) Connection, and
// an AAssociateRQ (rq) set up earlier.
// 1) Open a connection to the SCP
Association as = ae.connect(local, remote, rq);
// 2) Query
int priority = 0x0002; // low for the sake of demo :)
as.cfind(UID.StudyRootQueryRetrieveInformationModelFIND, query, null,
new DimseRSPHandler(as.nextMessageID()) {
@Override
public void onDimseRSP(Association assoc, Attributes cmd,
Attributes response) {
super.onDimseRSP(assoc, cmd, response);
int status = cmd.getInt(Tag.Status, -1);
if (Status.isPending(status)) {
//--------------------------------------------------------
// HERE follows handling of the response, which
// is just another Attributes object
//--------------------------------------------------------
String studyInstanceUID = response.getString(Tag.StudyInstanceUID);
// etc...
}
}
});
// 3) Close the connection to the SCP
if (as != null && as.isReadyForDataTransfer()) {
as.waitForOutstandingRSP();
as.release();
as = null;
}