[Rtk-users] Elekta XVI 5.0 XML reader
Yang K Park
theday79 at gmail.com
Sat May 16 00:14:51 CEST 2015
Hi RTK developers,
Regarding Rune’s request, I’ve coded rtkElektaXVI5GeometryXMLFile.h and rtkElektaXVI5GeometryXMLFile.cxx (as attached) to import “_Frame.xml” file from XVI 5.0.
Testing is successfully done with my RTK but I don’t have a commitment authority. Would anyone please commit them to the repository?
The way to use it is quite similar to ThreeDCircularProjectionGeometryXMLFileReader class. (actually, the new ones are coded with the back-bone of ThreeDCircularProjectionGeometryXMLFileReader)
For example, in rtkfdk example,
1) #include "rtkElektaXVI5GeometryXMLFile.h"
2) Replace the following codes:
rtk::ThreeDCircularProjectionGeometryXMLFileReader::Pointer geometryReader;
geometryReader = rtk::ThreeDCircularProjectionGeometryXMLFileReader::New();
with following codes:
rtk::ElektaXVI5GeometryXMLFileReader::Pointer geometryReader;
geometryReader = rtk::ElektaXVI5GeometryXMLFileReader::New();
Please let me know if there is any issue or bug.
Thanks.
Yang
From: Yang K Park [mailto:theday79 at gmail.com]
Sent: Friday, May 15, 2015 9:57 AM
To: 'Rune Slot Thing'; rtk-users at public.kitware.com
Subject: RE: [Rtk-users] New version of Eletka XVI software (5.0.2) no longer uses .DBF files
Hi Rune,
Our hospital has successfully installed XVI 5.0.2 last December and it is working fine now.
The most interesting feature is, the XVI can stream the kV images to any 3rd party client with ~5 Hz frame via Gigabit network (if the project streaming feature is purchased.) This feature also can be used while MV beam is on.
Regarding the geometry file, what the difference from the previous one is, from now on there is an individual xml file containing all the geometry information as well as other useful information such as beam-on flag (kV, MV) and acquisition time stamp. This file is saved in each projection directory, not a root folder. Therefore, we no longer need to backup FRAME.DBF and IMAGE.DBF files. However, SAD and SID information is not included in this xml file so we are using fixed values for them (SAD = 1000 mm, SID = 1536 mm), which I believe is identical to every XVI system.
Regarding the RTK compatibility, we’ve implemented a reader for the new xml file by using a Qt library in our in-house CBCT software based on RTK. So, it is working fine for us. However, since Qt is not a part of the official RTK I was planning to implement it using itk but not yet done. (It has been on my to-do-list for a long time, but I should confess my laziness :()
I’m going to resume working on soon and will keep you posted if any achievement is made.
(If it is urgent, I can also send you our compiled in-house software just in case.)
Or feel free to contribute to the development if you are interested in. I’m attaching a sample of the new xml file.
Congratulations on your new XVI system!
Yang
p.s. Hello RTK developers,
I have been a mere user of RTK and never have committed any code to the repository. May I have the commitment authority or can I send my files to someone who might be in charge of update? Thanks.
From: Rune Slot Thing [mailto:Rune.Slot.Thing at rsyd.dk]
Sent: Tuesday, May 12, 2015 3:19 AM
To: 'Yang Kyun Park'; rtk-users at public.kitware.com <mailto:rtk-users at public.kitware.com>
Subject: SV: [Rtk-users] New version of Eletka XVI software (5.0.2) no longer uses .DBF files
Dear all,
Following up on this question from November last year, has anyone succeeded in creating a geometry reader for the new Elekta XVI 5.0 system? We are facing the upgrade next week, and are very interested in any and all experiences with the new format and RTK, whether the code is part of the official RTK or not.
Thanks in advance, all help will be much appreciated.
Best regards,
Rune Slot Thing
PhD Student
Institute of Clinical Research, University of Southern Denmark
Laboratory of Radiation Physics, Odense University Hospital
<mailto:rune.slot.thing at rsyd.dk> rune.slot.thing at rsyd.dk
Fra: Rtk-users [ <mailto:rtk-users-bounces at public.kitware.com> mailto:rtk-users-bounces at public.kitware.com] På vegne af Yang Kyun Park
Sendt: 11. november 2014 16:53
Til: 'Simon Rit'
Cc: <mailto:rtk-users at public.kitware.com> rtk-users at public.kitware.com
Emne: Re: [Rtk-users] New version of Eletka XVI software (5.0.2) no longer uses .DBF files
Hi Simon,
I feel some responsibilities for it if I’m the first user/reporter of the new XVI system.
Let me try to figure it out.
Thanks.
Yang
From: <mailto:simon.rit at gmail.com> simon.rit at gmail.com [ <mailto:simon.rit at gmail.com> mailto:simon.rit at gmail.com] On Behalf Of Simon Rit
Sent: Tuesday, November 11, 2014 3:24 AM
To: Yang Kyun Park
Cc: <mailto:rtk-users at public.kitware.com> rtk-users at public.kitware.com
Subject: Re: [Rtk-users] New version of Eletka XVI software (5.0.2) no longer uses .DBF files
Hi Yang,
I knew this was coming but you are the first one to report it to me. This is actually good news because the DBF reader was far from efficient and SQL is easier. Would you be willing to try to develop a new reader? I'm sure there are many portable SQL readers that could help us.
Simon
On Mon, Nov 10, 2014 at 11:37 PM, Yang Kyun Park <theday79 at gmail.com <mailto:theday79 at gmail.com> > wrote:
Hi all,
I’ve been successfully using “ElektaSynergyGeometryReader” class to extract the CBCT geometry from our Elekta database files (IMAGE.DBF and FRAME.DBF).
Recently, our Elekta XVI systems are under upgrade and I found that this latest version of XVI (v 5.0.2) no longer uses those DBF files. Instead, there seems to be some .sql files that contains those geometry information.
I’m wondering if some of you are also “suffering” from this upgrade or having any ideas about this issue.
Thanks.
Yang
_______________________________________________
Rtk-users mailing list
Rtk-users at public.kitware.com <mailto:Rtk-users at public.kitware.com>
http://public.kitware.com/mailman/listinfo/rtk-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.creatis.insa-lyon.fr/pipermail/rtk-users/attachments/20150515/d7416b29/attachment.htm>
-------------- next part --------------
/*=========================================================================
*
* Copyright RTK Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef _rtkElektaXVI5GeometryXMLFile_cxx
#define _rtkElektaXVI5GeometryXMLFile_cxx
#include "rtkElektaXVI5GeometryXMLFile.h"
#include <itksys/SystemTools.hxx>
#include <itkMetaDataObject.h>
#include <itkIOCommon.h>
#include <iomanip>
namespace rtk
{
ElektaXVI5GeometryXMLFileReader::
ElektaXVI5GeometryXMLFileReader() :
m_Geometry(GeometryType::New() ),
m_CurCharacterData(""),
m_InPlaneAngle(0.),
m_OutOfPlaneAngle(0.),
m_GantryAngle(0.),
m_SourceToIsocenterDistance(1000.),
m_SourceOffsetX(0.),
m_SourceOffsetY(0.),
m_SourceToDetectorDistance(1536.),
m_ProjectionOffsetX(0.),
m_ProjectionOffsetY(0.),
m_Version(0)
{
this->m_OutputObject = &(*m_Geometry);
}
int
ElektaXVI5GeometryXMLFileReader::
CanReadFile(const char *name)
{
if(!itksys::SystemTools::FileExists(name) ||
itksys::SystemTools::FileIsDirectory(name) ||
itksys::SystemTools::FileLength(name) == 0)
return 0;
return 1;
}
void
ElektaXVI5GeometryXMLFileReader::
StartElement(const char * name,const char **atts)
{
m_CurCharacterData = "";
this->StartElement(name);
}
void
ElektaXVI5GeometryXMLFileReader::
StartElement(const char * itkNotUsed(name))
{
}
void
ElektaXVI5GeometryXMLFileReader::
EndElement(const char *name)
{
if (itksys::SystemTools::Strucmp(name, "GantryAngle") == 0 ||
itksys::SystemTools::Strucmp(name, "Angle") == 0) // Second one for backward compatibility
{
m_GantryAngle = atof(this->m_CurCharacterData.c_str());
if (m_GantryAngle < 0)
m_GantryAngle = m_GantryAngle + 360.0;
}
//Regarding PanelOffset, XVI5 specifies position of the center(UCentre, VCentre) instead of offset.
//Therefore, negation is required to get classical m_ProjectionOffsetX and m_ProjectionOffsetY values.
if (itksys::SystemTools::Strucmp(name, "UCentre") == 0)
m_ProjectionOffsetX = atof(this->m_CurCharacterData.c_str()) * -1.0;
if (itksys::SystemTools::Strucmp(name, "VCentre") == 0)
{
m_ProjectionOffsetY = atof(this->m_CurCharacterData.c_str()) * -1.0;
}
if (itksys::SystemTools::Strucmp(name, "Frame") == 0)
{
this->m_OutputObject->AddProjection(m_SourceToIsocenterDistance,
m_SourceToDetectorDistance,
m_GantryAngle,
m_ProjectionOffsetX,
m_ProjectionOffsetY,
m_OutOfPlaneAngle,
m_InPlaneAngle,
m_SourceOffsetX,
m_SourceOffsetY);
}
}
void
ElektaXVI5GeometryXMLFileReader::
CharacterDataHandler(const char *inData, int inLength)
{
for(int i = 0; i < inLength; i++)
m_CurCharacterData = m_CurCharacterData + inData[i];
}
}
#endif
-------------- next part --------------
/*=========================================================================
*
* Copyright RTK Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef __rtkElektaXVI5GeometryXMLFile_h
#define __rtkElektaXVI5GeometryXMLFile_h
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "rtkWin32Header.h"
#include <itkXMLFile.h>
#include "rtkThreeDCircularProjectionGeometry.h"
namespace rtk
{
/** \class ElektaXVI5GeometryXMLFileReader
*
* Reads an XML-format file of XVI version = 5.0.2 (_Frame.xml in each projection directory). From XVI_v5 on, thre is no need of accessing .DBF files (FRAME.DBF / IMAGE.DBF).
* This class is basically inspired by ThreeDCircularProjectionGeometryXMLFileReader.
* Writer is not implemented.
* SAD = 1000 mm, SID = 1536 mm are hard-coded since _Frame.xml doesn't include these values.
* Regarding PanelOffset, XVI5 specifies position of the center (UCentre, VCentre) instead of offset.
* Therefore, negation is required to get classical m_ProjectionOffsetX and m_ProjectionOffsetY values.
* \contributed by Yang K Park (theday79 at gmail.com), 2015/05/15
*
* \ingroup IOFilters
*/
class RTK_EXPORT ElektaXVI5GeometryXMLFileReader :
public itk::XMLReader< ThreeDCircularProjectionGeometry >
{
public:
/** Standard typedefs */
typedef ElektaXVI5GeometryXMLFileReader Self;
typedef itk::XMLReader< ThreeDCircularProjectionGeometry > Superclass;
typedef itk::SmartPointer<Self> Pointer;
/** Convenient typedefs */
typedef ThreeDCircularProjectionGeometry GeometryType;
typedef GeometryType::Pointer GeometryPointer;
/** Latest version */
static const unsigned int CurrentVersion = 2;
/** Run-time type information (and related methods). */
itkTypeMacro(ElektaXVI5GeometryXMLFileReader, itk::XMLFileReader);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Determine if a file can be read */
int CanReadFile(const char* name);
/** Get smart pointer to projection geometry. */
itkGetMacro(Geometry, GeometryPointer);
protected:
ElektaXVI5GeometryXMLFileReader();
~ElektaXVI5GeometryXMLFileReader() { };
/** Callback function -- called from XML parser with start-of-element
* information.
*/
void StartElement(const char * name,const char **atts);
void StartElement(const char * name);
void EndElement(const char *name);
void CharacterDataHandler(const char *inData, int inLength);
private:
//purposely not implemented
ElektaXVI5GeometryXMLFileReader(const Self&);
void operator=(const Self&);
GeometryPointer m_Geometry;
std::string m_CurCharacterData;
/** Projection parameters */
double m_InPlaneAngle;
double m_OutOfPlaneAngle;
double m_GantryAngle;
double m_SourceToIsocenterDistance;
double m_SourceOffsetX;
double m_SourceOffsetY;
double m_SourceToDetectorDistance;
double m_ProjectionOffsetX;
double m_ProjectionOffsetY;
/** Projection matrix */
ThreeDCircularProjectionGeometry::MatrixType m_Matrix;
/** File format version */
unsigned int m_Version;
};
}
#endif
-------------- next part --------------
#=========================================================
# Propagate cmake options in a header file
CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/rtkConfiguration.h.in
${CMAKE_BINARY_DIR}/rtkConfiguration.h)
SET (RTK_LIBRARIES RTK lpsolve55)
#=========================================================
#=========================================================
ADD_LIBRARY(RTK
rtkHisImageIO.cxx
rtkHisImageIOFactory.cxx
rtkElektaSynergyGeometryReader.cxx
rtkDbf.cxx
rtkHndImageIO.cxx
rtkHndImageIOFactory.cxx
rtkVarianObiXMLFileReader.cxx
rtkVarianObiGeometryReader.cxx
rtkEdfImageIO.cxx
rtkEdfImageIOFactory.cxx
rtkImagXImageIO.cxx
rtkImagXImageIOFactory.cxx
rtkDCMImagXImageIO.cxx
rtkDCMImagXImageIOFactory.cxx
rtkImagXXMLFileReader.cxx
rtkThreeDCircularProjectionGeometry.cxx
rtkReg23ProjectionGeometry.cxx
rtkThreeDCircularProjectionGeometryXMLFile.cxx
rtkGeometricPhantomFileReader.cxx
rtkDigisensGeometryXMLFileReader.cxx
rtkDigisensGeometryReader.cxx
rtkXRadGeometryReader.cxx
rtkXRadImageIO.cxx
rtkXRadImageIOFactory.cxx
rtkIOFactories.cxx
rtkConvertEllipsoidToQuadricParametersFunction.cxx
rtkElektaXVI5GeometryXMLFile.cxx)
TARGET_LINK_LIBRARIES(RTK ${ITK_LIBRARIES})
TARGET_LINK_LIBRARIES(RTK lpsolve55)
#=========================================================
#=========================================================
# OpenCL library stuff
IF(RTK_USE_OPENCL)
SET(RTK_LIBRARIES ${RTK_LIBRARIES} rtkopencl)
ADD_LIBRARY(rtkopencl
rtkOpenCLUtilities.cxx
rtkOpenCLFDKBackProjectionImageFilter.cxx)
TARGET_LINK_LIBRARIES(rtkopencl ${OPENCL_LIBRARIES} ${ITK_LIBRARIES})
FILE(GLOB openclSRCs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cl)
ADD_CUSTOM_TARGET(openclSRCCopy ALL COMMENT "Copying OpenCL source files")
FOREACH(openclSRC ${openclSRCs})
ADD_CUSTOM_COMMAND(TARGET openclSRCCopy
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${openclSRC}
${RTK_BINARY_DIR}/${openclSRC})
ENDFOREACH(openclSRC)
ADD_DEPENDENCIES(rtkopencl openclSRCCopy)
ENDIF(RTK_USE_OPENCL)
#=========================================================
#=========================================================
# Cuda library stuff
IF (RTK_USE_CUDA)
SET (RTK_LIBRARIES ${RTK_LIBRARIES} rtkcuda)
SET (rtkcuda_CUDA_FILES
rtkCudaCropImageFilter.cu
rtkCudaUtilities.cu
rtkCudaFDKBackProjectionImageFilter.cu
rtkCudaFFTConvolutionImageFilter.cu
rtkCudaFDKWeightProjectionFilter.cu
rtkCudaDisplacedDetectorImageFilter.cu
rtkCudaParkerShortScanImageFilter.cu
rtkCudaForwardProjectionImageFilter.cu
rtkCudaBackProjectionImageFilter.cu
rtkCudaSplatImageFilter.cu
rtkCudaInterpolateImageFilter.cu
rtkCudaWarpImageFilter.cu
rtkCudaForwardWarpImageFilter.cu
rtkCudaRayCastBackProjectionImageFilter.cu
rtkCudaTotalVariationDenoisingBPDQImageFilter.cu
rtkCudaLastDimensionTVDenoisingImageFilter.cu
rtkCudaConstantVolumeSource.cu
rtkCudaConstantVolumeSeriesSource.cu
rtkCudaConjugateGradientImageFilter_3f.cu
rtkCudaConjugateGradientImageFilter_4f.cu
rtkCudaAverageOutOfROIImageFilter.cu
)
# This is a fix for ITK4 to avoid too long cmd lines error
# (http://www.itk.org/Bug/view.php?id=12198)
IF(WIN32)
GET_DIRECTORY_PROPERTY(dirInc INCLUDE_DIRECTORIES)
FIND_PATH(itkMacroPath itkMacro.h ${dirInc})
FIND_PATH(itkConfigurePath itkConfigure.h ${dirInc})
FIND_PATH(rtkConfigurationPath rtkConfiguration.h ${dirInc})
SET_DIRECTORY_PROPERTIES(PROPERTIES INCLUDE_DIRECTORIES "${itkMacroPath};${itkConfigurePath};${rtkConfigurationPath}")
ENDIF()
CUDA_COMPILE (rtkcuda_CUDA_WRAPPERS ${rtkcuda_CUDA_FILES})
# Rollback to all includes
IF(WIN32)
SET_DIRECTORY_PROPERTIES(PROPERTIES INCLUDE_DIRECTORIES "${dirInc}")
ENDIF()
ADD_LIBRARY(rtkcuda
rtkCudaFDKWeightProjectionFilter.cxx
rtkCudaDisplacedDetectorImageFilter.cxx
rtkCudaParkerShortScanImageFilter.cxx
rtkCudaCropImageFilter.cxx
rtkCudaFDKBackProjectionImageFilter.cxx
rtkCudaFDKConeBeamReconstructionFilter.cxx
rtkCudaBackProjectionImageFilter.cxx
rtkCudaSplatImageFilter.cxx
rtkCudaInterpolateImageFilter.cxx
rtkCudaWarpImageFilter.cxx
rtkCudaForwardWarpImageFilter.cxx
rtkCudaRayCastBackProjectionImageFilter.cxx
rtkCudaTotalVariationDenoisingBPDQImageFilter.cxx
rtkCudaLastDimensionTVDenoisingImageFilter.cxx
rtkCudaConstantVolumeSource.cxx
rtkCudaConstantVolumeSeriesSource.cxx
rtkCudaConjugateGradientImageFilter_3f.cxx
rtkCudaConjugateGradientImageFilter_4f.cxx
rtkCudaAverageOutOfROIImageFilter.cxx
${rtkcuda_CUDA_WRAPPERS}
${rtkcuda_CUDA_FILES})
SET_TARGET_PROPERTIES (rtkcuda PROPERTIES LINKER_LANGUAGE CXX)
TARGET_LINK_LIBRARIES(rtkcuda ${CUDA_LIBRARIES} ${CUDA_cufft_LIBRARY} ${CUDA_cublas_LIBRARY} RTK ITKCudaCommon)
ENDIF (RTK_USE_CUDA)
#=========================================================
#=========================================================
# Installation code
IF(NOT RTK_INSTALL_NO_DEVELOPMENT)
# Generate RTKConfig.cmake for the install tree.
SET (RTK_USE_FILE "${CMAKE_INSTALL_PREFIX}/${RTK_INSTALL_PACKAGE_DIR}/UseRTK.cmake")
SET (RTK_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/${RTK_INSTALL_INCLUDE_DIR};${CMAKE_INSTALL_PREFIX}/${RTK_INSTALL_INCLUDE_DIR}/lpsolve")
SET (RTK_LIBRARY_DIRS "${CMAKE_INSTALL_PREFIX}/${RTK_INSTALL_LIB_DIR}")
CONFIGURE_FILE (${PROJECT_SOURCE_DIR}/cmake/RTKConfig.cmake.in ${RTK_BINARY_DIR}/CMakeFiles/RTKConfig.cmake @ONLY)
INSTALL(FILES ${RTK_BINARY_DIR}/CMakeFiles/RTKConfig.cmake
${RTK_SOURCE_DIR}/cmake/UseRTK.cmake
DESTINATION ${RTK_INSTALL_PACKAGE_DIR})
# Include .h and .txx files
FILE(GLOB __files1 "${PROJECT_SOURCE_DIR}/code/*.h")
FILE(GLOB __files2 "${PROJECT_SOURCE_DIR}/code/*.txx")
INSTALL(FILES ${__files1} ${__files2} ${RTK_BINARY_DIR}/rtkConfiguration.h
DESTINATION ${RTK_INSTALL_INCLUDE_DIR}
COMPONENT Development)
ENDIF(NOT RTK_INSTALL_NO_DEVELOPMENT)
IF(NOT RTK_INSTALL_NO_LIBRARIES)
INSTALL(TARGETS RTK
RUNTIME DESTINATION ${RTK_INSTALL_RUNTIME_DIR} COMPONENT Runtime
LIBRARY DESTINATION ${RTK_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${RTK_INSTALL_ARCHIVE_DIR} COMPONENT Development)
IF(RTK_USE_CUDA)
INSTALL(TARGETS rtkcuda
RUNTIME DESTINATION ${RTK_INSTALL_RUNTIME_DIR} COMPONENT Runtime
LIBRARY DESTINATION ${RTK_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${RTK_INSTALL_ARCHIVE_DIR} COMPONENT Development)
ENDIF(RTK_USE_CUDA)
IF(OPENCL_FOUND)
INSTALL(TARGETS rtkopencl
RUNTIME DESTINATION ${RTK_INSTALL_RUNTIME_DIR} COMPONENT Runtime
LIBRARY DESTINATION ${RTK_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${RTK_INSTALL_ARCHIVE_DIR} COMPONENT Development)
ENDIF(OPENCL_FOUND)
ENDIF(NOT RTK_INSTALL_NO_LIBRARIES)
#=========================================================
SET(RTK_LIBRARIES ${RTK_LIBRARIES} PARENT_SCOPE)
More information about the Rtk-users
mailing list