1 package org.lcsim.detector;
2
3 import hep.physics.vec.BasicHep3Vector;
4 import hep.physics.vec.Hep3Vector;
5
6 import java.util.Collection;
7
8 import org.lcsim.detector.solids.Inside;
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class PhysicalVolumeNavigator
45 implements IPhysicalVolumeNavigator
46 {
47 String name;
48
49
50
51
52
53
54
55
56
57
58 public IPhysicalVolumePath getPath(Hep3Vector globalPoint, int level)
59 {
60
61
62
63 IPhysicalVolumePath path = new PhysicalVolumePath();
64
65
66 IPhysicalVolume world = getTopPhysicalVolume();
67
68
69 ILogicalVolume lvCurr = world.getLogicalVolume();
70
71
72 if (lvCurr.getSolid().inside(globalPoint) == Inside.INSIDE)
73 {
74
75 path.add(world);
76 }
77
78 else {
79 System.err.println("!!! Point " + globalPoint.v() + " is outside the top volume <"+world.getName()+">. !!!");
80
81
82 return path;
83 }
84
85
86 int depth=0;
87
88
89
90
91 Hep3Vector localPoint = new BasicHep3Vector(globalPoint.x(),globalPoint.y(),globalPoint.z());
92
93
94
95
96 ITransform3D combinedTransform = new Transform3D();
97
98
99
100 while(lvCurr.getNumberOfDaughters() != 0)
101 {
102
103 boolean inDau=false;
104
105
106 for (IPhysicalVolume dau : lvCurr.getDaughters())
107 {
108
109
110 Hep3Vector checkLocalPoint =
111 dau.getTransform().inverse().transformed(localPoint);
112
113
114 if (dau.getLogicalVolume().getSolid().inside(checkLocalPoint) == Inside.INSIDE)
115 {
116
117 inDau=true;
118
119
120 path.add(dau);
121
122
123 lvCurr = dau.getLogicalVolume();
124
125
126 ++depth;
127
128
129 combinedTransform.multiplyBy(dau.getTransform());
130
131
132 localPoint = checkLocalPoint;
133
134
135 break;
136 }
137 }
138
139
140
141
142 if ( level != -1 && depth >= level || !inDau)
143 {
144 break;
145 }
146 }
147
148 return path;
149 }
150
151
152
153
154
155
156 public IPhysicalVolumePath getPath(Hep3Vector globalPoint)
157 {
158 return getPath(globalPoint,-1);
159 }
160
161
162
163
164
165 public Transform3D getTransform(String path)
166 {
167 return getTransform(getPath(path));
168 }
169
170
171
172
173
174
175 public Transform3D getTransform(IPhysicalVolumePath path)
176 {
177 Transform3D theTransform = new Transform3D();
178 for (IPhysicalVolume physvol : path)
179 {
180 theTransform.multiplyBy(physvol.getTransform());
181 }
182 return theTransform;
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197 private static String[] splitPath(String path)
198 {
199 if (path.equals("/"))
200 {
201 return new String[] {};
202 }
203
204
205 if (path.startsWith("/"))
206 {
207 path = path.substring(1);
208 }
209
210
211 if (path.endsWith("/"))
212 {
213 path = path.substring(0,(path.length()-1));
214 }
215
216
217
218
219 return path.split("/");
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 public IPhysicalVolumePath getPath(String[] path)
239 {
240
241 IPhysicalVolumePath physvols = new PhysicalVolumePath();
242
243
244 IPhysicalVolume pv = getTopPhysicalVolume();
245
246
247 physvols.add(pv);
248
249
250 for (String name : path)
251 {
252 PhysicalVolumeContainer pvSearch =
253 pv.getLogicalVolume().getDaughters().findByName(name);
254
255 if (pvSearch.size() > 1)
256 {
257 throw new RuntimeException("Got multiple matches on name <"+name+"> in mom <"+pv.getName() + ">.");
258 }
259 else if (pvSearch.size() == 0)
260 {
261 throw new RuntimeException("Path component <"+name+"> was not found!");
262 }
263 else {
264 IPhysicalVolume pvFound = pvSearch.get(0);
265
266 physvols.add(pvFound);
267 pv = pvSearch.get(0);
268 }
269 }
270 return physvols;
271 }
272
273
274
275
276 public IPhysicalVolumePath getPath(String path)
277 {
278 return getPath(splitPath(path));
279 }
280
281
282
283
284
285 public IPhysicalVolume getTopPhysicalVolume()
286 {
287 return pvTop;
288 }
289
290
291
292
293
294 public void setTopPhysicalVolume(IPhysicalVolume physvol)
295 {
296 if (physvol == null)
297 {
298 throw new IllegalArgumentException("Top volume points to null!");
299 }
300 pvTop = physvol;
301 }
302
303
304
305
306
307
308
309 public void setTopPhysicalVolume(IPhysicalVolumePath path)
310 {
311 if (path == null)
312 {
313 throw new IllegalArgumentException("The path cannot be null!");
314 }
315
316 if (path.isEmpty())
317 {
318 throw new IllegalArgumentException("The path is empty!");
319 }
320
321 setTopPhysicalVolume(path.getTopVolume());
322 }
323
324 private IPhysicalVolume pvTop;
325
326 public PhysicalVolumeNavigator(String name, IPhysicalVolume pvTop)
327 {
328 this.name = name;
329 setTopPhysicalVolume(pvTop);
330 PhysicalVolumeNavigatorStore.getInstance().add(this);
331 }
332
333 public PhysicalVolumeNavigator(String name, IPhysicalVolumePath path)
334 {
335 this.name = name;
336
337 if ( path == null )
338 {
339 throw new IllegalArgumentException("The path is null!");
340 }
341
342 setTopPhysicalVolume(path);
343
344 PhysicalVolumeNavigatorStore.getInstance().add(this);
345 }
346
347 public void traversePreOrder(
348 IPhysicalVolumeVisitor visitor)
349 {
350 if ( visitor == null )
351 {
352 throw new IllegalArgumentException("The Visitor is null!");
353 }
354
355 traversePreOrder(getTopPhysicalVolume(), visitor);
356 }
357
358
359
360
361
362
363
364
365
366 protected void traversePreOrder(
367 IPhysicalVolume physicalVolume,
368 IPhysicalVolumeVisitor visitor)
369 {
370
371 visitor.visit(physicalVolume);
372
373
374 if ( physicalVolume.getLogicalVolume().getNumberOfDaughters() > 0 )
375 {
376 for ( IPhysicalVolume child : physicalVolume.getLogicalVolume().getDaughters())
377 {
378 traversePreOrder(child, visitor);
379 }
380 }
381 }
382
383
384
385
386
387
388
389
390
391 protected void traversePostOrder(IPhysicalVolume physicalVolume, IPhysicalVolumeVisitor visitor)
392 {
393
394 if ( physicalVolume.getLogicalVolume().getNumberOfDaughters() > 0 )
395 {
396 for ( IPhysicalVolume child : physicalVolume.getLogicalVolume().getDaughters())
397 {
398 traversePostOrder(child, visitor);
399 }
400 }
401
402
403 visitor.visit(physicalVolume);
404 }
405
406
407
408
409
410
411
412
413
414 public void traversePostOrder(IPhysicalVolumeVisitor visitor)
415 {
416 traversePostOrder(getTopPhysicalVolume(), visitor);
417 }
418
419 public String getName()
420 {
421 return name;
422 }
423
424
425
426
427
428
429
430 public static void getLeafPaths(Collection<String> paths, IPhysicalVolume node, String path)
431 {
432 if (node == null)
433 {
434 return;
435 }
436 if (node.getLogicalVolume().getDaughters().size() == 0)
437 {
438 paths.add(path + "/" + node.getName());
439 return;
440 }
441
442 path += "/" + node.getName();
443 for (IPhysicalVolume dau : node.getLogicalVolume().getDaughters())
444 {
445 getLeafPaths(paths, dau, path);
446 }
447 }
448 }