1 |
jgs |
82 |
// $Id$ |
2 |
jgs |
121 |
|
3 |
jgs |
82 |
/* |
4 |
|
|
****************************************************************************** |
5 |
|
|
* * |
6 |
|
|
* COPYRIGHT ACcESS 2004 - All Rights Reserved * |
7 |
|
|
* * |
8 |
|
|
* This software is the property of ACcESS. No part of this code * |
9 |
|
|
* may be copied in any form or by any means without the expressed written * |
10 |
|
|
* consent of ACcESS. Copying, use or modification of this software * |
11 |
|
|
* by any unauthorised person is illegal unless that person has a software * |
12 |
|
|
* license agreement with ACcESS. * |
13 |
|
|
* * |
14 |
|
|
****************************************************************************** |
15 |
|
|
*/ |
16 |
|
|
|
17 |
jgs |
474 |
#include "DataTagged.h" |
18 |
jgs |
496 |
|
19 |
jgs |
474 |
#include "DataConstant.h" |
20 |
|
|
#include "DataException.h" |
21 |
jgs |
82 |
|
22 |
|
|
using namespace std; |
23 |
|
|
|
24 |
|
|
namespace escript { |
25 |
|
|
|
26 |
jgs |
121 |
DataTagged::DataTagged() |
27 |
|
|
: DataAbstract(FunctionSpace()) |
28 |
jgs |
82 |
{ |
29 |
jgs |
509 |
// default constructor |
30 |
|
|
|
31 |
jgs |
82 |
// create a scalar default value |
32 |
jgs |
151 |
m_data.resize(1,0.,1); |
33 |
jgs |
82 |
DataArrayView temp(m_data,DataArrayView::ShapeType()); |
34 |
|
|
setPointDataView(temp); |
35 |
|
|
} |
36 |
|
|
|
37 |
|
|
DataTagged::DataTagged(const TagListType& tagKeys, |
38 |
|
|
const ValueListType& values, |
39 |
|
|
const DataArrayView& defaultValue, |
40 |
jgs |
102 |
const FunctionSpace& what) |
41 |
|
|
: DataAbstract(what) |
42 |
jgs |
82 |
{ |
43 |
jgs |
509 |
// constructor |
44 |
|
|
|
45 |
jgs |
121 |
// initialise the array of data values |
46 |
|
|
// the default value is always the first item in the values list |
47 |
jgs |
151 |
int len = defaultValue.noValues(); |
48 |
|
|
m_data.resize(len,0.,len); |
49 |
jgs |
121 |
for (int i=0; i<defaultValue.noValues(); i++) { |
50 |
|
|
m_data[i]=defaultValue.getData(i); |
51 |
|
|
} |
52 |
|
|
|
53 |
jgs |
119 |
// create the data view |
54 |
jgs |
82 |
DataArrayView temp(m_data,defaultValue.getShape()); |
55 |
|
|
setPointDataView(temp); |
56 |
jgs |
121 |
|
57 |
jgs |
82 |
// add remaining tags and values |
58 |
|
|
addTaggedValues(tagKeys,values); |
59 |
|
|
} |
60 |
|
|
|
61 |
jgs |
119 |
DataTagged::DataTagged(const FunctionSpace& what, |
62 |
|
|
const DataArrayView::ShapeType &shape, |
63 |
|
|
const int tags[], |
64 |
jgs |
500 |
const ValueType& data) |
65 |
jgs |
119 |
: DataAbstract(what) |
66 |
|
|
{ |
67 |
jgs |
509 |
// alternative constructor |
68 |
|
|
// not unit_tested tested yet |
69 |
|
|
|
70 |
jgs |
121 |
// copy the data |
71 |
jgs |
119 |
m_data=data; |
72 |
jgs |
121 |
|
73 |
jgs |
119 |
// create the view of the data |
74 |
|
|
DataArrayView tempView(m_data,shape); |
75 |
|
|
setPointDataView(tempView); |
76 |
jgs |
121 |
|
77 |
jgs |
119 |
// create the tag lookup map |
78 |
|
|
for (int sampleNo=0; sampleNo<getNumSamples(); sampleNo++) { |
79 |
|
|
m_offsetLookup.insert(DataMapType::value_type(sampleNo,tags[sampleNo])); |
80 |
|
|
} |
81 |
|
|
} |
82 |
|
|
|
83 |
jgs |
102 |
DataTagged::DataTagged(const DataTagged& other) |
84 |
|
|
: DataAbstract(other.getFunctionSpace()), |
85 |
jgs |
82 |
m_data(other.m_data), |
86 |
|
|
m_offsetLookup(other.m_offsetLookup) |
87 |
|
|
{ |
88 |
jgs |
509 |
// copy constructor |
89 |
|
|
|
90 |
jgs |
119 |
// create the data view |
91 |
jgs |
82 |
DataArrayView temp(m_data,other.getPointDataView().getShape()); |
92 |
|
|
setPointDataView(temp); |
93 |
|
|
} |
94 |
|
|
|
95 |
jgs |
102 |
DataTagged::DataTagged(const DataConstant& other) |
96 |
|
|
: DataAbstract(other.getFunctionSpace()) |
97 |
jgs |
82 |
{ |
98 |
jgs |
509 |
// copy constructor |
99 |
|
|
|
100 |
jgs |
121 |
// fill the default value with the constant value item from "other" |
101 |
jgs |
82 |
const DataArrayView& value=other.getPointDataView(); |
102 |
jgs |
151 |
int len = value.noValues(); |
103 |
|
|
m_data.resize(len,0.,len); |
104 |
jgs |
121 |
for (int i=0; i<value.noValues(); i++) { |
105 |
|
|
m_data[i]=value.getData(i); |
106 |
|
|
} |
107 |
|
|
|
108 |
jgs |
119 |
// create the data view |
109 |
jgs |
82 |
DataArrayView temp(m_data,value.getShape()); |
110 |
|
|
setPointDataView(temp); |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
void |
114 |
|
|
DataTagged::reshapeDataPoint(const DataArrayView::ShapeType& shape) |
115 |
|
|
{ |
116 |
|
|
// can only reshape a rank zero data point |
117 |
|
|
if (getPointDataView().getRank()!=0) { |
118 |
|
|
stringstream temp; |
119 |
|
|
temp << "Error - Can only reshape Data with data points of rank 0. " |
120 |
|
|
<< "This Data has data points with rank: " |
121 |
|
|
<< getPointDataView().getRank(); |
122 |
|
|
throw DataException(temp.str()); |
123 |
|
|
} |
124 |
jgs |
121 |
|
125 |
jgs |
82 |
// allocate enough space for all values |
126 |
|
|
DataArrayView::ValueType newData(DataArrayView::noValues(shape)*(m_offsetLookup.size()+1)); |
127 |
|
|
DataArrayView newView(newData,shape); |
128 |
|
|
newView.copy(0,getDefaultValue()()); |
129 |
jgs |
121 |
|
130 |
|
|
// loop through the tag values |
131 |
jgs |
82 |
DataMapType::iterator pos; |
132 |
|
|
DataArrayView::ValueType::size_type tagOffset=DataArrayView::noValues(shape); |
133 |
jgs |
121 |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++){ |
134 |
jgs |
82 |
newView.copy(tagOffset,m_data[pos->second]); |
135 |
|
|
pos->second=tagOffset; |
136 |
|
|
tagOffset+=DataArrayView::noValues(shape); |
137 |
|
|
} |
138 |
|
|
m_data=newData; |
139 |
|
|
DataArrayView temp(m_data,shape); |
140 |
|
|
setPointDataView(temp); |
141 |
|
|
} |
142 |
|
|
|
143 |
|
|
DataAbstract* |
144 |
|
|
DataTagged::getSlice(const DataArrayView::RegionType& region) const |
145 |
|
|
{ |
146 |
jgs |
513 |
return new DataTagged(*this, region); |
147 |
jgs |
82 |
} |
148 |
|
|
|
149 |
jgs |
513 |
DataTagged::DataTagged(const DataTagged& other, |
150 |
|
|
const DataArrayView::RegionType& region) |
151 |
|
|
: DataAbstract(other.getFunctionSpace()) |
152 |
|
|
{ |
153 |
|
|
// slice constructor |
154 |
|
|
|
155 |
|
|
// get the shape of the slice to copy from other |
156 |
|
|
DataArrayView::ShapeType regionShape(DataArrayView::getResultSliceShape(region)); |
157 |
|
|
DataArrayView::RegionLoopRangeType regionLoopRange=getSliceRegionLoopRange(region); |
158 |
|
|
|
159 |
|
|
// allocate enough space in this for all values |
160 |
|
|
// (need to add one to allow for the default value) |
161 |
|
|
int len = DataArrayView::noValues(regionShape)*(other.m_offsetLookup.size()+1); |
162 |
|
|
m_data.resize(len,0.0,len); |
163 |
|
|
|
164 |
|
|
// create the data view |
165 |
|
|
DataArrayView temp(m_data,regionShape); |
166 |
|
|
setPointDataView(temp); |
167 |
|
|
|
168 |
|
|
// copy the default value from other to this |
169 |
|
|
getDefaultValue().copySlice(other.getDefaultValue(), regionLoopRange); |
170 |
|
|
|
171 |
|
|
// loop through the tag values copying these |
172 |
|
|
DataMapType::const_iterator pos; |
173 |
|
|
DataArrayView::ValueType::size_type tagOffset=getPointDataView().noValues(); |
174 |
|
|
for (pos=other.m_offsetLookup.begin();pos!=other.m_offsetLookup.end();pos++){ |
175 |
|
|
getPointDataView().copySlice(tagOffset,other.getPointDataView(),pos->second,regionLoopRange); |
176 |
|
|
m_offsetLookup.insert(DataMapType::value_type(pos->first,tagOffset)); |
177 |
|
|
tagOffset+=getPointDataView().noValues(); |
178 |
|
|
} |
179 |
|
|
} |
180 |
|
|
|
181 |
jgs |
82 |
void |
182 |
jgs |
513 |
DataTagged::setSlice(const DataAbstract* other, |
183 |
|
|
const DataArrayView::RegionType& region) |
184 |
jgs |
82 |
{ |
185 |
jgs |
513 |
|
186 |
|
|
// other must be another DataTagged object |
187 |
|
|
// Data:setSlice implementation should ensure this |
188 |
|
|
const DataTagged* otherTemp=dynamic_cast<const DataTagged*>(other); |
189 |
|
|
if (otherTemp==0) { |
190 |
jgs |
82 |
throw DataException("Programming error - casting to DataTagged."); |
191 |
|
|
} |
192 |
jgs |
121 |
|
193 |
jgs |
513 |
// determine shape of the specified region |
194 |
|
|
DataArrayView::ShapeType regionShape(DataArrayView::getResultSliceShape(region)); |
195 |
|
|
|
196 |
|
|
// modify region specification as needed to match rank of this object |
197 |
|
|
DataArrayView::RegionLoopRangeType regionLoopRange=getSliceRegionLoopRange(region); |
198 |
|
|
|
199 |
|
|
// ensure rank/shape of this object is compatible with specified region |
200 |
jgs |
82 |
if (getPointDataView().getRank()!=region.size()) { |
201 |
|
|
throw DataException("Error - Invalid slice region."); |
202 |
|
|
} |
203 |
jgs |
519 |
if (otherTemp->getPointDataView().getRank()>0 and !other->getPointDataView().checkShape(regionShape)) { |
204 |
jgs |
513 |
throw DataException (other->getPointDataView().createShapeErrorMessage( |
205 |
|
|
"Error - Couldn't copy slice due to shape mismatch.",regionShape)); |
206 |
jgs |
82 |
} |
207 |
jgs |
121 |
|
208 |
jgs |
513 |
// copy slice from other default value to this default value |
209 |
|
|
getDefaultValue().copySliceFrom(otherTemp->getDefaultValue(), regionLoopRange); |
210 |
jgs |
121 |
|
211 |
jgs |
513 |
// loop through the tag values copying slices from other to this |
212 |
jgs |
82 |
DataMapType::const_iterator pos; |
213 |
jgs |
121 |
for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++) { |
214 |
jgs |
513 |
getDataPointByTag(pos->first).copySliceFrom(otherTemp->getDataPointByTag(pos->first), regionLoopRange); |
215 |
jgs |
121 |
} |
216 |
jgs |
513 |
|
217 |
jgs |
82 |
} |
218 |
|
|
|
219 |
jgs |
149 |
int |
220 |
|
|
DataTagged::getTagNumber(int dpno) |
221 |
|
|
{ |
222 |
|
|
// |
223 |
|
|
// Get the number of samples and data-points per sample |
224 |
|
|
int numSamples = getNumSamples(); |
225 |
|
|
int numDataPointsPerSample = getNumDPPSample(); |
226 |
|
|
int numDataPoints = numSamples * numDataPointsPerSample; |
227 |
|
|
|
228 |
|
|
if (numDataPointsPerSample==0) { |
229 |
|
|
throw DataException("DataTagged::getTagNumber error: no data-points associated with this object."); |
230 |
|
|
} |
231 |
|
|
|
232 |
jgs |
496 |
if (dpno<0 || dpno>numDataPoints-1) { |
233 |
jgs |
149 |
throw DataException("DataTagged::getTagNumber error: invalid data-point number supplied."); |
234 |
|
|
} |
235 |
|
|
|
236 |
|
|
// |
237 |
|
|
// Determine the sample number which corresponds to this data-point number |
238 |
|
|
int sampleNo = dpno / numDataPointsPerSample; |
239 |
|
|
|
240 |
|
|
// |
241 |
|
|
// Determine the tag number which corresponds to this sample number |
242 |
|
|
int tagNo = getFunctionSpace().getTagFromSampleNo(sampleNo); |
243 |
|
|
|
244 |
|
|
// |
245 |
|
|
// return the tag number |
246 |
|
|
return(tagNo); |
247 |
|
|
} |
248 |
|
|
|
249 |
jgs |
82 |
void |
250 |
jgs |
509 |
DataTagged::setTaggedValues(const TagListType& tagKeys, |
251 |
|
|
const ValueListType& values) |
252 |
|
|
{ |
253 |
|
|
addTaggedValues(tagKeys,values); |
254 |
|
|
} |
255 |
|
|
|
256 |
|
|
void |
257 |
jgs |
82 |
DataTagged::setTaggedValue(int tagKey, |
258 |
|
|
const DataArrayView& value) |
259 |
|
|
{ |
260 |
jgs |
121 |
if (!getPointDataView().checkShape(value.getShape())) { |
261 |
|
|
throw DataException(getPointDataView().createShapeErrorMessage( |
262 |
|
|
"Error - Cannot setTaggedValue due to shape mismatch.", value.getShape())); |
263 |
|
|
} |
264 |
jgs |
82 |
DataMapType::iterator pos(m_offsetLookup.find(tagKey)); |
265 |
|
|
if (pos==m_offsetLookup.end()) { |
266 |
jgs |
121 |
// tag couldn't be found so use addTaggedValue |
267 |
jgs |
82 |
addTaggedValue(tagKey,value); |
268 |
|
|
} else { |
269 |
jgs |
121 |
// copy the values into the data array at the offset determined by m_offsetLookup |
270 |
|
|
int offset=pos->second; |
271 |
|
|
for (int i=0; i<getPointDataView().noValues(); i++) { |
272 |
|
|
m_data[offset+i]=value.getData(i); |
273 |
jgs |
82 |
} |
274 |
|
|
} |
275 |
|
|
} |
276 |
|
|
|
277 |
|
|
void |
278 |
jgs |
509 |
DataTagged::addTaggedValues(const TagListType& tagKeys, |
279 |
|
|
const ValueListType& values) |
280 |
|
|
{ |
281 |
|
|
if (values.size()==0) { |
282 |
|
|
// copy the current default value for each of the tags |
283 |
|
|
TagListType::const_iterator iT; |
284 |
|
|
for (iT=tagKeys.begin();iT!=tagKeys.end();iT++) { |
285 |
|
|
// the point data view for DataTagged points at the default value |
286 |
|
|
addTaggedValue(*iT,getPointDataView()); |
287 |
|
|
} |
288 |
|
|
} else if (values.size()==1 && tagKeys.size()>1) { |
289 |
|
|
// assume the one given value will be used for all tag values |
290 |
|
|
TagListType::const_iterator iT; |
291 |
|
|
for (iT=tagKeys.begin();iT!=tagKeys.end();iT++) { |
292 |
|
|
addTaggedValue(*iT,values[0]); |
293 |
|
|
} |
294 |
|
|
} else { |
295 |
|
|
if (tagKeys.size()!=values.size()) { |
296 |
|
|
stringstream temp; |
297 |
|
|
temp << "Error - (addTaggedValue) Number of tags: " << tagKeys.size() |
298 |
|
|
<< " doesn't match number of values: " << values.size(); |
299 |
|
|
throw DataException(temp.str()); |
300 |
|
|
} else { |
301 |
|
|
for (int i=0;i<tagKeys.size();i++) { |
302 |
|
|
addTaggedValue(tagKeys[i],values[i]); |
303 |
|
|
} |
304 |
|
|
} |
305 |
|
|
} |
306 |
|
|
} |
307 |
|
|
|
308 |
|
|
void |
309 |
jgs |
82 |
DataTagged::addTaggedValue(int tagKey, |
310 |
|
|
const DataArrayView& value) |
311 |
|
|
{ |
312 |
|
|
if (!getPointDataView().checkShape(value.getShape())) { |
313 |
|
|
throw DataException(getPointDataView().createShapeErrorMessage( |
314 |
jgs |
121 |
"Error - Cannot addTaggedValue due to shape mismatch.", value.getShape())); |
315 |
jgs |
82 |
} |
316 |
jgs |
121 |
DataMapType::iterator pos(m_offsetLookup.find(tagKey)); |
317 |
|
|
if (pos!=m_offsetLookup.end()) { |
318 |
|
|
// tag already exists so use setTaggedValue |
319 |
|
|
setTaggedValue(tagKey,value); |
320 |
|
|
} else { |
321 |
|
|
// save the key and the location of its data in the lookup tab |
322 |
|
|
m_offsetLookup.insert(DataMapType::value_type(tagKey,m_data.size())); |
323 |
|
|
// add the data given in "value" at the end of m_data |
324 |
|
|
// need to make a temp copy of m_data, resize m_data, then copy |
325 |
|
|
// all the old values plus the value to be added back into m_data |
326 |
|
|
ValueType m_data_temp(m_data); |
327 |
|
|
int oldSize=m_data.size(); |
328 |
|
|
int newSize=m_data.size()+value.noValues(); |
329 |
jgs |
151 |
m_data.resize(newSize,0.,newSize); |
330 |
jgs |
121 |
for (int i=0;i<oldSize;i++) { |
331 |
|
|
m_data[i]=m_data_temp[i]; |
332 |
|
|
} |
333 |
|
|
for (int i=0;i<value.noValues();i++) { |
334 |
|
|
m_data[oldSize+i]=value.getData(i); |
335 |
|
|
} |
336 |
|
|
} |
337 |
jgs |
82 |
} |
338 |
|
|
|
339 |
|
|
double* |
340 |
|
|
DataTagged::getSampleDataByTag(int tag) |
341 |
|
|
{ |
342 |
|
|
DataMapType::iterator pos(m_offsetLookup.find(tag)); |
343 |
|
|
if (pos==m_offsetLookup.end()) { |
344 |
|
|
// tag couldn't be found so return the default value |
345 |
|
|
return &(m_data[0]); |
346 |
|
|
} else { |
347 |
|
|
// return the data-point corresponding to the given tag |
348 |
|
|
return &(m_data[pos->second]); |
349 |
|
|
} |
350 |
|
|
} |
351 |
|
|
|
352 |
|
|
string |
353 |
|
|
DataTagged::toString() const |
354 |
|
|
{ |
355 |
|
|
stringstream temp; |
356 |
|
|
DataMapType::const_iterator i; |
357 |
|
|
temp << "Tag(Default)" << endl; |
358 |
|
|
temp << getDefaultValue().toString() << endl; |
359 |
|
|
// create a temporary view as the offset will be changed |
360 |
|
|
DataArrayView tempView(getPointDataView().getData(), getPointDataView().getShape()); |
361 |
|
|
for (i=m_offsetLookup.begin();i!=m_offsetLookup.end();++i) { |
362 |
|
|
temp << "Tag(" << i->first << ")" << endl; |
363 |
|
|
tempView.setOffset(i->second); |
364 |
|
|
temp << tempView.toString() << endl; |
365 |
|
|
} |
366 |
|
|
return temp.str(); |
367 |
|
|
} |
368 |
|
|
|
369 |
jgs |
496 |
DataArrayView::ValueType::size_type |
370 |
|
|
DataTagged::getPointOffset(int sampleNo, |
371 |
|
|
int dataPointNo) const |
372 |
jgs |
82 |
{ |
373 |
jgs |
496 |
int tagKey=getFunctionSpace().getTagFromSampleNo(sampleNo); |
374 |
|
|
DataMapType::const_iterator pos(m_offsetLookup.find(tagKey)); |
375 |
jgs |
82 |
DataArrayView::ValueType::size_type offset=m_defaultValueOffset; |
376 |
|
|
if (pos!=m_offsetLookup.end()) { |
377 |
|
|
offset=pos->second; |
378 |
|
|
} |
379 |
jgs |
496 |
return offset; |
380 |
jgs |
82 |
} |
381 |
|
|
|
382 |
jgs |
496 |
DataArrayView |
383 |
|
|
DataTagged::getDataPointByTag(int tag) const |
384 |
jgs |
82 |
{ |
385 |
jgs |
496 |
DataMapType::const_iterator pos(m_offsetLookup.find(tag)); |
386 |
jgs |
82 |
DataArrayView::ValueType::size_type offset=m_defaultValueOffset; |
387 |
|
|
if (pos!=m_offsetLookup.end()) { |
388 |
|
|
offset=pos->second; |
389 |
|
|
} |
390 |
jgs |
496 |
DataArrayView temp(getPointDataView()); |
391 |
|
|
temp.setOffset(offset); |
392 |
|
|
return temp; |
393 |
jgs |
82 |
} |
394 |
|
|
|
395 |
|
|
DataArrayView |
396 |
|
|
DataTagged::getDataPoint(int sampleNo, |
397 |
|
|
int dataPointNo) |
398 |
|
|
{ |
399 |
|
|
EsysAssert(validSampleNo(sampleNo),"(getDataPoint) Invalid sampleNo: " << sampleNo); |
400 |
|
|
int tagKey=getFunctionSpace().getTagFromSampleNo(sampleNo); |
401 |
|
|
return getDataPointByTag(tagKey); |
402 |
|
|
} |
403 |
|
|
|
404 |
jgs |
123 |
int |
405 |
|
|
DataTagged::archiveData(ofstream& archiveFile, |
406 |
|
|
const DataArrayView::ValueType::size_type noValues) const |
407 |
|
|
{ |
408 |
|
|
return(m_data.archiveData(archiveFile, noValues)); |
409 |
|
|
} |
410 |
|
|
|
411 |
|
|
int |
412 |
|
|
DataTagged::extractData(ifstream& archiveFile, |
413 |
|
|
const DataArrayView::ValueType::size_type noValues) |
414 |
|
|
{ |
415 |
|
|
return(m_data.extractData(archiveFile, noValues)); |
416 |
|
|
} |
417 |
|
|
|
418 |
jgs |
82 |
} // end of namespace |