BayesLocalOperation.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/sa/core/BayesLocalOperation.cpp
22 
23  \brief This file contains a class that represents the bayes local operation.
24 
25  \reference Adapted from TerraLib4.
26 */
27 
28 //TerraLib
29 #include "../../common/Exception.h"
30 #include "../../core/translator/Translator.h"
31 #include "../../common/progress/TaskProgress.h"
32 #include "../../dataaccess/datasource/DataSource.h"
33 #include "../../dataaccess/datasource/DataSourceManager.h"
34 #include "../../dataaccess/utils/Utils.h"
35 #include "../../datatype/SimpleProperty.h"
36 #include "../../geometry/Geometry.h"
37 #include "../../geometry/GeometryProperty.h"
38 #include "../../graph/core/AbstractGraph.h"
39 #include "../../graph/core/Edge.h"
40 #include "../../graph/core/Vertex.h"
41 #include "../../memory/DataSet.h"
42 #include "../../memory/DataSetItem.h"
43 #include "BayesLocalOperation.h"
44 #include "Utils.h"
45 
46 //STL
47 #include <cassert>
48 
50 
52 
54 {
55  assert(m_inputParams->m_ds.get());
56  assert(m_inputParams->m_dsType.get());
57 
58  //associate gpm event attribute
59  std::size_t eventIdx = m_inputParams->m_dsType->getPropertyPosition(m_inputParams->m_eventAttrName);
60  int eventType = m_inputParams->m_ds->getPropertyDataType(eventIdx);
61  int gpmEventIdx = te::sa::AssociateGPMVertexAttribute(m_inputParams->m_gpm.get(), m_inputParams->m_ds.get(), m_inputParams->m_gpmAttrLink, m_inputParams->m_eventAttrName, eventType);
62 
63  //associate gpm population attribute
64  std::size_t popIdx = m_inputParams->m_dsType->getPropertyPosition(m_inputParams->m_populationAttrName);
65  int popType = m_inputParams->m_ds->getPropertyDataType(popIdx);
66  int gpmPopIdx = te::sa::AssociateGPMVertexAttribute(m_inputParams->m_gpm.get(), m_inputParams->m_ds.get(), m_inputParams->m_gpmAttrLink, m_inputParams->m_populationAttrName, popType);
67 
68  //create output data
69  std::unique_ptr<te::da::DataSetType> outDsType = createDataSetType(m_inputParams->m_dsType.get());
70  std::unique_ptr<te::mem::DataSet> outDs = createDataSet(m_inputParams->m_ds.get(), outDsType.get());
71 
72  //run bayes
73  eventIdx = outDsType->getPropertyPosition(m_inputParams->m_eventAttrName);
74  popIdx = outDsType->getPropertyPosition(m_inputParams->m_populationAttrName);
75 
76  std::size_t idIdx = outDsType->getPropertyPosition(m_inputParams->m_gpmAttrLink);
77  std::size_t neighEventIdx = outDsType->getPropertyPosition(TE_SA_BAYESEVENT_ATTR_NAME);
78  std::size_t neighPopIdx = outDsType->getPropertyPosition(TE_SA_BAYESPOP_ATTR_NAME);
79  std::size_t bayesIdx = outDsType->getPropertyPosition(TE_SA_BAYES_ATTR_NAME);
80 
81  runBayesLocal(outDs.get(), idIdx, eventIdx, popIdx, neighEventIdx, neighPopIdx, bayesIdx, static_cast<size_t>(gpmEventIdx), static_cast<size_t>(gpmPopIdx));
82 
83  //save data
84  saveDataSet(outDs.get(), outDsType.get());
85 }
86 
88 {
89  m_inputParams.reset(inParams);
90  m_outputParams.reset(outParams);
91 }
92 
94 {
95  //save dataset
96  dataSet->moveBeforeFirst();
97 
98  std::map<std::string, std::string> options;
99 
100  m_outputParams->m_ds->createDataSet(dsType, options);
101 
102  m_outputParams->m_ds->add(m_outputParams->m_outputDataSetName, dataSet, options);
103 }
104 
105 std::unique_ptr<te::da::DataSetType> te::sa::BayesLocalOperation::createDataSetType(te::da::DataSetType* dsType)
106 {
107  std::unique_ptr<te::da::DataSetType> dataSetType(new te::da::DataSetType(m_outputParams->m_outputDataSetName));
108 
109  //create all input dataset properties
110  std::vector<te::dt::Property*> propertyVec = dsType->getProperties();
111 
112  for(std::size_t t = 0; t < propertyVec.size(); ++t)
113  {
114  te::dt::Property* prop = propertyVec[t];
115 
116  te::dt::Property* newProp = prop->clone();
117  newProp->setId(0);
118  newProp->setParent(nullptr);
119 
120  dataSetType->add(newProp);
121  }
122 
123  //create neighbour event property
125  dataSetType->add(neighEvent);
126 
127  //create neighbour population property
129  dataSetType->add(neighPop);
130 
131  //create bayes property
133  dataSetType->add(bayesProperty);
134 
135  return dataSetType;
136 }
137 
138 std::unique_ptr<te::mem::DataSet> te::sa::BayesLocalOperation::createDataSet(te::da::DataSet* inputDataSet, te::da::DataSetType* dsType)
139 {
140  std::unique_ptr<te::mem::DataSet> outDataset(new te::mem::DataSet(dsType));
141 
142  std::size_t nProp = inputDataSet->getNumProperties();
143 
144  inputDataSet->moveBeforeFirst();
145 
146  while(inputDataSet->moveNext())
147  {
148  //create dataset item
149  te::mem::DataSetItem* outDSetItem = new te::mem::DataSetItem(outDataset.get());
150 
151  for(std::size_t t = 0; t < nProp; ++t)
152  {
153  te::dt::AbstractData* ad = inputDataSet->getValue(t).release();
154 
155  outDSetItem->setValue(t, ad);
156  }
157 
158  //set kernel default value
159  outDSetItem->setDouble(TE_SA_BAYESEVENT_ATTR_NAME, 0.);
160 
161  //set kernel default value
162  outDSetItem->setDouble(TE_SA_BAYESPOP_ATTR_NAME, 0.);
163 
164  //set kernel default value
165  outDSetItem->setDouble(TE_SA_BAYES_ATTR_NAME, 0.);
166 
167  //add item into dataset
168  outDataset->add(outDSetItem);
169  }
170 
171  return outDataset;
172 }
173 
174 void te::sa::BayesLocalOperation::runBayesLocal(te::mem::DataSet* ds, std::size_t idIdx, std::size_t eventIdx, std::size_t popIdx,
175  std::size_t neighEventIdx, std::size_t neighPopIdx, std::size_t bayesIdx, std::size_t gpmEventIdx, std::size_t gpmPopIdx)
176 {
177  assert(m_inputParams->m_gpm.get());
178 
179  te::graph::AbstractGraph* graph = m_inputParams->m_gpm->getGraph();
180 
181  {
182  //create task
184 
185  task.setTotalSteps(static_cast<int>(ds->size()));
186  task.setMessage(TE_TR("Calculating events and population for each element."));
187 
188  //calculate neighbour events and population for each element
189  ds->moveBeforeFirst();
190 
191  while(ds->moveNext())
192  {
193  std::string strId = ds->getAsString(idIdx);
194 
195  int id = atoi(strId.c_str());
196 
197  double totEvent = ds->getDouble(eventIdx);
198  double totPop = ds->getDouble(popIdx);
199 
200  te::graph::Vertex* v = graph->getVertex(id);
201 
202  if(v)
203  {
204  std::set<int> neighbours = v->getSuccessors();
205  std::set<int>::iterator itNeighbours = neighbours.begin();
206  while(itNeighbours != neighbours.end())
207  {
208  te::graph::Edge* e = graph->getEdge(*itNeighbours);
209  te::graph::Vertex* vTo = nullptr;
210 
211  if(e)
212  {
213  if(e->getIdFrom() == id)
214  vTo = graph->getVertex(e->getIdTo());
215  else
216  vTo = graph->getVertex(e->getIdFrom());
217  }
218 
219  if(vTo)
220  {
221  totEvent += te::sa::GetDataValue(vTo->getAttributes()[gpmEventIdx]);
222  totPop += te::sa::GetDataValue(vTo->getAttributes()[gpmPopIdx]);
223  }
224 
225  ++itNeighbours;
226  }
227  }
228 
229  ds->setDouble(neighEventIdx, totEvent);
230  ds->setDouble(neighPopIdx, totPop);
231  }
232 
233  if(!task.isActive())
234  {
235  throw te::common::Exception(TE_TR("Operation canceled by the user."));
236  }
237 
238  task.pulse();
239  }
240 
241 
242  {
243  //create task
245 
246  task.setTotalSteps(static_cast<int>(ds->size()));
247  task.setMessage(TE_TR("Calculating Local Bayes."));
248 
249  //calculate local bayes values
250  ds->moveBeforeFirst();
251 
252  while(ds->moveNext())
253  {
254  std::string strId = ds->getAsString(idIdx);
255 
256  int id = atoi(strId.c_str());
257 
258  double myEvent = ds->getDouble(eventIdx);
259  double myPop = ds->getDouble(popIdx);
260 
261  double totEvent = ds->getDouble(neighEventIdx);
262  double totPop = ds->getDouble(neighPopIdx);
263 
264  if(totPop <= 0.)
265  throw;
266 
267  double mean = totEvent / totPop;
268 
269  double thetaI = (myPop > 0) ? myEvent / myPop : 0.0;
270 
271  te::graph::Vertex* v = graph->getVertex(id);
272 
273  if(v)
274  {
275  std::set<int> neighbours = v->getSuccessors();
276  std::set<int>::iterator itNeighbours = neighbours.begin();
277  int nNeighbours = static_cast<int>(neighbours.size());
278 
279  if(nNeighbours != 0)
280  {
281  double variance = myPop * pow((myEvent / myPop) - mean, 2);
282 
283  while(itNeighbours != neighbours.end())
284  {
285  te::graph::Edge* e = graph->getEdge(*itNeighbours);
286  te::graph::Vertex* vTo = nullptr;
287 
288  if(e)
289  {
290  if(e->getIdFrom() == id)
291  vTo = graph->getVertex(e->getIdTo());
292  else
293  vTo = graph->getVertex(e->getIdFrom());
294  }
295 
296  if(vTo)
297  {
298  double toEvent = te::sa::GetDataValue(vTo->getAttributes()[gpmEventIdx]);
299  double toPop = te::sa::GetDataValue(vTo->getAttributes()[gpmPopIdx]);
300 
301  variance += toPop * pow((toEvent / toPop) - mean, 2);
302  }
303 
304  ++itNeighbours;
305  }
306 
307  variance /= totPop;
308 
309  double aux = variance - (mean * (static_cast<double>(nNeighbours + 1.)) / totPop);
310 
311  if(aux < 0.)
312  aux = 0.;
313 
314  double wI = 1.;
315 
316  if(aux != 0. || mean != 0.)
317  wI = aux / (aux + (mean / myPop));
318 
319  thetaI = wI * (myEvent / myPop) + (1 - wI) * mean;
320  }
321  }
322 
323  ds->setDouble(bayesIdx, thetaI * m_inputParams->m_rate);
324  }
325 
326  if(!task.isActive())
327  {
328  throw te::common::Exception(TE_TR("Operation canceled by the user."));
329  }
330 
331  task.pulse();
332  }
333 }
std::size_t size() const
It returns the collection size, if it is known.
Class that represents the Bayes output parameters.
Definition: BayesParams.h:94
This file contains a class that represents the bayes global operation.
void setMessage(const std::string &message)
Set the task message.
void saveDataSet(te::da::DataSet *dataSet, te::da::DataSetType *dsType)
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
An atomic property like an integer or double.
A class that models the description of a dataset.
Definition: DataSetType.h:72
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
static te::dt::Date ds(2010, 01, 01)
std::vector< te::dt::AbstractData * > & getAttributes()
It returns the vector of attributes associated with this element.
Definition: Vertex.cpp:74
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
virtual Property * clone() const =0
It returns a clone of the object.
It models a property definition.
Definition: Property.h:59
bool isActive() const
Verify if the task is active.
From the point of view of graph theory, vertices are treated as featureless and indivisible objects...
Definition: Vertex.h:68
void setTotalSteps(int value)
Set the task total stepes.
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:118
std::unique_ptr< te::da::DataSetType > createDataSetType(te::da::DataSetType *dsType)
Class used to define the edge struct of a graph. Its compose with a identifier, the vertex origin and...
Definition: Edge.h:58
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
~BayesLocalOperation()
Virtual destructor.
#define TE_SA_BAYESPOP_ATTR_NAME
BayesLocalOperation()
Default constructor.
#define TE_SA_BAYES_ATTR_NAME
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
Abstract class used to define the main functions of graph struct. All graph implementations must used...
Definition: AbstractGraph.h:55
#define TE_SA_BAYESEVENT_ATTR_NAME
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
virtual std::string getAsString(std::size_t i, int precision=0) const
Method for retrieving a data value as a string plain representation.
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
std::set< int > & getSuccessors()
Returns the Successors vector.
Definition: Vertex.cpp:106
int getIdFrom()
It returns the vertex origin identification.
Definition: Edge.cpp:71
Utility functions for the data access module.
std::unique_ptr< te::mem::DataSet > createDataSet(te::da::DataSet *inputDataSet, te::da::DataSetType *dsType)
TESAEXPORT int AssociateGPMVertexAttribute(te::sa::GeneralizedProximityMatrix *gpm, te::da::DataSource *ds, std::string dataSetName, std::string attrLink, std::string attr, int dataType, int srid=TE_UNKNOWN_SRS, int subType=static_cast< int >(te::gm::UnknownGeometryType))
Function used to set a an attribute valeu from a dataset to the vertex objects from a gpm...
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
bool moveNext()
It moves the internal pointer to the next item of the collection.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
A dataset is the unit of information manipulated by the data access module of TerraLib.
Class that represents the Bayes input parameters.
Definition: BayesParams.h:56
double getDouble(std::size_t i) const
Method for retrieving a double attribute value.
void runBayesLocal(te::mem::DataSet *ds, std::size_t idIdx, std::size_t eventIdx, std::size_t popIdx, std::size_t neighEventIdx, std::size_t neighPopIdx, std::size_t bayesIdx, std::size_t gpmEventIdx, std::size_t gpmPopIdx)
virtual std::unique_ptr< te::dt::AbstractData > getValue(std::size_t i) const
Method for retrieving any other type of data value stored in the data source.
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
std::unique_ptr< te::sa::BayesOutputParams > m_outputParams
Attribute with the bayes output parameters.
TESAEXPORT double GetDataValue(te::dt::AbstractData *ad)
Function used to get the numeric value from a gpm property.
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
void setParameters(te::sa::BayesInputParams *inParams, te::sa::BayesOutputParams *outParams)
std::unique_ptr< te::sa::BayesInputParams > m_inputParams
Attribute with the bayes input parameters.
void setDouble(std::size_t i, double value)
void execute()
Function to execute the bayes operation.
int getIdTo()
It returns the vertex destiny identification.
Definition: Edge.cpp:76
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:177