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

#include <cxxtest/TestSuite.h>
#include <cmath>
#include <ostream>
#include <vector>
#include <algorithm>
#include <ctime>
10
#include <iomanip>
Russell Taylor's avatar
Russell Taylor committed
11

12
13
#include <boost/shared_ptr.hpp>

14
#include "MantidKernel/V3D.h" 
Nick Draper's avatar
re #843    
Nick Draper committed
15
16
17
18
19
20
21
22
#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"
23
#include "MantidGeometry/Objects/BoundingBox.h"
24
25
26
#include "MantidGeometry/Objects/ShapeFactory.h"

#include "MantidTestHelpers/ComponentCreationHelper.h"
27

Russell Taylor's avatar
Russell Taylor committed
28
29
using namespace Mantid;
using namespace Geometry;
30
using Mantid::Kernel::V3D;
Russell Taylor's avatar
Russell Taylor committed
31

32
class ObjectTest: public CxxTest::TestSuite
Russell Taylor's avatar
Russell Taylor committed
33
34
35
36
{

public:

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  void testCopyConstructorGivesObjectWithSameAttributes()
  {
    Object_sptr original = ComponentCreationHelper::createSphere(1.0, V3D(), "sphere");
    int objType(-1);
    double radius(-1.0), height(-1.0);
    std::vector<V3D> pts;
    original->GetObjectGeom(objType, pts, radius, height);
    TS_ASSERT_EQUALS(2, objType);
    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(original->getGeometryHandler()));

    Object copy(*original);
    // The copy should be a primitive object with a GluGeometryHandler
    objType = -1;
    copy.GetObjectGeom(objType, pts, radius, height);

    TS_ASSERT_EQUALS(2, objType);
    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(copy.getGeometryHandler()));
    TS_ASSERT_EQUALS(copy.getName(), original->getName());
    // Check the string representation is the same
    TS_ASSERT_EQUALS(copy.str(), original->str());
    TS_ASSERT_EQUALS(copy.getSurfaceIndex(), original->getSurfaceIndex());
  }

  void testAssignmentOperatorGivesObjectWithSameAttributes()
  {
    Object_sptr original = ComponentCreationHelper::createSphere(1.0, V3D(), "sphere");
    int objType(-1);
    double radius(-1.0), height(-1.0);
    std::vector<V3D> pts;
    original->GetObjectGeom(objType, pts, radius, height);
    TS_ASSERT_EQUALS(2, objType);
    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(original->getGeometryHandler()));

    Object lhs; // initialize
    lhs = *original; // assign
    // The copy should be a primitive object with a GluGeometryHandler
    objType = -1;
    lhs.GetObjectGeom(objType, pts, radius, height);

    TS_ASSERT_EQUALS(2, objType);
    TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(lhs.getGeometryHandler()));
  }
Russell Taylor's avatar
Russell Taylor committed
79

Nick Draper's avatar
re #843    
Nick Draper committed
80
  void testCreateUnitCube()
Russell Taylor's avatar
Russell Taylor committed
81
  {
82
    Object_sptr geom_obj = createUnitCube();
83

84
    TS_ASSERT_EQUALS(geom_obj->str(),"68 -6 5 -4 3 -2 1");
85
86

    double xmin(0.0), xmax(0.0), ymin(0.0), ymax(0.0), zmin(0.0), zmax(0.0);
87
    geom_obj->getBoundingBox(xmax, ymax, zmax, xmin, ymin, zmin);
88

Russell Taylor's avatar
Russell Taylor committed
89
90
  }

Nick Draper's avatar
re #843    
Nick Draper committed
91
  void testIsOnSideCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
92
  {
93
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
94
    //inside
95
96
97
98
99
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,0)),false); //origin
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,2.9,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-2.9,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-2.9)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,2.9)),false);
Russell Taylor's avatar
Russell Taylor committed
100
    //on the side
101
102
103
104
105
106
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,3)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,0)),true);
Russell Taylor's avatar
Russell Taylor committed
107
108

    //on the edges
109
110
111
112
113
114
115
116
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.2,0,3)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.2,0,3)),true);
Russell Taylor's avatar
Russell Taylor committed
117
    //out side
118
119
120
121
122
123
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,3.1,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-3.1,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-3.1)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,3.1)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(1.3,0,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(-3.3,0,0)),false);
Russell Taylor's avatar
Russell Taylor committed
124
125
126
127
  }

  void testIsValidCappedCylinder()
  {
128
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
129
    //inside
130
131
132
133
134
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,0)),true); //origin
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,2.9,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-2.9,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-2.9)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,2.9)),true);
Russell Taylor's avatar
Russell Taylor committed
135
    //on the side
136
137
138
139
140
141
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,3)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,0)),true);
Russell Taylor's avatar
Russell Taylor committed
142
143

    //on the edges
144
145
146
147
148
149
150
151
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.2,0,3)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,-3,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,-3)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.2,0,3)),true);
Russell Taylor's avatar
Russell Taylor committed
152
    //out side
153
154
155
156
157
158
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,3.1,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-3.1,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-3.1)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,3.1)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(1.3,0,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(-3.3,0,0)),false);
Russell Taylor's avatar
Russell Taylor committed
159
160
161
162
  }

  void testIsOnSideSphere()
  {
163
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
164
    //inside
165
166
167
168
169
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,0)),false); //origin
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.0,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.0,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.0)),false);
Russell Taylor's avatar
Russell Taylor committed
170
    //on the side
171
172
173
174
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.1,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.1,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.1)),true);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.1)),true);
Russell Taylor's avatar
Russell Taylor committed
175
176

    //out side
177
178
179
180
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,4.2,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,-4.2,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,-4.2)),false);
    TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0,0,4.2)),false);
Russell Taylor's avatar
Russell Taylor committed
181
182
183
184
  }

  void testIsValidSphere()
  {
185
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
186
    //inside
187
188
189
190
191
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,0)),true); //origin
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.0,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.0,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.0)),true);
Russell Taylor's avatar
Russell Taylor committed
192
    //on the side
193
194
195
196
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.1,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.1,0)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.1)),true);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.1)),true);
Russell Taylor's avatar
Russell Taylor committed
197
198

    //out side
199
200
201
202
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,4.2,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,-4.2,0)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,-4.2)),false);
    TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0,0,4.2)),false);
Russell Taylor's avatar
Russell Taylor committed
203
204
205
206
  }

  void testCalcValidTypeSphere()
  {
207
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
208
    //entry on the normal
209
210
211
212
213
214
215
216
    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
217
218

    //a glancing blow
219
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(0,1,0)),0);
Russell Taylor's avatar
Russell Taylor committed
220
    //not quite on the normal
221
222
    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
223
224
  }

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  void testGetBoundingBoxForSphere()
  {
    Object_sptr geom_obj = createSphere();    
    const double tolerance(1e-10);

    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=ymax=zmax=20;
    xmin=ymin=zmin=-20;
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
    TS_ASSERT_DELTA(xmax,4.1,tolerance);
    TS_ASSERT_DELTA(ymax,4.1,tolerance);
    TS_ASSERT_DELTA(zmax,4.1,tolerance);
    TS_ASSERT_DELTA(xmin,-4.1,tolerance);
    TS_ASSERT_DELTA(ymin,-4.1,tolerance);
    TS_ASSERT_DELTA(zmin,-4.1,tolerance);

241
242
243
244
245
246
247
248
    const BoundingBox & bbox  = geom_obj->getBoundingBox();

    TS_ASSERT_DELTA(bbox.xMax(),4.1,tolerance);
    TS_ASSERT_DELTA(bbox.yMax(),4.1,tolerance);
    TS_ASSERT_DELTA(bbox.zMax(),4.1,tolerance);
    TS_ASSERT_DELTA(bbox.xMin(),-4.1,tolerance);
    TS_ASSERT_DELTA(bbox.yMin(),-4.1,tolerance);
    TS_ASSERT_DELTA(bbox.zMin(),-4.1,tolerance);
249
250
  }

Russell Taylor's avatar
Russell Taylor committed
251
252
  void testCalcValidTypeCappedCylinder()
  {
253
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
254
    //entry on the normal
255
256
257
258
259
260
261
262
    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
263
264

    //a glancing blow
265
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-3.2,0,0),V3D(0,1,0)),0);
Russell Taylor's avatar
Russell Taylor committed
266
    //not quite on the normal
267
268
    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
269
270
271
272
  }

  void testInterceptSurfaceSphereZ()
  {
273
    std::vector<Link> expectedResults;
Russell Taylor's avatar
Russell Taylor committed
274
275
276
277
278
279
280
281
282
283
284
    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" ;

285
286
287
    Object_sptr geom_obj = Object_sptr(new Object); 
    geom_obj->setObject(41,ObjSphere);
    geom_obj->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
288
289
290
291


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

292
    // format = startPoint, endPoint, total distance so far
Russell Taylor's avatar
Russell Taylor committed
293
    // forward only intercepts means that start point should be track origin
294
295
    expectedResults.push_back(Link(V3D(-1,1.5,1),
      V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2));
Russell Taylor's avatar
Russell Taylor committed
296

297
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
298
299
300
301
  }

  void testInterceptSurfaceSphereY()
  {
302
    std::vector<Link> expectedResults;
303
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
304
305
    Track track(V3D(0,-10,0),V3D(0,1,0));

306
307
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(0,-4.1,0),V3D(0,4.1,0),14.1));
Russell Taylor's avatar
Russell Taylor committed
308

309
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
310
311
312
313
  }

  void testInterceptSurfaceSphereX()
  {
314
    std::vector<Link> expectedResults;
315
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
316
    Track track(V3D(-10,0,0),V3D(1,0,0));
317

318
319
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1));
320
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
321
322
323
324
  }

  void testInterceptSurfaceCappedCylinderY()
  {
325
    std::vector<Link> expectedResults;
326
    Object_sptr geom_obj = createCappedCylinder();
327
328
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(0,-3,0),V3D(0,3,0),13));
Russell Taylor's avatar
Russell Taylor committed
329
330

    Track track(V3D(0,-10,0),V3D(0,1,0));
331
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
332
333
334
335
  }

  void testInterceptSurfaceCappedCylinderX()
  {
336
    std::vector<Link> expectedResults;
337
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
338
339
    Track track(V3D(-10,0,0),V3D(1,0,0));

340
341
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2));
342
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
343
344
345
346
  }

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

351
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
352
353
  }

354
  void checkTrackIntercept(Track& track, const std::vector<Link>& expectedResults)
Russell Taylor's avatar
Russell Taylor committed
355
356
357
358
  {
    int index = 0;
    for (Track::LType::const_iterator it = track.begin(); it!=track.end();++it)
    {
359
360
      TS_ASSERT_DELTA(it->distFromStart,expectedResults[index].distFromStart,1e-6);
      TS_ASSERT_DELTA(it->distInsideObject,expectedResults[index].distInsideObject,1e-6);
361
      TS_ASSERT_EQUALS(it->componentID,expectedResults[index].componentID);
362
363
      TS_ASSERT_EQUALS(it->entryPoint,expectedResults[index].entryPoint);
      TS_ASSERT_EQUALS(it->exitPoint,expectedResults[index].exitPoint);
Russell Taylor's avatar
Russell Taylor committed
364
365
366
367
368
      ++index;
    }
    TS_ASSERT_EQUALS(index,static_cast<int>(expectedResults.size()));
  }

369
  void checkTrackIntercept(Object_sptr obj, Track& track, const std::vector<Link>& expectedResults)
Russell Taylor's avatar
Russell Taylor committed
370
  {
371
    int unitCount = obj->interceptSurface(track);
372
373
    TS_ASSERT_EQUALS(unitCount,expectedResults.size());
    checkTrackIntercept(track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
374
375
376
  }

  void xtestTrackTwoIsolatedCubes()
377
    /**
Russell Taylor's avatar
Russell Taylor committed
378
379
380
381
382
    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";
383

384
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
385
386
387
388
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

389
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
390
391
392
393
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

394
395
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
396
397

    // CARE: This CANNOT be called twice
398
399
    TS_ASSERT(object1.interceptSurface(TL)!=0);
    TS_ASSERT(object2.interceptSurface(TL)!=0);
Russell Taylor's avatar
Russell Taylor committed
400

401
402
403
    std::vector<Link> expectedResults;
    expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6));
    expectedResults.push_back(Link(V3D(4.5,0,0),V3D(6.5,0,0),11.5));
Russell Taylor's avatar
Russell Taylor committed
404
405
406
407
408
    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackTwoTouchingCubes()
409
    /**
Russell Taylor's avatar
Russell Taylor committed
410
411
412
413
414
415
    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";

416
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
417
418
419
420
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

421
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
422
423
424
425
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

426
    Track TL(Kernel::V3D(-5,0,0), Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
427
428

    // CARE: This CANNOT be called twice
429
430
    TS_ASSERT(object1.interceptSurface(TL)!=0);
    TS_ASSERT(object2.interceptSurface(TL)!=0);
Russell Taylor's avatar
Russell Taylor committed
431

432
433
434
    std::vector<Link> expectedResults;
    expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6));
    expectedResults.push_back(Link(V3D(1,0,0),V3D(6.5,0,0),11.5));
Russell Taylor's avatar
Russell Taylor committed
435
436
437
438
439
440

    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackCubeWithInternalSphere()
441
    /**
Russell Taylor's avatar
Russell Taylor committed
442
443
444
445
446
447
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 71";
    std::string ObjB="-71";

448
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
449
450
451
452
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

453
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
454
455
456
457
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

458
459
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
460
461
462
463
464

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

465
466
467
468
    std::vector<Link> expectedResults;
    expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.8,0,0),4.2));
    expectedResults.push_back(Link(V3D(-0.8,0,0),V3D(0.8,0,0),5.8));
    expectedResults.push_back(Link(V3D(0.8,0,0),V3D(1,0,0),6));
Russell Taylor's avatar
Russell Taylor committed
469
470
471
472
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheres()
473
    /**
Russell Taylor's avatar
Russell Taylor committed
474
475
476
477
478
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
479

480
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
481
482
483
484
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

485
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
486
487
488
489
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

490
    Track TL(Kernel::V3D(-5,0,0), Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
491
492
493
494
495
496


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

497
498
499
500
    std::vector<Link> expectedResults;
    expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.4,0,0),4.6));
    expectedResults.push_back(Link(V3D(-0.4,0,0),V3D(0.2,0,0),5.2));
    expectedResults.push_back(Link(V3D(0.2,0,0),V3D(1,0,0),6));
Russell Taylor's avatar
Russell Taylor committed
501
502
503
504
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheresMiss()
505
    /**
Russell Taylor's avatar
Russell Taylor committed
506
507
508
509
510
    Test a track missing an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
511

512
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
513
514
515
516
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

517
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
518
519
520
521
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

522
523
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(0,1,0));
Russell Taylor's avatar
Russell Taylor committed
524
525
526
527
528
529


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

530
    std::vector<Link> expectedResults; //left empty as this should miss
Russell Taylor's avatar
Russell Taylor committed
531
532
533
534
    checkTrackIntercept(TL,expectedResults);
  }

  void testFindPointInCube()
535
    /**
Russell Taylor's avatar
Russell Taylor committed
536
537
538
    Test find point in cube
    */
  {
539
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
540
    // initial guess in object
541
    Kernel::V3D pt;
542
    TS_ASSERT_EQUALS(geom_obj->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
543
544
545
546
547
548
    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");
549
550
    Object_sptr B =createCuboid(planes);
    TS_ASSERT_EQUALS(B->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
551
552
553
554
555
556
    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");
557
558
    Object_sptr C =createCuboid(planes);
    TS_ASSERT_EQUALS(C->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
559
560
561
562
563
564
    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");
565
566
    Object_sptr D =createCuboid(planes);
    TS_ASSERT_EQUALS(D->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
567
568
569
570
571
572
573
574
575
576
577
578
    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");
579
580
    Object_sptr E =createCuboid(planes);
    TS_ASSERT_EQUALS(E->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
581
582
583
584
585
586
587
588
589
590
591
    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");
592
593
    Object_sptr F =createCuboid(planes);
    TS_ASSERT_EQUALS(F->getPointInObject(pt),0);
Russell Taylor's avatar
Russell Taylor committed
594
    // Test use of defineBoundingBox to explictly set the bounding box, when the automatic method fails
595
    F->defineBoundingBox(0.5,-1/(2.0*sqrt(2.0)),-1.0/(2.0*sqrt(2.0)),
Russell Taylor's avatar
Russell Taylor committed
596
      -0.5,-sqrt(2.0)-1.0/(2.0*sqrt(2.0)),-sqrt(2.0)-1.0/(2.0*sqrt(2.0)));
597
598
599
    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
600
601
602
603
604
    TS_ASSERT_EQUALS(pt,V3D(0.0,0.0,0));
  }


  void testSolidAngleSphere()
605
    /**
Russell Taylor's avatar
Russell Taylor committed
606
607
608
    Test solid angle calculation for a sphere
    */
  {
609
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
610
611
612
613
614
615
    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
616
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(8.1,0,0)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
617
    // internal point (should be 4pi)
618
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
619
    // surface point
620
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
621
622
  }

623

Russell Taylor's avatar
Russell Taylor committed
624
  void testSolidAngleCappedCylinder()
625
    /**
Russell Taylor's avatar
Russell Taylor committed
626
627
628
    Test solid angle calculation for a capped cylinder
    */
  {
629
    Object_sptr geom_obj = createSmallCappedCylinder();
630
    // Want to test triangulation so setup a geometry handler
631
    boost::shared_ptr<GluGeometryHandler> h = boost::shared_ptr<GluGeometryHandler>(new GluGeometryHandler(geom_obj.get()));
632
    h->setCylinder(V3D(-0.0015,0.0,0.0), V3D(1., 0.0, 0.0), 0.005, 0.003);
633
    geom_obj->setGeometryHandler(h);
634

635
    double satol(1e-8); // tolerance for solid angle
Russell Taylor's avatar
Russell Taylor committed
636

637
    // solid angle at point -0.5 from capped cyl -1.0 -0.997 in x, rad 0.005 - approx WISH cylinder
638
639
    // We intentionally exclude the cylinder end caps so they this should produce 0
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.5, 0.0, 0.0)), 0.0, satol);
640
    // Other end
641
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-1.497, 0.0, 0.0)), 0.0, satol);
642

643
644
645
646
647
    // Side values
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0, 0, 0.1)), 0.00301186, satol);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0, 0, -0.1)), 0.00301186, satol);
    // Sweep in the axis of the cylinder angle to see if the solid angle decreases (as we are excluding the end caps)
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0.1, 0.0, 0.1)), 0.00100267, satol);
648

Russell Taylor's avatar
Russell Taylor committed
649
    // internal point (should be 4pi)
650
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.999, 0.0, 0.0)),4*M_PI,satol);
651
652

    // surface points
653
654
    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);
655

Russell Taylor's avatar
Russell Taylor committed
656
657
  }

658

Russell Taylor's avatar
Russell Taylor committed
659
  void testSolidAngleCubeTriangles()
660
    /**
Russell Taylor's avatar
Russell Taylor committed
661
662
663
664
    Test solid angle calculation for a cube using triangles
    - test for using Open Cascade surface triangulation for all solid angles.
    */
  {
665
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
666
667
668
669
670
671
    double satol=1e-3; // tolerance for solid angle

    // solid angle at distance 0.5 should be 4pi/6 by symmetry
    //
    // tests for Triangulated cube
    //
672
673
674
675
676
677
    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
678
679
  }

680
681
682
683
684
685
686
687
688
689
690
691
692
693


  /** Add a scale factor */
  void testSolidAngleCubeTriangles_WithScaleFactor()
  {
    Object_sptr geom_obj = createUnitCube();
    double satol=1e-3; // tolerance for solid angle
    // solid angle at distance 0.5 should be 4pi/6 by symmetry
    double expected = M_PI*2.0/3.0;
    V3D scaleFactor(2.0,2.0,2.0);
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(2.0,0,0), scaleFactor),expected,satol);
  }


694
  void testGetBoundingBoxForCylinder()
695
    /**
Russell Taylor's avatar
Russell Taylor committed
696
697
698
    Test bounding box for a object capped cylinder
    */
  {
699
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
700
701
702
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=ymax=zmax=100;
    xmin=ymin=zmin=-100;
703
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
704
705
706
707
708
709
710
711
    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);
  }

712
  void testdefineBoundingBox()
713
    /**
Russell Taylor's avatar
Russell Taylor committed
714
715
716
    Test use of defineBoundingBox
    */
  {
717
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
718
719
720
    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;
721
722

    TS_ASSERT_THROWS_NOTHING(geom_obj->defineBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin));
723

724
    const BoundingBox & boundBox = geom_obj->getBoundingBox();
725

726
727
728
729
730
731
    TS_ASSERT_EQUALS(boundBox.xMax(),1.2);
    TS_ASSERT_EQUALS(boundBox.yMax(),3.0);
    TS_ASSERT_EQUALS(boundBox.zMax(),3.0);
    TS_ASSERT_EQUALS(boundBox.xMin(),-3.2);
    TS_ASSERT_EQUALS(boundBox.yMin(),-3.0);
    TS_ASSERT_EQUALS(boundBox.zMin(),-3.0);
732
733

    //Inconsistent bounding box
Russell Taylor's avatar
Russell Taylor committed
734
    xmax=1.2;xmin=3.0;
735
    TS_ASSERT_THROWS(geom_obj->defineBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin),std::invalid_argument);
Russell Taylor's avatar
Russell Taylor committed
736
737
738

  }
  void testSurfaceTriangulation()
739
    /**
Russell Taylor's avatar
Russell Taylor committed
740
741
742
    Test triangle solid angle calc
    */
  {
743
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
744
745
746
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=20;ymax=20.0;zmax=20.0;
    xmin=-20.0;ymin=-20.0;zmin=-20.0;
747
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
748
749
    double saTri,saRay;
    V3D observer(4.2,0,0);
750

Russell Taylor's avatar
Russell Taylor committed
751
752
    double satol=1e-3; // typical result tolerance

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
//    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++)
//        saTri=geom_obj->triangleSolidAngle(observer);
//      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++)
//        saRay=geom_obj->rayTraceSolidAngle(observer);
//      endtime=clock();
//      std::cout << "Cyl ray time=" << (endtime-starttime)/(static_cast<double>(CLOCKS_PER_SEC*iter)) << std::endl;
//    }
Russell Taylor's avatar
Russell Taylor committed
770

771
772
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
773
774
    TS_ASSERT_DELTA(saTri,1.840302,0.001);
    TS_ASSERT_DELTA(saRay,1.840302,0.01);
775

Russell Taylor's avatar
Russell Taylor committed
776
    observer=V3D(-7.2,0,0);
777
778
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
779

Russell Taylor's avatar
Russell Taylor committed
780
781
782
783
    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
784
785
    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
786

787
    saTri=geom_obj->triangleSolidAngle(V3D(20,0,0));
Russell Taylor's avatar
Russell Taylor committed
788
    TS_ASSERT_DELTA(saTri,0.07850147,satol*0.0785);
789
    saTri=geom_obj->triangleSolidAngle(V3D(200,0,0));
Russell Taylor's avatar
Russell Taylor committed
790
    TS_ASSERT_DELTA(saTri,0.000715295,satol*0.000715);
791
    saTri=geom_obj->triangleSolidAngle(V3D(2000,0,0));
Russell Taylor's avatar
Russell Taylor committed
792
    TS_ASSERT_DELTA(saTri,7.08131e-6,satol*7.08e-6);
793

Russell Taylor's avatar
Russell Taylor committed
794
795
  }
  void testSolidAngleSphereTri()
796
    /**
Russell Taylor's avatar
Russell Taylor committed
797
798
799
    Test solid angle calculation for a sphere from triangulation
    */
  {
800
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
801
802
803
804
805
806
    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
807
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(8.1,0,0)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
808
    // internal point (should be 4pi)
809
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
810
    // surface point
811
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
812
813
814
815
816
817
818
819
820
  }

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;
821

Russell Taylor's avatar
Russell Taylor committed
822
823
  STYPE SMap;   ///< Surface Map

824
  Object_sptr createCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
825
826
827
828
829
830
831
832
833
834
835
836
  {
    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);
837
838
839
840
841
842
843
844
845
846
    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";

847
    Object_sptr retVal = Object_sptr(new Object); 
848
849
850
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);

851
    TS_ASSERT(retVal.get());
852
853
854

    return retVal;
  }
855

856
857
  // This creates a cylinder to test the solid angle that is more realistic in size
  // for a detector cylinder
858
  Object_sptr createSmallCappedCylinder()
859
860
861
862
863
864
865
866
867
868
869
870
  {
    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
871
872
873
874
875
876
877
878
879
880
    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";

881
882
883
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);
Russell Taylor's avatar
Russell Taylor committed
884
885
886
887

    return retVal;
  }

888
  Object_sptr createSphere()
Russell Taylor's avatar
Russell Taylor committed
889
890
891
892
893
894
895
896
897
898
899
900
  {
    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" ;

901
902
903
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(41,ObjSphere);
    retVal->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
904
905
906
907
908

    return retVal;
  }

  void clearSurfMap()
909
    /**
Russell Taylor's avatar
Russell Taylor committed
910
911
912
913
    Clears the surface map for a new test
    or destruction.
    */
  {
914
    SMap.clear();
Russell Taylor's avatar
Russell Taylor committed
915
916
917
    return;
  }

918
  void createSurfaces(const std::string& desired)
919
    /**
Russell Taylor's avatar
Russell Taylor committed
920
921
922
923
924
925
926
927
928
929
    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;
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
    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
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974

    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;
  }


975
  Object_sptr createUnitCube()
Russell Taylor's avatar
Russell Taylor committed
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
  {
    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);