ObjectTest.h 34.8 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

Russell Taylor's avatar
Russell Taylor committed
25
26
using namespace Mantid;
using namespace Geometry;
27
using Mantid::Kernel::V3D;
Russell Taylor's avatar
Russell Taylor committed
28

29
class ObjectTest: public CxxTest::TestSuite
Russell Taylor's avatar
Russell Taylor committed
30
31
32
33
34
{

public:


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

39
    TS_ASSERT_EQUALS(geom_obj->str(),"68 -6 5 -4 3 -2 1");
40
41

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

Russell Taylor's avatar
Russell Taylor committed
44
45
  }

Nick Draper's avatar
re #843    
Nick Draper committed
46
  void testIsOnSideCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
47
  {
48
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
49
    //inside
50
51
52
53
54
    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
55
    //on the side
56
57
58
59
60
61
    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
62
63

    //on the edges
64
65
66
67
68
69
70
71
    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
72
    //out side
73
74
75
76
77
78
    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
79
80
81
82
  }

  void testIsValidCappedCylinder()
  {
83
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
84
    //inside
85
86
87
88
89
    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
90
    //on the side
91
92
93
94
95
96
    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
97
98

    //on the edges
99
100
101
102
103
104
105
106
    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
107
    //out side
108
109
110
111
112
113
    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
114
115
116
117
  }

  void testIsOnSideSphere()
  {
118
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
119
    //inside
120
121
122
123
124
    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
125
    //on the side
126
127
128
129
    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
130
131

    //out side
132
133
134
135
    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
136
137
138
139
  }

  void testIsValidSphere()
  {
140
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
141
    //inside
142
143
144
145
146
    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
147
    //on the side
148
149
150
151
    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
152
153

    //out side
154
155
156
157
    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
158
159
160
161
  }

  void testCalcValidTypeSphere()
  {
162
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
163
    //entry on the normal
164
165
166
167
168
169
170
171
    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
172
173

    //a glancing blow
174
    TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1,0,0),V3D(0,1,0)),0);
Russell Taylor's avatar
Russell Taylor committed
175
    //not quite on the normal
176
177
    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
178
179
  }

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  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);

196
197
198
199
200
201
202
203
    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);
204
205
  }

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

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

  void testInterceptSurfaceSphereZ()
  {
228
    std::vector<Link> expectedResults;
Russell Taylor's avatar
Russell Taylor committed
229
230
231
232
233
234
235
236
237
238
239
    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" ;

240
241
242
    Object_sptr geom_obj = Object_sptr(new Object); 
    geom_obj->setObject(41,ObjSphere);
    geom_obj->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
243
244
245
246


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

247
    // format = startPoint, endPoint, total distance so far
Russell Taylor's avatar
Russell Taylor committed
248
    // forward only intercepts means that start point should be track origin
249
250
    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
251

252
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
253
254
255
256
  }

  void testInterceptSurfaceSphereY()
  {
257
    std::vector<Link> expectedResults;
258
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
259
260
    Track track(V3D(0,-10,0),V3D(0,1,0));

261
262
    //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
263

264
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
265
266
267
268
  }

  void testInterceptSurfaceSphereX()
  {
269
    std::vector<Link> expectedResults;
270
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
271
    Track track(V3D(-10,0,0),V3D(1,0,0));
272

273
274
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1));
275
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
276
277
278
279
  }

  void testInterceptSurfaceCappedCylinderY()
  {
280
    std::vector<Link> expectedResults;
281
    Object_sptr geom_obj = createCappedCylinder();
282
283
    //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
284
285

    Track track(V3D(0,-10,0),V3D(0,1,0));
286
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
287
288
289
290
  }

  void testInterceptSurfaceCappedCylinderX()
  {
291
    std::vector<Link> expectedResults;
292
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
293
294
    Track track(V3D(-10,0,0),V3D(1,0,0));

295
296
    //format = startPoint, endPoint, total distance so far
    expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2));
297
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
298
299
300
301
  }

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

306
    checkTrackIntercept(geom_obj,track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
307
308
  }

309
  void checkTrackIntercept(Track& track, const std::vector<Link>& expectedResults)
Russell Taylor's avatar
Russell Taylor committed
310
311
312
313
  {
    int index = 0;
    for (Track::LType::const_iterator it = track.begin(); it!=track.end();++it)
    {
314
315
      TS_ASSERT_DELTA(it->distFromStart,expectedResults[index].distFromStart,1e-6);
      TS_ASSERT_DELTA(it->distInsideObject,expectedResults[index].distInsideObject,1e-6);
316
      TS_ASSERT_EQUALS(it->componentID,expectedResults[index].componentID);
317
318
      TS_ASSERT_EQUALS(it->entryPoint,expectedResults[index].entryPoint);
      TS_ASSERT_EQUALS(it->exitPoint,expectedResults[index].exitPoint);
Russell Taylor's avatar
Russell Taylor committed
319
320
321
322
323
      ++index;
    }
    TS_ASSERT_EQUALS(index,static_cast<int>(expectedResults.size()));
  }

324
  void checkTrackIntercept(Object_sptr obj, Track& track, const std::vector<Link>& expectedResults)
Russell Taylor's avatar
Russell Taylor committed
325
  {
326
    int unitCount = obj->interceptSurface(track);
327
328
    TS_ASSERT_EQUALS(unitCount,expectedResults.size());
    checkTrackIntercept(track,expectedResults);
Russell Taylor's avatar
Russell Taylor committed
329
330
331
  }

  void xtestTrackTwoIsolatedCubes()
332
    /**
Russell Taylor's avatar
Russell Taylor committed
333
334
335
336
337
    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";
338

339
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
340
341
342
343
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

344
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
345
346
347
348
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

349
350
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
351
352

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

356
357
358
    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
359
360
361
362
363
    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackTwoTouchingCubes()
364
    /**
Russell Taylor's avatar
Russell Taylor committed
365
366
367
368
369
370
    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";

371
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
372
373
374
375
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

376
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
377
378
379
380
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

381
    Track TL(Kernel::V3D(-5,0,0), Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
382
383

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

387
388
389
    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
390
391
392
393
394
395

    checkTrackIntercept(TL,expectedResults);

  }

  void testTrackCubeWithInternalSphere()
396
    /**
Russell Taylor's avatar
Russell Taylor committed
397
398
399
400
401
402
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 71";
    std::string ObjB="-71";

403
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
404
405
406
407
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

408
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
409
410
411
412
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

413
414
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
415
416
417
418
419

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

420
421
422
423
    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
424
425
426
427
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheres()
428
    /**
Russell Taylor's avatar
Russell Taylor committed
429
430
431
432
433
    Test a track going through an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
434

435
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
436
437
438
439
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

440
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
441
442
443
444
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

445
    Track TL(Kernel::V3D(-5,0,0), Kernel::V3D(1,0,0));
Russell Taylor's avatar
Russell Taylor committed
446
447
448
449
450
451


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

452
453
454
455
    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
456
457
458
459
    checkTrackIntercept(TL,expectedResults);
  }

  void testTrack_CubePlusInternalEdgeTouchSpheresMiss()
460
    /**
Russell Taylor's avatar
Russell Taylor committed
461
462
463
464
465
    Test a track missing an object
    */
  {
    std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
    std::string ObjB="(-72 : -73)";
466

467
    createSurfaces(ObjA);
Russell Taylor's avatar
Russell Taylor committed
468
469
470
471
    Object object1=Object();
    object1.setObject(3,ObjA);
    object1.populate(SMap);

472
    createSurfaces(ObjB);
Russell Taylor's avatar
Russell Taylor committed
473
474
475
476
    Object object2=Object();
    object2.setObject(4,ObjB);
    object2.populate(SMap);

477
478
    Track TL(Kernel::V3D(-5,0,0),
      Kernel::V3D(0,1,0));
Russell Taylor's avatar
Russell Taylor committed
479
480
481
482
483
484


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

485
    std::vector<Link> expectedResults; //left empty as this should miss
Russell Taylor's avatar
Russell Taylor committed
486
487
488
489
    checkTrackIntercept(TL,expectedResults);
  }

  void testFindPointInCube()
490
    /**
Russell Taylor's avatar
Russell Taylor committed
491
492
493
    Test find point in cube
    */
  {
494
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
495
    // initial guess in object
496
    Kernel::V3D pt;
497
    TS_ASSERT_EQUALS(geom_obj->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
498
499
500
501
502
503
    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");
504
505
    Object_sptr B =createCuboid(planes);
    TS_ASSERT_EQUALS(B->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
506
507
508
509
510
511
    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");
512
513
    Object_sptr C =createCuboid(planes);
    TS_ASSERT_EQUALS(C->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
514
515
516
517
518
519
    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");
520
521
    Object_sptr D =createCuboid(planes);
    TS_ASSERT_EQUALS(D->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
522
523
524
525
526
527
528
529
530
531
532
533
    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");
534
535
    Object_sptr E =createCuboid(planes);
    TS_ASSERT_EQUALS(E->getPointInObject(pt),1);
Russell Taylor's avatar
Russell Taylor committed
536
537
538
539
540
541
542
543
544
545
546
    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");
547
548
    Object_sptr F =createCuboid(planes);
    TS_ASSERT_EQUALS(F->getPointInObject(pt),0);
Russell Taylor's avatar
Russell Taylor committed
549
    // Test use of defineBoundingBox to explictly set the bounding box, when the automatic method fails
550
    F->defineBoundingBox(0.5,-1/(2.0*sqrt(2.0)),-1.0/(2.0*sqrt(2.0)),
Russell Taylor's avatar
Russell Taylor committed
551
      -0.5,-sqrt(2.0)-1.0/(2.0*sqrt(2.0)),-sqrt(2.0)-1.0/(2.0*sqrt(2.0)));
552
553
554
    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
555
556
557
558
559
    TS_ASSERT_EQUALS(pt,V3D(0.0,0.0,0));
  }


  void testSolidAngleSphere()
560
    /**
Russell Taylor's avatar
Russell Taylor committed
561
562
563
    Test solid angle calculation for a sphere
    */
  {
564
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
565
566
567
568
569
570
    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
571
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(8.1,0,0)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
572
    // internal point (should be 4pi)
573
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
574
    // surface point
575
    TS_ASSERT_DELTA(geom_obj->rayTraceSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
576
577
  }

578

Russell Taylor's avatar
Russell Taylor committed
579
  void testSolidAngleCappedCylinder()
580
    /**
Russell Taylor's avatar
Russell Taylor committed
581
582
583
    Test solid angle calculation for a capped cylinder
    */
  {
584
    Object_sptr geom_obj = createSmallCappedCylinder();
585
    // Want to test triangulation so setup a geometry handler
586
    boost::shared_ptr<GluGeometryHandler> h = boost::shared_ptr<GluGeometryHandler>(new GluGeometryHandler(geom_obj.get()));
587
    h->setCylinder(V3D(-0.0015,0.0,0.0), V3D(1., 0.0, 0.0), 0.005, 0.003);
588
    geom_obj->setGeometryHandler(h);
589

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

592
    // solid angle at point -0.5 from capped cyl -1.0 -0.997 in x, rad 0.005 - approx WISH cylinder
593
594
    // 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);
595
    // Other end
596
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-1.497, 0.0, 0.0)), 0.0, satol);
597

598
599
600
601
602
    // 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);
603

Russell Taylor's avatar
Russell Taylor committed
604
    // internal point (should be 4pi)
605
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(-0.999, 0.0, 0.0)),4*M_PI,satol);
606
607

    // surface points
608
609
    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);
610

Russell Taylor's avatar
Russell Taylor committed
611
612
  }

613

Russell Taylor's avatar
Russell Taylor committed
614
  void testSolidAngleCubeTriangles()
615
    /**
Russell Taylor's avatar
Russell Taylor committed
616
617
618
619
    Test solid angle calculation for a cube using triangles
    - test for using Open Cascade surface triangulation for all solid angles.
    */
  {
620
    Object_sptr geom_obj = createUnitCube();
Russell Taylor's avatar
Russell Taylor committed
621
622
623
624
625
626
    double satol=1e-3; // tolerance for solid angle

    // solid angle at distance 0.5 should be 4pi/6 by symmetry
    //
    // tests for Triangulated cube
    //
627
628
629
630
631
632
    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
633
634
  }

635
636
637
638
639
640
641
642
643
644
645
646
647
648


  /** 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);
  }


649
  void testGetBoundingBoxForCylinder()
650
    /**
Russell Taylor's avatar
Russell Taylor committed
651
652
653
    Test bounding box for a object capped cylinder
    */
  {
654
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
655
656
657
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=ymax=zmax=100;
    xmin=ymin=zmin=-100;
658
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
659
660
661
662
663
664
665
666
    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);
  }

667
  void testdefineBoundingBox()
668
    /**
Russell Taylor's avatar
Russell Taylor committed
669
670
671
    Test use of defineBoundingBox
    */
  {
672
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
673
674
675
    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;
676
677

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

679
    const BoundingBox & boundBox = geom_obj->getBoundingBox();
680

681
682
683
684
685
686
    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);
687
688

    //Inconsistent bounding box
Russell Taylor's avatar
Russell Taylor committed
689
    xmax=1.2;xmin=3.0;
690
    TS_ASSERT_THROWS(geom_obj->defineBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin),std::invalid_argument);
Russell Taylor's avatar
Russell Taylor committed
691
692
693

  }
  void testSurfaceTriangulation()
694
    /**
Russell Taylor's avatar
Russell Taylor committed
695
696
697
    Test triangle solid angle calc
    */
  {
698
    Object_sptr geom_obj = createCappedCylinder();
Russell Taylor's avatar
Russell Taylor committed
699
700
701
    double xmax,ymax,zmax,xmin,ymin,zmin;
    xmax=20;ymax=20.0;zmax=20.0;
    xmin=-20.0;ymin=-20.0;zmin=-20.0;
702
    geom_obj->getBoundingBox(xmax,ymax,zmax,xmin,ymin,zmin);
Russell Taylor's avatar
Russell Taylor committed
703
704
    double saTri,saRay;
    V3D observer(4.2,0,0);
705

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

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
//    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
725

726
727
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
Russell Taylor's avatar
Russell Taylor committed
728
729
    TS_ASSERT_DELTA(saTri,1.840302,0.001);
    TS_ASSERT_DELTA(saRay,1.840302,0.01);
730

Russell Taylor's avatar
Russell Taylor committed
731
    observer=V3D(-7.2,0,0);
732
733
    saTri=geom_obj->triangleSolidAngle(observer);
    saRay=geom_obj->rayTraceSolidAngle(observer);
734

Russell Taylor's avatar
Russell Taylor committed
735
736
737
738
    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
739
740
    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
741

742
    saTri=geom_obj->triangleSolidAngle(V3D(20,0,0));
Russell Taylor's avatar
Russell Taylor committed
743
    TS_ASSERT_DELTA(saTri,0.07850147,satol*0.0785);
744
    saTri=geom_obj->triangleSolidAngle(V3D(200,0,0));
Russell Taylor's avatar
Russell Taylor committed
745
    TS_ASSERT_DELTA(saTri,0.000715295,satol*0.000715);
746
    saTri=geom_obj->triangleSolidAngle(V3D(2000,0,0));
Russell Taylor's avatar
Russell Taylor committed
747
    TS_ASSERT_DELTA(saTri,7.08131e-6,satol*7.08e-6);
748

Russell Taylor's avatar
Russell Taylor committed
749
750
  }
  void testSolidAngleSphereTri()
751
    /**
Russell Taylor's avatar
Russell Taylor committed
752
753
754
    Test solid angle calculation for a sphere from triangulation
    */
  {
755
    Object_sptr geom_obj = createSphere();
Russell Taylor's avatar
Russell Taylor committed
756
757
758
759
760
761
    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
762
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(8.1,0,0)),0.864364,satol);
Russell Taylor's avatar
Russell Taylor committed
763
    // internal point (should be 4pi)
764
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(0,0,0)),4*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
765
    // surface point
766
    TS_ASSERT_DELTA(geom_obj->triangleSolidAngle(V3D(4.1,0,0)),2*M_PI,satol);
Russell Taylor's avatar
Russell Taylor committed
767
768
769
770
771
772
773
774
775
  }

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

Russell Taylor's avatar
Russell Taylor committed
777
778
  STYPE SMap;   ///< Surface Map

779
  Object_sptr createCappedCylinder()
Russell Taylor's avatar
Russell Taylor committed
780
781
782
783
784
785
786
787
788
789
790
791
  {
    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);
792
793
794
795
796
797
798
799
800
801
    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";

802
    Object_sptr retVal = Object_sptr(new Object); 
803
804
805
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);

806
    TS_ASSERT(retVal.get());
807
808
809

    return retVal;
  }
810

811
812
  // This creates a cylinder to test the solid angle that is more realistic in size
  // for a detector cylinder
813
  Object_sptr createSmallCappedCylinder()
814
815
816
817
818
819
820
821
822
823
824
825
  {
    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
826
827
828
829
830
831
832
833
834
835
    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";

836
837
838
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(21,ObjCapCylinder);
    retVal->populate(CylSurMap);
Russell Taylor's avatar
Russell Taylor committed
839
840
841
842

    return retVal;
  }

843
  Object_sptr createSphere()
Russell Taylor's avatar
Russell Taylor committed
844
845
846
847
848
849
850
851
852
853
854
855
  {
    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" ;

856
857
858
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(41,ObjSphere);
    retVal->populate(SphSurMap);
Russell Taylor's avatar
Russell Taylor committed
859
860
861
862
863

    return retVal;
  }

  void clearSurfMap()
864
    /**
Russell Taylor's avatar
Russell Taylor committed
865
866
867
868
    Clears the surface map for a new test
    or destruction.
    */
  {
869
    SMap.clear();
Russell Taylor's avatar
Russell Taylor committed
870
871
872
    return;
  }

873
  void createSurfaces(const std::string& desired)
874
    /**
Russell Taylor's avatar
Russell Taylor committed
875
876
877
878
879
880
881
882
883
884
    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;
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
    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
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929

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


930
  Object_sptr createUnitCube()
Russell Taylor's avatar
Russell Taylor committed
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  {
    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";

965
966
967
    Object_sptr retVal = Object_sptr(new Object); 
    retVal->setObject(68,ObjCube);
    retVal->populate(CubeSurMap);
Russell Taylor's avatar
Russell Taylor committed
968
969
970
971
972

    return retVal;
  }


973
  Object_sptr createCuboid(std::vector<std::string>& planes)
Russell Taylor's avatar
Russell Taylor committed
974
975
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=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;
    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);