e118b27e |
1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * |
3 | * * |
4 | * Author: The ALICE Off-line Project. * |
5 | * Contributors are mentioned in the code where appropriate. * |
6 | * * |
7 | * Permission to use, copy, modify and distribute this software and its * |
8 | * documentation strictly for non-commercial purposes is hereby granted * |
9 | * without fee, provided that the above copyright notice appears in all * |
10 | * copies and that both the copyright notice and this permission notice * |
11 | * appear in the supporting documentation. The authors make no claims * |
12 | * about the suitability of this software for any purpose. It is * |
13 | * provided "as is" without express or implied warranty. * |
14 | **************************************************************************/ |
15 | |
89cc3034 |
16 | // $Id$ |
f7006443 |
17 | |
3d1463c8 |
18 | //----------------------------------------------------------------------------- |
89cc3034 |
19 | // Class AliMUONGeometryEnvelopeStore |
20 | // ---------------------------------- |
21 | // Class for definititon of the temporary volume envelopes |
22 | // used in geometry construction |
89cc3034 |
23 | // Author: Ivana Hrivnacova, IPN Orsay |
3d1463c8 |
24 | //----------------------------------------------------------------------------- |
89cc3034 |
25 | |
89cc3034 |
26 | #include "AliMUONGeometryEnvelopeStore.h" |
89cc3034 |
27 | #include "AliMUONGeometryEnvelope.h" |
e118b27e |
28 | #include "AliMUONGeometryDetElement.h" |
6cfb12b4 |
29 | #include "AliMUONGeometryBuilder.h" |
7183d525 |
30 | |
49fd2f87 |
31 | #include "AliMpExMap.h" |
32 | |
8c343c7c |
33 | #include "AliLog.h" |
89cc3034 |
34 | |
7183d525 |
35 | #include <TGeoMatrix.h> |
36 | #include <TObjArray.h> |
37 | #include <Riostream.h> |
38 | #include <TString.h> |
39 | |
b80faac0 |
40 | using std::cout; |
41 | using std::endl; |
a9aad96e |
42 | /// \cond CLASSIMP |
89cc3034 |
43 | ClassImp(AliMUONGeometryEnvelopeStore) |
a9aad96e |
44 | /// \endcond |
89cc3034 |
45 | |
46 | //______________________________________________________________________________ |
47 | AliMUONGeometryEnvelopeStore::AliMUONGeometryEnvelopeStore( |
49fd2f87 |
48 | AliMpExMap* detElements) |
89cc3034 |
49 | : TObject(), |
89cc3034 |
50 | fEnvelopes(0), |
e118b27e |
51 | fDetElements(detElements), |
6cfb12b4 |
52 | fReferenceFrame(), |
89cc3034 |
53 | fDebug(false), |
54 | fAlign(false) |
55 | { |
692de412 |
56 | /// Standard constructor |
89cc3034 |
57 | |
58 | fEnvelopes = new TObjArray(100); |
59 | } |
60 | |
61 | |
62 | //______________________________________________________________________________ |
63 | AliMUONGeometryEnvelopeStore::AliMUONGeometryEnvelopeStore() |
64 | : TObject(), |
89cc3034 |
65 | fEnvelopes(0), |
e118b27e |
66 | fDetElements(0), |
6cfb12b4 |
67 | fReferenceFrame(), |
89cc3034 |
68 | fDebug(false), |
69 | fAlign(false) |
70 | { |
692de412 |
71 | /// Default constructor |
89cc3034 |
72 | } |
73 | |
74 | |
75 | //______________________________________________________________________________ |
89cc3034 |
76 | AliMUONGeometryEnvelopeStore::~AliMUONGeometryEnvelopeStore() |
77 | { |
692de412 |
78 | /// Destructor |
89cc3034 |
79 | |
80 | // Add deleting rotation matrices |
81 | |
82 | if (fEnvelopes) { |
83 | fEnvelopes->Delete(); |
84 | delete fEnvelopes; |
85 | } |
86 | } |
87 | |
89cc3034 |
88 | // |
89 | // private methods |
90 | // |
91 | |
92 | //______________________________________________________________________________ |
6cfb12b4 |
93 | TGeoHMatrix |
6ec9cd4e |
94 | AliMUONGeometryEnvelopeStore::ConvertDETransform(const TGeoHMatrix& transform) const |
6cfb12b4 |
95 | { |
a9aad96e |
96 | /// Convert transformation into the reference frame |
6cfb12b4 |
97 | |
98 | if ( fReferenceFrame.IsIdentity() ) |
99 | return transform; |
100 | else { |
101 | return AliMUONGeometryBuilder::Multiply( fReferenceFrame.Inverse(), |
6ec9cd4e |
102 | transform ); |
6cfb12b4 |
103 | } |
104 | } |
105 | |
106 | //______________________________________________________________________________ |
89cc3034 |
107 | AliMUONGeometryEnvelope* |
108 | AliMUONGeometryEnvelopeStore::FindEnvelope(const TString& name) const |
109 | { |
692de412 |
110 | /// Find the envelope specified by name. |
89cc3034 |
111 | |
112 | for (Int_t i=0; i<fEnvelopes->GetEntriesFast(); i++) { |
113 | AliMUONGeometryEnvelope* envelope |
114 | = (AliMUONGeometryEnvelope*)fEnvelopes->At(i); |
115 | |
116 | if (envelope->GetName() == name) return envelope; |
117 | } |
118 | |
119 | return 0; |
120 | } |
121 | |
122 | //______________________________________________________________________________ |
123 | Bool_t AliMUONGeometryEnvelopeStore::AlignEnvelope( |
124 | AliMUONGeometryEnvelope* envelope) const |
125 | { |
692de412 |
126 | /// Find transformation by the detection element Id (if not 0) |
127 | /// (= unique ID of enevelope) and set it to the envelope. |
128 | /// Return true if transformation is applied, false otherwise. |
89cc3034 |
129 | |
130 | Int_t detElemId = envelope->GetUniqueID(); |
131 | if (detElemId == 0) return false; |
132 | |
e118b27e |
133 | AliMUONGeometryDetElement* detElement |
49fd2f87 |
134 | = (AliMUONGeometryDetElement*) fDetElements->GetValue(detElemId); |
e118b27e |
135 | if (!detElement) { |
8c343c7c |
136 | AliWarning("Transformation not found."); |
89cc3034 |
137 | return false; |
138 | }; |
139 | |
6cfb12b4 |
140 | // Apply frame transform |
141 | TGeoHMatrix newTransform |
6ec9cd4e |
142 | = ConvertDETransform(*(detElement->GetLocalTransformation())); |
6cfb12b4 |
143 | |
144 | envelope->SetTransform(newTransform); |
145 | |
89cc3034 |
146 | return true; |
147 | } |
148 | |
149 | // |
150 | // public methods |
151 | // |
152 | |
153 | //______________________________________________________________________________ |
154 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
155 | Int_t id, |
156 | Bool_t isVirtual, |
157 | const char* only) |
158 | { |
692de412 |
159 | /// Add the volume with the specified name and transformation |
160 | /// to the list of envelopes. |
89cc3034 |
161 | |
8c343c7c |
162 | if (!isVirtual) AliDebug(1,Form("Adding non-virtual envelope %s id %d",name.Data(),id)); |
163 | // else AliDebug(1,Form("Adding virtual envelope %s id %d",name.Data(),id)); |
89cc3034 |
164 | |
165 | AliMUONGeometryEnvelope* envelope |
166 | = new AliMUONGeometryEnvelope(name, id, isVirtual, only); |
167 | |
168 | if (fAlign) AlignEnvelope(envelope); |
169 | |
170 | fEnvelopes->Add(envelope); |
171 | } |
172 | |
173 | //______________________________________________________________________________ |
174 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
175 | Int_t id, |
176 | Bool_t isVirtual, |
177 | const TGeoTranslation& translation, |
178 | const char* only) |
179 | { |
692de412 |
180 | /// Add the volume with the specified name and transformation |
181 | /// to the list of envelopes. |
89cc3034 |
182 | |
183 | if (fDebug) { |
184 | cout << "... Adding "; |
185 | if (!isVirtual) cout << " non-"; |
186 | cout << "virtual envelope " << name |
187 | << " id " << id |
188 | << " with translation" << endl; |
189 | } |
190 | |
191 | AliMUONGeometryEnvelope* envelope |
192 | = new AliMUONGeometryEnvelope(name, id, isVirtual, only); |
193 | |
194 | Bool_t aligned = false; |
195 | if (fAlign) aligned = AlignEnvelope(envelope); |
196 | |
197 | if (!aligned) |
198 | envelope->SetTranslation(translation); |
199 | |
200 | fEnvelopes->Add(envelope); |
201 | } |
202 | |
203 | //______________________________________________________________________________ |
204 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
205 | Int_t id, |
206 | Bool_t isVirtual, |
207 | const TGeoTranslation& translation, |
208 | const TGeoRotation& rotation, |
209 | const char* only) |
210 | { |
692de412 |
211 | /// Add the volume with the specified name and transformation |
212 | /// to the list of envelopes. |
89cc3034 |
213 | |
214 | if (fDebug) { |
215 | cout << "... Adding "; |
216 | if (!isVirtual) cout << " non-"; |
217 | cout << "virtual envelope " << name |
218 | << " id " << id |
219 | << " with translation and rotation" << endl; |
220 | } |
221 | |
222 | /* |
223 | cout << "Adding env... name: " << name; |
224 | |
225 | const Double_t* xyz = translation.GetTranslation(); |
226 | cout << " translation: " << xyz[0] << ", " << xyz[1] << ", " << xyz[2] |
227 | << " rotation: "; |
228 | |
229 | Double_t a1, a2, a3, a4, a5, a6; |
230 | rotation.GetAngles(a1, a2, a3, a4, a5, a6); |
231 | cout << a1 << ", " << a2 << ", " << a3 << ", " << a4 << ", " << a5 << ", " << a6 << endl; |
232 | */ |
233 | // fEnvelopes->Add(new TGeoCombiTrans(name, translation, rotation)); |
234 | // would be nice to be so simple |
235 | |
236 | AliMUONGeometryEnvelope* envelope |
237 | = new AliMUONGeometryEnvelope(name, id, isVirtual, only); |
238 | |
239 | Bool_t aligned = false; |
240 | if (fAlign) aligned = AlignEnvelope(envelope); |
241 | |
242 | if (!aligned) { |
243 | envelope->SetRotation(rotation); |
244 | envelope->SetTranslation(translation); |
245 | } |
246 | |
247 | fEnvelopes->Add(envelope); |
248 | } |
249 | |
250 | //______________________________________________________________________________ |
251 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
252 | Int_t id, |
253 | Bool_t isVirtual, |
254 | const TGeoCombiTrans& transform, |
255 | const char* only) |
256 | { |
692de412 |
257 | /// Add the volume with the specified name and transformation |
258 | /// to the list of envelopes. |
89cc3034 |
259 | |
260 | if (fDebug) { |
261 | cout << "... Adding "; |
262 | if (!isVirtual) cout << " non-"; |
263 | cout << "virtual envelope " << name |
264 | << " id " << id |
265 | << " with transformation" << endl; |
266 | } |
267 | |
268 | // fEnvelopes->Add(new TGeoCombiTrans(name, translation, rotation)); |
269 | // would be nice to be so simple |
270 | |
271 | AliMUONGeometryEnvelope* envelope |
272 | = new AliMUONGeometryEnvelope(name, id, isVirtual, only); |
273 | |
274 | Bool_t aligned = false; |
275 | if (fAlign) aligned = AlignEnvelope(envelope); |
276 | |
277 | if (!aligned) |
278 | envelope->SetTransform(transform); |
279 | |
280 | fEnvelopes->Add(envelope); |
281 | } |
282 | |
283 | //______________________________________________________________________________ |
284 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
285 | Int_t id, |
286 | Int_t copyNo, |
287 | const char* only) |
288 | { |
692de412 |
289 | /// Add the volume with the specified name and transformation |
290 | /// to the list of envelopes. |
89cc3034 |
291 | |
292 | if (fDebug) { |
293 | cout << "... Adding " |
294 | << " non-virtual envelope " << name |
295 | << " id " << id |
296 | << " with copyNo " << copyNo << endl; |
297 | } |
298 | |
299 | AliMUONGeometryEnvelope* envelope |
300 | = new AliMUONGeometryEnvelope(name, id, copyNo, only); |
301 | |
302 | if (fAlign) AlignEnvelope(envelope); |
303 | |
304 | fEnvelopes->Add(envelope); |
305 | } |
306 | |
307 | //______________________________________________________________________________ |
308 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
309 | Int_t id, |
310 | Int_t copyNo, |
311 | const TGeoTranslation& translation, |
312 | const char* only) |
313 | { |
692de412 |
314 | /// Add the volume with the specified name and transformation |
315 | /// to the list of envelopes. |
89cc3034 |
316 | |
317 | if (fDebug) { |
318 | cout << "... Adding " |
319 | << " non-virtual envelope " << name |
320 | << " id " << id |
321 | << " with copyNo " << copyNo |
322 | << " with translation " << endl; |
323 | } |
324 | |
325 | AliMUONGeometryEnvelope* envelope |
326 | = new AliMUONGeometryEnvelope(name, id, copyNo, only); |
327 | |
328 | Bool_t aligned = false; |
329 | if (fAlign) aligned = AlignEnvelope(envelope); |
330 | |
331 | if (!aligned) |
332 | envelope->SetTranslation(translation); |
333 | |
334 | fEnvelopes->Add(envelope); |
335 | } |
336 | |
337 | //______________________________________________________________________________ |
338 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
339 | Int_t id, |
340 | Int_t copyNo, |
341 | const TGeoTranslation& translation, |
342 | const TGeoRotation& rotation, |
343 | const char* only) |
344 | { |
692de412 |
345 | /// Add the volume with the specified name and transformation |
346 | /// to the list of envelopes. |
89cc3034 |
347 | |
348 | if (fDebug) { |
349 | cout << "... Adding " |
350 | << " non-virtual envelope " << name |
351 | << " id " << id |
352 | << " with copyNo " << copyNo |
353 | << " with translation and rotation" << endl; |
354 | } |
355 | |
356 | // fEnvelopes->Add(new TGeoCombiTrans(name, translation, rotation)); |
357 | // would be nice to be so simple |
358 | |
359 | AliMUONGeometryEnvelope* envelope |
360 | = new AliMUONGeometryEnvelope(name, id, copyNo, only); |
361 | |
362 | Bool_t aligned = false; |
363 | if (fAlign) aligned = AlignEnvelope(envelope); |
364 | |
365 | if (!aligned) { |
366 | envelope->SetRotation(rotation); |
367 | envelope->SetTranslation(translation); |
368 | } |
369 | |
370 | fEnvelopes->Add(envelope); |
371 | } |
372 | |
373 | //______________________________________________________________________________ |
374 | void AliMUONGeometryEnvelopeStore::AddEnvelope(const TString& name, |
375 | Int_t id, |
376 | Int_t copyNo, |
377 | const TGeoCombiTrans& transform, |
378 | const char* only) |
379 | { |
692de412 |
380 | /// Add the volume with the specified name and transformation |
381 | /// to the list of envelopes. |
89cc3034 |
382 | |
383 | if (fDebug) { |
384 | cout << "... Adding " |
385 | << " non-virtual envelope " << name |
386 | << " id " << id |
387 | << " with copyNo " << copyNo |
388 | << " with translation and rotation" << endl; |
389 | } |
390 | |
391 | // fEnvelopes->Add(new TGeoCombiTrans(name, translation, rotation)); |
392 | // would be nice to be so simple |
393 | |
394 | AliMUONGeometryEnvelope* envelope |
395 | = new AliMUONGeometryEnvelope(name, id, copyNo, only); |
396 | |
397 | Bool_t aligned = false; |
398 | if (fAlign) aligned = AlignEnvelope(envelope); |
399 | |
400 | if (!aligned) |
401 | envelope->SetTransform(transform); |
402 | |
403 | fEnvelopes->Add(envelope); |
404 | } |
405 | |
406 | //______________________________________________________________________________ |
407 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituent(const TString& name, |
408 | const TString& envName, Int_t copyNo) |
409 | { |
692de412 |
410 | /// Add the volume with the specified name and transformation |
a9aad96e |
411 | /// as a constituent of the envelope envName. |
89cc3034 |
412 | |
413 | if (fDebug) { |
414 | cout << "... Adding constituent " << name |
415 | << " to envelope " << envName |
416 | << " with copyNo " << copyNo << endl; |
417 | } |
418 | |
419 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
420 | |
421 | if (!envelope) { |
422 | // add warning |
423 | return; |
424 | } |
425 | |
426 | envelope->AddConstituent(name, copyNo); |
427 | } |
428 | |
429 | //______________________________________________________________________________ |
430 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituent(const TString& name, |
431 | const TString& envName, Int_t copyNo, |
432 | const TGeoTranslation& translation) |
433 | { |
692de412 |
434 | /// Add the volume with the specified name and transformation |
a9aad96e |
435 | /// as a constituent of the envelope envName. |
89cc3034 |
436 | |
437 | if (fDebug) { |
438 | cout << "... Adding constituent " << name |
439 | << " to envelope " << envName |
440 | << " with copyNo " << copyNo |
441 | << " with translation" << endl; |
442 | } |
443 | |
444 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
445 | |
446 | if (!envelope) { |
447 | // add warning |
448 | return; |
449 | } |
450 | |
451 | envelope->AddConstituent(name, copyNo, translation); |
452 | } |
453 | |
454 | //______________________________________________________________________________ |
455 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituent(const TString& name, |
456 | const TString& envName, Int_t copyNo, |
457 | const TGeoTranslation& translation, |
458 | const TGeoRotation& rotation) |
459 | { |
692de412 |
460 | /// Add the volume with the specified name and transformation |
a9aad96e |
461 | /// as a constituent of the envelope envName. |
89cc3034 |
462 | |
463 | if (fDebug) { |
464 | cout << "... Adding constituent " << name |
465 | << " to envelope " << envName |
466 | << " with copyNo " << copyNo |
467 | << " with translation and rotation" << endl; |
468 | } |
469 | |
470 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
471 | |
472 | if (!envelope) { |
473 | // add warning |
474 | return; |
475 | } |
476 | |
477 | envelope->AddConstituent(name, copyNo, translation, rotation); |
478 | } |
479 | |
480 | //______________________________________________________________________________ |
481 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituent(const TString& name, |
482 | const TString& envName, Int_t copyNo, |
483 | const TGeoCombiTrans& transform) |
484 | { |
692de412 |
485 | /// Add the volume with the specified name and transformation |
a9aad96e |
486 | /// as a constituent of the envelope envName. |
89cc3034 |
487 | |
488 | if (fDebug) { |
489 | cout << "... Adding constituent " << name |
490 | << " to envelope " << envName |
491 | << " with copyNo " << copyNo |
492 | << " with translation and rotation" << endl; |
493 | } |
494 | |
495 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
496 | |
497 | if (!envelope) { |
498 | // add warning |
499 | return; |
500 | } |
501 | |
502 | envelope->AddConstituent(name, copyNo, transform); |
503 | } |
504 | |
505 | //______________________________________________________________________________ |
506 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituentParam(const TString& name, |
507 | const TString& envName, Int_t copyNo, |
508 | Int_t npar, Double_t* param) |
509 | { |
692de412 |
510 | /// Add the volume with the specified name and transformation |
a9aad96e |
511 | /// as a constituent of the envelope envName. |
89cc3034 |
512 | |
513 | if (fDebug) { |
514 | cout << "... Adding parameterised constituent " << name |
515 | << " to envelope " << envName |
516 | << " with copyNo " << copyNo << endl; |
517 | } |
518 | |
519 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
520 | |
521 | if (!envelope) { |
522 | // add warning |
523 | return; |
524 | } |
525 | |
526 | envelope->AddConstituentParam(name, copyNo, npar, param); |
527 | } |
528 | |
529 | //______________________________________________________________________________ |
530 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituentParam(const TString& name, |
531 | const TString& envName, Int_t copyNo, |
532 | const TGeoTranslation& translation, |
533 | Int_t npar, Double_t* param) |
534 | { |
692de412 |
535 | /// Add the volume with the specified name and transformation |
a9aad96e |
536 | /// as a constituent of the envelope envName. |
89cc3034 |
537 | |
538 | if (fDebug) { |
539 | cout << "... Adding parameterised constituent " << name |
540 | << " to envelope " << envName |
541 | << " with copyNo " << copyNo |
542 | << " with translation" << endl; |
543 | } |
544 | |
545 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
546 | |
547 | if (!envelope) { |
548 | // add warning |
549 | return; |
550 | } |
551 | |
552 | envelope->AddConstituentParam(name, copyNo, translation, npar, param); |
553 | } |
554 | |
555 | //______________________________________________________________________________ |
556 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituentParam(const TString& name, |
557 | const TString& envName, Int_t copyNo, |
558 | const TGeoTranslation& translation, |
559 | const TGeoRotation& rotation, |
560 | Int_t npar, Double_t* param) |
561 | { |
692de412 |
562 | /// Add the volume with the specified name and transformation |
a9aad96e |
563 | /// as a constituent of the envelope envName. |
89cc3034 |
564 | |
565 | if (fDebug) { |
566 | cout << "... Adding parameterised constituent " << name |
567 | << " to envelope " << envName |
568 | << " with copyNo " << copyNo |
569 | << " with translation and rotation" << endl; |
570 | } |
571 | |
572 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
573 | |
574 | if (!envelope) { |
575 | // add warning |
576 | return; |
577 | } |
578 | |
579 | envelope->AddConstituentParam(name, copyNo, translation, rotation, npar, param); |
580 | } |
581 | |
582 | //______________________________________________________________________________ |
583 | void AliMUONGeometryEnvelopeStore::AddEnvelopeConstituentParam(const TString& name, |
584 | const TString& envName, Int_t copyNo, |
585 | const TGeoCombiTrans& transform, |
586 | Int_t npar, Double_t* param) |
587 | { |
692de412 |
588 | /// Add the volume with the specified name and transformation |
a9aad96e |
589 | /// as a constituent of the envelope envName. |
89cc3034 |
590 | |
591 | if (fDebug) { |
592 | cout << "... Adding parameterised constituent " << name |
593 | << " to envelope " << envName |
594 | << " with copyNo " << copyNo |
595 | << " with translation and rotation" << endl; |
596 | } |
597 | |
598 | AliMUONGeometryEnvelope* envelope = FindEnvelope(envName); |
599 | |
600 | if (!envelope) { |
601 | // add warning |
602 | return; |
603 | } |
604 | |
605 | envelope->AddConstituentParam(name, copyNo, transform, npar, param); |
606 | } |
607 | |
e118b27e |
608 | //______________________________________________________________________________ |
609 | Int_t AliMUONGeometryEnvelopeStore::GetNofDetElements() const |
610 | { |
692de412 |
611 | /// Return the number od envelopes with detElemId>0. |
e118b27e |
612 | |
613 | Int_t nofDetElems = 0; |
614 | |
615 | for(Int_t i=0; i<fEnvelopes->GetEntriesFast(); i++) |
616 | if ( fEnvelopes->At(i)->GetUniqueID() > 0 ) nofDetElems++; |
617 | |
618 | return nofDetElems; |
619 | } |