Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkUSDiPhASDevice.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkUSDiPhASDevice.h"
15 
16 mitk::USDiPhASDevice::USDiPhASDevice(std::string manufacturer, std::string model)
17  : mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USDiPhASProbesControls::New(this)),
18  m_ImageSource(mitk::USDiPhASImageSource::New(this)),
19  m_ControlInterfaceCustom(mitk::USDiPhASCustomControls::New(this)),
20  m_IsRunning(false),
21  m_BurstHalfwaveClockCount(7),
22  m_Interleaved(true)
23 {
25  this->SetNumberOfIndexedOutputs(m_NumberOfOutputs);
26 
27  SetNthOutput(0, this->MakeOutput(0));
28  SetNthOutput(1, this->MakeOutput(1));
29 }
30 
32 {
33 }
34 
35 //Gets
36 
38 {
39  return "org.mitk.modules.us.USDiPhASDevice";
40 }
41 
42 mitk::USControlInterfaceProbes::Pointer mitk::USDiPhASDevice::GetControlInterfaceProbes()
43 {
44  return m_ControlsProbes.GetPointer();
45 };
46 
47 mitk::USAbstractControlInterface::Pointer mitk::USDiPhASDevice::GetControlInterfaceCustom()
48 {
49  return m_ControlInterfaceCustom.GetPointer();
50 }
51 
52 mitk::USImageSource::Pointer mitk::USDiPhASDevice::GetUSImageSource()
53 {
54  return m_ImageSource.GetPointer();
55 }
56 
58 {
59  return m_ScanMode;
60 }
61 
62 // Setup and Cleanup
63 
65 {
66  return true;
67 }
68 
69 //----------------------------------------------------------------------------------------------------------------------------
70 /* ugly wrapper stuff - find better solution so it isn't necessary to create a global pointer to USDiPhASDevice...
71  * passing a lambda function would be nicer - sadly something goes wrong when passing the adress of a lambda function:
72  * the API produces access violations. Passing the Lambda function itself would be preferable, but that's not possible
73 */
74 
77 
78 void WrapperMessageCallback(const char* message)
79 {
80  w_device->MessageCallback(message);
81 }
82 
84  short* rfDataChannelData, int channelDatalinesPerDataset, int channelDataSamplesPerChannel, int channelDataTotalDatasets,
85  short* rfDataArrayBeamformed, int beamformedLines, int beamformedSamples, int beamformedTotalDatasets,
86  unsigned char* imageData, int imageWidth, int imageHeight, int imagePixelFormat, int imageSetsTotal, double timeStamp)
87 {
88  w_ISource->ImageDataCallback(
89  rfDataChannelData, channelDatalinesPerDataset, channelDataSamplesPerChannel, channelDataTotalDatasets,
90  rfDataArrayBeamformed, beamformedLines, beamformedSamples, beamformedTotalDatasets,
91  imageData, imageWidth, imageHeight, imagePixelFormat, imageSetsTotal, timeStamp);
92 }
93 
94 //----------------------------------------------------------------------------------------------------------------------------
95 
97 {
98  w_device = this;
99  w_ISource = m_ImageSource;
100  // Need those pointers for the forwarders to call member functions; createBeamformer expects non-member function pointers.
101  createBeamformer((StringMessageCallback)&WrapperMessageCallback, (NewDataCallback)&WrapperImageDataCallback);
102 
104  initBeamformer(); //start the hardware connection
105 
106  m_ImageSource->UpdateImageGeometry(); //make sure the image geometry is initialized!
107  // pass the new scanmode to the device:
108  setupScan(this->m_ScanMode);
109  return true;
110 }
111 
113 {
114  //close the beamformer so hardware is disconnected
115  closeBeamformer();
116  return true;
117 }
118 
120 {
121  // probe controls are available now
122  m_ControlsProbes->SetIsActive(true);
123 
124  if (m_ControlsProbes->GetProbesCount() < 1)
125  {
126  MITK_WARN("USDevice")("USDiPhASDevice") << "No probe found.";
127  return false;
128  }
129 
130  m_ControlsProbes->SelectProbe(0);
131 
132  // toggle the beamformer of the API
133  if(!m_IsRunning)
134  m_IsRunning=toggleFreeze();
135  return true;
136 }
137 
139 {
140  if(m_IsRunning)
141  m_IsRunning=toggleFreeze();
142  return true;
143 }
144 
146 {
147  if(m_IsRunning==freeze)
148  m_IsRunning=toggleFreeze(); // toggleFreeze() returns true if it starts running the beamformer, otherwise false
149 }
150 
152 {
153  OnFreeze(true);
154  SetInterleaved(m_Interleaved); // update the beamforming parameters...
156 
157  if (!(dynamic_cast<mitk::USDiPhASCustomControls*>(this->m_ControlInterfaceCustom.GetPointer())->GetSilentUpdate()))
158  {
159  setupScan(this->m_ScanMode);
160  m_ImageSource->UpdateImageGeometry();
161  }
162 
163  OnFreeze(false);
164 }
165 
167 {
168  int numChannels = m_ScanMode.reconstructionLines;
169 
170  // transmitEventsCount defines only the number of acoustic measurements (angles); there will be one event added to the start for OA measurement
171  m_ScanMode.TransmitEvents = new TransmitEventNative[m_ScanMode.transmitEventsCount];
172 
173  for (int ev = 0; ev < m_ScanMode.transmitEventsCount; ++ev)
174  {
175  m_ScanMode.TransmitEvents[ev].transmitEventDelays = new float[numChannels];
176  m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel = new int[numChannels];
177  m_ScanMode.TransmitEvents[ev].BurstCountPerChannel = new int[numChannels];
178  m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel = new bool[numChannels];
179  m_ScanMode.TransmitEvents[ev].ChannelMultiplexerSetups = nullptr;
180  float tiltStrength = ((m_ScanMode.transmitEventsCount - 1) / 2 - ev) * 20e-9f;
181 
182  for (int i = 0; i < numChannels; ++i)
183  {
184  m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel[i] = m_BurstHalfwaveClockCount; // 120 MHz / (2 * (predefinedBurstHalfwaveClockCount + 1)) --> 7.5 MHz
185  m_ScanMode.TransmitEvents[ev].BurstCountPerChannel[i] = 1; // Burst with 1 cycle
186  m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel[i] = true;
187  m_ScanMode.TransmitEvents[ev].transmitEventDelays[i] = 2e-6f + (i - numChannels / 2) * tiltStrength;
188  }
189  }
190 
191  m_ScanMode.transmitSequenceCount = 1;
192  m_ScanMode.transmitSequences = new SequenceNative[m_ScanMode.transmitSequenceCount];
193  m_ScanMode.transmitSequences[0].startEvent = 0;
194  m_ScanMode.transmitSequences[0].endEvent = m_ScanMode.transmitEventsCount;
195 }
196 
197 
198 
200 {
201  // create a scanmode to be used for measurements:
202  m_ScanMode.scanModeName = "InterleavedMode";
203 
204  // configure a linear transducer
205  m_ScanMode.transducerName = "L5-10";
206  m_ScanMode.transducerCurvedRadiusMeter = 0;
207  m_ScanMode.transducerElementCount = 128;
208  m_ScanMode.transducerFrequencyHz = 7500000;
209  m_ScanMode.transducerPitchMeter = 0.0003f;
210  m_ScanMode.transducerType = 1;
211 
212  // configure the receive paramters:
213  m_ScanMode.receivePhaseLengthSeconds = 185e-6f; // about 15 cm imaging depth
214  m_ScanMode.tgcdB = new unsigned char[8];
215  for (int tgc = 0; tgc < 8; ++tgc)
216  m_ScanMode.tgcdB[tgc] = tgc * 2 + 10;
217  m_ScanMode.accumulation = 1;
218  m_ScanMode.bandpassApply = false;
219  m_ScanMode.averagingCount = 1;
220 
221  // configure general processing:
222  m_ScanMode.transferChannelData = true;
223 
224  // configure reconstruction processing:
225  m_ScanMode.averageSpeedOfSound = 1540;
226  m_ScanMode.computeBeamforming = true;
227 
228  // setup beamforming parameters:
229  SetInterleaved(true);
230 
231  m_ScanMode.reconstructedLinePitchMmOrAngleDegree = 0.3f;
232  m_ScanMode.reconstructionLines = 128;
233  m_ScanMode.reconstructionSamplesPerLine = 2048;
234  m_ScanMode.transferBeamformedData = true;
235 
236  // configure the transmit sequence(s):
237  m_ScanMode.transmitEventsCount = 1;
238  m_ScanMode.transmitPhaseLengthSeconds = 1e-6f;
239  m_ScanMode.voltageV = 75;
241 
242  // configure bandpass:
243  m_ScanMode.bandpassApply = false;
244  m_ScanMode.bandpassFrequencyLowHz = 1e6f;
245  m_ScanMode.bandpassFrequencyHighHz = 20e6f;
246 
247  // configure image generation:
248  m_ScanMode.imageWidth = 512;
249  m_ScanMode.imageHeight = 512;
250  m_ScanMode.imageMultiplier = 1;
251  m_ScanMode.imageLeveling = 0;
252  m_ScanMode.transferImageData = false;
253 
254  // Trigger setup:
255  m_ScanMode.triggerSetup.enabled = true;
256  m_ScanMode.triggerSetup.constantPulseRepetitionRateHz = 20;
257  m_ScanMode.triggerSetup.triggerWidthMicroseconds = 15;
258  m_ScanMode.triggerSetup.delayTrigger2Microseconds = 300;
259 }
260 
261 // callback for the DiPhAS API
262 
263 void mitk::USDiPhASDevice::MessageCallback(const char* message)
264 {
265  MITK_INFO << "DiPhAS API: " << message << '\n';
266 }
267 
269 {
270  m_BurstHalfwaveClockCount = bursts;
271 }
272 
274 {
275  return m_Interleaved;
276 }
277 
279 {
280  m_Interleaved = interleaved;
281  if (interleaved) {
282  m_ScanMode.scanModeName = "Interleaved Beamforming Mode";
283  m_CurrentBeamformingAlgorithm = Beamforming::Interleaved_OA_US;
284 
285  paramsInterleaved.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound;
286  paramsInterleaved.angleSkipFactor = 1;
287  paramsInterleaved.OptoacousticDelay = 0.0000003; // 300ns
289 
290  m_ScanMode.beamformingAlgorithmParameters = &paramsInterleaved;
291  }
292  else {
293  m_ScanMode.scanModeName = "Plane Wave Beamforming Mode";
294  m_CurrentBeamformingAlgorithm = Beamforming::PlaneWaveCompound;
295 
296  paramsPlaneWave.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound;
297  paramsPlaneWave.angleSkipFactor = 0;
298  paramsPlaneWave.usePhaseCoherence = 0;
299 
300  m_ScanMode.beamformingAlgorithmParameters = &paramsPlaneWave;
301  }
302  m_ScanMode.beamformingAlgorithm = m_CurrentBeamformingAlgorithm;
303 }
void ImageDataCallback(short *rfDataChannelData, int &channelDataChannelsPerDataset, int &channelDataSamplesPerChannel, int &channelDataTotalDatasets, short *rfDataArrayBeamformed, int &beamformedLines, int &beamformedSamples, int &beamformedTotalDatasets, unsigned char *imageData, int &imageWidth, int &imageHeight, int &imagePixelFormat, int &imageSetsTotal, double &timeStamp)
Implementation of mitk::USControlInterfaceProbes for DiPhAS ultrasound devices. See documentation of ...
A device holds information about it&#39;s model, make and the connected probes. It is the common super cl...
Definition: mitkUSDevice.h:73
virtual bool OnActivation()
Is called during the activation process. After this method is finished, the device is generating imag...
BeamformingParametersPlaneWaveCompound paramsPlaneWave
itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) override
Make a DataObject of the correct type to used as the specified output.
#define MITK_INFO
Definition: mitkLogMacros.h:18
void WrapperMessageCallback(const char *message)
Implementation of mitk::USImageSource for DiPhAS API devices. The method mitk::USImageSource::GetNext...
mitk::USDiPhASImageSource::Pointer m_ImageSource
mitk::USDiPhASDevice * w_device
DataCollection - Class to facilitate loading/accessing structured data.
BeamformingParametersInterleaved_OA_US paramsInterleaved
Beamforming m_CurrentBeamformingAlgorithm
virtual bool OnConnection()
Is called during the connection process. Connect to the DiPhAS API.
virtual bool OnInitialization()
Is called during the initialization process. There is nothing done on the initialization of a mik::US...
USDiPhASDevice(std::string manufacturer, std::string model)
#define MITK_WARN
Definition: mitkLogMacros.h:19
void SetInterleaved(bool interleaved)
void MessageCallback(const char *message)
virtual bool OnDeactivation()
Is called during the deactivation process. After a call to this method the device is connected...
void SetBursts(int bursts)
unsigned int m_NumberOfOutputs
Definition: mitkUSDevice.h:503
USDiPhASProbesControls::Pointer m_ControlsProbes
USImageSource::Pointer GetUSImageSource()
virtual USControlInterfaceProbes::Pointer GetControlInterfaceProbes()
Default getter for the probes control interface. Has to be implemented in a subclass if a probes cont...
ScanModeNative & GetScanMode()
virtual void OnFreeze(bool freeze)
Changes scan state of the device if freeze is toggeled in mitk::USDevice.
virtual std::string GetDeviceClass()
Returns the class of the device.
virtual bool OnDisconnection()
Is called during the disconnection process. Deactivate and remove all DiPhAS API controls. A disconnect from the DiPhAS API is not possible for which reason the hardware stays in connected state even after calling this method.
mitk::USDiPhASImageSource * w_ISource
virtual itk::SmartPointer< USAbstractControlInterface > GetControlInterfaceCustom()
Default getter for the custom control interface. Has to be implemented in a subclass if a custom cont...
void WrapperImageDataCallback(short *rfDataChannelData, int channelDatalinesPerDataset, int channelDataSamplesPerChannel, int channelDataTotalDatasets, short *rfDataArrayBeamformed, int beamformedLines, int beamformedSamples, int beamformedTotalDatasets, unsigned char *imageData, int imageWidth, int imageHeight, int imagePixelFormat, int imageSetsTotal, double timeStamp)
itk::SmartPointer< USAbstractControlInterface > m_ControlInterfaceCustom