/[escript]/trunk/escript/src/DataTagged.cpp
ViewVC logotype

Contents of /trunk/escript/src/DataTagged.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 519 - (show annotations)
Tue Feb 14 05:30:50 2006 UTC (13 years, 7 months ago) by jgs
File size: 13595 byte(s)
fix comments for setSlice - were totally misleading!

1 // $Id$
2
3 /*
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 #include "DataTagged.h"
18
19 #include "DataConstant.h"
20 #include "DataException.h"
21
22 using namespace std;
23
24 namespace escript {
25
26 DataTagged::DataTagged()
27 : DataAbstract(FunctionSpace())
28 {
29 // default constructor
30
31 // create a scalar default value
32 m_data.resize(1,0.,1);
33 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 const FunctionSpace& what)
41 : DataAbstract(what)
42 {
43 // constructor
44
45 // initialise the array of data values
46 // the default value is always the first item in the values list
47 int len = defaultValue.noValues();
48 m_data.resize(len,0.,len);
49 for (int i=0; i<defaultValue.noValues(); i++) {
50 m_data[i]=defaultValue.getData(i);
51 }
52
53 // create the data view
54 DataArrayView temp(m_data,defaultValue.getShape());
55 setPointDataView(temp);
56
57 // add remaining tags and values
58 addTaggedValues(tagKeys,values);
59 }
60
61 DataTagged::DataTagged(const FunctionSpace& what,
62 const DataArrayView::ShapeType &shape,
63 const int tags[],
64 const ValueType& data)
65 : DataAbstract(what)
66 {
67 // alternative constructor
68 // not unit_tested tested yet
69
70 // copy the data
71 m_data=data;
72
73 // create the view of the data
74 DataArrayView tempView(m_data,shape);
75 setPointDataView(tempView);
76
77 // 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 DataTagged::DataTagged(const DataTagged& other)
84 : DataAbstract(other.getFunctionSpace()),
85 m_data(other.m_data),
86 m_offsetLookup(other.m_offsetLookup)
87 {
88 // copy constructor
89
90 // create the data view
91 DataArrayView temp(m_data,other.getPointDataView().getShape());
92 setPointDataView(temp);
93 }
94
95 DataTagged::DataTagged(const DataConstant& other)
96 : DataAbstract(other.getFunctionSpace())
97 {
98 // copy constructor
99
100 // fill the default value with the constant value item from "other"
101 const DataArrayView& value=other.getPointDataView();
102 int len = value.noValues();
103 m_data.resize(len,0.,len);
104 for (int i=0; i<value.noValues(); i++) {
105 m_data[i]=value.getData(i);
106 }
107
108 // create the data view
109 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
125 // 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
130 // loop through the tag values
131 DataMapType::iterator pos;
132 DataArrayView::ValueType::size_type tagOffset=DataArrayView::noValues(shape);
133 for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++){
134 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 return new DataTagged(*this, region);
147 }
148
149 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 void
182 DataTagged::setSlice(const DataAbstract* other,
183 const DataArrayView::RegionType& region)
184 {
185
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 throw DataException("Programming error - casting to DataTagged.");
191 }
192
193 // 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 if (getPointDataView().getRank()!=region.size()) {
201 throw DataException("Error - Invalid slice region.");
202 }
203 if (otherTemp->getPointDataView().getRank()>0 and !other->getPointDataView().checkShape(regionShape)) {
204 throw DataException (other->getPointDataView().createShapeErrorMessage(
205 "Error - Couldn't copy slice due to shape mismatch.",regionShape));
206 }
207
208 // copy slice from other default value to this default value
209 getDefaultValue().copySliceFrom(otherTemp->getDefaultValue(), regionLoopRange);
210
211 // loop through the tag values copying slices from other to this
212 DataMapType::const_iterator pos;
213 for (pos=m_offsetLookup.begin();pos!=m_offsetLookup.end();pos++) {
214 getDataPointByTag(pos->first).copySliceFrom(otherTemp->getDataPointByTag(pos->first), regionLoopRange);
215 }
216
217 }
218
219 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 if (dpno<0 || dpno>numDataPoints-1) {
233 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 void
250 DataTagged::setTaggedValues(const TagListType& tagKeys,
251 const ValueListType& values)
252 {
253 addTaggedValues(tagKeys,values);
254 }
255
256 void
257 DataTagged::setTaggedValue(int tagKey,
258 const DataArrayView& value)
259 {
260 if (!getPointDataView().checkShape(value.getShape())) {
261 throw DataException(getPointDataView().createShapeErrorMessage(
262 "Error - Cannot setTaggedValue due to shape mismatch.", value.getShape()));
263 }
264 DataMapType::iterator pos(m_offsetLookup.find(tagKey));
265 if (pos==m_offsetLookup.end()) {
266 // tag couldn't be found so use addTaggedValue
267 addTaggedValue(tagKey,value);
268 } else {
269 // 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 }
274 }
275 }
276
277 void
278 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 DataTagged::addTaggedValue(int tagKey,
310 const DataArrayView& value)
311 {
312 if (!getPointDataView().checkShape(value.getShape())) {
313 throw DataException(getPointDataView().createShapeErrorMessage(
314 "Error - Cannot addTaggedValue due to shape mismatch.", value.getShape()));
315 }
316 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 m_data.resize(newSize,0.,newSize);
330 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 }
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 DataArrayView::ValueType::size_type
370 DataTagged::getPointOffset(int sampleNo,
371 int dataPointNo) const
372 {
373 int tagKey=getFunctionSpace().getTagFromSampleNo(sampleNo);
374 DataMapType::const_iterator pos(m_offsetLookup.find(tagKey));
375 DataArrayView::ValueType::size_type offset=m_defaultValueOffset;
376 if (pos!=m_offsetLookup.end()) {
377 offset=pos->second;
378 }
379 return offset;
380 }
381
382 DataArrayView
383 DataTagged::getDataPointByTag(int tag) const
384 {
385 DataMapType::const_iterator pos(m_offsetLookup.find(tag));
386 DataArrayView::ValueType::size_type offset=m_defaultValueOffset;
387 if (pos!=m_offsetLookup.end()) {
388 offset=pos->second;
389 }
390 DataArrayView temp(getPointDataView());
391 temp.setOffset(offset);
392 return temp;
393 }
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 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 } // end of namespace

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26