WPOCT Software Developer's Kit (SDK)
SDK For using Wasatch Photonics OCT Spectrometers
Dispersion.h
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include "OCTTypeDefs.h"
9 #include <boost/signals2.hpp>
10 #include <boost/bind.hpp>
11 #include <mutex>
12 #include "ScanProcessor.h"
13 
14 // Forward class declarations.
15 class ScanProcessor;
16 
18 {
19 public:
20  Dispersion (ScanProcessor* scanProcessor);
21 
22  virtual ~Dispersion ();
23 
24  bool CalcCoefficients (const unsigned short* inData, int inWidth,
25  int inHeight, float* coefficients);
26  bool SetOptimizationParameters (int numCoefficients, int maxIterations,
27  float* initialGuesses, int startLine,
28  int stopLine, int offset);
29  bool ComputeDispersionArray ();
30 
31  std::vector<float> GetCoefficients () { return _coefficients; }
32 
33  void GetCoefficients (float* coefficients);
34  bool SetCoefficients (const float *source, int len);
35  void ProcessChunk (int start, int stop, bool localPad, const SGL* inData,
36  SGL*& intensity, SGL*& interimData);
37 
38  virtual void InitGPUMethods (int programIndex) { }
39  virtual void OnWidthHeightChanged (int width, int height) { }
40  virtual bool SetDispersionArrays (float *dispersionPhi) { return false; }
41 
42  template<typename T>
43  void FringeMethodHilbert(const T* inData, T*& outData, T*& interimData)
44  {
45  int width = _scanProcessor->GetWidth();
46  // try splitting this computation up - need speed!
47  int c = 0;
48  int cSize = width / _numChunks;
49  bool isZeroPad = _scanProcessor->GetIsZeroPad();
50  //smessage("len "+i2S(_numChunks)+" cSize "+i2S(cSize));
51 
52  boost::thread_group threadGroup;
53  for (c = 0; c < _numChunks - 1; c++)
54  {
55  int cStart = c*cSize;
56  threadGroup.create_thread(boost::bind(&Dispersion::ProcessChunk, this, cStart,
57  cStart + cSize, isZeroPad, c, inData, outData, interimData));
58  }
59  int cStart = (_numChunks - 1)*cSize;
60  threadGroup.create_thread(boost::bind(&Dispersion::ProcessChunk, this, cStart, width,
61  isZeroPad, c, inData, outData, interimData));
62  threadGroup.join_all();
63  }
64 
65 protected:
66 
67  ScanProcessor* _scanProcessor;
68  bool _initialized;
69 
70  static std::mutex _mutexCorrect;
71 
72  virtual void InitStorage ();
73  virtual void ReleaseStorage () { }
74 
75  template<typename T>
76  void SumCorrectedPhase(T &corrPhase, int i)
77  {
78  if (_coefficients.size() == 0)
79  {
80  return;
81  }
82 
83  for (int order = 0; order < (int)_coefficients.size(); order++)
84  {
85  corrPhase += _coefficients[order] * ShiftedLegendrePolynomial<T>(order, i);
86  }
87  }
88 
89 private:
90  boost::signals2::connection _widthHeightConnection;
91 
92  // Dispersion vectors.
93  std::vector<float> _coefficients;
94  std::vector<float> _coefficientsBackup;
95 
96  std::vector<SGL> _dispersionArrayReal;
97  std::vector<SGL> _dispersionArrayImag;
98  std::vector<SGL> _dispersionArrayPhi;
99  std::vector<SGL> _interimData;
100  std::vector<float> _initialGuesses;
101 
102 
103  bool _findingDispCoeff;
104  int _numChunks; // size of threadpool for one frame
105  int _offset;
106  int _maxIterations;
107  int _numPolynomials;
108  UINT _startLine, _stopLine;
109 
110 
111  // Methods
112  void Init ();
113  void ReleaseDispersionArrays ();
114  int Compute (const unsigned short *raw, float *&interim, float *&outData);
115  void WriteDebugMessages (int numLines);
116  void BackupCoefficients ();
117  bool FindBestDispersion (const unsigned short* inData, int length, int numLines,
118  int width, int height, float* coefficients);
119  void CheckCandidates (float startingGuess, float increment, int ai,
120  std::vector<float>& coeffOfVariance,
121  const unsigned short* inData, SGL*& intensity,
122  int length, int numLines, int height,
123  std::vector<float>& sumOfVariance);
124  template<typename T>
125  T ShiftedLegendrePolynomial(int order, int x)
126  {
127  int height = _scanProcessor->GetHeight();
128  // use range [0,imageHeight - 1];
129  T y = (2 * x - (height - 1)) / (T)(height - 1);
130  T ans = 0;
131 
132  if (false)
133  {
134  return pow(y, order + 2);
135  }
136  else
137  {
138  switch (order)
139  {
140  case 0: //really 2
141  ans = (T)(0.5 * (3 * y * y - 1));
142  break;
143  case 1: // really 3
144  ans = (T)(0.5 * (5 * y * y * y - 3 * y));
145  break;
146  case 2: // 4
147  ans = (T)(0.125 *(35 * y * y * y * y - 30 * y * y + 3));
148  break;
149  case 3: // 5
150  ans = (T)(0.125 *(63 * y * y * y * y * y - 70 * y * y * y + 15 * y));
151  break;
152  case 4: //6
153  ans = (T)((1 / 16.0)*(231 * y * y * y * y * y * y - 315 * y * y * y * y + 105 * y * y - 5));
154  break;
155  default: //7
156  ans = (T)((1 / 16.0)*(429 * y * y * y * y * y * y * y - 693 * y * y * y * y * y + 315 *
157  y * y * y - 35 * y));
158  break;
159  }
160  }
161 
162  return ans;
163  }
164 };
typedefs used across UtensilConverter
Interface of the ScanProcessor class.
Definition: Dispersion.h:18
Class that processes scans.
Definition: ScanProcessor.h:32