Instrument Neutral Distributed Interface INDI  2.0.2
convolution.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 *******************************************************************************/
18 
19 #include "convolution.h"
20 #include "indistandardproperty.h"
21 #include "indicom.h"
22 #include "indilogger.h"
23 #include "dsp.h"
24 #include "base64.h"
25 
26 #define _USE_MATH_DEFINES
27 #include <cmath>
28 #include <dirent.h>
29 #include <cerrno>
30 #include <cstring>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <algorithm>
34 #include <thread>
35 #include <chrono>
36 #include <fcntl.h>
37 #include <unistd.h>
38 
39 namespace DSP
40 {
41 
42 Convolution::Convolution(INDI::DefaultDevice *dev) : Interface(dev, DSP_CONVOLUTION, "CONVOLUTION", "Convolution")
43 {
44  IUFillBLOB(&DownloadB, "CONVOLUTION_DOWNLOAD", "Convolution Matrix", "");
45  IUFillBLOBVector(&DownloadBP, &FitsB, 1, m_Device->getDeviceName(), "CONVOLUTION", "Matrix Data", DSP_TAB, IP_RW, 60,
46  IPS_IDLE);
47 }
48 
50 {
51 }
52 
54 {
55  m_Device->defineProperty(&DownloadBP);
57 }
58 
60 {
61  m_Device->deleteProperty(DownloadBP.name);
63 }
64 
65 bool Convolution::ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[],
66  char *names[], int n)
67 {
68  if(!strcmp(dev, getDeviceName()))
69  {
70  if(!strcmp(name, DownloadBP.name))
71  {
72  IUUpdateBLOB(&DownloadBP, sizes, blobsizes, blobs, formats, names, n);
73  LOGF_INFO("Received matrix BLOB for %s", getDeviceName());
74  if(matrix != nullptr)
75  {
76  dsp_stream_free_buffer(matrix);
77  dsp_stream_free(matrix);
78  }
79  matrix = loadFITS(blobs[0], sizes[0]);
80  if (matrix != nullptr)
81  {
82  LOGF_INFO("Matrix for %s loaded", getDeviceName());
83  matrix_loaded = true;
84  return true;
85  }
86  }
87  }
88  return false;
89 }
90 
91 bool Convolution::processBLOB(uint8_t *buf, uint32_t dims, int *sizes, int bits_per_sample)
92 {
93  if(!PluginActive) return false;
94  if(!matrix_loaded) return false;
95  setStream(buf, dims, sizes, bits_per_sample);
97  dsp_fourier_dft(matrix, 1);
99  return Interface::processBLOB(getStream(), stream->dims, stream->sizes, bits_per_sample);
100 }
101 
102 Wavelets::Wavelets(INDI::DefaultDevice *dev) : Interface(dev, DSP_WAVELETS, "WAVELETS", "Wavelets")
103 {
104  for(int i = 0; i < N_WAVELETS; i++)
105  {
106  char strname[MAXINDINAME];
107  char strlabel[MAXINDILABEL];
108  sprintf(strname, "WAVELET_%0d", i);
109  sprintf(strlabel, "%d pixels Gaussian Wavelet", (i + 1) * 3);
110  IUFillNumber(&WaveletsN[i], strname, strlabel, "%3.3f", -15.0, 255.0, 1.0, 0.0);
111  }
112  IUFillNumberVector(&WaveletsNP, WaveletsN, N_WAVELETS, m_Device->getDeviceName(), "WAVELETS", "Wavelets", DSP_TAB, IP_RW,
113  60, IPS_IDLE);
114 }
115 
117 {
118 }
119 
121 {
122  m_Device->defineProperty(&WaveletsNP);
124 }
125 
127 {
128  m_Device->deleteProperty(WaveletsNP.name);
130 }
131 
132 bool Wavelets::ISNewNumber(const char *dev, const char *name, double *values, char *names[], int n)
133 {
134  if (!strcmp(dev, getDeviceName()) && !strcmp(name, WaveletsNP.name))
135  {
136  IUUpdateNumber(&WaveletsNP, values, names, n);
137  IDSetNumber(&WaveletsNP, nullptr);
138  }
139  return true;
140 }
141 
142 bool Wavelets::processBLOB(uint8_t *buf, uint32_t dims, int *sizes, int bits_per_sample)
143 {
144  if(!PluginActive) return false;
145  setStream(buf, dims, sizes, bits_per_sample);
146  double min = dsp_stats_min(stream->buf, stream->len);
147  double max = dsp_stats_max(stream->buf, stream->len);
149  for (int i = 0; i < WaveletsNP.nnp; i++)
150  {
151  int size = (i + 1) * 3;
153  dsp_stream_p matrix = dsp_stream_new();
154  dsp_stream_add_dim(matrix, size);
155  dsp_stream_add_dim(matrix, size);
156  dsp_stream_alloc_buffer(matrix, matrix->len);
157  for(int y = 0; y < size; y++)
158  {
159  for(int x = 0; x < size; x++)
160  {
161  matrix->buf[x + y * size] = sin(static_cast<double>(x) * M_PI / static_cast<double>(size)) * sin(static_cast<double>
162  (y) * M_PI / static_cast<double>(size));
163  }
164  }
165  dsp_fourier_dft(tmp, 1);
166  dsp_fourier_dft(matrix, 1);
167  dsp_convolution_convolution(tmp, matrix);
168  dsp_buffer_sub(tmp, matrix->buf, matrix->len);
169  dsp_buffer_mul1(tmp, WaveletsNP.np[i].value / 8.0);
170  dsp_buffer_sum(out, tmp->buf, tmp->len);
171  dsp_buffer_normalize(tmp->buf, min, max, tmp->len);
172  dsp_stream_free_buffer(matrix);
173  dsp_stream_free(matrix);
175  dsp_stream_free(tmp);
176  }
179  stream = dsp_stream_copy(out);
180  return Interface::processBLOB(getStream(), stream->dims, stream->sizes, bits_per_sample);
181 }
182 }
void Activated() override
Activated Called after activation from client application.
Definition: convolution.cpp:53
void Deactivated() override
Deactivated Called after deactivation from client application.
Definition: convolution.cpp:59
bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) override
Definition: convolution.cpp:65
Convolution(INDI::DefaultDevice *dev)
Definition: convolution.cpp:42
virtual bool processBLOB(uint8_t *out, uint32_t dims, int *sizes, int bits_per_sample) override
processBLOB Propagate to Callback and generate BLOBs for parent device.
Definition: convolution.cpp:91
const char * getDeviceName()
uint8_t * getStream()
virtual void Activated()
Activated Called after activation from client application.
virtual bool processBLOB(uint8_t *buf, uint32_t ndims, int *dims, int bits_per_sample)
processBLOB Propagate to Callback and generate BLOBs for parent device.
dsp_stream_p stream
Definition: dspinterface.h:213
bool setStream(void *buf, uint32_t dims, int *sizes, int bits_per_sample)
INDI::DefaultDevice * m_Device
Definition: dspinterface.h:198
dsp_stream_p loadFITS(char *buf, int len)
loadFITS Converts FITS data into a dsp_stream structure pointer.
virtual void Deactivated()
Deactivated Called after deactivation from client application.
virtual bool processBLOB(uint8_t *out, uint32_t dims, int *sizes, int bits_per_sample) override
processBLOB Propagate to Callback and generate BLOBs for parent device.
bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
void Deactivated() override
Deactivated Called after deactivation from client application.
Wavelets(INDI::DefaultDevice *dev)
void Activated() override
Activated Called after activation from client application.
const char * getDeviceName() const
Definition: basedevice.cpp:821
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
#define N_WAVELETS
Definition: convolution.h:26
double max(void)
double min(void)
int * sizes
Sizes of each dimension.
Definition: dsp.h:373
int dims
Number of dimensions of the buffers.
Definition: dsp.h:371
dsp_t * buf
buffer
Definition: dsp.h:375
int len
The buffers length.
Definition: dsp.h:369
void dsp_buffer_sum(dsp_stream_p stream, dsp_t *in, int inlen)
Sum elements of one stream to another's.
Definition: buffer.c:68
#define dsp_buffer_normalize(buf, len, mn, mx)
Normalize the input stream to the minimum and maximum values.
Definition: dsp.h:832
void dsp_buffer_sub(dsp_stream_p stream, dsp_t *in, int inlen)
Subtract elements of one stream from another's.
Definition: buffer.c:57
void dsp_buffer_mul1(dsp_stream_p stream, double val)
Multiply elements of the input stream to a value.
Definition: buffer.c:195
void dsp_convolution_convolution(dsp_stream_p stream, dsp_stream_p matrix)
A cross-convolution processor.
Definition: convolution.c:22
DLL_EXPORT void dsp_stream_free(dsp_stream_p stream)
Free the DSP stream passed as argument.
Definition: stream.c:163
DLL_EXPORT dsp_stream_p dsp_stream_copy(dsp_stream_p stream)
Create a copy of the DSP stream passed as argument.
Definition: stream.c:192
DLL_EXPORT dsp_stream_p dsp_stream_new(void)
Allocate a new DSP stream type.
Definition: stream.c:124
DLL_EXPORT void dsp_stream_add_dim(dsp_stream_p stream, int len)
Add a dimension with length len to a DSP stream.
Definition: stream.c:227
DLL_EXPORT void dsp_stream_alloc_buffer(dsp_stream_p stream, int len)
Allocate a buffer with length len on the stream passed as argument.
Definition: stream.c:78
DLL_EXPORT void dsp_stream_free_buffer(dsp_stream_p stream)
Free the buffer of the DSP Stream passed as argument.
Definition: stream.c:112
DLL_EXPORT void dsp_fourier_dft(dsp_stream_p stream, int exp)
Perform a discrete Fourier Transform of a dsp_stream.
Definition: fft.c:135
#define dsp_stats_min(buf, len)
Gets the minimum value of the input stream.
Definition: dsp.h:562
#define dsp_stats_max(buf, len)
Gets the maximum value of the input stream.
Definition: dsp.h:580
@ IP_RW
Definition: indiapi.h:186
@ IPS_IDLE
Definition: indiapi.h:161
#define MAXINDILABEL
Definition: indiapi.h:192
#define MAXINDINAME
Definition: indiapi.h:191
Implementations for common driver routines.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:272
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidevapi.c:180
void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a BLOB vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:310
void IUFillBLOB(IBLOB *bp, const char *name, const char *label, const char *format)
Assign attributes for a BLOB property. The BLOB's data and auxiliary elements will be set to NULL.
Definition: indidevapi.c:216
int IUUpdateBLOB(IBLOBVectorProperty *bvp, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update all BLOB members in a BLOB vector property.
Definition: indidriver.c:1422
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:1362
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
The DSP Namespace adds signal processing to INDI drivers. Primarily written for sensors and detectors...
Definition: convolution.cpp:40
const char * DSP_TAB
char name[MAXINDINAME]
Definition: indiapi.h:475
char name[MAXINDINAME]
Definition: indiapi.h:323
Contains a set of informations and data relative to a buffer and how to use it.
Definition: dsp.h:363