Blame view

src/ParamGetImpl/DDServerInterface/VirtualInstrument.cc 14.5 KB
fbe3c2bb   Benjamin Renard   First commit
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
/*
 * VirtualInstrument.cc
 *
 *  Created on: Jan 17, 2013
 *      Author: f.casimir
 */

#include <algorithm>    // std::find

#include "DicError.hh"
#include "TimeUtil.hh"

#include "DDServerInterfaceConfig.hh"
#include "VirtualInstrument.hh"
#include "VirtualInstrumentInterval.hh"

using namespace AMDA::Parameters;

namespace AMDA {
namespace DDServerInterface {

		VirtualInstrument::VirtualInstrument(VirtualInstrumentManager& pVirtualInstrumentManager, const std::string& viName) :
				_virtualInstrumentManager(pVirtualInstrumentManager),
				_viName(viName),
				_id(-1) {

			// Set user host
			_ddClient.setUserHost(_virtualInstrumentManager.getUserHost());
29bf0a3d   Elena.Budnik   setUserName() cal...
29
30
31
			// Set user login
			_ddClient.setUserName(_virtualInstrumentManager.getUserName());
			
fbe3c2bb   Benjamin Renard   First commit
32
			/// Open Connection
29bf0a3d   Elena.Budnik   setUserName() cal...
33
			_id = _ddClient.DD_SetVariable(const_cast<char *>(_viName.c_str()));			
fbe3c2bb   Benjamin Renard   First commit
34
35
36
37
			LOG4CXX_INFO(gLogger,"ParamGetDDBase: DD_SetVariable("<< _viName << ") returns = (" << _id << ")");

			if (_id < 0) {
				_ddClient.DD_Close(99);
80111081   Benjamin Renard   Add executable am...
38
				BOOST_THROW_EXCEPTION(exception() << errno_code(VirtualInstrumentManager::getInstance()->ddErrorToAmdaError(_id)));
fbe3c2bb   Benjamin Renard   First commit
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
			}

			/// Set GlobalStart
			{
				_globalStartTime = getDDTimeInfo("GlobalStart");
			}
			/// Set GlobalStop
			{
				_globalStopTime = getDDTimeInfo("GlobalStop");
			}
			/// Set MinSampling
			{
				const InfoList& lInfoList = getDDInfo("MinSampling");
				_minSampling = lInfoList.begin()->second->at(0);
			}
			/// Set MaxSampling
			{
				const InfoList& lInfoList = getDDInfo("MaxSampling");
				if (lInfoList.empty()) { //Sampling constant
					_maxSampling = _minSampling;
				} else {
					_maxSampling = lInfoList.begin()->second->at(0);
				}
			}
			/// Set FillValue
			{
				const InfoList& lInfoList = getDDInfo("FillValue");
				if ( ! lInfoList.empty()) {
					_fillValue = (*lInfoList.begin()->second)[0];
				} else {
					_fillValue = NAN;
				}
			}
		}

		VirtualInstrument::~VirtualInstrument() {
			if(_id!=-1) { _ddClient.DD_Close(_id); }
			VirtualInstrumentManager::releaseInstance();
		}

		double VirtualInstrument::getDDTimeInfo(const char *timeTag) {
			DD_data_t *data;
			_ddClient.DD_GetInform(_id, const_cast<char *>(timeTag), &data);
			if (data->type != DD_CHAR || data->DimNumber != 1
					|| data->Dimensions[0] <= 0) {
				LOG4CXX_ERROR(gLogger, "DD_GetInform(" << timeTag << ") not good type ");
				BOOST_THROW_EXCEPTION(exception() << errno_code(AMDA_ERROR_UNKNOWN));
			}
			LOG4CXX_DEBUG(gLogger, "getDDTimeInfo(" << timeTag << ") = " << (char*)data->Variables[0]);
			return TimeUtil::readTimeInIso((char *) data->Variables[0]);
		}

		template <typename type>
		void VirtualInstrument::setInfoValues( InfoList& storage, const std::string& pInfoName, unsigned int pNbData, void* data) {
			// Read data
			type* lFloatData = reinterpret_cast<type*>(data);
			InfoValuesSPtr lInfo = InfoValuesSPtr(new InfoValues(pNbData));
			lInfo->assign(lFloatData,lFloatData+pNbData);
			storage.insert(std::pair<std::string,InfoValuesSPtr>( pInfoName, lInfo));
		}

		unsigned int getNbTab( unsigned int pNbDimension, unsigned int pDepth, int* pDimensions) {
			if ( pDepth == pNbDimension) {
				return 1;
			} else {
				return pDimensions[pDepth]*getNbTab(pNbDimension,pDepth+1,pDimensions);
			}
		}

		template <typename Type>
		void VirtualInstrument::recurseInfoValues( InfoList& storage, const std::string& pInfoName, unsigned int pNbDimension, int* pDimensions, void* data) {
			if ( pNbDimension == 1 ) {
				setInfoValues<Type>(storage,pInfoName,pDimensions[0],data);
			} else {
				int lTabSize     = pDimensions[pNbDimension-1];
				unsigned int lStepIndex   = getNbTab(pNbDimension-1,0,pDimensions);
				for ( unsigned int i = 0; i < lStepIndex; ++i) {
					unsigned int lStepPointer = sizeof(Type)*i*lTabSize;
					std::stringstream lInfoName; lInfoName << pInfoName << "_" << i;
					setInfoValues<Type>(storage,lInfoName.str(), lTabSize, (char *)data + lStepPointer);
				}
			}
		}

		const InfoList& VirtualInstrument::getDDInfo(const char* pIinfoName) {
			DD_data_t *data = NULL;
			auto lIt = _infoMap.find(pIinfoName);
			if (lIt == _infoMap.end()) {
				int result = 0;
				InfoList& infoList = _infoMap[pIinfoName];
				if ((result = _ddClient.DD_GetInform( _id, const_cast<char *>(pIinfoName), &data)) >= 0) {
					LOG4CXX_DEBUG(gLogger,"ParamGetDDBase:getInfoDD( "<< _id << ", " << pIinfoName << ") returns = ( return: " << result << ", type: " << data->type << ", DimNumber: " << data->DimNumber << ", Dimensions[0]: " << data->Dimensions[0] << ", VarNumber: " << data->VarNumber << ")");

					if (data->VarNumber == 1) {
						if (data->type == DD_FLOAT) {
							recurseInfoValues<float>(infoList, pIinfoName,
									data->DimNumber, data->Dimensions,
									*data->Variables);
						} else if (data->type == DD_DOUBLE) {
							recurseInfoValues<double>(infoList, pIinfoName,
									data->DimNumber, data->Dimensions,
									*data->Variables);
f2db3c16   Benjamin Renard   Support variable ...
141
142
143
144
						} else if (data->type == DD_SHORT) {
							recurseInfoValues<short>(infoList, pIinfoName,
									data->DimNumber, data->Dimensions,
									*data->Variables);
fbe3c2bb   Benjamin Renard   First commit
145
146
147
148
149
150
151
152
153
154
155
156
157
						}
					} else {

					}
				} else {
					LOG4CXX_INFO(gLogger,
							"ParamGetDDBase:getInfoDD( "<< _id << ", " << pIinfoName << ") returns = (" << result << ")");
				}
				return infoList;
			}
			return lIt->second;
		}

ff482c31   Benjamin Renard   Give the possibil...
158
		AMDA::Parameters::ContainerType VirtualInstrument::getParamContainerType(DD_data_t *data, int dim3Num)
fbe3c2bb   Benjamin Renard   First commit
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
		{
			if (data == NULL)
				return AMDA::Parameters::ContainerType::CT_UNKNOWN;
			switch (data->DimNumber)
			{
				case 1 :
					//vector or scalar
					if (data->Dimensions[0] > 1)
						return AMDA::Parameters::ContainerType::CT_TAB1D;
					else if (data->Dimensions[0] == 1)
						return AMDA::Parameters::ContainerType::CT_SCALAR;
					break;
				case 2 :
					if (data->Dimensions[1] == 1)
					{
						if (data->Dimensions[0] == 1)
							return AMDA::Parameters::ContainerType::CT_SCALAR;
						else if (data->Dimensions[0] > 1)
							return AMDA::Parameters::ContainerType::CT_TAB1D;
					}
					else if (data->Dimensions[1] > 1)
					{
						if (data->Dimensions[0] == 1)
							return AMDA::Parameters::ContainerType::CT_TAB1D;
						else if (data->Dimensions[0] > 1)
							return AMDA::Parameters::ContainerType::CT_TAB2D;
					}
					break;
ff482c31   Benjamin Renard   Give the possibil...
187
188
189
190
191
				case 3 :
					if (dim3Num < 0 || dim3Num > 2) {
						return AMDA::Parameters::ContainerType::CT_UNKNOWN;
					}
					return AMDA::Parameters::ContainerType::CT_TAB2D;
fbe3c2bb   Benjamin Renard   First commit
192
193
194
195
196
197
198
				default:
					return AMDA::Parameters::ContainerType::CT_UNKNOWN;
			}
			return AMDA::Parameters::ContainerType::CT_UNKNOWN;
		}

		//TODO Replace by DD_Client::getParamType
6edc9ff8   Hacene SI HADJ MOHAND   rm_6463
199
		AMDA::Parameters::Base::Pusher* VirtualInstrument::getParamPusher( const std::string& pParName, int maxDim1Size, int maxDim2Size, int maxDim3Size, int dim3Num, int dim3CutIndex, int minSumIndex, int maxSumIndex) {
fbe3c2bb   Benjamin Renard   First commit
200
201
202
203

			AMDA::Parameters::Base::Pusher* lPusher = nullptr;
			int error = 0;
			DD_Client lDDClient;
29bf0a3d   Elena.Budnik   setUserName() cal...
204
			
fbe3c2bb   Benjamin Renard   First commit
205
			lDDClient.setUserHost(_virtualInstrumentManager.getUserHost());
29bf0a3d   Elena.Budnik   setUserName() cal...
206
207
			lDDClient.setUserName(_virtualInstrumentManager.getUserName());
			
fbe3c2bb   Benjamin Renard   First commit
208
209
210
211
			DD_data_t *data = nullptr;
			LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getParamPusher: DD_SetVariable("<< _viName << ") call");
			int lId = lDDClient.DD_SetVariable(const_cast<char *>(_viName.c_str()));
			LOG4CXX_INFO(gLogger, "VirtualInstrument::getParamPusher: DD_SetVariable("<< _viName << ") returns = (" << _id << ")");
fbe3c2bb   Benjamin Renard   First commit
212
213
214
215
216
217
218
219
			if (lId < 0) {
				lDDClient.DD_Close(99);
				BOOST_THROW_EXCEPTION(exception() << errno_code(lId));
			}

			char startTime[TIMELENGTH];
			Double2DD_Time(startTime,_globalStartTime);
			LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getParamPusher: DD_SetTime("<< startTime << ") call");
11062ddb   Benjamin Renard   Add Themis A ESA ...
220

fbe3c2bb   Benjamin Renard   First commit
221
			if ((error = lDDClient.DD_SetTime(lId, startTime)) < 0) {
11062ddb   Benjamin Renard   Add Themis A ESA ...
222
223
224
225
226
227
228
229
230
				while ((error == WAITEXTCALL) || (error == TRYAGAIN))
				{
					sleep(2);
					error = lDDClient.DD_SetTime(lId, startTime);
				}
				if (error < 0)
				{
					lDDClient.DD_Close(lId);
					LOG4CXX_ERROR(gLogger, "VirtualInstrument::getParamPusher: DD_SetTime("<< startTime << ") returns = (" << error << ")");
80111081   Benjamin Renard   Add executable am...
231
					BOOST_THROW_EXCEPTION(exception() << errno_code(VirtualInstrumentManager::getInstance()->ddErrorToAmdaError(error)));
11062ddb   Benjamin Renard   Add Themis A ESA ...
232
				}
fbe3c2bb   Benjamin Renard   First commit
233
234
235
236
237
238
239
240
241
			}

			LOG4CXX_INFO(gLogger, "VirtualInstrument::getParamPusher: DD_SetTime("<< startTime << ") returns = (" << error << ")");

			char timeInt[TIMELENGTH];
			Double2DD_Time(timeInt, _maxSampling);
			LOG4CXX_DEBUG(gLogger, "VirtualInstrument::getParamPusher: DD_GetData("<< pParName << "," << timeInt << ") call");

			error = lDDClient.DD_GetData(lId, const_cast<char *>(pParName.c_str()), timeInt, &data);
11062ddb   Benjamin Renard   Add Themis A ESA ...
242
			while ((error == MOREDELAY) || (error == WAITEXTCALL) || (error == TRYAGAIN)) {
fbe3c2bb   Benjamin Renard   First commit
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
				sleep(2);
				error = lDDClient.DD_GetData(lId, const_cast<char *>(pParName.c_str()), timeInt, &data);
			}

			lDDClient.DD_Close(lId);

			if (error >= 0 || error == MOREDATA) {
				//#define DD_SHORT 4
				//#define DD_INT     1
				//#define DD_FLOAT   2
				//#define DD_DOUBLE 3
				//#define DD_CHAR   0
				LOG4CXX_DEBUG(gLogger, "getParamPusher data->type = " << data->type << ", dimNumber :" << data->DimNumber <<" var number : " << data->VarNumber);

				const int numDataType = data->type;

ff482c31   Benjamin Renard   Give the possibil...
259
				AMDA::Parameters::ContainerType containerType = getParamContainerType(data,dim3Num);
fbe3c2bb   Benjamin Renard   First commit
260
261
262
263
264
265
266
267
268
269
270
271
272
273
				switch (containerType)
				{
				case AMDA::Parameters::ContainerType::CT_SCALAR :
					switch (numDataType)
					{
					case DD_FLOAT:
						lPusher = new Pusher<DD_FLOAT, AMDA::Parameters::ContainerType::CT_SCALAR>();
						break;
					case DD_INT :
						lPusher = new Pusher<DD_INT, AMDA::Parameters::ContainerType::CT_SCALAR>();
						break;
					case DD_SHORT :
						lPusher = new Pusher<DD_SHORT, AMDA::Parameters::ContainerType::CT_SCALAR>();
						break;
11062ddb   Benjamin Renard   Add Themis A ESA ...
274
275
276
					case DD_DOUBLE :
						lPusher = new Pusher<DD_DOUBLE, AMDA::Parameters::ContainerType::CT_SCALAR>();
						break;
fbe3c2bb   Benjamin Renard   First commit
277
278
279
280
281
282
283
284
285
					default :
						BOOST_THROW_EXCEPTION(
						exception() << errno_code(AMDA_TYPE_DATA_UNKNOWN));
					}
					break;
				case AMDA::Parameters::ContainerType::CT_TAB1D :
					switch (numDataType)
					{
					case DD_FLOAT:
0dfc4085   Benjamin Renard   Give the possibil...
286
						lPusher = new Pusher<DD_FLOAT, AMDA::Parameters::ContainerType::CT_TAB1D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[0]);
fbe3c2bb   Benjamin Renard   First commit
287
288
						break;
					case DD_INT :
0dfc4085   Benjamin Renard   Give the possibil...
289
						lPusher = new Pusher<DD_INT, AMDA::Parameters::ContainerType::CT_TAB1D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[0]);
fbe3c2bb   Benjamin Renard   First commit
290
291
						break;
					case DD_SHORT :
0dfc4085   Benjamin Renard   Give the possibil...
292
						lPusher = new Pusher<DD_SHORT, AMDA::Parameters::ContainerType::CT_TAB1D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[0]);
fbe3c2bb   Benjamin Renard   First commit
293
						break;
11062ddb   Benjamin Renard   Add Themis A ESA ...
294
					case DD_DOUBLE :
0dfc4085   Benjamin Renard   Give the possibil...
295
						lPusher = new Pusher<DD_DOUBLE, AMDA::Parameters::ContainerType::CT_TAB1D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[0]);
11062ddb   Benjamin Renard   Add Themis A ESA ...
296
						break;
fbe3c2bb   Benjamin Renard   First commit
297
298
299
300
301
302
					default :
						BOOST_THROW_EXCEPTION(
						exception() << errno_code(AMDA_TYPE_DATA_UNKNOWN));
					}
					break;
				case AMDA::Parameters::ContainerType::CT_TAB2D :
ff482c31   Benjamin Renard   Give the possibil...
303
304
305
306
307
308
				{
					int dim1N = 0;
					int dim2N = 1;
					int dim3Size = 1;
					if (dim3Num >= 0) {
						dim1N = (dim3Num == 0) ? 1 : 0;
197552e8   Benjamin Renard   Fix abug when cut...
309
310
311
312
313
314
						if (dim1N == 0) {
							dim2N = (dim3Num == 1) ? 2 : 1;
						}
						else if (dim1N == 1) {
							dim2N = (dim3Num == 0) ? 2 : 1;
						}
ff482c31   Benjamin Renard   Give the possibil...
315
316
						dim3Size = data->Dimensions[dim3Num];
					}
fbe3c2bb   Benjamin Renard   First commit
317
318
319
					switch (numDataType)
					{
					case DD_FLOAT:
6edc9ff8   Hacene SI HADJ MOHAND   rm_6463
320
						lPusher = new Pusher<DD_FLOAT, AMDA::Parameters::ContainerType::CT_TAB2D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[dim1N], maxDim2Size > -1 ? maxDim2Size : data->Dimensions[dim2N], maxDim3Size > -1 ? maxDim3Size : dim3Size, dim1N, dim2N, dim3Num, dim3CutIndex, minSumIndex, maxSumIndex);
fbe3c2bb   Benjamin Renard   First commit
321
322
						break;
					case DD_INT :
6edc9ff8   Hacene SI HADJ MOHAND   rm_6463
323
						lPusher = new Pusher<DD_INT, AMDA::Parameters::ContainerType::CT_TAB2D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[dim1N], maxDim2Size > -1 ? maxDim2Size : data->Dimensions[dim2N], maxDim3Size > -1 ? maxDim3Size : dim3Size, dim1N, dim2N, dim3Num, dim3CutIndex,  minSumIndex, maxSumIndex);
fbe3c2bb   Benjamin Renard   First commit
324
325
						break;
					case DD_SHORT :
6edc9ff8   Hacene SI HADJ MOHAND   rm_6463
326
						lPusher = new Pusher<DD_SHORT, AMDA::Parameters::ContainerType::CT_TAB2D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[dim1N], maxDim2Size > -1 ? maxDim2Size : data->Dimensions[dim2N], maxDim3Size > -1 ? maxDim3Size : dim3Size, dim1N, dim2N, dim3Num, dim3CutIndex, minSumIndex, maxSumIndex);
fbe3c2bb   Benjamin Renard   First commit
327
						break;
11062ddb   Benjamin Renard   Add Themis A ESA ...
328
					case DD_DOUBLE :
6edc9ff8   Hacene SI HADJ MOHAND   rm_6463
329
						lPusher = new Pusher<DD_DOUBLE, AMDA::Parameters::ContainerType::CT_TAB2D>(maxDim1Size > -1 ? maxDim1Size : data->Dimensions[dim1N], maxDim2Size > -1 ? maxDim2Size : data->Dimensions[dim2N], maxDim3Size > -1 ? maxDim3Size : dim3Size, dim1N, dim2N, dim3Num, dim3CutIndex, minSumIndex, maxSumIndex);
11062ddb   Benjamin Renard   Add Themis A ESA ...
330
						break;
fbe3c2bb   Benjamin Renard   First commit
331
332
333
334
335
					default :
						BOOST_THROW_EXCEPTION(
						exception() << errno_code(AMDA_TYPE_DATA_UNKNOWN));
					}
					break;
ff482c31   Benjamin Renard   Give the possibil...
336
				}
fbe3c2bb   Benjamin Renard   First commit
337
338
339
340
341
342
343
344
345
				default:
					LOG4CXX_INFO(gLogger, "VirtualInstrument::getParamPusher( "<< lId <<", " << pParName << ") - Unknown container type");
					lDDClient.DD_Close(lId);
					BOOST_THROW_EXCEPTION(exception() << errno_code(AMDA_TYPE_DATA_UNKNOWN));
				}
				lPusher->setFillValue(_fillValue);
			} else {
				LOG4CXX_INFO(gLogger, "VirtualInstrument::getParamPusher( "<< lId <<", " << pParName << ") returns = (" << error << ")");
				lDDClient.DD_Close(lId);
80111081   Benjamin Renard   Add executable am...
346
				BOOST_THROW_EXCEPTION(exception() << errno_code(VirtualInstrumentManager::getInstance()->ddErrorToAmdaError(error)));
fbe3c2bb   Benjamin Renard   First commit
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
			}

			return lPusher;
		}

		VI::ParamFlowSPtr VirtualInstrument::getParamFlow(const std::string& pParamName, TimeIntervalListSPtr pTimeIntervalList) {
			// Define function to compare two TimeIntervalListSptr.
			// This used to identify if the requested TimeIntervalList already exist in _intervalList attribute or not.
			auto lIt = std::find_if( _intervalList.begin(), _intervalList.end(), [&](const IntervalList::value_type& val) -> bool {
				if (val.first->size() != pTimeIntervalList->size()) {
					return false;
				} else {
					TimeIntervalList::const_iterator itA = val.first->begin();
					TimeIntervalList::const_iterator itB = pTimeIntervalList->begin();
					while (itA != val.first->end()) {
						if ( (itA->_startTime != itB->_startTime) || (itA->_stopTime != itB->_stopTime) ) {
							return false;
						} else {
							++itA;
							++itB;
						}
					}
					return true;
				}
			});

			// TimeIntervalListSPtr not found
			if (lIt == _intervalList.end()) {
				std::pair<TimeIntervalListSPtr, VirtualIntrumentIntervalSPtr> value(pTimeIntervalList, VirtualIntrumentIntervalSPtr(new VirtualInstrumentInterval(*this, pTimeIntervalList.get())));
				std::pair<IntervalList::iterator,bool> lIter = _intervalList.insert(value);
				lIt = lIter.first;
			} else {
				// Nothing to do.
			}

			return lIt->second->getParamFlow(pParamName);
		}

	} /* namespace DDServerInterface */
} /* namespace AMDA */