My Project
ContinuousProperty.h
1 /*-----------------------------------------------------------------------
2 Copyright F2I-CONSULTING, (2014-2016)
3 
4 philippe.verney@f2i-consulting.com
5 
6 This software is a computer program whose purpose is to access to data formatted using Energistics standards.
7 
8 This software is governed by the CeCILL-B license under French law and
9 abiding by the rules of distribution of free software. You can use,
10 modify and/ or redistribute the software under the terms of the CeCILL-B
11 license as circulated by CEA, CNRS and INRIA at the following URL
12 "http://www.cecill.info".
13 
14 As a counterpart to the access to the source code and rights to copy,
15 modify and redistribute granted by the license, users are provided only
16 with a limited warranty and the software's author, the holder of the
17 economic rights, and the successive licensors have only limited
18 liability.
19 
20 In this respect, the user's attention is drawn to the risks associated
21 with loading, using, modifying and/or developing or reproducing the
22 software by the user in light of its specific status of free software,
23 that may mean that it is complicated to manipulate, and that also
24 therefore means that it is reserved for developers and experienced
25 professionals having in-depth computer knowledge. Users are therefore
26 encouraged to load and test the software's suitability as regards their
27 requirements in conditions enabling the security of their systems and/or
28 data to be ensured and, more generally, to use and operate it in the
29 same conditions as regards security.
30 
31 The fact that you are presently reading this means that you have had
32 knowledge of the CeCILL-B license and that you accept its terms.
33 -----------------------------------------------------------------------*/
34 #pragma once
35 
36 #include "resqml2/AbstractValuesProperty.h"
37 #include "resqml2/AbstractHdfProxy.h"
38 
39 #include <stdexcept>
40 #include <sstream> // std::ostringstream
41 
42 namespace resqml2_0_1
43 {
44  class DLL_IMPORT_OR_EXPORT ContinuousProperty : public resqml2::AbstractValuesProperty
45  {
46  protected:
47 
52 
53  private:
54 
63  void init(resqml2::AbstractRepresentation * rep, const std::string & guid, const std::string & title,
64  const unsigned int & dimension, const gsoap_resqml2_0_1::resqml2__IndexableElements & attachmentKind);
65 
66  public:
67 
78  ContinuousProperty(resqml2::AbstractRepresentation * rep, const std::string & guid, const std::string & title,
79  const unsigned int & dimension, const gsoap_resqml2_0_1::resqml2__IndexableElements & attachmentKind, const gsoap_resqml2_0_1::resqml2__ResqmlUom & uom, const gsoap_resqml2_0_1::resqml2__ResqmlPropertyKind & energisticsPropertyKind);
80 
91  ContinuousProperty(resqml2::AbstractRepresentation * rep, const std::string & guid, const std::string & title,
92  const unsigned int & dimension, const gsoap_resqml2_0_1::resqml2__IndexableElements & attachmentKind, const gsoap_resqml2_0_1::resqml2__ResqmlUom & uom, resqml2::PropertyKind * localPropKind);
93 
104  ContinuousProperty(resqml2::AbstractRepresentation * rep, const std::string & guid, const std::string & title,
105  const unsigned int & dimension, const gsoap_resqml2_0_1::resqml2__IndexableElements & attachmentKind, const std::string & nonStandardUom, const gsoap_resqml2_0_1::resqml2__ResqmlPropertyKind & energisticsPropertyKind);
106 
117  ContinuousProperty(resqml2::AbstractRepresentation * rep, const std::string & guid, const std::string & title,
118  const unsigned int & dimension, const gsoap_resqml2_0_1::resqml2__IndexableElements & attachmentKind, const std::string & nonStandardUom, resqml2::PropertyKind * localPropKind);
119 
123  ContinuousProperty(gsoap_resqml2_0_1::_resqml2__ContinuousProperty* fromGsoap): AbstractValuesProperty(fromGsoap) {}
124 
128  virtual ~ContinuousProperty() {}
129 
130  static const char* XML_TAG;
131  virtual std::string getXmlTag() const {return XML_TAG;}
132 
136  const gsoap_resqml2_0_1::resqml2__ResqmlUom & getUom() const;
137 
141  std::string getUomAsString() const;
142 
151  void pushBackDoubleHdf5Array1dOfValues(double * values, const ULONG64 & valueCount, resqml2::AbstractHdfProxy* proxy,
152  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
153 
163  void pushBackDoubleHdf5Array2dOfValues(double * values, const ULONG64 & valueCountInFastestDim, const ULONG64 & valueCountInSlowestDim, resqml2::AbstractHdfProxy* proxy,
164  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
165 
176  void pushBackDoubleHdf5Array3dOfValues(double * values, const ULONG64 & valueCountInFastestDim, const ULONG64 & valueCountInMiddleDim, const ULONG64 & valueCountInSlowestDim, resqml2::AbstractHdfProxy* proxy,
177  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
178 
188  void pushBackDoubleHdf5ArrayOfValues(double * values, unsigned long long * numValues, const unsigned int & numArrayDimensions, resqml2::AbstractHdfProxy* proxy,
189  double * minimumValue = nullptr, double * maximumValue = nullptr);
190 
199  void pushBackFloatHdf5Array1dOfValues(float * values, const ULONG64 & valueCount, resqml2::AbstractHdfProxy* proxy,
200  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
201 
211  void pushBackFloatHdf5Array2dOfValues(float * values, const ULONG64 & valueCountInFastestDim, const ULONG64 & valueCountInSlowestDim, resqml2::AbstractHdfProxy* proxy,
212  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
213 
224  void pushBackFloatHdf5Array3dOfValues(float * values, const ULONG64 & valueCountInFastestDim, const ULONG64 & valueCountInMiddleDim, const ULONG64 & valueCountInSlowestDim, resqml2::AbstractHdfProxy* proxy,
225  const double & minimumValue = std::numeric_limits<double>::quiet_NaN(), const double & maximumValue = std::numeric_limits<double>::quiet_NaN());
226 
236  void pushBackFloatHdf5ArrayOfValues(float * values, unsigned long long * numValues, const unsigned int & numArrayDimensions, resqml2::AbstractHdfProxy* proxy,
237  double * minimumValue = nullptr, double * maximumValue = nullptr);
238 
245  void createFloatHdf5ArrayOfValues(
246  unsigned long long* numValues,
247  const unsigned int& numArrayDimensions,
249  );
250 
258  void createFloatHdf5Array3dOfValues(
259  const ULONG64& valueCountInFastestDim,
260  const ULONG64& valueCountInMiddleDim,
261  const ULONG64& valueCountInSlowestDim,
263  );
264 
276  void pushBackFloatHdf5SlabArray3dOfValues(
277  float* values,
278  const ULONG64& valueCountInFastestDim,
279  const ULONG64& valueCountInMiddleDim,
280  const ULONG64& valueCountInSlowestDim,
281  const ULONG64& offsetInFastestDim,
282  const ULONG64& offsetInMiddleDim,
283  const ULONG64& offsetInSlowestDim,
285  );
286 
296  void pushBackFloatHdf5SlabArrayOfValues(
297  float * values,
298  unsigned long long * numValues,
299  unsigned long long * offsetValues,
300  const unsigned int & numArrayDimensions,
302  );
303 
308  void getDoubleValuesOfPatch(const unsigned int & patchIndex, double * values);
309 
314  void getFloatValuesOfPatch(const unsigned int & patchIndex, float * values);
315 
324  void getFloatValuesOfPatch(
325  const unsigned int& patchIndex,
326  float* values,
327  unsigned long long* numValuesInEachDimension,
328  unsigned long long* offsetInEachDimension,
329  const unsigned int& numArrayDimensions
330  );
331 
343  void getFloatValuesOf3dPatch(
344  const unsigned int& patchIndex,
345  float* values,
346  const ULONG64& valueCountInFastestDim,
347  const ULONG64& valueCountInMiddleDim,
348  const ULONG64& valueCountInSlowestDim,
349  const ULONG64& offsetInFastestDim,
350  const ULONG64& offsetInMiddleDim,
351  const ULONG64& offsetInSlowestDim
352  );
353 
354  double getMinimumValue();
355  double getMaximumValue();
356 
357  gsoap_resqml2_0_1::resqml2__ResqmlPropertyKind getFirstAllowedPropertyKindParent() const;
358 
359  private:
360 
367  template <class T>
368  void setPropertyMinMax(
369  T* values,
370  unsigned long long* numValuesInEachDimension,
371  const unsigned int& numArrayDimensions
372  ) {
373  gsoap_resqml2_0_1::_resqml2__ContinuousProperty* prop =
374  static_cast<gsoap_resqml2_0_1::_resqml2__ContinuousProperty*>(gsoapProxy2_0_1);
375  if (prop->Count == 1) {
376 
377  ULONG64 nValues = numValuesInEachDimension[0];
378 
379  for (unsigned int dim = 1; dim < numArrayDimensions; dim++) {
380  nValues *= numValuesInEachDimension[dim];
381  }
382 
383  T computedMin = prop->MinimumValue[0];
384  T computedMax = prop->MaximumValue[0];
385 
386  for (ULONG64 i = 0; i < nValues; ++i) {
387  if( values[i] < computedMin ) {
388  computedMin = values[i];
389  } else if( values[i] > computedMax ) {
390  computedMax = values[i];
391  }
392  }
393  prop->MinimumValue[0] = computedMin;
394  prop->MaximumValue[0] = computedMax;
395  } else if (prop->Count > 1) {
396  //In this case, the last (fastest) dimension
397  //has the number of elements in the representation.
398  ULONG64 nValues = numValuesInEachDimension[0];
399 
400  for (unsigned int dim = 1; dim < numArrayDimensions-1; dim++) {
401  nValues *= numValuesInEachDimension[dim];
402  }
403 
404  const int nProperties = prop->Count;
405 
406  for(int propIndex = 0; propIndex < nProperties; ++propIndex) {
407  T computedMin = prop->MinimumValue[propIndex];
408  T computedMax = prop->MaximumValue[propIndex];
409 
410  for (ULONG64 valIndex = 0; valIndex < nValues; ++valIndex) {
411  T propVal = values[propIndex+(nProperties*valIndex)];
412  if( propVal < computedMin ) {
413  computedMin = values[valIndex];
414  } else if( propVal > computedMax ) {
415  computedMax = values[valIndex];
416  }
417  }
418  prop->MinimumValue.push_back(computedMin);
419  prop->MaximumValue.push_back(computedMax);
420  }
421  }
422  }
423 
424  template <class valueType>
425  void pushBackXmlPartOfArrayNdOfExplicitValues(valueType * values, unsigned long long * numValues, const unsigned int & numValueDimensions, resqml2::AbstractHdfProxy * proxy,
426  double * minimumValue = nullptr, double * maximumValue = nullptr)
427  {
428  setHdfProxy(proxy);
429  gsoap_resqml2_0_1::_resqml2__ContinuousProperty* prop = static_cast<gsoap_resqml2_0_1::_resqml2__ContinuousProperty*>(gsoapProxy2_0_1);
430 
431  if (prop->Count == 1)
432  {
433  double computedMinimumValue;
434  double computedMaximumValue;
435  if (minimumValue == nullptr || maximumValue == nullptr)
436  {
437  ULONG64 numTotalValues = numValues[0];
438  for (unsigned int dim = 1; dim < numValueDimensions; dim++)
439  numTotalValues *= numValues[dim];
440 
441  unsigned int i = 0;
442  computedMinimumValue = std::numeric_limits<double>::quiet_NaN();
443  computedMaximumValue = std::numeric_limits<double>::quiet_NaN();
444  while (values[i] != values[i]) ++i;
445  if (i < numTotalValues)
446  {
447  computedMinimumValue = values[i];
448  computedMaximumValue = values[i];
449  }
450  for (; i < numTotalValues; ++i)
451  {
452  if (values[i] == values[i])
453  {
454  if (values[i] > computedMaximumValue)
455  computedMaximumValue = values[i];
456  else if (values[i] < computedMinimumValue)
457  computedMinimumValue = values[i];
458  }
459  }
460  }
461  else
462  {
463  computedMinimumValue = minimumValue[0];
464  computedMaximumValue = maximumValue[0];
465  }
466 
467  prop->MinimumValue.push_back(computedMinimumValue);
468  prop->MaximumValue.push_back(computedMaximumValue);
469  }
470  else if (minimumValue || maximumValue)
471  {
472  if (minimumValue)
473  {
474  prop->MinimumValue.clear();
475  for (unsigned int i = 0; i < prop->Count; i++)
476  {
477  prop->MinimumValue.push_back(minimumValue[i]);
478  }
479  }
480  if (maximumValue)
481  {
482  prop->MaximumValue.clear();
483  for (unsigned int i = 0; i < prop->Count; i++)
484  {
485  prop->MaximumValue.push_back(maximumValue[i]);
486  }
487  }
488  }
489 
490  gsoap_resqml2_0_1::resqml2__PatchOfValues* patch = gsoap_resqml2_0_1::soap_new_resqml2__PatchOfValues(gsoapProxy2_0_1->soap, 1);
491  patch->RepresentationPatchIndex = static_cast<ULONG64*>(soap_malloc(gsoapProxy2_0_1->soap, sizeof(ULONG64)));
492  *(patch->RepresentationPatchIndex) = prop->PatchOfValues.size();
493 
494  // XML
495  gsoap_resqml2_0_1::resqml2__DoubleHdf5Array* xmlValues = gsoap_resqml2_0_1::soap_new_resqml2__DoubleHdf5Array(gsoapProxy2_0_1->soap, 1);
496  xmlValues->Values = gsoap_resqml2_0_1::soap_new_eml__Hdf5Dataset(gsoapProxy2_0_1->soap, 1);
497  xmlValues->Values->HdfProxy = proxy->newResqmlReference();
498  std::ostringstream ossForHdf;
499  ossForHdf << "values_patch" << *(patch->RepresentationPatchIndex);
500  xmlValues->Values->PathInHdfFile = "/RESQML/" + prop->uuid + "/" + ossForHdf.str();
501  patch->Values = xmlValues;
502 
503  prop->PatchOfValues.push_back(patch);
504  }
505  };
506 }
Definition: AbstractHdfProxy.h:44
virtual ~ContinuousProperty()
Definition: ContinuousProperty.h:128
Definition: AbstractValuesProperty.h:40
Definition: PropertyKind.h:40
Definition: ContinuousProperty.h:44
virtual std::string getXmlTag() const
Definition: ContinuousProperty.h:131
Definition: EpcDocument.h:79
Definition: AbstractRepresentation.h:40
ContinuousProperty()
Definition: ContinuousProperty.h:51
ContinuousProperty(gsoap_resqml2_0_1::_resqml2__ContinuousProperty *fromGsoap)
Definition: ContinuousProperty.h:123