QTrk
lv_queuetrk_api.cpp
Go to the documentation of this file.
1 
5 #include "std_incl.h"
6 #include "utils.h"
7 #include "labview.h"
8 #include "QueuedTracker.h"
9 #include "threads.h"
10 
11 #include "lv_qtrk_api.h"
12 
13 #include "ResultManager.h"
14 #include "FisherMatrix.h"
15 #include "BeadFinder.h"
16 
18 static std::vector<QueuedTracker*> trackerList;
19 
21 {
22  trackerListMutex.lock();
23  DeleteAllElems(trackerList);
24  trackerListMutex.unlock();
25 }
26 
27 void SetLVString (LStrHandle str, const char *text)
28 {
29  int msglen = strlen(text);
30  MgErr err = NumericArrayResize(uB, 1, (UHandle*)&str, msglen);
31  if (!err)
32  {
33  MoveBlock(text, LStrBuf(*str), msglen);
34  LStrLen(*str) = msglen;
35  }
36 }
37 
38 std::vector<std::string> LVGetStringArray(int count, LStrHandle *str)
39 {
40  std::vector<std::string> result(count);
41 
42  for (int x=0;x<count;x++) {
43  uChar *val = LHStrBuf(str[x]);
44  int len = LHStrLen (str[x]);
45  result[x]=std::string((const char*)val, (size_t)len );
46  }
47  return result;
48 }
49 
50 MgErr FillErrorCluster(MgErr err, const char *message, ErrorCluster *error)
51 {
52  if (err)
53  {
54  error->status = LVBooleanTrue;
55  error->code = err;
56  SetLVString ( error->message, message );
57  }
58  return err;
59 }
60 
61 void ArgumentErrorMsg(ErrorCluster* e, const std::string& msg)
62 {
63  FillErrorCluster(mgArgErr, msg.c_str(), e);
64 }
65 
66 bool ValidateTracker(QueuedTracker* tracker, ErrorCluster* e, const char *funcname)
67 {
68  if (std::find(trackerList.begin(), trackerList.end(), tracker)==trackerList.end()) {
69  ArgumentErrorMsg(e, SPrintf("QTrk C++ function %s called with invalid tracker pointer: %p", funcname, tracker));
70  return false;
71  }
72  return true;
73 }
74 
76 {
77  int w,h;
78  if (ValidateTracker(qtrk, e, "qtrk_get_debug_image")) {
79  float* img;
80  if (qtrk->GetDebugImage(id, &w,&h, &img)) {
81  ResizeLVArray2D(data, h, w);
82  for (int i=0;i<w*h;i++) (*data)->elem[i]=img[i];
83  delete[] img;
84  return 1;
85  }
86  }
87  return 0;
88 }
89 
91 {
92  dbgsetlogfile(path);
93 }
94 
96 {
97  if (ValidateTracker(qtrk, err, "get computed config"))
98  *cc = qtrk->cfg;
99 }
100 
102 {
103  LVArray3D<float>* zlut = *pZlut;
104 
105  if (ValidateTracker(tracker,e, "set ZLUT")) {
106 
107  int numLUTs = zlut->dimSizes[0];
108  int planes = zlut->dimSizes[1];
109  int res = zlut->dimSizes[2];
110 
111  dbgprintf("Setting ZLUT size: %d beads, %d planes, %d radialsteps\n", numLUTs, planes, res);
112 
113  float* zcmp = 0;
114  if (zcmpWindow && (*zcmpWindow)->dimSize > 0) {
115  if ( (*zcmpWindow)->dimSize != res)
116  ArgumentErrorMsg(e, SPrintf("Z Compare window should have the same resolution as the ZLUT (%d elements)", res));
117  else
118  zcmp = (*zcmpWindow)->elem;
119  }
120 
121  if (numLUTs * planes * res == 0) {
122  tracker->SetRadialZLUT(0, 0, 0);
123  } else {
124  if (res != tracker->cfg.zlut_radialsteps)
125  ArgumentErrorMsg(e, SPrintf("set_ZLUT: 3rd dimension should have size of zlut_radialsteps (%d instead of %d)", tracker->cfg.zlut_radialsteps, res));
126  else {
127 
128  if (normalize) {
129  NormalizeZLUT( zlut->elem, numLUTs, planes, res );
130  }
131 
132  tracker->SetRadialZLUT(zlut->elem, numLUTs, planes);
133  tracker->SetRadialWeights(zcmp);
134  }
135  }
136  }
137 }
138 
140 {
141  if (ValidateTracker(tracker, e, "get ZLUT")) {
142  int dims[3];
143 
144  tracker->GetRadialZLUTSize(dims[0], dims[1], dims[2]);
145  if(dims[0]*dims[1]*dims[2]>0) {
146  ResizeLVArray3D(pzlut, dims[0], dims[1], dims[2]);
147  tracker->GetRadialZLUT( (*pzlut)->elem );
148  }
149  }
150 }
151 
153 {
154  if (ValidateTracker(qtrk, e, "get_image_lut")) {
155 
156  int dims[4];
157  qtrk->GetImageZLUTSize(dims);
158  ResizeLVArray(imageLUT, dims);
159 
160  if ( (*imageLUT)->numElem () > 0 ){
161  qtrk->GetImageZLUT( (*imageLUT)->elem );
162  }
163  }
164 }
165 
167 {
168  if (ValidateTracker(qtrk, e, "set_image_lut")) {
169  if ( (*imageLUT)->numElem () == 0 ){
170  qtrk->SetImageZLUT (0, 0, 0);
171  }
172  else {
173  qtrk->SetImageZLUT( (*imageLUT)->elem, (*radialZLUT)->elem, (*imageLUT)->dimSizes );
174  }
175  }
176 }
177 
178 CDLL_EXPORT void DLL_CALLCONV qtrk_set_pixel_calib_factors(QueuedTracker* qtrk, float offsetFactor, float gainFactor, ErrorCluster* e)
179 {
180  if (ValidateTracker(qtrk, e, "set pixel calib factors")) {
181  qtrk->SetPixelCalibrationFactors(offsetFactor, gainFactor);
182  }
183 }
184 
186 {
187  if (ValidateTracker(qtrk, e, "set pixel calibration images")) {
188  int count, planes, radialSteps;
189  qtrk->GetRadialZLUTSize(count, planes, radialSteps);
190 
191  float *offset_data = 0, *gain_data = 0;
192 
193  if((*offset)->dimSizes[0] != 0) {
194  if (qtrk->cfg.width != (*offset)->dimSizes[2] || qtrk->cfg.height != (*offset)->dimSizes[1]) {
195  ArgumentErrorMsg(e, SPrintf("set_pixel_calib: Offset images passed with invalid dimension (%d,%d)", (*offset)->dimSizes[2], (*offset)->dimSizes[1]));
196  return;
197  }
198  if (count != (*offset)->dimSizes[0]) {
199  ArgumentErrorMsg(e, SPrintf("set_pixel_calib: Expecting offset to have %d images (same as ZLUT). %d given", count, (*offset)->dimSizes[0]));
200  return;
201  }
202  offset_data = (*offset)->elem;
203  }
204 
205  if((*gain)->dimSizes[0] != 0) {
206  if (qtrk->cfg.width != (*gain)->dimSizes[2] || qtrk->cfg.height != (*gain)->dimSizes[1]) {
207  ArgumentErrorMsg(e, SPrintf("set_pixel_calib: Gain images passed with invalid dimension (%d,%d)", (*gain)->dimSizes[2], (*gain)->dimSizes[1]));
208  return;
209  }
210  if (count != (*gain)->dimSizes[0]) {
211  ArgumentErrorMsg(e, SPrintf("set_pixel_calib: Expecting gain to have %d images (same as ZLUT). %d given", count, (*gain)->dimSizes[0]));
212  return;
213  }
214  gain_data = (*gain)->elem;
215  }
216 
217  qtrk->SetPixelCalibrationImages(offset_data, gain_data);
218  }
219 }
220 
221 CDLL_EXPORT QueuedTracker* qtrk_create(QTrkSettings* settings, LStrHandle warnings, ErrorCluster* e)
222 {
223  QueuedTracker* tracker = 0;
224  try {
225  QTrkComputedConfig cc(*settings);
226  cc.WriteToLog();
227 
228  tracker = CreateQueuedTracker(cc);
229 
230  std::string w = tracker->GetWarnings();
231  if (!w.empty()) SetLVString(warnings, w.c_str());
232 
233  trackerListMutex.lock();
234  trackerList.push_back(tracker);
235  trackerListMutex.unlock();
236  } catch(const std::runtime_error &exc) {
237  FillErrorCluster(kAppErrorBase, exc.what(), e );
238  }
239  return tracker;
240 }
241 
243 {
244  trackerListMutex.lock();
245 
246  auto pos = std::find(trackerList.begin(),trackerList.end(),qtrk);
247  if (pos == trackerList.end()) {
248  ArgumentErrorMsg(error, SPrintf( "Trying to call qtrk_destroy with invalid qtrk pointer %p", qtrk));
249  qtrk = 0;
250  }
251  else
252  trackerList.erase(pos);
253 
254  trackerListMutex.unlock();
255 
256  if(qtrk) delete qtrk;
257 }
258 
259 template<typename T>
261 {
262  if (!data) {
263  ArgumentErrorMsg(error, "Image data array is empty");
264  return false;
265  } else if( (*data)->dimSizes[1] != qtrk->cfg.width || (*data)->dimSizes[0] != qtrk->cfg.height ) {
266  ArgumentErrorMsg(error, SPrintf( "Image data array has wrong size (%d,%d). Should be: (%d,%d)", (*data)->dimSizes[1], (*data)->dimSizes[0], qtrk->cfg.width, qtrk->cfg.height));
267  return false;
268  }
269  return true;
270 }
271 
273 {
274  if (CheckImageInput(qtrk, data, error))
275  {
276  qtrk->ScheduleLocalization( (uchar*)(*data)->elem, sizeof(ushort)*(*data)->dimSizes[1], QTrkU16, jobInfo);
277  }
278 }
279 
281 {
282  if (CheckImageInput(qtrk, data, error))
283  {
284 #ifdef _DEBUG
285  //dbgprintf("Job: 8bit image, frame %d, bead %d\n", jobInfo->frame, jobInfo->zlutIndex);
286 #endif
287 
288  qtrk->ScheduleLocalization( (*data)->elem, sizeof(uchar)*(*data)->dimSizes[1], QTrkU8, jobInfo);
289  }
290 }
291 
293 {
294  if (CheckImageInput(qtrk, data, error))
295  {
296  qtrk->ScheduleLocalization( (uchar*) (*data)->elem, sizeof(float)*(*data)->dimSizes[1], QTrkFloat, jobInfo);
297  }
298 }
299 
300 
301 CDLL_EXPORT void qtrk_queue_pitchedmem(QueuedTracker* qtrk, uchar* data, int pitch, uint pdt, const LocalizationJob *jobInfo)
302 {
303  qtrk->ScheduleLocalization(data, pitch, (QTRK_PixelDataType)pdt, jobInfo);
304 }
305 
307 {
308  uint pitch;
309 
310  if (pdt == QTrkFloat)
311  pitch = sizeof(float);
312  else if(pdt == QTrkU16)
313  pitch = 2;
314  else pitch = 1;
315 
316  if (!CheckImageInput(qtrk, data, error))
317  return;
318 
319  pitch *= (*data)->dimSizes[1]; // LVArray2D<uchar> type works for ushort and float as well
320 // dbgprintf("zlutindex: %d, zlutplane: %d\n", zlutIndex,zlutPlane);
321  qtrk_queue_pitchedmem(qtrk, (*data)->elem, pitch, pdt, jobInfo);
322 }
323 
325 {
326  if (w*h<4) return 0;
327 
328  uint ts;
329  uchar *timestamp = (uchar*)&ts;
330  // Assume little endian only
331  for (int i=0;i<4;i++)
332  timestamp[i] = image[i];
333  return ts;
334 }
335 
336 CDLL_EXPORT uint qtrk_queue_frame(QueuedTracker* qtrk, uchar* image, int pitch, int w,int h,
337  uint pdt, ROIPosition* pos, int numROI, const LocalizationJob *pJobInfo, QueueFrameFlags flags, ErrorCluster* e)
338 {
339  LocalizationJob jobInfo = *pJobInfo;
340  int nQueued;
341  if ( (nQueued=qtrk->ScheduleFrame(image, pitch, w,h, pos, numROI, (QTRK_PixelDataType)pdt, &jobInfo)) != numROI) {
342  ArgumentErrorMsg(e, SPrintf( "Not all ROIs (%d out of %d) were queued. Check image borders vs ROIs.", nQueued, numROI));
343  }
344  return jobInfo.timestamp;
345 }
346 
348 {
349  if (ValidateTracker(qtrk, e, "clear results")) {
350  qtrk->ClearResults();
351  }
352 }
353 
354 // Accepts data as 3D image [numbeads]*[width]*[height]
356 {
357  if (ValidateTracker(qtrk, err, "build_lut_plane")) {
358  if ((*data)->dimSizes[2] != qtrk->cfg.width || (*data)->dimSizes[1] != qtrk->cfg.height) {
359  ArgumentErrorMsg(err, SPrintf("Invalid size: %dx%d. Expecting %dx%d\n", (*data)->dimSizes[2], (*data)->dimSizes[1], qtrk->cfg.width, qtrk->cfg.height));
360  return;
361  }
362 
363  int cnt,planes,rsteps;
364  qtrk->GetRadialZLUTSize(cnt, planes, rsteps);
365 
366  if ((*data)->dimSizes[0] != cnt) {
367  ArgumentErrorMsg(err, SPrintf("Invalid number of images given (%d). Expecting %d", (*data)->dimSizes[0], cnt));
368  return;
369  }
370 
371  qtrk->BuildLUT( (*data)->elem, sizeof(float*) * qtrk->cfg.width, QTrkFloat, plane);
372  }
373 }
374 
376 {
377  if (ValidateTracker(qtrk, e, "finalize_lut"))
378  qtrk->FinalizeLUT();
379 }
380 
381 
383 {
384  if (ValidateTracker(qtrk, e, "fullqueue"))
385  return qtrk->GetQueueLength(maxQueueLen);
386  return 0;
387 }
388 
390 {
391  if (ValidateTracker(qtrk, e, "resultcount")) {
392  return qtrk->GetResultCount();
393  }
394  return 0;
395 }
396 
398 {
399  if (ValidateTracker(qtrk, e, "flush")) {
400  qtrk->Flush();
401  }
402 }
403 
404 CDLL_EXPORT int qtrk_get_results(QueuedTracker* qtrk, LocalizationResult* results, int maxResults, int sortByID, ErrorCluster* e)
405 {
406  if (ValidateTracker(qtrk, e, "get_results")) {
407  int resultCount = qtrk->FetchResults(results, maxResults);
408 
409  if (sortByID) {
410  std::sort(results, results+resultCount, [](decltype(*results) a, decltype(*results) b) { return a.job.frame<b.job.frame; } );
411  }
412 
413  return resultCount;
414  }
415  return 0;
416 }
417 
419 {
420  if (ValidateTracker(qtrk, e, "get zlut compare profiles"))
421  {
422  int cnt,planes,rsteps;
423  qtrk->GetRadialZLUTSize(cnt,planes,rsteps);
424  ResizeLVArray2D(output, cnt, planes);
425 
426  qtrk->GetRadialZLUTCompareProfile((*output)->elem);
427  }
428 }
429 
431 {
432  if (ValidateTracker(qtrk, e, "enable zlut cmpprof"))
433  qtrk->EnableRadialZLUTCompareProfile(enable);
434 }
435 
436 
438 {
439  if (ValidateTracker(qtrk, e, "set_localization_mode")) {
440  qtrk->SetLocalizationMode( (LocMode_t)locType );
441  }
442 }
443 
445 {
446  if (ValidateTracker(qtrk, e, "is_idle"))
447  return qtrk->IsIdle() ? 1 : 0;
448  return 0;
449 }
450 
451 CDLL_EXPORT void qtrk_compute_zlut_bias_table(QueuedTracker* qtrk, int bias_planes, LVArray2D<float>** lvresult, int smpPerPixel, int useSplineInterp,ErrorCluster* e)
452 {
453  if(ValidateTracker(qtrk, e,"compute_zlut_bias_table")) {
454  CImageData result;
455  qtrk->ComputeZBiasCorrection(bias_planes, &result, smpPerPixel, useSplineInterp!=0);
456 
457  ResizeLVArray2D(lvresult, result.h, result.w);
458  result.copyTo ( (*lvresult)->elem );
459  }
460 }
461 
463 {
464  if (ValidateTracker(qtrk, e,"set zlut bias table")) {
465  int numbeads,planes,radialsteps;
466  qtrk->GetRadialZLUTSize(numbeads, planes, radialsteps);
467 
468  if ((*biastbl)->dimSizes[1] != numbeads) {
469  ArgumentErrorMsg(e, SPrintf( "Bias table should be [numbeads] high and [biasplanes] wide. Expected #beads=%d", numbeads) );
470  }
471  else {
472  qtrk->SetZLUTBiasCorrection( ImageData( (*biastbl)->elem, (*biastbl)->dimSizes[0], (*biastbl)->dimSizes[1] ) );
473  }
474  }
475 }
476 
477 CDLL_EXPORT void DLL_CALLCONV qtrk_generate_gaussian_spot(LVArray2D<float>** image, vector2f* pos, float sigma, float I0, float Ibg, int applyNoise)
478 {
479  ImageData img((*image)->elem, (*image)->dimSizes[1], (*image)->dimSizes[0]);
480 
481  GenerateGaussianSpotImage(&img, *pos, sigma, I0, Ibg);
482 
483  if (applyNoise)
484  ApplyPoissonNoise(img,1);
485 }
486 
488  float *LUTradii, vector2f* position, float z, float M, float sigma_noise)
489 {
490  ImageData img((*image)->elem, (*image)->dimSizes[1], (*image)->dimSizes[0]);
491  ImageData zlut((*lut)->elem, (*lut)->dimSizes[1], (*lut)->dimSizes[0]);
492 
493  vector3f pos (position->x, position->y, z);
494  GenerateImageFromLUT(&img, &zlut, LUTradii[0], LUTradii[1], pos);
495  //img.normalize();
496  if(sigma_noise>0)
497  ApplyGaussianNoise(img, sigma_noise);
498 }
499 
500 
502 {
503 #ifdef USE_MEMDBG
504  _CrtDumpMemoryLeaks();
505 #endif
506 }
507 
509 {
510  SetLVString(str, qtrk->GetProfileReport().c_str());
511 }
512 
513 
515  LVArray2D<float> ** inverseMatrix, vector3f* xyzVariance, int Nsamples, float maxPixelValue)
516 {
517  QTrkComputedConfig cc (*cfg);
518  ImageData lutImg( (*lut)->elem, (*lut)->dimSizes[1], (*lut)->dimSizes[0] );
519  SampleFisherMatrix fm(maxPixelValue);
520  Matrix3X3 mat = fm.ComputeAverageFisher(*pos, Nsamples, vector3f(1,1,1), vector3f(1,1,1)*0.001f, cfg->width, cfg->height, [&](ImageData&out, vector3f pos) {
521  GenerateImageFromLUT(&out, &lutImg, cc.zlut_minradius,cc.zlut_maxradius, pos);
522  });
523 
524  if (fisherMatrix) {
525  ResizeLVArray2D( fisherMatrix, 3, 3);
526  for (int i=0;i<9;i++)
527  (*fisherMatrix)->elem[i] = mat[i];
528  }
529 
530  if (inverseMatrix) {
531  Matrix3X3 inv = mat.Inverse();
532  ResizeLVArray2D( inverseMatrix, 3, 3);
533  for (int i=0;i<9;i++)
534  (*inverseMatrix)->elem[i] = inv[i];
535  }
536 
537  if (xyzVariance)
538  *xyzVariance = mat.Inverse().diag();
539 }
540 
541 
542 CDLL_EXPORT void qtrk_find_beads(uint8_t* image, int pitch, int w,int h, int* smpCornerPos, int roi, float imgRelDist, float acceptance, LVArray2D<uint32_t> **output)
543 {
544  BeadFinder::Config cfg;
545  cfg.img_distance = imgRelDist;
546  cfg.roi = roi;
547  cfg.similarity = acceptance;
548  auto results = BeadFinder::Find(image, pitch, w,h, smpCornerPos[0], smpCornerPos[1], &cfg);
549 
550  ResizeLVArray2D(output, results.size(), 2);
551  for (uint i=0;i<results.size();i++)
552  {
553  (*output)->get(i, 0) = results[i].x;
554  (*output)->get(i, 1) = results[i].y;
555  }
556 }
557 
558 
560 {
561  for (int i=0;i<(*int2D)->dimSizes[0];i++)
562  {
563  for (int j=0;j<(*int2D)->dimSizes[1];j++)
564  {
565  dbgprintf("%d\t", (*int2D)->get(i, j));
566  }
567  dbgprintf("\n");
568  }
569 
570  ResizeLVArray(flt1D, n);
571  ResizeLVArray(int1D, n);
572  ResizeLVArray2D(flt2D, n/2,n);
573  ResizeLVArray2D(int2D, n/2,n);
574  for (int i=0;i<n;i++) {
575  (*int1D)->elem[i]=(i+1)*i;
576  (*flt1D)->elem[i]=sqrtf(i);
577  for (int j=0;j<n/2;j++) {
578  (*int2D)->get(j, i) = j*2+i;
579  (*flt2D)->get(j, i) = j*2+i;
580  }
581  }
582 }
583 
584 CDLL_EXPORT void qtrk_simulate_tracking(QueuedTracker* qtrk, int nsmp, int beadIndex, vector3f* centerPos, vector3f* range, vector3f *outBias, vector3f* outScatter, float photonsPerWell, ErrorCluster* e)
585 {
586  if (ValidateTracker(qtrk, e, "qtrk_simulate_tracking")) {
587 
588  int nZLUT, nPlanes, nRadialSteps;
589  qtrk->GetRadialZLUTSize(nZLUT, nPlanes, nRadialSteps);
590 
591  float* lut = new float[nZLUT*nPlanes*nRadialSteps];
592  qtrk->GetRadialZLUT(lut);
593 
594  ImageData img = ImageData::alloc(qtrk->cfg.width,qtrk->cfg.height);
595  ImageData zlut;
596  zlut.data = & lut [nRadialSteps*nPlanes*beadIndex];
597  zlut.w = nRadialSteps;
598  zlut.h = nPlanes;
599 
600  // Generate images
601  std::vector<vector3f> positions(nsmp);
602  for (int i=0;i<nsmp;i++) {
603  vector3f pos = *centerPos + *range * vector3f(rand_uniform<float>(), rand_uniform<float>(), rand_uniform<float>());
604  positions[i]=pos;
605  GenerateImageFromLUT( &img, &zlut, qtrk->cfg.zlut_minradius, qtrk->cfg.zlut_maxradius, pos);
606  ApplyPoissonNoise(img, photonsPerWell);
607  qtrk->ScheduleLocalization((uchar*)img.data, sizeof(float)*img.w, QTrkFloat,i,i,0,beadIndex);
608  }
609 
610  img.free();
611 
612  qtrk->Flush();
613  while (!qtrk->IsIdle());
614 
615  LocalizationResult* results=new LocalizationResult[nsmp];
616  qtrk->FetchResults(results, nsmp);
617  vector3f sumBias, sumScatter;
618  for (int i=0;i<nsmp;i++) {
619  vector3f truepos = positions [ results[i].job.frame ];
620  vector3f diff = results[i].pos - truepos;
621  sumBias += diff;
622  }
623  vector3f meanBias = sumBias / nsmp;
624  for (int i=0;i<nsmp;i++) {
625  vector3f truepos = positions [ results[i].job.frame ];
626  vector3f diff = results[i].pos - truepos;
627  diff -= meanBias;
628  sumScatter += diff*diff;
629  }
630  *outScatter = sqrt (sumScatter / nsmp);
631  *outBias = sumBias;
632  }
633 }
634 
635 
636 #if defined(CUDA_TRACK) || defined(DOXYGEN)
637 
638 #include "cuda_runtime.h"
639 
641 {
642  SetCUDADevices( (*devices)->elem, (*devices)->dimSize );
643 }
644 
646 {
647  int c;
648  if (CheckCUDAErrorLV(cudaGetDeviceCount(&c), e)) {
649  return c;
650  }
651  return 0;
652 }
653 
655 {
656  cudaDeviceProp prop;
657  if (CheckCUDAErrorLV(cudaGetDeviceProperties(&prop, device), e)) {
658  info->multiProcCount = prop.multiProcessorCount;
659  info->clockRate = prop.clockRate;
660  info->major = prop.major;
661  info->minor = prop.minor;
662  SetLVString(info->name, prop.name);
663  }
664 }
665 
667 {
668  if (ValidateTracker(qtrk, e, "enable_texture_cache")) {
669  qtrk->SetConfigValue("use_texturecache", enable?"1":"0");
670  }
671 }
672 
673 #else // Generate empty functions to prevent labview crashes
674 
675 CDLL_EXPORT int qtrkcuda_device_count(ErrorCluster* e) { return 0; }
676 CDLL_EXPORT void qtrkcuda_get_device(int device, void *info, ErrorCluster* e) {}
677 
678 #endif
679 
static Threads::Mutex trackerListMutex
virtual int GetResultCount()=0
Get the number of finished localization jobs (=results) available in memory.
float zlut_minradius
Distance in pixels from the bead center from which to start sampling profiles. Default 1...
Definition: qtrk_c_api.h:135
T elem[1]
Definition: labview.h:59
virtual int ScheduleFrame(void *imgptr, int pitch, int width, int height, ROIPosition *positions, int numROI, QTRK_PixelDataType pdt, const LocalizationJob *jobInfo)
Schedule an entire frame at once, allowing for further optimizations.
CDLL_EXPORT void qtrk_set_zlut_bias_table(QueuedTracker *qtrk, LVArray2D< float > **biastbl, ErrorCluster *e)
virtual void BuildLUT(void *data, int pitch, QTRK_PixelDataType pdt, int plane, vector2f *known_pos=0)=0
Add a new lookup table plane.
CDLL_EXPORT int qtrk_get_queue_len(QueuedTracker *qtrk, int *maxQueueLen, ErrorCluster *e)
int32_t dimSizes[3]
Definition: labview.h:58
void ApplyGaussianNoise(ImageData &img, float sigma)
Definition: utils.cpp:454
virtual void GetRadialZLUTSize(int &count, int &planes, int &radialsteps)=0
Get the dimensions of the radial lookup table data.
CDLL_EXPORT void DLL_CALLCONV qtrk_get_computed_config(QueuedTracker *qtrk, QTrkComputedConfig *cc, ErrorCluster *err)
64 bit float
Definition: qtrk_c_api.h:37
TImageData< float > ImageData
Definition: QueuedTracker.h:69
CDLL_EXPORT int qtrk_get_debug_image(QueuedTracker *qtrk, int id, LVArray2D< float > **data, ErrorCluster *e)
CDLL_EXPORT void DLL_CALLCONV qtrk_get_ZLUT(QueuedTracker *tracker, LVArray3D< float > **pzlut, ErrorCluster *e)
CDLL_EXPORT void qtrk_destroy(QueuedTracker *qtrk, ErrorCluster *error)
CDLL_EXPORT void DLL_CALLCONV qtrk_set_pixel_calib(QueuedTracker *qtrk, LVArray3D< float > **offset, LVArray3D< float > **gain, ErrorCluster *e)
Set pixel calibration images.
CDLL_EXPORT uint qtrk_read_timestamp(uchar *image, int w, int h)
int32 code
Definition: labview.h:27
int width
Width of regions of interest to be handled. Typically equals height (square ROI). ...
Definition: qtrk_c_api.h:106
virtual void Flush()=0
Stop waiting for more jobs to do, and just process the current batch.
CDLL_EXPORT uint qtrk_queue_frame(QueuedTracker *qtrk, uchar *image, int pitch, int w, int h, uint pdt, ROIPosition *pos, int numROI, const LocalizationJob *pJobInfo, QueueFrameFlags flags, ErrorCluster *e)
int32_t dimSize
Definition: labview.h:34
16 bit unsigned int
Definition: qtrk_c_api.h:36
CDLL_EXPORT void qtrkcuda_enable_texture_cache(QueuedTracker *qtrk, int enable, ErrorCluster *e)
LStrHandle name
Definition: lv_qtrk_api.h:17
void WriteToLog()
Write all settings to specified log file (Jelmer)
CDLL_EXPORT void DLL_CALLCONV qtrk_get_image_lut(QueuedTracker *qtrk, LVArrayND< float, 4 > **imageLUT, ErrorCluster *e)
Struct used to define the top-left corner position of an ROI within a frame. ROI is [ x ...
Definition: qtrk_c_api.h:178
virtual void SetConfigValue(std::string name, std::string value)=0
Set an additional setting.
void lock()
Definition: threads.h:74
unsigned int uint
Definition: std_incl.h:127
QueuedTracker * CreateQueuedTracker(const QTrkComputedConfig &cc)
Helper function to create a QueuedTracker instance.
bool ValidateTracker(QueuedTracker *tracker, ErrorCluster *e, const char *funcname)
Verify the referenced tracker is a valid QueuedTracker instance.
void SetLVString(LStrHandle str, const char *text)
QueueFrameFlags
Definition: lv_qtrk_api.h:10
void GenerateImageFromLUT(ImageData *image, ImageData *zlut, float minradius, float maxradius, vector3f pos, bool splineInterp, int oversampleSubdiv)
Definition: utils.cpp:354
CDLL_EXPORT void qtrk_set_localization_mode(QueuedTracker *qtrk, uint locType, ErrorCluster *e)
CDLL_EXPORT void qtrk_queue_u16(QueuedTracker *qtrk, ErrorCluster *error, LVArray2D< ushort > **data, const LocalizationJob *jobInfo)
CDLL_EXPORT void qtrk_flush(QueuedTracker *qtrk, ErrorCluster *e)
void ResizeLVArray(LVArrayND< T, N > **&d, int *dims)
Definition: labview.h:118
virtual void GetRadialZLUT(float *dst)=0
Get the radial lookup tables used for z tracking.
bool CheckImageInput(QueuedTracker *qtrk, LVArray2D< T > **data, ErrorCluster *error)
CDLL_EXPORT void qtrk_dump_memleaks()
CDLL_EXPORT void qtrk_get_profile_report(QueuedTracker *qtrk, LStrHandle str)
Structure for job results.
Definition: qtrk_c_api.h:67
static bool CheckCUDAErrorLV(cudaError err, ErrorCluster *e)
Definition: lv_qtrk_api.h:26
CDLL_EXPORT int qtrk_get_results(QueuedTracker *qtrk, LocalizationResult *results, int maxResults, int sortByID, ErrorCluster *e)
CDLL_EXPORT void qtrk_build_lut_plane(QueuedTracker *qtrk, LVArray3D< float > **data, uint flags, int plane, ErrorCluster *err)
int height
Height of regions of interest to be handled. Typically equals width (square ROI). ...
Definition: qtrk_c_api.h:107
void normalize(TPixel *d, uint w, uint h)
Definition: utils.h:27
CDLL_EXPORT void DLL_CALLCONV qtrk_generate_gaussian_spot(LVArray2D< float > **image, vector2f *pos, float sigma, float I0, float Ibg, int applyNoise)
virtual void SetPixelCalibrationFactors(float offsetFactor, float gainFactor)=0
Set the pixel calibration factors.
CDLL_EXPORT void qtrk_queue_float(QueuedTracker *qtrk, ErrorCluster *error, LVArray2D< float > **data, const LocalizationJob *jobInfo)
unsigned short ushort
Definition: std_incl.h:128
virtual bool GetDebugImage(int ID, int *w, int *h, float **pData)
Get the debug image for a specific thread.
CDLL_EXPORT void qtrk_enable_zlut_cmpprof(QueuedTracker *qtrk, bool enable, ErrorCluster *e)
CDLL_EXPORT void qtrk_finalize_lut(QueuedTracker *qtrk, ErrorCluster *e)
Structure for the settings used by the algorithms implemented in QueuedTracker.
Definition: qtrk_c_api.h:82
8 bit unsigned int
Definition: qtrk_c_api.h:35
int zlut_radialsteps
Number of radial steps to sample on.
Definition: qtrk_c_api.h:198
vector3< T > sqrt(const vector3< T > &a)
Definition: std_incl.h:112
std::vector< Position > Find(ImageData *img, float *sample, Config *cfg)
Definition: BeadFinder.cpp:168
virtual void FinalizeLUT()=0
Finalize the lookup tables in memory.
uint timestamp
Time stamp of the frame.
Definition: qtrk_c_api.h:57
virtual void SetLocalizationMode(LocMode_t locType)=0
Select which algorithm is to be used.
uint frame
Frame number this ROI belongs to.
Definition: qtrk_c_api.h:56
static TImageData alloc(int w, int h)
Definition: utils.h:110
int LocMode_t
Definition: qtrk_c_api.h:30
LabVIEW Array template.
Definition: labview.h:33
LVBoolean status
Definition: labview.h:26
CDLL_EXPORT void DLL_CALLCONV qtrk_set_logfile_path(const char *path)
CDLL_EXPORT void qtrkcuda_get_device(int device, CUDADeviceInfo *info, ErrorCluster *e)
virtual void SetRadialZLUT(float *data, int count, int planes)=0
Set the radial lookup tables to be used for z tracking.
void ResizeLVArray3D(LVArray3D< T > **&d, int depth, int rows, int cols)
Definition: labview.h:107
void SetZLUTBiasCorrection(const CImageData &data)
virtual std::string GetWarnings()
Get a report of encountered errors.
CDLL_EXPORT void qtrk_test_array_passing(int n, LVArray< float > **flt1D, LVArray2D< float > **flt2D, LVArray< int > **int1D, LVArray2D< int > **int2D)
CDLL_EXPORT void DLL_CALLCONV qtrk_set_image_lut(QueuedTracker *qtrk, LVArrayND< float, 4 > **imageLUT, LVArray3D< float > **radialZLUT, ErrorCluster *e)
Matrix3X3 Inverse() const
Definition: utils.h:298
CDLL_EXPORT void qtrk_queue_pitchedmem(QueuedTracker *qtrk, uchar *data, int pitch, uint pdt, const LocalizationJob *jobInfo)
virtual bool IsIdle()=0
Test to see if the tracker is idle.
void ArgumentErrorMsg(ErrorCluster *e, const std::string &msg)
virtual bool SetImageZLUT(float *src, float *radial_zlut, int *dims)
Set the image lookup tables to be used for z tracking.
CDLL_EXPORT void qtrk_queue_array(QueuedTracker *qtrk, ErrorCluster *error, LVArray2D< uchar > **data, uint pdt, const LocalizationJob *jobInfo)
virtual void GetRadialZLUTCompareProfile(float *dst)=0
Get saved error curve.
void GenerateGaussianSpotImage(ImageData *img, vector2f pos, float sigma, float I0, float Ibg)
Definition: utils.cpp:421
virtual int GetQueueLength(int *maxQueueLen=0)=0
Get the lengths of the queue of jobs to be handled.
virtual void GetImageZLUTSize(int *dims)
Get the dimensions of the image lookup table data.
vector3f diag() const
Definition: utils.h:277
CDLL_EXPORT void qtrk_find_beads(uint8_t *image, int pitch, int w, int h, int *smpCornerPos, int roi, float imgRelDist, float acceptance, LVArray2D< uint32_t > **output)
CDLL_EXPORT QueuedTracker * qtrk_create(QTrkSettings *settings, LStrHandle warnings, ErrorCluster *e)
#define CDLL_EXPORT
Definition: dllmacros.h:9
virtual void EnableRadialZLUTCompareProfile(bool enabled)=0
Set a flag to enable saving of error curves.
void dbgsetlogfile(const char *path)
Definition: utils.cpp:49
CDLL_EXPORT void DLL_CALLCONV qtrk_set_pixel_calib_factors(QueuedTracker *qtrk, float offsetFactor, float gainFactor, ErrorCluster *e)
Set pixel calibration factors.
virtual void ScheduleLocalization(void *data, int pitch, QTRK_PixelDataType pdt, const LocalizationJob *jobInfo)=0
Add a job to the queue to be processed. A job entails running the required algorithms on a single reg...
LocalizationJob job
Job metadata. See LocalizationJob.
Definition: qtrk_c_api.h:68
QTrkComputedConfig cfg
The settings used by this instance of QueuedTracker.
void free()
Definition: utils.h:111
CDLL_EXPORT void qtrk_queue_u8(QueuedTracker *qtrk, ErrorCluster *error, LVArray2D< uchar > **data, const LocalizationJob *jobInfo)
void ResizeLVArray2D(LVArray2D< T > **&d, int rows, int cols)
Definition: labview.h:98
virtual void SetPixelCalibrationImages(float *offset, float *gain)=0
Set the pixel calibration images.
CDLL_EXPORT void DLL_CALLCONV qtrk_free_all()
void DeleteAllElems(T &c)
Definition: utils.h:19
QTRK_PixelDataType
Flags indicating the data type of image data.
Definition: qtrk_c_api.h:33
virtual std::string GetProfileReport()
Get the output of performance profiling.
Matrix3X3 ComputeAverageFisher(vector3f pos, int Nsamples, vector3f sampleRange, vector3f delta, int w, int h, std::function< void(ImageData &out, vector3f pos)> imggen)
Definition: FisherMatrix.h:107
CDLL_EXPORT int qtrkcuda_device_count(ErrorCluster *e)
virtual void GetImageZLUT(float *dst)
Get the image lookup tables used.
Structure for derived settings computed from base settings in QTrkSettings.
Definition: qtrk_c_api.h:189
LabVIEW N dimensions array template.
Definition: labview.h:66
CDLL_EXPORT int qtrk_idle(QueuedTracker *qtrk, ErrorCluster *e)
LabVIEW 3D Array template.
Definition: labview.h:57
int h
Definition: utils.h:81
LabVIEW 2D Array template.
Definition: labview.h:41
CDLL_EXPORT void qtrk_get_zlut_cmpprof(QueuedTracker *qtrk, LVArray2D< float > **output, ErrorCluster *e)
CDLL_EXPORT void DLL_CALLCONV qtrk_set_ZLUT(QueuedTracker *tracker, LVArray3D< float > **pZlut, LVArray< float > **zcmpWindow, int normalize, ErrorCluster *e)
void SetCUDADevices(int *devices, int numdev)
Set the list of devices to be used when QTrkComputedConfig::cuda_device is set to QTrkCUDA_UseList...
static std::vector< QueuedTracker * > trackerList
LStrHandle message
Definition: labview.h:28
vector3< float > vector3f
Definition: std_incl.h:114
void dbgprintf(const char *fmt,...)
Definition: utils.cpp:149
std::vector< std::string > LVGetStringArray(int count, LStrHandle *str)
CDLL_EXPORT void qtrk_simulate_tracking(QueuedTracker *qtrk, int nsmp, int beadIndex, vector3f *centerPos, vector3f *range, vector3f *outBias, vector3f *outScatter, float photonsPerWell, ErrorCluster *e)
#define DLL_CALLCONV
Definition: dllmacros.h:3
void ComputeZBiasCorrection(int bias_planes, CImageData *result, int smpPerPixel, bool useSplineInterp)
CDLL_EXPORT void DLL_CALLCONV qtrk_generate_image_from_lut(LVArray2D< float > **image, LVArray2D< float > **lut, float *LUTradii, vector2f *position, float z, float M, float sigma_noise)
CDLL_EXPORT void qtrkcuda_set_device_list(LVArray< int > **devices)
virtual int FetchResults(LocalizationResult *results, int maxResults)=0
Fetch available results.
void copyTo(float *dst)
Definition: utils.h:93
virtual void SetRadialWeights(float *zcmp)=0
Set radial weights used for comparing LUT profiles.
virtual void ClearResults()=0
Clear results.
void unlock()
Definition: threads.h:79
Abstract tracker interface, implemented by QueuedCUDATracker and QueuedCPUTracker.
Definition: QueuedTracker.h:86
CDLL_EXPORT void qtrk_clear_results(QueuedTracker *qtrk, ErrorCluster *e)
CDLL_EXPORT void qtrk_compute_fisher(LVArray2D< float > **lut, QTrkSettings *cfg, vector3f *pos, LVArray2D< float > **fisherMatrix, LVArray2D< float > **inverseMatrix, vector3f *xyzVariance, int Nsamples, float maxPixelValue)
Structure for region of interest metadata.
Definition: qtrk_c_api.h:49
float zlut_maxradius
Max radius in pixels of the sampling circle.
Definition: qtrk_c_api.h:200
unsigned char uchar
Definition: std_incl.h:130
CDLL_EXPORT void qtrk_compute_zlut_bias_table(QueuedTracker *qtrk, int bias_planes, LVArray2D< float > **lvresult, int smpPerPixel, int useSplineInterp, ErrorCluster *e)
CDLL_EXPORT int qtrk_resultcount(QueuedTracker *qtrk, ErrorCluster *e)
std::string SPrintf(const char *fmt,...)
Definition: utils.cpp:132
T * data
Definition: utils.h:80
int w
Definition: utils.h:81
void NormalizeZLUT(float *zlut, int numBeads, int planes, int radialsteps)
Definition: utils.cpp:291
MgErr FillErrorCluster(MgErr err, const char *message, ErrorCluster *error)
void ApplyPoissonNoise(ImageData &img, float poissonMax, float maxval)
Definition: utils.cpp:432