ObjectTest.h 35.9 KB
Newer Older
Russell Taylor's avatar
Russell Taylor committed
1
2
3
4
5
6
7
8
9
10
#ifndef MANTID_TESTOBJECT__
#define MANTID_TESTOBJECT__

#include <cxxtest/TestSuite.h>
#include <cmath>
#include <ostream>
#include <vector>
#include <algorithm>
#include <ctime>

11
12
#include <boost/shared_ptr.hpp>

Russell Taylor's avatar
Russell Taylor committed
13
#include "MantidGeometry/V3D.h" 
Nick Draper's avatar
re #843    
Nick Draper committed
14
15
16
17
18
19
20
21
#include "MantidGeometry/Objects/Object.h" 
#include "MantidGeometry/Surfaces/Cylinder.h" 
#include "MantidGeometry/Surfaces/Sphere.h" 
#include "MantidGeometry/Surfaces/Plane.h" 
#include "MantidGeometry/Math/Algebra.h" 
#include "MantidGeometry/Surfaces/SurfaceFactory.h" 
#include "MantidGeometry/Objects/Track.h" 
#include "MantidGeometry/Rendering/GluGeometryHandler.h"
22

Russell Taylor's avatar
Russell Taylor committed
23
24
25
using namespace Mantid;
using namespace Geometry;

26
27
typedef boost::shared_ptr<Object> Object_sptr;

Russell Taylor's avatar
Russell Taylor committed
28
29
30
31
32
33
34
35
class testObject: public CxxTest::TestSuite
{
private:


public:


Nick Draper's avatar
re #843    
Nick Draper committed
36
  void testCreateUnitCube()
Russell Taylor's avatar
Russell Taylor committed
37
  {
38
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
39

40
    TS_ASSERT_EQUALS(geom_obj->str(),"68 -1 0 -6 5 -4 3 -2 1");
Russell Taylor's avatar
Russell Taylor committed
41
42
  }

Nick Draper's avatar
re #843    
Nick Draper committed
43
  void testIsOnSideCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
44
  {
45
	Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
46
    //inside
47
48
49
50
51
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,0)),0); //origin
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,2.9,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-2.9,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-2.9)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,2.9)),0);
Russell Taylor's avatar
Russell Taylor committed
52
    //on the side
53
54
55
56
57
58
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,3)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,0)),1);
Russell Taylor's avatar
Russell Taylor committed
59
60

    //on the edges
61
62
63
64
65
66
67
68
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,3)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,3)),1);
Russell Taylor's avatar
Russell Taylor committed
69
    //out side
70
71
72
73
74
75
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,3.1,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-3.1,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-3.1)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,3.1)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.3,0,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.3,0,0)),0);
Russell Taylor's avatar
Russell Taylor committed
76
77
78
79
  }

  void testIsValidCappedCylinder()
  {
80
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
81
    //inside
82
83
84
85
86
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,0)),1); //origin
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,2.9,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-2.9,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-2.9)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,2.9)),1);
Russell Taylor's avatar
Russell Taylor committed
87
    //on the side
88
89
90
91
92
93
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,3)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,0)),1);
Russell Taylor's avatar
Russell Taylor committed
94
95

    //on the edges
96
97
98
99
100
101
102
103
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,3)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,-3,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,-3)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,3)),1);
Russell Taylor's avatar
Russell Taylor committed
104
    //out side
105
106
107
108
109
110
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,3.1,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-3.1,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-3.1)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,3.1)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.3,0,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.3,0,0)),0);
Russell Taylor's avatar
Russell Taylor committed
111
112
113
114
  }

  void testIsOnSideSphere()
  {
115
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
116
    //inside
117
118
119
120
121
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,0)),0); //origin
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.0,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.0,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.0)),0);
Russell Taylor's avatar
Russell Taylor committed
122
    //on the side
123
124
125
126
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.1)),1);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.1)),1);
Russell Taylor's avatar
Russell Taylor committed
127
128

    //out side
129
130
131
132
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.2,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.2,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.2)),0);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.2)),0);
Russell Taylor's avatar
Russell Taylor committed
133
134
135
136
  }

  void testIsValidSphere()
  {
137
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
138
    //inside
139
140
141
142
143
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,0)),1); //origin
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.0)),1);
Russell Taylor's avatar
Russell Taylor committed
144
    //on the side
145
146
147
148
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.1)),1);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.1)),1);
Russell Taylor's avatar
Russell Taylor committed
149
150

    //out side
151
152
153
154
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.2,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.2,0)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.2)),0);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.2)),0);
Russell Taylor's avatar
Russell Taylor committed
155
156
157
158
  }

  void testCalcValidTypeSphere()
  {
159
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
160
    //entry on the normal
161
162
163
164
165
166
167
168
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(1,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(-1,0,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(4.1,0,0),V3D(1,0,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(4.1,0,0),V3D(-1,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,-4.1,0),V3D(0,1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,-4.1,0),V3D(0,-1,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,4.1,0),V3D(0,1,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,4.1,0),V3D(0,-1,0)),1);
Russell Taylor's avatar
Russell Taylor committed
169
170

    //a glancing blow
171
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(0,1,0)),0);
Russell Taylor's avatar
Russell Taylor committed
172
    //not quite on the normal
173
174
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(0.5,0.5,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(4.1,0,0),V3D(0.5,0.5,0)),-1);
Russell Taylor's avatar
Russell Taylor committed
175
176
177
178
  }

  void testCalcValidTypeCappedCylinder()
  {
179
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
180
    //entry on the normal
181
182
183
184
185
186
187
188
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-3.2,0,0),V3D(1,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-3.2,0,0),V3D(-1,0,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(1.2,0,0),V3D(1,0,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(1.2,0,0),V3D(-1,0,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,-3,0),V3D(0,1,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,-3,0),V3D(0,-1,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,3,0),V3D(0,1,0)),-1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(0,3,0),V3D(0,-1,0)),1);
Russell Taylor's avatar
Russell Taylor committed
189
190

    //a glancing blow
191
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-3.2,0,0),V3D(0,1,0)),0);
Russell Taylor's avatar
Russell Taylor committed
192
    //not quite on the normal
193
194
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-3.2,0,0),V3D(0.5,0.5,0)),1);
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(1.2,0,0),V3D(0.5,0.5,0)),-1);
Russell Taylor's avatar
Russell Taylor committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  }

  void testInterceptSurfaceSphereZ()
  {
    std::vector<TUnit> expectedResults;
    std::string S41="s 1 1 1 4";         // Sphere at (1,1,1) radius 4

    // First create some surfaces
    std::map<int,Surface*> SphSurMap;
    SphSurMap[41]=new Sphere();
    SphSurMap[41]->setSurface(S41);
    SphSurMap[41]->setName(41);

    // A sphere 
    std::string ObjSphere="-41" ;

211
212
213
    Object_sptr geom_obj = Object_sptr(new Object); 
    geom_obj->setObject(41,ObjSphere);
    geom_obj->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
214
215
216
217
218
219
220
221


    Track track(V3D(-1,1.5,1),V3D(1,0,0));

    // format = startPoint, endPoint, total distance so far, objectID
    // forward only intercepts means that start point should be track origin
    //expectedResults.push_back(TUnit(V3D(-sqrt(16-0.25)+1,1.5,1),
    expectedResults.push_back(TUnit(V3D(-1,1.5,1),
222
      V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2,geom_obj->getName()));
Russell Taylor's avatar
Russell Taylor committed
223

224
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
225
226
227
228
229
  }

  void testInterceptSurfaceSphereY()
  {
    std::vector<TUnit> expectedResults;
230
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
231
232
233
    Track track(V3D(0,-10,0),V3D(0,1,0));

    //format = startPoint, endPoint, total distance so far, objectID
234
    expectedResults.push_back(TUnit(V3D(0,-4.1,0),V3D(0,4.1,0),14.1,geom_obj->getName()));
Russell Taylor's avatar
Russell Taylor committed
235

236
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
237
238
239
240
241
  }

  void testInterceptSurfaceSphereX()
  {
    std::vector<TUnit> expectedResults;
242
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
243
244
    Track track(V3D(-10,0,0),V3D(1,0,0));
    //format = startPoint, endPoint, total distance so far, objectID
245
246
    expectedResults.push_back(TUnit(V3D(-4.1,0,0),V3D(4.1,0,0),14.1,geom_obj->getName()));
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
247
248
249
250
251
  }

  void testInterceptSurfaceCappedCylinderY()
  {
    std::vector<TUnit> expectedResults;
252
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
253
    //format = startPoint, endPoint, total distance so far, objectID
254
    expectedResults.push_back(TUnit(V3D(0,-3,0),V3D(0,3,0),13,geom_obj->getName()));
Russell Taylor's avatar
Russell Taylor committed
255
256

    Track track(V3D(0,-10,0),V3D(0,1,0));
257
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
258
259
260
261
262
  }

  void testInterceptSurfaceCappedCylinderX()
  {
    std::vector<TUnit> expectedResults;
263
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
264
265
266
    Track track(V3D(-10,0,0),V3D(1,0,0));

    //format = startPoint, endPoint, total distance so far, objectID
267
    expectedResults.push_back(TUnit(V3D(-3.2,0,0),V3D(1.2,0,0),11.2,geom_obj->getName()));
Russell Taylor's avatar
Russell Taylor committed
268

269
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
270
271
272
273
274
  }

  void testInterceptSurfaceCappedCylinderMiss()
  {
    std::vector<TUnit> expectedResults; //left empty as there are no expected results
275
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
276
277
    Track track(V3D(-10,0,0),V3D(1,1,0));

278
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  }

  void checkTrackIntercept(Track& track, std::vector<TUnit>& expectedResults)
  {
    int index = 0;
    for (Track::LType::const_iterator it = track.begin(); it!=track.end();++it)
    {
      TS_ASSERT_DELTA(it->Dist,expectedResults[index].Dist,1e-6);
      TS_ASSERT_DELTA(it->Length,expectedResults[index].Length,1e-6);
      TS_ASSERT_EQUALS(it->ObjID,expectedResults[index].ObjID);
      TS_ASSERT_EQUALS(it->PtA,expectedResults[index].PtA);
      TS_ASSERT_EQUALS(it->PtB,expectedResults[index].PtB);
      ++index;
    }
    TS_ASSERT_EQUALS(index,static_cast<int>(expectedResults.size()));
  }

296
  void checkTrackIntercept(Object_sptr obj, Track& track, std::vector<TUnit>& expectedResults)
Russell Taylor's avatar
Russell Taylor committed
297
  {
298
    int unitCount = obj->interceptSurface(track);
Russell Taylor's avatar
Russell Taylor committed
299
300
301
302
303
304
305
306
307
308
309
310
    TS_ASSERT_EQUALS(unitCount,expectedResults.size())
      checkTrackIntercept(track,expectedResults);
  }

  void xtestTrackTwoIsolatedCubes()
    /*!
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006";
    std::string ObjB="80001 -80002 60003 -60004 60005 -60006";
    
311
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
312
313
314
315
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

316
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

    Track TL(Geometry::V3D(-5,0,0),
      Geometry::V3D(1,0,0));

    // CARE: This CANNOT be called twice
    TS_ASSERT(object1.interceptSurface(TL)!=0)
      TS_ASSERT(object2.interceptSurface(TL)!=0)

      std::vector<TUnit> expectedResults;
    expectedResults.push_back(TUnit(V3D(-1,0,0),V3D(1,0,0),6,3));
    expectedResults.push_back(TUnit(V3D(4.5,0,0),V3D(6.5,0,0),11.5,4));
    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackTwoTouchingCubes()
    /*!
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006";
    std::string ObjB="60002 -80002 60003 -60004 60005 -60006";

343
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
344
345
346
347
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

348
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
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
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

    Track TL(Geometry::V3D(-5,0,0),
      Geometry::V3D(1,0,0));

    // CARE: This CANNOT be called twice
    TS_ASSERT(object1.interceptSurface(TL)!=0)
      TS_ASSERT(object2.interceptSurface(TL)!=0)

      std::vector<TUnit> expectedResults;
    expectedResults.push_back(TUnit(V3D(-1,0,0),V3D(1,0,0),6,3));
    expectedResults.push_back(TUnit(V3D(1,0,0),V3D(6.5,0,0),11.5,4));

    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackCubeWithInternalSphere()
    /*!
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 71";
    std::string ObjB="-71";

376
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
377
378
379
380
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

381
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

    Track TL(Geometry::V3D(-5,0,0),
      Geometry::V3D(1,0,0));

    // CARE: This CANNOT be called twice
    TS_ASSERT(object1.interceptSurface(TL)!=0);
    TS_ASSERT(object2.interceptSurface(TL)!=0);

    std::vector<TUnit> expectedResults;
    expectedResults.push_back(TUnit(V3D(-1,0,0),V3D(-0.8,0,0),4.2,3));
    expectedResults.push_back(TUnit(V3D(-0.8,0,0),V3D(0.8,0,0),5.8,4));
    expectedResults.push_back(TUnit(V3D(0.8,0,0),V3D(1,0,0),6,3));
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheres()
    /*!
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
   
408
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
409
410
411
412
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

413
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

    Track TL(Geometry::V3D(-5,0,0),
      Geometry::V3D(1,0,0));


    // CARE: This CANNOT be called twice
    TS_ASSERT(object1.interceptSurface(TL)!=0);
    TS_ASSERT(object2.interceptSurface(TL)!=0);

    std::vector<TUnit> expectedResults;
    expectedResults.push_back(TUnit(V3D(-1,0,0),V3D(-0.4,0,0),4.6,4));
    expectedResults.push_back(TUnit(V3D(-0.4,0,0),V3D(0.2,0,0),5.2,3));
    expectedResults.push_back(TUnit(V3D(0.2,0,0),V3D(1,0,0),6,4));
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheresMiss()
    /*!
    Test a track missing an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
    
441
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
442
443
444
445
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

446
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

    Track TL(Geometry::V3D(-5,0,0),
      Geometry::V3D(0,1,0));


    // CARE: This CANNOT be called twice
    TS_ASSERT_EQUALS(object1.interceptSurface(TL),0);
    TS_ASSERT_EQUALS(object2.interceptSurface(TL),0);

    std::vector<TUnit> expectedResults; //left empty as this should miss
    checkTrackIntercept(TL,expectedResults);
  }

  void testFindPointInCube()
    /*!
    Test find point in cube
    */
  {
468
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
469
470
    // initial guess in object
    Geometry::V3D pt;
471
    TS_ASSERT_EQUALS(geom_obj->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
472
473
474
475
476
477
    TS_ASSERT_EQUALS(pt,V3D(0,0,0));
    // initial guess not in object, but on x-axis
    std::vector<std::string> planes;
    planes.push_back("px 10"); planes.push_back("px 11");
    planes.push_back("py -0.5"); planes.push_back("py 0.5");
    planes.push_back("pz -0.5"); planes.push_back("pz 0.5");
478
479
    Object_sptr B =createCuboid(planes);
    TS_ASSERT_EQUALS(B->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
480
481
482
483
484
485
    TS_ASSERT_EQUALS(pt,V3D(10,0,0));
    // on y axis
    planes.clear();
    planes.push_back("px -0.5"); planes.push_back("px 0.5");
    planes.push_back("py -22"); planes.push_back("py -21");
    planes.push_back("pz -0.5"); planes.push_back("pz 0.5");
486
487
    Object_sptr C =createCuboid(planes);
    TS_ASSERT_EQUALS(C->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
488
489
490
491
492
493
    TS_ASSERT_EQUALS(pt,V3D(0,-21,0));
    // not on principle axis, now works using getBoundingBox
    planes.clear();
    planes.push_back("px 0.5"); planes.push_back("px 1.5");
    planes.push_back("py -22"); planes.push_back("py -21");
    planes.push_back("pz -0.5"); planes.push_back("pz 0.5");
494
495
    Object_sptr D =createCuboid(planes);
    TS_ASSERT_EQUALS(D->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
496
497
498
499
500
501
502
503
504
505
506
507
    TS_ASSERT_DELTA(pt.X(),1.0,1e-6);
    TS_ASSERT_DELTA(pt.Y(),-21.5,1e-6);
    TS_ASSERT_DELTA(pt.Z(),0.0,1e-6);
    planes.clear();
    // Test non axis aligned (AA) case - getPointInObject works because the object is on a principle axis
    // However, if not on a principle axis then the getBoundingBox fails to find correct minima (maxima are OK)
    // This is related to use of the complement for -ve surfaces and might be avoided by only using +ve surfaces
    // for defining non-AA objects. However, BoundingBox is poor for non-AA and needs improvement if these are
    // common
    planes.push_back("p 1 0 0 -0.5"); planes.push_back("p 1 0 0 0.5");
    planes.push_back("p 0 .70710678118 .70710678118 -1.1"); planes.push_back("p 0 .70710678118 .70710678118 -0.1");
    planes.push_back("p 0 -.70710678118 .70710678118 -0.5"); planes.push_back("p 0 -.70710678118 .70710678118 0.5");
508
509
    Object_sptr E =createCuboid(planes);
    TS_ASSERT_EQUALS(E->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
510
511
512
513
514
515
516
517
518
519
520
    TS_ASSERT_DELTA(pt.X(),0.0,1e-6);
    TS_ASSERT_DELTA(pt.Y(),-0.1414213562373,1e-6);
    TS_ASSERT_DELTA(pt.Z(),0.0,1e-6);
    planes.clear();
    // This test fails to find a point in object, as object not on a principle axis
    // and getBoundingBox does not give a useful result in this case.
    // Object is unit cube located at +-0.5 in x but centred on z=y=-1.606.. and rotated 45deg
    // to these two axes
    planes.push_back("p 1 0 0 -0.5"); planes.push_back("p 1 0 0 0.5");
    planes.push_back("p 0  .70710678118 .70710678118 -2"); planes.push_back("p 0  .70710678118 .70710678118 -1");
    planes.push_back("p 0 -.70710678118 .70710678118 -0.5"); planes.push_back("p 0 -.70710678118 .70710678118 0.5");
521
522
    Object_sptr F =createCuboid(planes);
    TS_ASSERT_EQUALS(F->getPointInObject(pt),0);
Russell Taylor's avatar
Russell Taylor committed
523
    // Test use of defineBoundingBox to explictly set the bounding box, when the automatic method fails
524
    F->defineBoundingBox(0.5,-1/(2.0*sqrt(2.0)),-1.0/(2.0*sqrt(2.0)),
Russell Taylor's avatar
Russell Taylor committed
525
      -0.5,-sqrt(2.0)-1.0/(2.0*sqrt(2.0)),-sqrt(2.0)-1.0/(2.0*sqrt(2.0)));
526
527
528
    TS_ASSERT_EQUALS(F->getPointInObject(pt),1);
    Object_sptr S = createSphere();
    TS_ASSERT_EQUALS(S->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
529
530
531
532
533
534
535
536
537
    TS_ASSERT_EQUALS(pt,V3D(0.0,0.0,0));
  }


  void testSolidAngleSphere()
    /*!
    Test solid angle calculation for a sphere
    */
  {
538
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
539
540
541
542
543
544
    double satol=2e-2; // tolerance for solid angle

    // Solid angle at distance 8.1 from centre of sphere radius 4.1 x/y/z
    // Expected solid angle calculated values from sa=2pi(1-cos(arcsin(R/r))
    // where R is sphere radius and r is distance of observer from sphere centre
    // Intercept for track in reverse direction now worked round
545
546
547
548
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(8.1,0,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,8.1,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,0,8.1)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,0,-8.1)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
549
    // internal point (should be 4pi)
550
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
551
    // surface point
552
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
553
    // distant points
554
555
556
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(20,0,0)),0.133442,satol);
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(200,0,0)),0.0013204,satol);
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(2000,0,0)),1.32025e-5,satol);
Russell Taylor's avatar
Russell Taylor committed
557
558
559
    //
    // test solidAngle interface, which will be main method to solid angle
    //
560
561
562
563
    TS_ASSERT_DELTA(geom_obj->solidAngle(V3D(8.1,0,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->solidAngle(V3D(0,8.1,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->solidAngle(V3D(0,0,8.1)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->solidAngle(V3D(0,0,-8.1)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
564
565
566
567
568
569
570
571
    //
  }

  void testSolidAngleCappedCylinder()
    /*!
    Test solid angle calculation for a capped cylinder
    */
  {
572
    Object_sptr geom_obj = createSmallCappedCylinder();
573
    // Want to test triangulation so setup a geometry handler
574
    boost::shared_ptr<GluGeometryHandler> h = boost::shared_ptr<GluGeometryHandler>(new GluGeometryHandler(geom_obj.get()));
575
    h->setCylinder(V3D(-1.0,0.0,0.0), V3D(1., 0.0, 0.0), 0.005, 0.003);
576
    geom_obj->setGeometryHandler(h);
577
578

    double satol(1e-4); // tolerance for solid angle
Russell Taylor's avatar
Russell Taylor committed
579

580
    // solid angle at point -0.5 from capped cyl -1.0 -0.997 in x, rad 0.005 - approx WISH cylinder
Russell Taylor's avatar
Russell Taylor committed
581
582
    //
    // soild angle of circle radius 3, distance 3 is 2pi(1-cos(t)) where
583
    // t is atan(3/3), should be 0.000317939
584
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.5, 0.0, 0.0)), 0.000317939, satol);
585
    // Other end
586
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-1.497, 0.0, 0.0)), 0.000317939, satol);
587

Russell Taylor's avatar
Russell Taylor committed
588
    // No analytic value for side on SA, using hi-res value
589
590
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0, 0, 0.1)), 8.03225e-05, satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0, 0.1, 0)), 8.03225e-05, satol);
591

Russell Taylor's avatar
Russell Taylor committed
592
    // internal point (should be 4pi)
593
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.999, 0.0, 0.0)),4*M_PI,satol);
594
595

    // surface points
596
597
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-1.0, 0.0, 0.0)),2*M_PI,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.997, 0.0, 0.0)),2*M_PI,satol);
598

Russell Taylor's avatar
Russell Taylor committed
599
600
601
602
603
604
605
606
  }

  void testSolidAngleCubeTriangles()
    /*!
    Test solid angle calculation for a cube using triangles
    - test for using Open Cascade surface triangulation for all solid angles.
    */
  {
607
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
608
609
610
611
612
613
    double satol=1e-3; // tolerance for solid angle

    // solid angle at distance 0.5 should be 4pi/6 by symmetry
    //
    // tests for Triangulated cube
    //
614
615
616
617
618
619
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(1.0,0,0)),M_PI*2.0/3.0,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-1.0,0,0)),M_PI*2.0/3.0,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,1.0,0)),M_PI*2.0/3.0,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,-1.0,0)),M_PI*2.0/3.0,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,1.0)),M_PI*2.0/3.0,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,-1.0)),M_PI*2.0/3.0,satol);
Russell Taylor's avatar
Russell Taylor committed
620
621
622
623
624
625
626
627
628
629

    if(timeTest)
    {
      // block to test time of solid angle methods
      // change false to true to include
      double saRay,saTri;
      V3D observer(1.0,0,0);
      int iter=4000;
      int starttime=clock();
      for (int i=0;i<iter;i++)
630
        saTri=geom_obj->triangleSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
631
632
633
634
635
      int endtime=clock();
      std::cout << std::endl << "Cube tri time=" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
      iter=50;
      starttime=clock();
      for (int i=0;i<iter;i++)
636
        saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
637
638
639
640
641
642
643
644
645
646
647
      endtime=clock();
      std::cout << "Cube ray time=" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
    }

  }

  void testGetBoundingBox()
    /*!
    Test bounding box for a object capped cylinder
    */
  {
648
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
649
650
651
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=ymax=zmax=100;
    xmin=ymin=zmin=-100;
652
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
653
654
655
656
657
658
659
660
661
662
663
664
665
    TS_ASSERT_DELTA(xmax,1.2,0.0001);
    TS_ASSERT_DELTA(ymax,3.0,0.0001);
    TS_ASSERT_DELTA(zmax,3.0,0.0001);
    TS_ASSERT_DELTA(xmin,-3.2,0.0001);
    TS_ASSERT_DELTA(ymin,-3.0,0.0001);
    TS_ASSERT_DELTA(zmin,-3.0,0.0001);
  }

  void defineBoundingBox()
    /*!
    Test use of defineBoundingBox
    */
  {
666
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
667
668
669
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=1.2;ymax=3.0;zmax=3.0;
    xmin=-3.2;ymin=-3.0;zmin=-3.0;
670
671
    geom_obj->defineBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
672
673
674
675
676
677
678
    TS_ASSERT_EQUALS(xmax,1.2);
    TS_ASSERT_EQUALS(ymax,3.0);
    TS_ASSERT_EQUALS(zmax,3.0);
    TS_ASSERT_EQUALS(xmin,-3.2);
    TS_ASSERT_EQUALS(ymin,-3.0);
    TS_ASSERT_EQUALS(zmin,-3.0);
    xmax=1.2;xmin=3.0;
679
    TS_ASSERT_THROWS(geom_obj->defineBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin),std::invalid_argument&);
Russell Taylor's avatar
Russell Taylor committed
680
681
682
683
684
685
686

  }
  void testSurfaceTriangulation()
    /*!
    Test triangle solid angle calc
    */
  {
687
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
688
689
690
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=20;ymax=20.0;zmax=20.0;
    xmin=-20.0;ymin=-20.0;zmin=-20.0;
691
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
692
693
694
695
696
697
698
699
700
701
702
703
    double saTri,saRay;
    V3D observer(4.2,0,0);
    
    double satol=1e-3; // typical result tolerance

    if(timeTest)
    {
      // block to test time of solid angle methods
      // change false to true to include
      int iter=4000;
      int starttime=clock();
      for (int i=0;i<iter;i++)
704
        saTri=geom_obj->triangleSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
705
706
707
708
709
      int endtime=clock();
      std::cout << std::endl << "Cyl tri time=" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
      iter=50;
      starttime=clock();
      for (int i=0;i<iter;i++)
710
        saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
711
712
713
714
      endtime=clock();
      std::cout << "Cyl ray time=" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
    }

715
716
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
717
718
719
720
    TS_ASSERT_DELTA(saTri,1.840302,0.001);
    TS_ASSERT_DELTA(saRay,1.840302,0.01);
    
    observer=V3D(-7.2,0,0);
721
722
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
723
724
725
726
727
    
    TS_ASSERT_DELTA(saTri,1.25663708,0.001);
    TS_ASSERT_DELTA(saRay,1.25663708,0.001);

    // No analytic value for side on SA, using hi-res value
728
729
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,7)),0.7531,0.753*satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,7,0)),0.7531,0.753*satol);
Russell Taylor's avatar
Russell Taylor committed
730

731
    saTri=geom_obj->triangleSolidAngle(V3D(20,0,0));
Russell Taylor's avatar
Russell Taylor committed
732
    TS_ASSERT_DELTA(saTri,0.07850147,satol*0.0785);
733
    saTri=geom_obj->triangleSolidAngle(V3D(200,0,0));
Russell Taylor's avatar
Russell Taylor committed
734
    TS_ASSERT_DELTA(saTri,0.000715295,satol*0.000715);
735
    saTri=geom_obj->triangleSolidAngle(V3D(2000,0,0));
Russell Taylor's avatar
Russell Taylor committed
736
737
738
739
740
741
742
743
    TS_ASSERT_DELTA(saTri,7.08131e-6,satol*7.08e-6);
    
  }
  void testSolidAngleSphereTri()
    /*!
    Test solid angle calculation for a sphere from triangulation
    */
  {
744
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
745
746
747
748
749
750
    double satol=1e-3; // tolerance for solid angle

    // Solid angle at distance 8.1 from centre of sphere radius 4.1 x/y/z
    // Expected solid angle calculated values from sa=2pi(1-cos(arcsin(R/r))
    // where R is sphere radius and r is distance of observer from sphere centre
    // Intercept for track in reverse direction now worked round
751
752
753
754
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(8.1,0,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,8.1,0)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,8.1)),0.864364,satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,-8.1)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
755
    // internal point (should be 4pi)
756
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
757
    // surface point
758
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
759
    // distant points
760
761
762
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(20,0,0)),0.133442,satol*0.133);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(200,0,0)),0.0013204,satol*0.00132);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(2000,0,0)),1.32025e-5,satol*1.32e-5);
Russell Taylor's avatar
Russell Taylor committed
763
764
765
766
767
768
769
770
771
772

    if(timeTest)
    {
      // block to test time of solid angle methods
      // change false to true to include
      double saTri,saRay;
      int iter=400;
      V3D observer(8.1,0,0);
      int starttime=clock();
      for (int i=0;i<iter;i++)
773
        saTri=geom_obj->triangleSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
774
775
776
777
778
      int endtime=clock();
      std::cout << std::endl << "Sphere tri time =" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
      iter=40;
      starttime=clock();
      for (int i=0;i<iter;i++)
779
        saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
      endtime=clock();
      std::cout << "Sphere ray time =" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
    }

  }

private:

  /// Surface type
  typedef std::map<int,Surface*> STYPE ; 

  /// set timeTest true to get time comparisons of soild angle methods
  const static bool timeTest=false;
  
  STYPE SMap;   ///< Surface Map

796
  Object_sptr createCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
797
798
799
800
801
802
803
804
805
806
807
808
  {
    std::string C31="cx 3.0";         // cylinder x-axis radius 3
    std::string C32="px 1.2";
    std::string C33="px -3.2";

    // First create some surfaces
    std::map<int,Surface*> CylSurMap;
    CylSurMap[31]=new Cylinder();
    CylSurMap[32]=new Plane();
    CylSurMap[33]=new Plane();

    CylSurMap[31]->setSurface(C31);
809
810
811
812
813
814
815
816
817
818
    CylSurMap[32]->setSurface(C32);
    CylSurMap[33]->setSurface(C33);
    CylSurMap[31]->setName(31);
    CylSurMap[32]->setName(32);
    CylSurMap[33]->setName(33);

    // Capped cylinder (id 21) 
    // using surface ids: 31 (cylinder) 32 (plane (top) ) and 33 (plane (base))
    std::string ObjCapCylinder="-31 -32 33";

819
820
821
822
823
	Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);

	TS_ASSERT(retVal.get())
824
825
826
827
828
829

    return retVal;
  }
  
  // This creates a cylinder to test the solid angle that is more realistic in size
  // for a detector cylinder
830
  Object_sptr createSmallCappedCylinder()
831
832
833
834
835
836
837
838
839
840
841
842
  {
    std::string C31="cx 0.005";         // cylinder x-axis radius 0.005 and height 0.003
    std::string C32="px -0.997";
    std::string C33="px -1.0";

    // First create some surfaces
    std::map<int,Surface*> CylSurMap;
    CylSurMap[31]=new Cylinder();
    CylSurMap[32]=new Plane();
    CylSurMap[33]=new Plane();

    CylSurMap[31]->setSurface(C31);
Russell Taylor's avatar
Russell Taylor committed
843
844
845
846
847
848
849
850
851
852
    CylSurMap[32]->setSurface(C32);
    CylSurMap[33]->setSurface(C33);
    CylSurMap[31]->setName(31);
    CylSurMap[32]->setName(32);
    CylSurMap[33]->setName(33);

    // Capped cylinder (id 21) 
    // using surface ids: 31 (cylinder) 32 (plane (top) ) and 33 (plane (base))
    std::string ObjCapCylinder="-31 -32 33";

853
854
855
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);
Russell Taylor's avatar
Russell Taylor committed
856
857
858
859

    return retVal;
  }

860
  Object_sptr createSphere()
Russell Taylor's avatar
Russell Taylor committed
861
862
863
864
865
866
867
868
869
870
871
872
  {
    std::string S41="so 4.1";         // Sphere at origin radius 4.1

    // First create some surfaces
    std::map<int,Surface*> SphSurMap;
    SphSurMap[41]=new Sphere();
    SphSurMap[41]->setSurface(S41);
    SphSurMap[41]->setName(41);

    // A sphere 
    std::string ObjSphere="-41" ;

873
874
875
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(41,ObjSphere);
    retVal->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
876
877
878
879
880
881
882
883
884
885

    return retVal;
  }

  void clearSurfMap()
    /*!
    Clears the surface map for a new test
    or destruction.
    */
  {
886
    SMap.clear();
Russell Taylor's avatar
Russell Taylor committed
887
888
889
    return;
  }

890
  void createSurfaces(const std::string& desired)
Russell Taylor's avatar
Russell Taylor committed
891
892
893
894
895
896
897
898
899
900
901
    /*!
    Creates a list of surfaces for used in the objects
    and populates the MObj layers.
    */
  {
    clearSurfMap();

    // PLANE SURFACES:

    typedef std::pair<int,std::string> SCompT;
    std::vector<SCompT> SurfLine;
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
    if (desired.find("60001") != std::string::npos)
      SurfLine.push_back(SCompT(60001,"px -1"));
    if (desired.find("60002") != std::string::npos)
      SurfLine.push_back(SCompT(60002,"px 1"));
    if (desired.find("60003") != std::string::npos)
      SurfLine.push_back(SCompT(60003,"py -2"));
    if (desired.find("60004") != std::string::npos)
      SurfLine.push_back(SCompT(60004,"py 2"));
    if (desired.find("60005") != std::string::npos)
      SurfLine.push_back(SCompT(60005,"pz -3"));
    if (desired.find("60006") != std::string::npos)
      SurfLine.push_back(SCompT(60006,"pz 3"));

    if (desired.find("80001") != std::string::npos)
      SurfLine.push_back(SCompT(80001,"px 4.5"));
    if (desired.find("80002") != std::string::npos)
      SurfLine.push_back(SCompT(80002,"px 6.5"));

    if (desired.find("71") != std::string::npos)
      SurfLine.push_back(SCompT(71,"so 0.8"));
    if (desired.find("72") != std::string::npos)
      SurfLine.push_back(SCompT(72,"s -0.7 0 0 0.3"));
    if (desired.find("73") != std::string::npos)
      SurfLine.push_back(SCompT(73,"s 0.6 0 0 0.4"));
Russell Taylor's avatar
Russell Taylor committed
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

    std::vector<SCompT>::const_iterator vc;

    // Note that the testObject now manages the "new Plane"
    Geometry::Surface* A;
    for(vc=SurfLine.begin();vc!=SurfLine.end();vc++)
    {  
      A=Geometry::SurfaceFactory::Instance()->processLine(vc->second);
      if (!A)
      {
        std::cerr<<"Failed to process line "<<vc->second<<std::endl;
        exit(1);
      }
      A->setName(vc->first);
      SMap.insert(STYPE::value_type(vc->first,A));
    }

    return;
  }


947
  Object_sptr createUnitCube()
Russell Taylor's avatar
Russell Taylor committed
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
  {
    std::string C1="px -0.5";         // cube +/-0.5
    std::string C2="px 0.5";
    std::string C3="py -0.5";
    std::string C4="py 0.5";
    std::string C5="pz -0.5";
    std::string C6="pz 0.5";

    // Create surfaces
    std::map<int,Surface*> CubeSurMap;
    CubeSurMap[1]=new Plane();
    CubeSurMap[2]=new Plane();
    CubeSurMap[3]=new Plane();
    CubeSurMap[4]=new Plane();
    CubeSurMap[5]=new Plane();
    CubeSurMap[6]=new Plane();

    CubeSurMap[1]->setSurface(C1);
    CubeSurMap[2]->setSurface(C2);
    CubeSurMap[3]->setSurface(C3);
    CubeSurMap[4]->setSurface(C4);
    CubeSurMap[5]->setSurface(C5);
    CubeSurMap[6]->setSurface(C6);
    CubeSurMap[1]->setName(1);
    CubeSurMap[2]->setName(2);
    CubeSurMap[3]->setName(3);
    CubeSurMap[4]->setName(4);
    CubeSurMap[5]->setName(5);
    CubeSurMap[6]->setName(6);

    // Cube (id 68) 
    // using surface ids:  1-6
    std::string ObjCube="1 -2 3 -4 5 -6";

982
983
984
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(68,ObjCube);
    retVal->populate(CubeSurMap);
Russell Taylor's avatar
Russell Taylor committed
985
986
987
988
989

    return retVal;
  }


990
  Object_sptr createCuboid(std::vector<std::string>& planes)
Russell Taylor's avatar
Russell Taylor committed
991
992
993
994
995
996
997
998
999
1000
  {
    std::string C1=planes[0];
    std::string C2=planes[1];
    std::string C3=planes[2];
    std::string C4=planes[3];
    std::string C5=planes[4];
    std::string C6=planes[5];

    // Create surfaces
    std::map<int,Surface*> CubeSurMap;