Deleting of RT structures in lua

  • Dear Conquest&Lua users!



    I want to use lua scripting with conquest to process patient datasets (CT/RTDOSE/RTSTRUC/RTPLAN) exported from TPS before they are imported in R&V. E.g. I want to delete some help structures used during the planning. I take deletebody.lua as example and do the following:




    Code
    x = DicomObject:new()x.PatientName = ''x.PatientID = ''x.QueryRetrieveLevel = 'STUDY'x.StudyInstanceUID = '' -- you want these returned for the loopx.ModalitiesInStudy = ''b=dicomquery('CONQUESTSRV1', 'STUDY', x)for i=0, #b-1 do StudyUID = b[i].StudyInstanceUID Modality = b[i].Modality Modalities = b[i].ModalitiesInStudy print('Found ', b[i].PatientName, ' ', StudyUID, ' Modalities: ', Modalities, ' Modality: ', Modality) -- try to extract RTS if string.find(Modalities, "RTSTRUCT")~=NIL then local SeriesInst = dbquery('DICOMSeries', 'SeriesInst', 'StudyInsta = "'..StudyUID..'" and Modality = "RTSTRUCT"')[1][1] local StructSOP = dbquery('DICOMImages', 'SOPInstanc', 'SeriesInst = "'..SeriesInst..'"')[1][1] strucs = newdicomobject() strucs:Read(b[i].PatientID..':'..StructSOP); strucs:Dump('J:\\strucs0.txt') print(' strucs modality: ', strucs.Modality) -- loop over RTS print('#Structures:', #strucs.StructureSetROISequence) local roinumber, index for istruc=0, #strucs.StructureSetROISequence-1 do print(strucs.StructureSetROISequence[istruc].ROINumber, ' ', strucs.StructureSetROISequence[istruc].ROIName); -- find help contour if strucs.StructureSetROISequence[istruc].ROIName=='HC_Rektum' then roinumber = strucs.StructureSetROISequence[istruc].ROINumber index = istruc print(' Found ', strucs.StructureSetROISequence[istruc].ROIName, ' roi# ', roinumber, ' index ', index) end; -- if HC found end; -- istruc -- try to delete help contour print(' deleting in StructureSetROISequence') print(' before StructureSetROISequence[', index, ']:', strucs.StructureSetROISequence[index]) strucs.StructureSetROISequence[index]=nil print(' after StructureSetROISequence[', index, ']:', strucs.StructureSetROISequence[index]) print(' after StructureSetROISequence[', index, ']:', strucs.StructureSetROISequence[index]) print(' after StructureSetROISequence[', index, ']:', strucs.StructureSetROISequence[index]) for istruc=0, #strucs.ROIContourSequence-1 do if strucs.ROIContourSequence[istruc].ReferencedROINumber==roinumber then index = istruc print(' Found roi# ', roinumber, ' in ROIContourSequence, index ', index) end; end; print(' deleting in ROIContourSequence, index: ', index) strucs.ROIContourSequence[index]=0 for istruc=0, #strucs.RTROIObservationsSequence-1 do if strucs.RTROIObservationsSequence[istruc].ReferencedROINumber==roinumber then index = istruc print(' Found roi# ', roinumber, ' in RTROIObservationsSequence, index ', index) end; end; print(' deleting in RTROIObservationsSequence, index: ', index) strucs.RTROIObservationsSequence[index]=0 strucs:Dump('J:\\strucs1.txt') end; -- if RTSTRUCTend



    Here's the output from CONQUESTSRV1 (1.4.17d):



    Code
    [CONQUESTSRV1] UPACS THREAD 41: STARTED AT: Tue Nov 18 08:57:43 2014[CONQUESTSRV1] Calling Application Title : "CONQUESTSRV1 "[CONQUESTSRV1] Called Application Title : "CONQUESTSRV1 "[CONQUESTSRV1] Application Context : "1.2.840.10008.3.1.1.1", PDU length: 16384[CONQUESTSRV1] Presentation Context 0 "1.2.840.10008.5.1.4.1.2.2.1" 1[CONQUESTSRV1] (StudyRootQuery) search level: STUDY [CONQUESTSRV1] C-Find (StudyRoot) located 2 records[CONQUESTSRV1] UPACS THREAD 41: ENDED AT: Tue Nov 18 08:57:43 2014[CONQUESTSRV1] UPACS THREAD 41: TOTAL RUNNING TIME: 0 SECONDS[CONQUESTSRV1] Found HEAD EXP2 1.3.46.670589.5.2.10.2156913941.892665384.993397 Modalities: CT Modality: nil[CONQUESTSRV1] Found XXXX 1.3.12.2.1107.5.8.9.1010144715133114222.1008359 Modalities: RTSTRUCT\RTPLAN\RTDOSE\CT Modality: nil[CONQUESTSRV1] strucs modality: RTSTRUCT[CONQUESTSRV1] #Structures: 31[CONQUESTSRV1] 1 REF[CONQUESTSRV1] 2 1ISO[CONQUESTSRV1] 3 NORM[CONQUESTSRV1] 4 Rektum[CONQUESTSRV1] 5 Bladder[CONQUESTSRV1] 6 Hueftkopf li[CONQUESTSRV1] 7 Hueftkopf re[CONQUESTSRV1] 8 Prostatabett[CONQUESTSRV1] 9 Boost[CONQUESTSRV1] 10 PTV[CONQUESTSRV1] 11 TischModell_10mm[CONQUESTSRV1] 12 RV sine PTV[CONQUESTSRV1] 13 RV cum PTV[CONQUESTSRV1] 14 Blase-PTV[CONQUESTSRV1] 15 HC_Deckelung[CONQUESTSRV1] 16 HC_Rektum[CONQUESTSRV1] Found HC_Rektum roi# 16 index 15[CONQUESTSRV1] 17 h[CONQUESTSRV1] 18 HC_PTV_1-0[CONQUESTSRV1] 19 HC_PTV_2-1[CONQUESTSRV1] 20 Outline[CONQUESTSRV1] 21 Outline-0.5[CONQUESTSRV1] 22 Outline-(PTV+2)[CONQUESTSRV1] 23 _Boost-0.5[CONQUESTSRV1] 24 _Boost+0.5[CONQUESTSRV1] 25 _PTV-Boost[CONQUESTSRV1] 26 _(PTV-Boost)-0.5[CONQUESTSRV1] 27 _PTV-(Boost+0.5)[CONQUESTSRV1] 28 Grad[CONQUESTSRV1] 29 Boost-0.5[CONQUESTSRV1] 30 (PTV-Boost)-0.5[CONQUESTSRV1] 31 PTV-Boost[CONQUESTSRV1] deleting in StructureSetROISequence[CONQUESTSRV1] before StructureSetROISequence[ 15 ]: userdata:0253F8A0[CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:02542D10[CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:01278400[CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:0128E258[CONQUESTSRV1] Found roi# 16 in ROIContourSequence, index 15[CONQUESTSRV1] deleting in ROIContourSequence, index: 15[CONQUESTSRV1] Found roi# 16 in RTROIObservationsSequence, index 15[CONQUESTSRV1] deleting in RTROIObservationsSequence, index: 15


    Questions:
    1) The dumps in strucs0.txt and strucs1.txt are completely identical. The assignments of the kind:



    Code
    strucs.StructureSetROISequence[index]=nil



    do not seem to delete objects from memory. What am I doing wrong?


    2) I don't understand the result of consequtive print statements:



    Code
    [CONQUESTSRV1] deleting in StructureSetROISequence
    [CONQUESTSRV1] before StructureSetROISequence[ 15 ]: userdata:0253F8A0
    [CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:02542D10
    [CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:01278400
    [CONQUESTSRV1] after StructureSetROISequence[ 15 ]: userdata:0128E258



    What is "02542D10" in "userdata:02542D10"? If this is an object address, why does it differ from print statement to print statement?


    Any help and advice is highly appreciated!


    Kostya

  • Hi,


    I believe deleting sequence items is not implemented. You can delete items inside a sequence I think.


    The address chanegs every time because the lua wrapper around the dicom objects is created new everry time. The underlying data remains the same.


    Marcel

  • Hi Marcel,


    thank you very much for the reply. I was using deletebody.lua from the lua folder as an example, here is the original listing:


    Code
    -- This script delete the 'BODY' contour in RTSTRUCT--[[ To test; r-click evaluate in console after project-run:readdicom('c:\\data\\rtstruct.dcm')Data.Dump('c:\\data\\rtstruct_in.txt')dofile('deletebody.lua')Data.Dump('c:\\data\\rtstruct_out.txt')]]local roinumber, index, ifor i=0, #Data.StructureSetROISequence-1 do print('Found ', Data.StructureSetROISequence[i].ROINumber, ' ', Data.StructureSetROISequence[i].ROIName); if Data.StructureSetROISequence[i].ROIName=='BODY' then --print('Trying to delete ', Data.StructureSetROISequence[i].ROIName) roinumber = Data.StructureSetROISequence[i].ROINumber index = i endendData.StructureSetROISequence[index]=nilfor i=0, #Data.ROIContourSequence-1 do if Data.ROIContourSequence[i].ReferencedROINumber==roinumber then index = i endendData.ROIContourSequence[index]=nilfor i=0, #Data.RTROIObservationsSequence-1 do if Data.RTROIObservationsSequence[i].ReferencedROINumber==roinumber then index = i endendData.RTROIObservationsSequence[index]=nil


    It seems deleting sequence items should work, isn't it? Maybe there is special way this script should be called, smth like


    Code
    FileNameSyntax = lua:dofile('deletebody.lua')


    Kostya


  • Hi,


    the file should be called as:


    ImportConverter0 = deletebody.lua


    or


    [lua]
    ImportConverter0 = dofile('deletebody.lua')


    It then triggers on incoming data. I cannot remember the history of deletebody - it may not have been tested.


    Marcel

  • Marcel, thank you!


    I've put "ImportConverter0 = dofile('deletebody.lua')" in dicom.ini,
    istalled MIPAV 7.1.1 and tried to send RTS dicom to Conquest. The RTS file landed in Conquest withput changes:


    Code
    [CONQUESTSRV1] UPACS THREAD 7: STARTED AT: Mon Dec 01 15:07:41 2014
    [CONQUESTSRV1] Calling Application Title : "SampleStorage "
    [CONQUESTSRV1] Called Application Title : " CONQUESTSRV1 "
    [CONQUESTSRV1] Application Context : "1.2.840.10008.3.1.1.1", PDU length: 1024
    [CONQUESTSRV1] Presentation Context 0 "1.2.840.10008.5.1.4.1.1.481.3" 1
    [CONQUESTSRV1] No image number
    [CONQUESTSRV1] Written file: J:\soft\conquest\dicomserver1417d\data\2000195478\2.16.840.1.113669.2.931128.398608374.20141110102010.326622_0001_000000_14174428620003.dcm
    [CONQUESTSRV1] UPACS THREAD 7: ENDED AT: Mon Dec 01 15:07:42 2014
    [CONQUESTSRV1] UPACS THREAD 7: TOTAL RUNNING TIME: 1 SECONDS


    HC_Rektum contour is still there - I checked the dumps, and there were no printout messages from lua like "Found HC_Rektum", "Trying to delete HC_Rektum". Is dicom.ini a correct place to put [lua] code?


  • Hi Marcel,


    I can sent images/structures to conquest from MIPAV 7.1.1: the connection with conquest works and deletebody.lua gets called (I'm trying to delete HC_Rektum in this case):


    Code
    [CONQUESTSRV1] UPACS THREAD 3: STARTED AT: Tue Dec 02 08:21:56 2014[CONQUESTSRV1] Calling Application Title : "SampleStorage "[CONQUESTSRV1] Called Application Title : " CONQUESTSRV1 "[CONQUESTSRV1] Application Context : "1.2.840.10008.3.1.1.1", PDU length: 1024[CONQUESTSRV1] Presentation Context 0 "1.2.840.10008.5.1.4.1.1.481.3" 1[CONQUESTSRV1] Found 1 REF[CONQUESTSRV1] Found 2 1ISO[CONQUESTSRV1] Found 3 NORM[CONQUESTSRV1] Found 4 Rektum[CONQUESTSRV1] Found 5 Bladder[CONQUESTSRV1] Found 6 Hueftkopf li[CONQUESTSRV1] Found 7 Hueftkopf re[CONQUESTSRV1] Found 8 Prostatabett[CONQUESTSRV1] Found 9 Boost[CONQUESTSRV1] Found 10 PTV[CONQUESTSRV1] Found 11 TischModell_10mm[CONQUESTSRV1] Found 12 RV sine PTV[CONQUESTSRV1] Found 13 RV cum PTV[CONQUESTSRV1] Found 14 Blase-PTV[CONQUESTSRV1] Found 15 HC_Deckelung[CONQUESTSRV1] Found 16 HC_Rektum[CONQUESTSRV1] Trying to delete HC_Rektum[CONQUESTSRV1] Found 17 h[CONQUESTSRV1] Found 18 HC_PTV_1-0[CONQUESTSRV1] Found 19 HC_PTV_2-1[CONQUESTSRV1] Found 20 Outline[CONQUESTSRV1] Found 21 Outline-0.5[CONQUESTSRV1] Found 22 Outline-(PTV+2)[CONQUESTSRV1] Found 23 _Boost-0.5[CONQUESTSRV1] Found 24 _Boost+0.5[CONQUESTSRV1] Found 25 _PTV-Boost[CONQUESTSRV1] Found 26 _(PTV-Boost)-0.5[CONQUESTSRV1] Found 27 _PTV-(Boost+0.5)[CONQUESTSRV1] Found 28 Grad[CONQUESTSRV1] Found 29 Boost-0.5[CONQUESTSRV1] Found 30 (PTV-Boost)-0.5[CONQUESTSRV1] Found 31 PTV-Boost[CONQUESTSRV1] Rewritten file: J:\soft\conquest\dicomserver1417d\Data\2000195478\2.16.840.1.113669.2.931128.398608374.20141110102010.326622_0001_000000_14174428620003.dcm[CONQUESTSRV1] UPACS THREAD 3: ENDED AT: Tue Dec 02 08:21:58 2014[CONQUESTSRV1] UPACS THREAD 3: TOTAL RUNNING TIME: 2 SECONDS


    Here's once again the lua script I'm calling:





    Unfortunately HC_Rektum is still there at server side - I checked the dump. Are there plans to properly implement deleting sequence items? It could provide elegant solutions for some use cases.


    Thank you once again for the advices!


    Kostya



  • Hi Marcel and other Conquest users,


    were it possible to run python scripts on incoming data at server side?


    Thx
    Kostya



  • Hi,


    I was travelling. You can delete an entire sequence but not an item in a sequence I think (the script I posted was untested).


    Can you delete some stuff inside the sequence item to make it invalid?


    There is no way to call python.


    Marcel

  • Hy Marcel and others,


    I just wonder what's the present status: can lua delete sequence items now? And it seems one can now call python on server side? (http://forum.image-systems.biz/viewtopic.php?f=33&t=43580)


    Thanks in advance,
    Kostya


Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!