-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmex_wrapper.cpp
executable file
·168 lines (135 loc) · 5.8 KB
/
mex_wrapper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//
// Created by Sylvain Renevey on 1/25/2019.
//
/*! \class MexFunction
* \brief Class defining the entry point to get the EarthGRAM2016 atmospheric density from MATLAB.
*
* When called from MATLAB, the following inputs must be provided:
* -# altitude (km).
* -# latitude (degrees).
* -# longitude (degrees).
* -# char array containing the epoch. Must be in the format: 'YYYY-MM-DD hh:mm:ss'.
*
* The output argument is:
* -# density (kg/m^3).
*
* MATLAB code example:
*
* h = 20;
* lat = 30;
* lon = 120;
* epoch = '2019-01-25 14:30:00';
* density = get_atm_density(h, lat, lon, epoch);
*
*/
#ifdef _WIN32
#ifdef _WIN64
#define TO_STRING_AUX( x ) #x
#define TO_STRING( x ) TO_STRING_AUX( x )
#define EARTHGRAM2016 TO_STRING( EARTHGRAM2016_PATH )
#endif
#elif __APPLE__
#define EARTHGRAM2016 EARTHGRAM2016_PATH
#elif __unix__
#define EARTHGRAM2016 EARTHGRAM2016_PATH
#endif
#ifndef MEX_WRAPPER
#define MEX_WRAPPER
#include "mex.hpp"
#include "mexAdapter.hpp"
#include "Atmod1.h"
#endif //MEX_WRAPPER
using matlab::mex::ArgumentList;
using matlab::engine::convertUTF8StringToUTF16String;
class MexFunction : public matlab::mex::Function {
private:
matlab::data::ArrayFactory m_factory;
std::shared_ptr<matlab::engine::MATLABEngine> m_matlabPtr;
public:
/*! \fn MexFunction()
* \brief Public constructor of the class
*/
MexFunction() {
// Get pointer to engine
m_matlabPtr = getEngine();
}
/*! \fn void operator()(ArgumentList outputs, ArgumentList inputs)
* \brief This method is called when the mex function is called from MATLAB.
*
* \param outputs ArgumentList containing the outputs of the program.
* \param inputs ArgumentList containing the inputs of the program.
*
*/
void operator()(ArgumentList outputs, ArgumentList inputs) {
checkArguments(outputs, inputs);
// Read inputs in MATLAB Data API defined variables
double h = inputs[0][0];
double lat = inputs[1][0];
double lon = inputs[2][0];
const matlab::data::CharArray epoch_c_str = inputs[3];
// Convert char array to string
std::string epoch( epoch_c_str.toAscii() );
// Get density
Atm1 earth_gram_atm_model;
earth_gram_atm_model.initdata(EARTHGRAM2016, "NameRef.txt", epoch);
double pm1, density, tm1, um1, vm1, wm1, pp1, dp1, tp1, up1, vp1, wp1, ps1, ds1, ts1,
us1, vs1, ws1, psmall, dsmall, tsmall, usmall, vsmall, wsmall, sos, sosp;
int iupdate = 1;
int initonce = 1;
double time = 0.0;
earth_gram_atm_model.traj(h, lat, lon, time, iupdate, initonce, &density, &pm1, &tm1, &um1, &vm1, &wm1,
&dp1, &pp1, &tp1, &up1, &vp1, &wp1, &ds1, &ps1, &ts1, &us1, &vs1, &ws1, &dsmall,
&psmall, &tsmall, &usmall, &vsmall, &wsmall, &sos, &sosp);
// Create output
outputs[0] = m_factory.createScalar<double>(density);
}
/*! \fn void checkArguments(ArgumentList outputs, ArgumentList inputs)
* \brief This method checks that 4 inputs have been passed in as arguments and are valid and that one output is retrieved.
*
* \param outputs ArgumentList containing the output of the program.
* \param inputs ArgumentList containing the inputs of the program.
*
*/
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
// Check that four input arguments are passed
if (inputs.size() != 4) {
m_matlabPtr->feval(matlab::engine::convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("Four inputs are required.") }));
}
// Check first input argument
if (inputs[0].getType() != matlab::data::ArrayType::DOUBLE ||
inputs[0].getType() == matlab::data::ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
m_matlabPtr->feval(convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("The first input must be a scalar.") }));
}
// Check second input argument
if (inputs[1].getType() != matlab::data::ArrayType::DOUBLE ||
inputs[1].getType() == matlab::data::ArrayType::COMPLEX_DOUBLE ||
inputs[1].getNumberOfElements() != 1)
{
m_matlabPtr->feval(convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("The second input must be a scalar.") }));
}
// Check third input argument
if (inputs[2].getType() != matlab::data::ArrayType::DOUBLE ||
inputs[2].getType() == matlab::data::ArrayType::COMPLEX_DOUBLE ||
inputs[2].getNumberOfElements() != 1)
{
m_matlabPtr->feval(convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("The third input must be a scalar.") }));
}
// Check fourth input argument
if (inputs[3].getType() != matlab::data::ArrayType::CHAR)
{
m_matlabPtr->feval(convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("The fourth input must be an array of chars") }));
}
// Check number of outputs
if (outputs.size() > 1) {
m_matlabPtr->feval(convertUTF8StringToUTF16String("error"),
0, std::vector<matlab::data::Array>({ m_factory.createScalar("A single output is returned") }));
}
}
};