ctkDICOMTester.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QDebug>
  16. #include <QDir>
  17. #include <QFileInfo>
  18. #include <QProcess>
  19. #include <QTextStream>
  20. // ctkDICOM includes
  21. #include "ctkDICOMTester.h"
  22. #include "ctkLogger.h"
  23. //------------------------------------------------------------------------------
  24. static ctkLogger logger("org.commontk.dicom.DICOMTester" );
  25. //------------------------------------------------------------------------------
  26. //------------------------------------------------------------------------------
  27. class ctkDICOMTesterPrivate
  28. {
  29. Q_DECLARE_PUBLIC(ctkDICOMTester);
  30. protected:
  31. ctkDICOMTester* const q_ptr;
  32. public:
  33. ctkDICOMTesterPrivate(ctkDICOMTester&);
  34. ~ctkDICOMTesterPrivate();
  35. QString findFile(const QStringList& nameFilters, const QString& subDir)const;
  36. QString findDCMQRSCPExecutable()const;
  37. QString findDCMQRSCPConfigFile()const;
  38. QString findStoreSCUExecutable()const;
  39. void printProcessOutputs(const QString& program, QProcess* process)const;
  40. QProcess* DCMQRSCPProcess;
  41. QString DCMQRSCPExecutable;
  42. QString DCMQRSCPConfigFile;
  43. int DCMQRSCPPort;
  44. QString StoreSCUExecutable;
  45. };
  46. //------------------------------------------------------------------------------
  47. // ctkDICOMTesterPrivate methods
  48. //------------------------------------------------------------------------------
  49. ctkDICOMTesterPrivate::ctkDICOMTesterPrivate(ctkDICOMTester& o): q_ptr(&o)
  50. {
  51. this->DCMQRSCPProcess = 0;
  52. this->DCMQRSCPExecutable = this->findDCMQRSCPExecutable();
  53. this->DCMQRSCPConfigFile = this->findDCMQRSCPConfigFile();
  54. this->DCMQRSCPPort = 11112;
  55. this->StoreSCUExecutable = this->findStoreSCUExecutable();
  56. }
  57. //------------------------------------------------------------------------------
  58. ctkDICOMTesterPrivate::~ctkDICOMTesterPrivate()
  59. {
  60. delete this->DCMQRSCPProcess;
  61. this->DCMQRSCPProcess = 0;
  62. }
  63. //------------------------------------------------------------------------------
  64. QString ctkDICOMTesterPrivate::findFile(const QStringList& nameFilters, const QString& subDir)const
  65. {
  66. // Search in the build tree first
  67. QDir searchDir = QDir::current();
  68. do
  69. {
  70. QFileInfo dcmExecutables(searchDir, subDir);
  71. if (dcmExecutables.isDir() &&
  72. dcmExecutables.exists())
  73. {
  74. QDir bin(dcmExecutables.absoluteFilePath());
  75. QFileInfoList found = bin.entryInfoList(nameFilters, QDir::Files);
  76. if (found.count() > 0)
  77. {
  78. return found[0].absoluteFilePath();
  79. }
  80. }
  81. }
  82. while (searchDir.cdUp())
  83. ;
  84. // TODO: take care of the installed case
  85. return QString();
  86. }
  87. //------------------------------------------------------------------------------
  88. QString ctkDICOMTesterPrivate::findDCMQRSCPExecutable()const
  89. {
  90. return this->findFile(QStringList("dcmqrscp*"), "CMakeExternals/Install/bin");
  91. }
  92. //------------------------------------------------------------------------------
  93. QString ctkDICOMTesterPrivate::findDCMQRSCPConfigFile()const
  94. {
  95. return this->findFile(QStringList("dcmqrscp.cfg"), "Libs/DICOM/Core");
  96. }
  97. //------------------------------------------------------------------------------
  98. QString ctkDICOMTesterPrivate::findStoreSCUExecutable()const
  99. {
  100. return this->findFile(QStringList("storescu*"), "CMakeExternals/Install/bin");
  101. }
  102. //------------------------------------------------------------------------------
  103. void ctkDICOMTesterPrivate::printProcessOutputs(const QString& program, QProcess* process)const
  104. {
  105. QTextStream out(stdout);
  106. out << "Process " << program << " is finished.\n";
  107. QByteArray standardOutput = process->readAllStandardOutput();
  108. if (standardOutput.count())
  109. {
  110. out << "Standard Output:\n";
  111. out << standardOutput;
  112. }
  113. QByteArray standardError = process->readAllStandardError();
  114. if (standardError.count())
  115. {
  116. out << "Standard Error:\n";
  117. out << standardError;
  118. }
  119. }
  120. //------------------------------------------------------------------------------
  121. // ctkDICOMTester methods
  122. //------------------------------------------------------------------------------
  123. ctkDICOMTester::ctkDICOMTester(QObject* parentObject)
  124. : QObject(parentObject)
  125. , d_ptr(new ctkDICOMTesterPrivate(*this))
  126. {
  127. }
  128. //------------------------------------------------------------------------------
  129. ctkDICOMTester::ctkDICOMTester(const QString& dcmqrscp,
  130. const QString& configFile,
  131. QObject* parentObject)
  132. : QObject(parentObject)
  133. , d_ptr(new ctkDICOMTesterPrivate(*this))
  134. {
  135. this->setDCMQRSCPExecutable(dcmqrscp);
  136. this->setDCMQRSCPConfigFile(configFile);
  137. }
  138. //------------------------------------------------------------------------------
  139. ctkDICOMTester::~ctkDICOMTester()
  140. {
  141. // just in case
  142. this->stopDCMQRSCP();
  143. }
  144. //------------------------------------------------------------------------------
  145. void ctkDICOMTester::setDCMQRSCPExecutable(const QString& dcmqrscp)
  146. {
  147. Q_D(ctkDICOMTester);
  148. d->DCMQRSCPExecutable = dcmqrscp;
  149. }
  150. //------------------------------------------------------------------------------
  151. QString ctkDICOMTester::dcmqrscpExecutable()const
  152. {
  153. Q_D(const ctkDICOMTester);
  154. return d->DCMQRSCPExecutable;
  155. }
  156. //------------------------------------------------------------------------------
  157. void ctkDICOMTester::setDCMQRSCPConfigFile(const QString& configFile)
  158. {
  159. Q_D(ctkDICOMTester);
  160. d->DCMQRSCPConfigFile = configFile;
  161. }
  162. //------------------------------------------------------------------------------
  163. QString ctkDICOMTester::dcmqrscpConfigFile()const
  164. {
  165. Q_D(const ctkDICOMTester);
  166. return d->DCMQRSCPConfigFile;
  167. }
  168. //------------------------------------------------------------------------------
  169. void ctkDICOMTester::setStoreSCUExecutable(const QString& storeSCU)
  170. {
  171. Q_D(ctkDICOMTester);
  172. d->StoreSCUExecutable = storeSCU;
  173. }
  174. //------------------------------------------------------------------------------
  175. QString ctkDICOMTester::storeSCUExecutable()const
  176. {
  177. Q_D(const ctkDICOMTester);
  178. return d->StoreSCUExecutable;
  179. }
  180. //------------------------------------------------------------------------------
  181. void ctkDICOMTester::setDCMQRSCPPort(int port)
  182. {
  183. Q_D(ctkDICOMTester);
  184. d->DCMQRSCPPort = port;
  185. }
  186. //------------------------------------------------------------------------------
  187. int ctkDICOMTester::dcmqrscpPort()const
  188. {
  189. Q_D(const ctkDICOMTester);
  190. return d->DCMQRSCPPort;
  191. }
  192. //------------------------------------------------------------------------------
  193. QProcess* ctkDICOMTester::startDCMQRSCP()
  194. {
  195. Q_D(ctkDICOMTester);
  196. if (d->DCMQRSCPProcess)
  197. {
  198. return 0;
  199. }
  200. d->DCMQRSCPProcess = new QProcess(this);
  201. QStringList dcmqrscpArgs;
  202. if (!d->DCMQRSCPConfigFile.isEmpty())
  203. {
  204. dcmqrscpArgs << "--config" << d->DCMQRSCPConfigFile;
  205. }
  206. //dcmqrscp_args << "--debug" << "--verbose";
  207. dcmqrscpArgs << QString::number(d->DCMQRSCPPort);
  208. d->DCMQRSCPProcess->start(d->DCMQRSCPExecutable, dcmqrscpArgs);
  209. d->DCMQRSCPProcess->waitForStarted(-1);
  210. return d->DCMQRSCPProcess;
  211. }
  212. //------------------------------------------------------------------------------
  213. bool ctkDICOMTester::stopDCMQRSCP()
  214. {
  215. Q_D(ctkDICOMTester);
  216. if (!d->DCMQRSCPProcess)
  217. {
  218. return false;
  219. }
  220. d->DCMQRSCPProcess->kill();
  221. bool res = d->DCMQRSCPProcess->waitForFinished(-1);
  222. d->printProcessOutputs("DCMQRSCP", d->DCMQRSCPProcess);
  223. delete d->DCMQRSCPProcess;
  224. d->DCMQRSCPProcess = 0;
  225. return res;
  226. }
  227. //------------------------------------------------------------------------------
  228. bool ctkDICOMTester::storeData(const QStringList& data)
  229. {
  230. Q_D(ctkDICOMTester);
  231. if (data.count() == 0)
  232. {
  233. return true;
  234. }
  235. // There is no point of calling storescu if no-one is listening
  236. if (!d->DCMQRSCPProcess)
  237. {
  238. return false;
  239. }
  240. QProcess storeSCU(this);
  241. // usage of storescu:
  242. // storescu -aec CTK_AE -aet CTK_AE localhost 11112 ./CMakeExternals/Source/CTKData/Data/DICOM/MRHEAD/*.IMA
  243. QStringList storescuArgs;
  244. storescuArgs << "-aec" << "CTK_AE";
  245. storescuArgs << "-aet" << "CTK_AE";
  246. storescuArgs << "localhost" << QString::number(d->DCMQRSCPPort);
  247. storescuArgs << data;
  248. storeSCU.start(d->StoreSCUExecutable, storescuArgs);
  249. bool res = storeSCU.waitForFinished(-1);
  250. d->printProcessOutputs("StoreSCU", &storeSCU);
  251. return res;
  252. }