Dcm4che从本地存档中删除研究(dicomdir) [英] Dcm4che delete study from local archive (dicomdir)

查看:105
本文介绍了Dcm4che从本地存档中删除研究(dicomdir)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在对dcm4che3和dicom协议进行了一些研究之后,重述了我的原始文章.

Rephrasing my original post after some research in dcm4che3 and dicom protocol.

我正在使用dcm4che3工具包来构建本质上将是简单的

I am using dcm4che3 toolkit to build an application that is essentially going to be a simple Image Archive able to forward studies on demand to other modalities.The tool also implements a s-store scu service to query itself but also other modalities.

一项要求是能够从此本地存档中定期删除"研究.

A requirement is to able and "delete" periodically studies from this local archive.

我也是dicom协议和dcm4che的新手,所以我试图理解底层dicomdir(由dcm4che-tool-dcmqrscp使用)的逻辑,以及用于删除研究的任何可用服务或方法.

I am also new to the dicom protocol and dcm4che, so i am trying to understand the logic of the underlying dicomdir (used by dcm4che-tool-dcmqrscp) as also any available services or methods for deleting studies.

所以我的问题如下:

  • 在dicom协议的上下文中,删除研究"一词是否有效?

  • In the context of dicom protocol is it valid the term: "Delete a study"?

我可以看到"dcm4che-tool-dcmdir "(使用该工具)时,实际上发生的事情是通过设置其Record In来从现有目录文件中删除引用由file ..或directory ..自变量指定的DICOM文件的记录.-use Flag = 0,因此文件保留在文件系统上.

As i can see the "dcm4che-tool-dcmdir" when deleting a study (using the tool), what happens actually is to "delete records referring DICOM files specified by file.. or directory.. arguments from existing directory file by setting its Record In-use Flag = 0" so the files remain on the filesystem.

当我使用c查找scu查询档案时,如果尝试以此方式删除研究(工具dicomdir中的-d选项),我可以找到研究>.因此,即使我对归档文件执行c查找查询,即使dicomdir中的记录被标记为不活动",我仍然可以将其提取.

Even more if i try and delete a study in this way (-d option in tool-dicomdir) when i query the archive with my c-find scu, i can find the study. So even if the record in dicomdir is marked as Inactive if i perform a c-find query to the archive i can still fetch it.

如果我尝试从文件系统中手动删除研究文件,我猜dicomdir损坏了.

If i try and delete study files manually from the filesystem i guess that the dicomdir becomes corrupted.

是否还有其他方法(或协议的一部分)以一致的方式从dicomdir中删除研究(永久地从dicomdir记录中删除,如果可能的话,还从文件系统中删除)?

Are there any other ways (or part of protocol) for deleting in consistent way a study (permanently from dicomdir records but also from filesystem if possibly) from the dicomdir?

我用于删除研究的代码(在dicomdir中使用带有-d选项的类似方法)是:

The code i use to delete the study (using similar approach with -d option in dicomdir) is:

public void deleteDicomDir(String studyDir) throws IOException {

        DcmDir1 main = new DcmDir1();

        long start = System.currentTimeMillis();
        LOG.info("$$$ Trying to delete dicomdir: " + studyDir);
        main.open(new File("C:\\dicomrouter_dev\\dcmrouter_root\\dicomdir"));
        main.removeReferenceTo(new File(studyDir));
        main.close();
        long end = System.currentTimeMillis();
        System.out.println();
        System.out.println(MessageFormat.format(
            rb.getString("deleted"),
            num, main.getFile(), (end - start)));
}

"removeReferenceTo()"方法的实际作用是在DicomDirWritter方法的末尾调用:

And what actually does the "removeReferenceTo()" method is calling at the end DicomDirWritter method:

public synchronized boolean deleteRecord(Attributes rec)
            throws IOException {
        if (rec.getInt(Tag.RecordInUseFlag, 0) == INACTIVE)
            return false; // already disabled

        for (Attributes lowerRec = readLowerDirectoryRecord(rec);
                lowerRec != null; 
                lowerRec = readNextDirectoryRecord(lowerRec))
            deleteRecord(lowerRec);

        rec.setInt(Tag.RecordInUseFlag, VR.US, INACTIVE);
        markAsDirty(rec);
        return true;
}

感谢您的宝贵时间,我期待可以声明这一点的任何信息

Thanks for your time and i am looking forward for any info that will declare this

实际上,在对dicom协议以及dcm4che工具包进行了一些研究之后,我能够删除记录并同步我的DICOMDIR,并通过3个步骤将Record in-use Flag = 0删除研究(或文件):

Actually after some research on dicom protocol as also dcm4che toolkit i am able to delete a study and synchonize my DICOMDIR and remove studies(or files) with Record In-use Flag = 0 in 3 steps:

//delete records referring DICOM files specified by <directory:studyDir> arguments from existing directory file <dicomdir> by setting its Record In-use Flag = 0
public void deleteDicomDir(String studyDir) {        
        String dicomdir = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
        DcmDir1 main = new DcmDir1();
        long start = System.currentTimeMillis();
        try {
            LOG.info("$$$ Trying to delete dicomdir: " + studyDir);
            main.open(new File(dicomdir));
            int num = 0;               
            main.removeReferenceTo(new File(studyDir));
            main.close();
            long end = System.currentTimeMillis();
            System.out.println();
            System.out.println(MessageFormat.format(
                rb.getString("deleted"),
                num, main.getFile(), (end - start)));
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
                main.close();
        }        
}


//purge records without file references from directory file <dicomdir> by setting its Record In-use Flag = 0
public void purgeDicomDir() {
        String dicomdir = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
        DcmDir1 main = new DcmDir1();
        long start = System.currentTimeMillis();
        try {
            main.open(new File(dicomdir));
            int num = main.purge();
            main.close();
            long end = System.currentTimeMillis();
            System.out.println(MessageFormat.format(
                rb.getString("purged"),
                num, main.getFile(), (end - start)));
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
                main.close();
        }  
}

//compact existing directory file <dicomdir> by removing records with Record In-use Flag != 0
public void compactDicomDir() {        
        String fpath = "C:\\dicomrouter_dev\\dcmrouter_root\\DICOMDIR";
        File f = new File(fpath);
        File bak = new File(fpath + "~");        
        DcmDir1 main = new DcmDir1();
        long start = System.currentTimeMillis();        
        try {
            LOG.info("$$$ Trying to compact dicomdir: " + fpath);
            main.compact(f, bak);
            long end = System.currentTimeMillis();
            System.out.println(MessageFormat.format(
                rb.getString("compacted"),
                f, bak.length(), f.length(), (end - start)));
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(DcmDir1.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
                main.close();
        }
}

然后,我也可以安全地从磁盘中删除文件.

Then i can also safely delete the files from the disk.

推荐答案

我已经在注释中向您说明了这一点(现已删除).我还向您指出了这个问题,该问题讨论了同一件事.正如我在评论中所说,这更多是关于协议而不是工具包.

I have already explained this to you in comments (now deleted). I have also pointed you to this question which discusses same thing. As I said in comments, this is more about protocol than toolkit.

第一件事,当您说删除研究"时,我假设您实际上是想从硬盘上删除DICOM文件,并将其引用放在其他位置(DICOMDIR或数据库等).

First thing, when you say "Delete a study", I assume you actually want to delete the DICOM files from the hard disk with their references in other (DICOMDIR or database etc) locations.

在DICOM中无法做到这一点.

There is no way to do this in DICOM.

N-DELETE命令不用于此目的.如答案中所述,您可以尝试

N-DELETE command in DICOM is not for this purpose. As explained in this answer, you may attempt Imaging Object Change Management IHE Integration Profile. I never used that; so sorry, I cannot comment on that further.

在dicom协议中,删除研究"一词是否有效?

In the context of dicom protocol is it valid the term: "Delete a study"?

正如我上面所说的;不.

As I said above; no.

正如我在删除研究(使用该工具)时看到的"dcm4che-tool-dcmdir"一样,实际上发生的是从现有目录文件中删除引用由file ..或directory ..参数指定的DICOM文件的记录.通过设置其记录使用中标志= 0",使文件保留在文件系统中.

As i can see the "dcm4che-tool-dcmdir" when deleting a study (using the tool), what happens actually is to "delete records referring DICOM files specified by file.. or directory.. arguments from existing directory file by setting its Record In-use Flag = 0" so the files remain on the filesystem.

这似乎很自然.该命令应只修改DICOMDIR即可删除文件.它不应从硬盘删除物理文件.

This seems natural. The command should just modify the DICOMDIR to remove the file. It should not delete the physical file from hard disk.

当我使用c查找scu查询档案时,如果我尝试以这种方式(在tool-dicomdir中使用-d选项)删除研究,则可以找到研究.因此,即使我对归档文件执行c查找查询,即使dicomdir中的记录被标记为不活动",我仍然可以将其提取.

Even more if i try and delete a study in this way (-d option in tool-dicomdir) when i query the archive with my c-find scu, i can find the study. So even if the record in dicomdir is marked as Inactive if i perform a c-find query to the archive i can still fetch it.

我不知道您的 C-FIND-RESPONSE 的来源.如果它本身是DICOMDIR,则很可能不会保存您在之前的步骤中所做的修改.保存所做的修改,它应该可以正常工作.但是请记住,这仍然不会从物理存储中删除文件.您只是删除它的引用.

I do not know what is the source of your C-FIND-RESPONSE. If it is DICOMDIR itself, most probably the modifications you did to it in earlier step are not saved. Save the modifications and that should work. But remember, this still will not delete the file from physical storage. You are just removing reference of it.

我不是您正在使用的工具包的专家.但是,在您的问题中包含以下代码:

I am not expert in the toolkit you are working with. But, with following code in your question:

main.open(new File("C:\\dicomrouter_dev\\dcmrouter_root\\dicomdir"));
main.removeReferenceTo(new File(studyDir));
//Check if you need to save the changes here before closing
main.close();

似乎您正在打开DICOMDIR-从中删除目录引用-关闭DICOMDIR.我不知道 removeReferenceTo 方法的实现;可能是来自>代码> DicomOutputStream 类即可.我在此处找到了以下示例代码:

it seems you are opening DICOMDIR -- removing the directory reference from it -- closing DICOMDIR. I do not know the implementation of removeReferenceTo method; may be it is from github. If it does not save the changes as well, you have to save the changes explicitly. May be you need to use DicomOutputStream class to do it. I found following sample code here:

FileOutputStream fos = new FileOutputStream(fileOutput +".dcm");
BufferedOutputStream bos = new BufferedOutputStream(fos);
DicomOutputStream dos = new DicomOutputStream(bos);
dos.writeDicomFile(dio);
dos.close();

如果我尝试从文件系统中手动删除研究文件,我猜dicomdir损坏了.

If i try and delete study files manually from the filesystem i guess that the dicomdir becomes corrupted.

是;这是正确的.为避免这种情况,还请相应地修改DICOMDIR.物理存储和DICOMDIR都应处于一致状态.

Yes; that's right. To avoid this, also modify DICOMDIR accordingly. Both, physical storage and DICOMDIR should be in consistent state.

建议-1:

  1. 确定应触发删除操作的事件/动作(发送给调用应用程序的C-STORE-SUCCESS可能是).您始终在应用程序中知道事件/操作已触发.
  2. 手动删除文件,或通过DICOM之外的一些代码删除文件.
  3. 更新基础引用(DICOMDIR,数据库等)以反映此更改(您所说的 -d 命令).
  4. 保存更改.以防万一您错过了这一步.
  5. 验证更改是否反映在引用中.在数据库上运行查询以检查记录.在某些DICOM加载程序/转储应用程序中加载DICOMDIR,并查看相关条目是否已消失.
  6. 尝试再次查询以查看其进展.

建议-2:

使用DICOM命令,实现自定义行为.修改DICOM命令的行为(可能为N-DELETE)以执行其他操作.这只有在您有权访问源代码并愿意更改它的情况下才有可能.我个人不建议这样做,因为:

Using DICOM Commands, implement the custom behavior. Modify the behavior of DICOM command (N-DELETE may be) to do your additional actions. This is only possible if you have access to source code and willing to change it. I personally do not recommend this because:

  • 这绝对不是DICOM.
  • 除了这样做,您始终可以在应用程序中实现相同的代码.

这篇关于Dcm4che从本地存档中删除研究(dicomdir)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆