]>
Commit | Line | Data |
---|---|---|
afc8e661 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * SigmaEffect_thetadegrees * | |
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 purpeateose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // $Id$ | |
3d1463c8 | 17 | |
18 | //----------------------------------------------------------------------------- | |
afc8e661 | 19 | // Class AliMUONGeometryTransformer |
20 | // ---------------------------- | |
21 | // Top container class for geometry transformations | |
afc8e661 | 22 | // Author: Ivana Hrivnacova, IPN Orsay |
3d1463c8 | 23 | //----------------------------------------------------------------------------- |
afc8e661 | 24 | |
afc8e661 | 25 | #include "AliMUONGeometryTransformer.h" |
26 | #include "AliMUONGeometryModuleTransformer.h" | |
27 | #include "AliMUONGeometryDetElement.h" | |
2864a3ac | 28 | #include "AliMUONGeometryBuilder.h" |
afc8e661 | 29 | |
ea7ea157 | 30 | #include "AliMpDEManager.h" |
327d1302 | 31 | #include "AliMpConstants.h" |
ea7ea157 | 32 | #include "AliMpExMap.h" |
88544f7e | 33 | #include "AliMpCDB.h" |
9bf6860b | 34 | #include "AliMpArea.h" |
35 | #include <float.h> | |
36 | #include "AliMpVPadIterator.h" | |
37 | #include "AliMpPad.h" | |
38 | #include "AliMpDEIterator.h" | |
39 | #include <TVector2.h> | |
40 | #include "AliMpVSegmentation.h" | |
41 | #include "AliMpSegmentation.h" | |
630711ed | 42 | #include "AliMpExMapIterator.h" |
a7d4e65b | 43 | #include "AliLog.h" |
44 | #include "AliAlignObjMatrix.h" | |
bf16b32c | 45 | #include "AliAlignObj.h" |
a7d4e65b | 46 | |
47 | #include <Riostream.h> | |
48 | #include <TSystem.h> | |
49 | #include <TClonesArray.h> | |
50 | #include <TGeoManager.h> | |
51 | #include <TGeoPhysicalNode.h> | |
a6269834 | 52 | #include <TFile.h> |
327d1302 | 53 | #include <TString.h> |
a7d4e65b | 54 | |
55 | #include <sstream> | |
afc8e661 | 56 | |
a9aad96e | 57 | /// \cond CLASSIMP |
afc8e661 | 58 | ClassImp(AliMUONGeometryTransformer) |
a9aad96e | 59 | /// \endcond |
327d1302 | 60 | |
31edb2d7 | 61 | // |
62 | // static private methods | |
63 | // | |
64 | ||
65 | //______________________________________________________________________________ | |
66 | const TString& AliMUONGeometryTransformer::GetDefaultDetectorName() | |
67 | { | |
68 | /// Default detector name | |
69 | static const TString kDefaultDetectorName = "MUON"; | |
70 | return kDefaultDetectorName; | |
71 | } | |
afc8e661 | 72 | |
31edb2d7 | 73 | // |
74 | // ctor, dtor | |
75 | // | |
76 | ||
afc8e661 | 77 | //______________________________________________________________________________ |
327d1302 | 78 | AliMUONGeometryTransformer::AliMUONGeometryTransformer() |
d4d05625 | 79 | |
afc8e661 | 80 | : TObject(), |
31edb2d7 | 81 | fDetectorName(GetDefaultDetectorName()), |
a7d4e65b | 82 | fModuleTransformers(0), |
9bf6860b | 83 | fMisAlignArray(0), |
84 | fDEAreas(0x0) | |
afc8e661 | 85 | { |
86 | /// Standard constructor | |
87 | ||
88 | // Create array for geometry modules | |
ea7ea157 | 89 | fModuleTransformers = new TObjArray(100); |
327d1302 | 90 | fModuleTransformers->SetOwner(true); |
afc8e661 | 91 | } |
92 | ||
93 | //______________________________________________________________________________ | |
327d1302 | 94 | AliMUONGeometryTransformer::AliMUONGeometryTransformer(TRootIOCtor* /*ioCtor*/) |
afc8e661 | 95 | : TObject(), |
d4d05625 | 96 | fDetectorName(), |
a7d4e65b | 97 | fModuleTransformers(0), |
9bf6860b | 98 | fMisAlignArray(0), |
99 | fDEAreas(0x0) | |
afc8e661 | 100 | { |
101 | /// Default constructor | |
102 | } | |
103 | ||
afc8e661 | 104 | //______________________________________________________________________________ |
105 | AliMUONGeometryTransformer::~AliMUONGeometryTransformer() | |
106 | { | |
107 | /// Destructor | |
108 | ||
109 | delete fModuleTransformers; | |
a7d4e65b | 110 | delete fMisAlignArray; |
9bf6860b | 111 | delete fDEAreas; |
afc8e661 | 112 | } |
113 | ||
afc8e661 | 114 | // |
115 | // private methods | |
116 | // | |
117 | ||
9bf6860b | 118 | |
119 | //_____________________________________________________________________________ | |
120 | AliMpArea* | |
121 | AliMUONGeometryTransformer::GetDEArea(Int_t detElemId) const | |
122 | { | |
123 | /// Get area (in global coordinates) covered by a given detection element | |
124 | if (!fDEAreas) | |
125 | { | |
126 | CreateDEAreas(); | |
127 | } | |
128 | return static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId)); | |
129 | } | |
130 | ||
131 | //_____________________________________________________________________________ | |
132 | void | |
133 | AliMUONGeometryTransformer::CreateDEAreas() const | |
134 | { | |
135 | /// Create DE areas | |
136 | ||
630711ed | 137 | fDEAreas = new AliMpExMap; |
9bf6860b | 138 | |
139 | AliMpDEIterator it; | |
140 | ||
141 | it.First(); | |
142 | ||
143 | /// Generate the DE areas in global coordinates | |
144 | ||
145 | while ( !it.IsDone() ) | |
146 | { | |
147 | Int_t detElemId = it.CurrentDEId(); | |
148 | ||
149 | if ( !HasDE(detElemId) ) continue; | |
150 | ||
151 | const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0); | |
152 | ||
153 | Double_t xg,yg,zg; | |
154 | ||
155 | AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId); | |
156 | ||
157 | Double_t xl(0.0), yl(0.0), zl(0.0); | |
6e97fbb8 | 158 | Double_t dx(seg->GetDimensionX()); |
159 | Double_t dy(seg->GetDimensionY()); | |
9bf6860b | 160 | |
4e51cfd2 | 161 | if ( stationType == AliMp::kStation12 ) |
9bf6860b | 162 | { |
163 | Double_t xmin(FLT_MAX); | |
164 | Double_t xmax(-FLT_MAX); | |
165 | Double_t ymin(FLT_MAX); | |
166 | Double_t ymax(-FLT_MAX); | |
167 | ||
168 | for ( Int_t icathode = 0; icathode < 2; ++icathode ) | |
169 | { | |
170 | const AliMpVSegmentation* cathode | |
171 | = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(icathode)); | |
172 | ||
14a02207 | 173 | AliMpVPadIterator* itp = cathode->CreateIterator(); |
9bf6860b | 174 | |
14a02207 | 175 | itp->First(); |
9bf6860b | 176 | |
14a02207 | 177 | while ( !itp->IsDone() ) |
9bf6860b | 178 | { |
14a02207 | 179 | AliMpPad pad = itp->CurrentItem(); |
6e97fbb8 | 180 | AliMpArea a(pad.GetPositionX(),pad.GetPositionY(), |
181 | pad.GetDimensionX(), pad.GetDimensionY()); | |
9bf6860b | 182 | xmin = TMath::Min(xmin,a.LeftBorder()); |
183 | xmax = TMath::Max(xmax,a.RightBorder()); | |
184 | ymin = TMath::Min(ymin,a.DownBorder()); | |
185 | ymax = TMath::Max(ymax,a.UpBorder()); | |
14a02207 | 186 | itp->Next(); |
9bf6860b | 187 | } |
188 | ||
14a02207 | 189 | delete itp; |
9bf6860b | 190 | } |
191 | ||
192 | xl = (xmin+xmax)/2.0; | |
193 | yl = (ymin+ymax)/2.0; | |
194 | dx = (xmax-xmin)/2.0; | |
195 | dy = (ymax-ymin)/2.0; | |
196 | ||
197 | Local2Global(detElemId,xl,yl,zl,xg,yg,zg); | |
198 | } | |
199 | else | |
200 | { | |
201 | Local2Global(detElemId,xl,yl,zl,xg,yg,zg); | |
202 | } | |
203 | ||
6e97fbb8 | 204 | fDEAreas->Add(detElemId,new AliMpArea(xg,yg,dx,dy)); |
9bf6860b | 205 | |
206 | it.Next(); | |
207 | } | |
208 | } | |
209 | ||
88544f7e | 210 | //_____________________________________________________________________________ |
211 | Bool_t AliMUONGeometryTransformer::LoadMapping() const | |
212 | { | |
213 | /// Load mapping from CDB | |
214 | ||
215 | if ( ! AliMpCDB::LoadMpSegmentation() ) | |
216 | { | |
217 | AliFatal("Could not access mapping from OCDB !"); | |
218 | return false; | |
219 | } | |
220 | ||
221 | return true; | |
222 | } | |
223 | ||
afc8e661 | 224 | //_____________________________________________________________________________ |
225 | AliMUONGeometryModuleTransformer* | |
226 | AliMUONGeometryTransformer::GetModuleTransformerNonConst( | |
227 | Int_t index, Bool_t warn) const | |
228 | { | |
229 | /// Return the geometry module specified by index | |
230 | ||
231 | if (index < 0 || index >= fModuleTransformers->GetEntriesFast()) { | |
232 | if (warn) { | |
233 | AliWarningStream() | |
234 | << "Index: " << index << " outside limits" << std::endl; | |
235 | } | |
236 | return 0; | |
237 | } | |
238 | ||
239 | return (AliMUONGeometryModuleTransformer*) fModuleTransformers->At(index); | |
240 | } | |
241 | ||
afc8e661 | 242 | //______________________________________________________________________________ |
243 | TGeoHMatrix AliMUONGeometryTransformer::GetTransform( | |
244 | Double_t x, Double_t y, Double_t z, | |
245 | Double_t a1, Double_t a2, Double_t a3, | |
246 | Double_t a4, Double_t a5, Double_t a6) const | |
247 | { | |
a9aad96e | 248 | /// Build the transformation from the given parameters |
afc8e661 | 249 | |
250 | // Compose transform | |
251 | return TGeoCombiTrans(TGeoTranslation(x, y, z), | |
252 | TGeoRotation("rot", a1, a2, a3, a4, a5, a6)); | |
253 | } | |
254 | ||
255 | ||
a7d4e65b | 256 | //______________________________________________________________________________ |
257 | void AliMUONGeometryTransformer::FillModuleTransform(Int_t moduleId, | |
afc8e661 | 258 | Double_t x, Double_t y, Double_t z, |
259 | Double_t a1, Double_t a2, Double_t a3, | |
260 | Double_t a4, Double_t a5, Double_t a6) | |
261 | { | |
a9aad96e | 262 | /// Fill the transformation of the module. |
afc8e661 | 263 | |
afc8e661 | 264 | AliMUONGeometryModuleTransformer* moduleTransformer |
317aa7dc | 265 | = GetModuleTransformerNonConst(moduleId, false); |
afc8e661 | 266 | |
267 | if ( !moduleTransformer) { | |
a7d4e65b | 268 | AliErrorStream() |
269 | << "Module " << moduleId << " has not volume path defined." << endl; | |
fc2293be | 270 | return; |
afc8e661 | 271 | } |
272 | ||
273 | // Build the transformation from the parameters | |
274 | TGeoHMatrix transform | |
275 | = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6); | |
276 | ||
277 | moduleTransformer->SetTransformation(transform); | |
afc8e661 | 278 | } |
279 | ||
280 | //______________________________________________________________________________ | |
a7d4e65b | 281 | void AliMUONGeometryTransformer::FillDetElemTransform( |
282 | Int_t detElemId, | |
afc8e661 | 283 | Double_t x, Double_t y, Double_t z, |
284 | Double_t a1, Double_t a2, Double_t a3, | |
285 | Double_t a4, Double_t a5, Double_t a6) | |
286 | { | |
a9aad96e | 287 | /// Fill the transformation of the detection element. |
afc8e661 | 288 | |
289 | // Module Id | |
ea7ea157 | 290 | Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId); |
afc8e661 | 291 | |
a7d4e65b | 292 | // Get module transformer |
2864a3ac | 293 | const AliMUONGeometryModuleTransformer* kModuleTransformer |
294 | = GetModuleTransformer(moduleId); | |
a7d4e65b | 295 | |
2864a3ac | 296 | if ( ! kModuleTransformer ) { |
a7d4e65b | 297 | AliFatal(Form("Module transformer not defined, detElemId: %d", detElemId)); |
298 | return; | |
2864a3ac | 299 | } |
300 | ||
a7d4e65b | 301 | // Get detection element |
302 | AliMUONGeometryDetElement* detElement | |
303 | = kModuleTransformer->GetDetElement(detElemId); | |
304 | ||
305 | if ( ! detElement ) { | |
306 | AliFatal(Form("Det element %d has not volume path defined", detElemId)); | |
307 | return; | |
308 | } | |
309 | ||
310 | // Build the transformation from the parameters | |
311 | TGeoHMatrix localTransform | |
312 | = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6); | |
313 | detElement->SetLocalTransformation(localTransform); | |
314 | ||
315 | // Compute global transformation | |
2864a3ac | 316 | TGeoHMatrix globalTransform |
317 | = AliMUONGeometryBuilder::Multiply( | |
318 | *kModuleTransformer->GetTransformation(), | |
319 | localTransform ); | |
320 | detElement->SetGlobalTransformation(globalTransform); | |
afc8e661 | 321 | } |
a7d4e65b | 322 | |
afc8e661 | 323 | //______________________________________________________________________________ |
a7d4e65b | 324 | TString AliMUONGeometryTransformer::ReadModuleTransforms(ifstream& in) |
afc8e661 | 325 | { |
a9aad96e | 326 | /// Read and fill modules transformations from the stream. |
327 | /// Return true, if reading finished correctly. | |
afc8e661 | 328 | |
ea7ea157 | 329 | TString key(AliMUONGeometryModuleTransformer::GetModuleNamePrefix()); |
330 | while ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() ) { | |
a7d4e65b | 331 | Int_t id; |
afc8e661 | 332 | Double_t x, y, z; |
333 | Double_t a1, a2, a3, a4, a5, a6; | |
334 | TString dummy; | |
335 | ||
336 | in >> id; | |
afc8e661 | 337 | in >> dummy; |
338 | in >> x; | |
339 | in >> y; | |
340 | in >> z; | |
341 | in >> dummy; | |
342 | in >> a1; | |
343 | in >> a2; | |
344 | in >> a3; | |
345 | in >> a4; | |
346 | in >> a5; | |
347 | in >> a6; | |
348 | ||
a7d4e65b | 349 | //cout << "moduleId=" << id << " " |
afc8e661 | 350 | // << "position= " << x << ", " << y << ", " << z << " " |
351 | // << "rotation= " << a1 << ", " << a2 << ", " << a3 << ", " | |
352 | // << a4 << ", " << a5 << ", " << a6 | |
353 | // << endl; | |
354 | ||
355 | // Fill data | |
a7d4e65b | 356 | FillModuleTransform(id, x, y, z, a1, a2, a3, a4, a5, a6); |
afc8e661 | 357 | |
358 | // Go to next line | |
359 | in >> key; | |
360 | } | |
361 | ||
362 | return key; | |
363 | } | |
364 | ||
365 | //______________________________________________________________________________ | |
a7d4e65b | 366 | TString AliMUONGeometryTransformer::ReadDetElemTransforms(ifstream& in) |
afc8e661 | 367 | { |
a9aad96e | 368 | /// Read detection elements transformations from the stream. |
369 | /// Return true, if reading finished correctly. | |
afc8e661 | 370 | |
ea7ea157 | 371 | TString key(AliMUONGeometryDetElement::GetDENamePrefix()); |
372 | while ( key == AliMUONGeometryDetElement::GetDENamePrefix() ) { | |
afc8e661 | 373 | |
374 | // Input data | |
375 | Int_t detElemId; | |
afc8e661 | 376 | Double_t x, y, z; |
377 | Double_t a1, a2, a3, a4, a5, a6; | |
378 | TString dummy; | |
379 | ||
380 | in >> detElemId; | |
afc8e661 | 381 | in >> dummy; |
382 | in >> x; | |
383 | in >> y; | |
384 | in >> z; | |
385 | in >> dummy; | |
386 | in >> a1; | |
387 | in >> a2; | |
388 | in >> a3; | |
389 | in >> a4; | |
390 | in >> a5; | |
391 | in >> a6; | |
392 | ||
393 | //cout << "detElemId=" << detElemId << " " | |
afc8e661 | 394 | // << "position= " << x << ", " << y << ", " << z << " " |
395 | // << "rotation= " << a1 << ", " << a2 << ", " << a3 << ", " | |
a7d4e65b | 396 | // << a4 << ", " << a5 << ", " << a6 |
afc8e661 | 397 | // << endl; |
398 | ||
399 | // Fill data | |
a7d4e65b | 400 | FillDetElemTransform(detElemId, x, y, z, a1, a2, a3, a4, a5, a6); |
afc8e661 | 401 | |
402 | // Go to next line | |
403 | in >> key; | |
404 | } | |
405 | ||
406 | return key; | |
407 | } | |
408 | ||
a7d4e65b | 409 | //______________________________________________________________________________ |
410 | Bool_t | |
411 | AliMUONGeometryTransformer::ReadTransformations(const TString& fileName) | |
412 | { | |
a9aad96e | 413 | /// Read transformations from a file. |
414 | /// Return true, if reading finished correctly. | |
a7d4e65b | 415 | |
416 | // File path | |
417 | TString filePath = gSystem->Getenv("ALICE_ROOT"); | |
418 | filePath += "/MUON/data/"; | |
419 | filePath += fileName; | |
420 | ||
421 | // Open input file | |
422 | ifstream in(filePath, ios::in); | |
423 | if (!in) { | |
424 | cerr << filePath << endl; | |
425 | AliFatal("File not found."); | |
426 | return false; | |
427 | } | |
428 | ||
429 | TString key; | |
430 | in >> key; | |
431 | while ( !in.eof() ) { | |
ea7ea157 | 432 | if ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() ) |
a7d4e65b | 433 | key = ReadModuleTransforms(in); |
ea7ea157 | 434 | else if ( key == AliMUONGeometryDetElement::GetDENamePrefix() ) |
a7d4e65b | 435 | key = ReadDetElemTransforms(in); |
436 | else { | |
437 | AliFatal(Form("%s key not recognized", key.Data())); | |
438 | return false; | |
439 | } | |
440 | } | |
441 | ||
442 | return true; | |
443 | } | |
444 | ||
afc8e661 | 445 | //______________________________________________________________________________ |
446 | void AliMUONGeometryTransformer::WriteTransform(ofstream& out, | |
a7d4e65b | 447 | const TGeoMatrix* transform) const |
afc8e661 | 448 | { |
a9aad96e | 449 | /// Write given transformation |
afc8e661 | 450 | |
451 | out << " pos: "; | |
452 | const Double_t* xyz = transform->GetTranslation(); | |
453 | out << setw(10) << setprecision(4) << xyz[0] << " " | |
454 | << setw(10) << setprecision(4) << xyz[1] << " " | |
455 | << setw(10) << setprecision(4) << xyz[2]; | |
456 | ||
457 | out << " rot: "; | |
458 | const Double_t* rm = transform->GetRotationMatrix(); | |
459 | TGeoRotation rotation; | |
460 | rotation.SetMatrix(const_cast<Double_t*>(rm)); | |
461 | Double_t a1, a2, a3, a4, a5, a6; | |
462 | rotation.GetAngles(a1, a2, a3, a4, a5, a6); | |
463 | ||
464 | out << setw(8) << setprecision(4) << a1 << " " | |
465 | << setw(8) << setprecision(4) << a2 << " " | |
466 | << setw(8) << setprecision(4) << a3 << " " | |
467 | << setw(8) << setprecision(4) << a4 << " " | |
468 | << setw(8) << setprecision(4) << a5 << " " | |
469 | << setw(8) << setprecision(4) << a6 << " " << endl; | |
470 | } | |
471 | ||
a7d4e65b | 472 | //______________________________________________________________________________ |
473 | void AliMUONGeometryTransformer::WriteModuleTransforms(ofstream& out) const | |
474 | { | |
a9aad96e | 475 | /// Write module transformations for all module transformers |
afc8e661 | 476 | |
477 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { | |
478 | AliMUONGeometryModuleTransformer* moduleTransformer | |
479 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
a7d4e65b | 480 | const TGeoMatrix* transform |
afc8e661 | 481 | = moduleTransformer->GetTransformation(); |
482 | ||
a7d4e65b | 483 | // Write data on out |
ea7ea157 | 484 | out << AliMUONGeometryModuleTransformer::GetModuleNamePrefix() << " " |
485 | << setw(4) << moduleTransformer->GetModuleId(); | |
afc8e661 | 486 | |
487 | WriteTransform(out, transform); | |
488 | } | |
489 | out << endl; | |
490 | } | |
491 | ||
492 | //______________________________________________________________________________ | |
a7d4e65b | 493 | void AliMUONGeometryTransformer::WriteDetElemTransforms(ofstream& out) const |
afc8e661 | 494 | { |
a9aad96e | 495 | /// Write detection element transformations for all detection elements in all |
496 | /// module transformers | |
afc8e661 | 497 | |
afc8e661 | 498 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { |
499 | AliMUONGeometryModuleTransformer* moduleTransformer | |
500 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
ea7ea157 | 501 | AliMpExMap* detElements = moduleTransformer->GetDetElementStore(); |
630711ed | 502 | TIter next(detElements->CreateIterator()); |
503 | AliMUONGeometryDetElement* detElement; | |
504 | while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) ) | |
505 | { | |
a7d4e65b | 506 | const TGeoMatrix* transform |
afc8e661 | 507 | = detElement->GetLocalTransformation(); |
508 | ||
afc8e661 | 509 | // Write data on out |
ea7ea157 | 510 | out << AliMUONGeometryDetElement::GetDENamePrefix() << " " |
511 | << setw(4) << detElement->GetId(); | |
afc8e661 | 512 | |
513 | WriteTransform(out, transform); | |
514 | } | |
515 | out << endl; | |
516 | } | |
517 | } | |
518 | ||
d4d05625 | 519 | //______________________________________________________________________________ |
520 | TString AliMUONGeometryTransformer::GetModuleSymName(Int_t moduleId) const | |
521 | { | |
522 | /// Return the module symbolic name (use for alignment) | |
523 | ||
327d1302 | 524 | return "/" + fDetectorName + "/" |
525 | + AliMUONGeometryModuleTransformer::GetModuleName(moduleId); | |
d4d05625 | 526 | } |
527 | ||
528 | //______________________________________________________________________________ | |
529 | TString AliMUONGeometryTransformer::GetDESymName(Int_t detElemId) const | |
530 | { | |
9c4d2d12 | 531 | /// Return the detection element symbolic name (used for alignment) |
d4d05625 | 532 | |
d4d05625 | 533 | // Module Id |
ea7ea157 | 534 | Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId); |
d4d05625 | 535 | |
327d1302 | 536 | return GetModuleSymName(moduleId) + "/" |
537 | + AliMUONGeometryDetElement::GetDEName(detElemId); | |
d4d05625 | 538 | } |
539 | ||
afc8e661 | 540 | // |
541 | // public functions | |
542 | // | |
543 | ||
450ca6fb | 544 | //______________________________________________________________________________ |
545 | Bool_t | |
546 | AliMUONGeometryTransformer::LoadTransformations() | |
547 | { | |
548 | /// Load transformations for defined modules and detection elements | |
549 | /// using AliGeomManager | |
550 | ||
551 | if ( ! AliGeomManager::GetGeometry() ) { | |
552 | AliFatal("Geometry has to be laoded in AliGeomManager first."); | |
553 | return false; | |
554 | } | |
555 | ||
556 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { | |
557 | AliMUONGeometryModuleTransformer* moduleTransformer | |
558 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
559 | ||
560 | // Module symbolic name | |
561 | TString symname = GetModuleSymName(moduleTransformer->GetModuleId()); | |
562 | ||
563 | // Set matrix from physical node | |
564 | TGeoHMatrix* matrix = AliGeomManager::GetMatrix(symname); | |
565 | if ( ! matrix ) { | |
566 | AliErrorStream() << "Geometry module matrix not found." << endl; | |
567 | return false; | |
568 | } | |
569 | moduleTransformer->SetTransformation(*matrix); | |
570 | ||
571 | // Loop over detection elements | |
572 | AliMpExMap* detElements = moduleTransformer->GetDetElementStore(); | |
573 | TIter next(detElements->CreateIterator()); | |
574 | AliMUONGeometryDetElement* detElement; | |
575 | ||
576 | while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) ) | |
577 | { | |
578 | // Det element symbolic name | |
579 | TString symnameDE = GetDESymName(detElement->GetId()); | |
580 | ||
581 | // Set global matrix from physical node | |
582 | TGeoHMatrix* globalMatrix = AliGeomManager::GetMatrix(symnameDE); | |
583 | if ( ! globalMatrix ) { | |
584 | AliErrorStream() << "Detection element matrix not found." << endl; | |
585 | return false; | |
586 | } | |
587 | detElement->SetGlobalTransformation(*globalMatrix, false); | |
588 | ||
589 | // Set local matrix | |
590 | TGeoHMatrix localMatrix = | |
591 | AliMUONGeometryBuilder::Multiply( | |
592 | (*matrix).Inverse(), (*globalMatrix) ); | |
593 | detElement->SetLocalTransformation(localMatrix, false); | |
594 | } | |
595 | } | |
596 | return true; | |
597 | } | |
598 | ||
afc8e661 | 599 | //______________________________________________________________________________ |
600 | Bool_t | |
327d1302 | 601 | AliMUONGeometryTransformer::LoadGeometryData(const TString& fileName) |
afc8e661 | 602 | { |
327d1302 | 603 | /// Read geometry data either from ASCII file with transformations or |
604 | /// from root geometry file (if fileName has ".root" extension) | |
a7d4e65b | 605 | |
327d1302 | 606 | CreateModules(); |
a7d4e65b | 607 | |
608 | // Get file extension | |
327d1302 | 609 | std::string fileName2 = fileName.Data(); |
610 | std::string rootExt = fileName2.substr(fileName2.size()-5, fileName2.size()); | |
a7d4e65b | 611 | |
327d1302 | 612 | if ( rootExt != ".root" ) |
613 | return ReadTransformations(fileName); | |
614 | else { | |
615 | // Load root geometry | |
616 | AliGeomManager::LoadGeometry(fileName.Data()); | |
617 | return LoadTransformations(); | |
618 | } | |
a7d4e65b | 619 | } |
620 | ||
621 | //______________________________________________________________________________ | |
622 | Bool_t | |
327d1302 | 623 | AliMUONGeometryTransformer::LoadGeometryData() |
a7d4e65b | 624 | { |
327d1302 | 625 | /// Load geometry data from already loaded Root geometry using AliGeomManager |
a7d4e65b | 626 | |
327d1302 | 627 | if ( ! AliGeomManager::GetGeometry() ) { |
628 | AliErrorStream() << "Geometry has not been loaded in AliGeomManager" << endl; | |
629 | return false; | |
630 | } | |
afc8e661 | 631 | |
327d1302 | 632 | CreateModules(); |
a7d4e65b | 633 | |
327d1302 | 634 | return LoadTransformations(); |
a7d4e65b | 635 | } |
afc8e661 | 636 | |
637 | //______________________________________________________________________________ | |
638 | Bool_t | |
639 | AliMUONGeometryTransformer::WriteTransformations(const TString& fileName) const | |
640 | { | |
a9aad96e | 641 | /// Write transformations into a file. |
642 | /// Return true, if writing finished correctly. | |
afc8e661 | 643 | |
644 | // No writing | |
645 | // if builder is not associated with any geometry module | |
646 | if (fModuleTransformers->GetEntriesFast() == 0) return false; | |
647 | ||
648 | // File path | |
649 | TString filePath = gSystem->Getenv("ALICE_ROOT"); | |
650 | filePath += "/MUON/data/"; | |
651 | filePath += fileName; | |
652 | ||
a7d4e65b | 653 | // Open output file |
afc8e661 | 654 | ofstream out(filePath, ios::out); |
655 | if (!out) { | |
656 | cerr << filePath << endl; | |
657 | AliError("File not found."); | |
658 | return false; | |
659 | } | |
660 | #if !defined (__DECCXX) | |
661 | out.setf(std::ios::fixed); | |
662 | #endif | |
a7d4e65b | 663 | WriteModuleTransforms(out); |
664 | WriteDetElemTransforms(out); | |
665 | ||
666 | return true; | |
667 | } | |
668 | ||
669 | //______________________________________________________________________________ | |
670 | Bool_t | |
671 | AliMUONGeometryTransformer::WriteMisAlignmentData(const TString& fileName) const | |
672 | { | |
a9aad96e | 673 | /// Write misalignment data into a file |
674 | /// Return true, if writing finished correctly. | |
a7d4e65b | 675 | |
676 | // No writing | |
677 | // if builder is not associated with any geometry module | |
678 | if ( fModuleTransformers->GetEntriesFast() == 0 ) { | |
679 | AliWarningStream() << "No geometry modules defined." << endl; | |
680 | return false; | |
681 | } | |
682 | ||
683 | // No writing | |
684 | // if builder has no mis-alignment data | |
685 | if ( ! fMisAlignArray ) { | |
686 | AliWarningStream() << "No mis-alignment data defined." << endl; | |
687 | return false; | |
688 | } | |
689 | ||
690 | // File path | |
691 | TString filePath = gSystem->Getenv("ALICE_ROOT"); | |
692 | filePath += "/MUON/data/"; | |
693 | filePath += fileName; | |
694 | ||
695 | // Write mis-alignment data in the root file | |
696 | TFile file(fileName.Data(), "RECREATE"); | |
697 | fMisAlignArray->Write(); | |
698 | file.Close(); | |
afc8e661 | 699 | |
700 | return true; | |
701 | } | |
702 | ||
703 | //_____________________________________________________________________________ | |
704 | void AliMUONGeometryTransformer::AddModuleTransformer( | |
705 | AliMUONGeometryModuleTransformer* moduleTransformer) | |
706 | { | |
a9aad96e | 707 | /// Add the module transformer to the array |
afc8e661 | 708 | |
ea7ea157 | 709 | // Expand the size if not sufficient |
710 | Int_t moduleId = moduleTransformer->GetModuleId(); | |
711 | if ( moduleId >= fModuleTransformers->GetSize() ) | |
712 | fModuleTransformers->Expand(moduleId+1); | |
713 | ||
714 | fModuleTransformers->AddAt(moduleTransformer, moduleId); | |
afc8e661 | 715 | } |
716 | ||
a7d4e65b | 717 | //_____________________________________________________________________________ |
718 | void AliMUONGeometryTransformer::AddMisAlignModule(Int_t moduleId, | |
d148dd1c | 719 | const TGeoHMatrix& matrix, Bool_t bGlobal) |
a7d4e65b | 720 | { |
a9aad96e | 721 | /// Build AliAlignObjMatrix with module ID, its volumePath |
a7d4e65b | 722 | /// and the given delta transformation matrix |
723 | ||
724 | if ( ! fMisAlignArray ) | |
725 | fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200); | |
726 | ||
727 | const AliMUONGeometryModuleTransformer* kTransformer | |
728 | = GetModuleTransformer(moduleId); | |
729 | if ( ! kTransformer ) { | |
730 | AliErrorStream() << "Module " << moduleId << " not found." << endl; | |
731 | return; | |
732 | } | |
733 | ||
bf16b32c | 734 | // Get unique align object ID |
ae079791 | 735 | Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId); |
bf16b32c | 736 | |
a7d4e65b | 737 | // Create mis align matrix |
738 | TClonesArray& refArray =*fMisAlignArray; | |
739 | Int_t pos = fMisAlignArray->GetEntriesFast(); | |
d4d05625 | 740 | new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, |
d148dd1c | 741 | const_cast<TGeoHMatrix&>(matrix),bGlobal); |
a7d4e65b | 742 | } |
743 | ||
744 | //_____________________________________________________________________________ | |
745 | void AliMUONGeometryTransformer::AddMisAlignDetElement(Int_t detElemId, | |
d148dd1c | 746 | const TGeoHMatrix& matrix, Bool_t bGlobal) |
a7d4e65b | 747 | { |
a9aad96e | 748 | /// Build AliAlignObjMatrix with detection element ID, its volumePath |
a7d4e65b | 749 | /// and the given delta transformation matrix |
750 | ||
751 | if ( ! fMisAlignArray ) | |
752 | fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200); | |
753 | ||
754 | const AliMUONGeometryDetElement* kDetElement | |
755 | = GetDetElement(detElemId); | |
756 | ||
757 | if ( ! kDetElement ) { | |
758 | AliErrorStream() << "Det element " << detElemId << " not found." << endl; | |
759 | return; | |
760 | } | |
761 | ||
bf16b32c | 762 | // Get unique align object ID |
ae079791 | 763 | Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId); |
bf16b32c | 764 | |
a7d4e65b | 765 | // Create mis align matrix |
766 | TClonesArray& refArray =*fMisAlignArray; | |
767 | Int_t pos = fMisAlignArray->GetEntriesFast(); | |
d4d05625 | 768 | new(refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, |
d148dd1c | 769 | const_cast<TGeoHMatrix&>(matrix),bGlobal); |
a7d4e65b | 770 | } |
771 | ||
327d1302 | 772 | //______________________________________________________________________________ |
773 | void AliMUONGeometryTransformer::CreateModules() | |
774 | { | |
775 | /// Create modules and their detection elements using info from mapping; | |
776 | /// but do not fill matrices | |
777 | ||
88544f7e | 778 | // Load mapping as its info is used to define modules & DEs |
779 | LoadMapping(); | |
327d1302 | 780 | |
b96f7067 | 781 | if ( fModuleTransformers->GetEntriesFast() == 0 ) { |
782 | // Create modules only if they do not yet exist | |
783 | ||
784 | // Loop over geometry module | |
785 | for (Int_t moduleId = 0; moduleId < AliMpConstants::NofGeomModules(); ++moduleId ) { | |
327d1302 | 786 | |
b96f7067 | 787 | // Create geometry module transformer |
788 | AliMUONGeometryModuleTransformer* moduleTransformer | |
789 | = new AliMUONGeometryModuleTransformer(moduleId); | |
790 | AddModuleTransformer(moduleTransformer); | |
791 | } | |
792 | } | |
327d1302 | 793 | |
794 | // Loop over detection elements | |
795 | AliMpDEIterator it; | |
796 | for ( it.First(); ! it.IsDone(); it.Next() ) { | |
797 | ||
798 | Int_t detElemId = it.CurrentDEId(); | |
799 | Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId); | |
800 | ||
801 | // Get detection element store | |
802 | AliMpExMap* detElements = | |
803 | GetModuleTransformer(moduleId)->GetDetElementStore(); | |
804 | ||
805 | // Add detection element | |
806 | AliMUONGeometryDetElement* detElement | |
807 | = new AliMUONGeometryDetElement(detElemId); | |
808 | detElements->Add(detElemId, detElement); | |
809 | } | |
810 | } | |
811 | ||
d4d05625 | 812 | //_____________________________________________________________________________ |
813 | void AliMUONGeometryTransformer::AddAlignableVolumes() const | |
814 | { | |
df22c125 | 815 | /// Set symbolic names and matrices to alignable objects to TGeo |
d4d05625 | 816 | |
817 | if ( ! gGeoManager ) { | |
818 | AliWarning("TGeoManager not defined."); | |
819 | return; | |
820 | } | |
821 | ||
822 | // Modules | |
823 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { | |
824 | AliMUONGeometryModuleTransformer* module | |
825 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
826 | ||
827 | // Set module symbolic name | |
df22c125 | 828 | TGeoPNEntry* pnEntry |
327d1302 | 829 | = gGeoManager->SetAlignableEntry(GetModuleSymName(module->GetModuleId()), |
df22c125 | 830 | module->GetVolumePath()); |
327d1302 | 831 | if ( ! pnEntry ) { |
832 | AliErrorStream() | |
b96f7067 | 833 | << "Volume path " << module->GetVolumePath().Data() |
834 | << " for geometry module " << module->GetModuleId() << " " << module | |
327d1302 | 835 | << " not found in geometry." << endl; |
836 | } | |
837 | else { | |
838 | // Set module matrix | |
839 | pnEntry->SetMatrix(new TGeoHMatrix(*module->GetTransformation())); | |
840 | // the matrix will be deleted via TGeoManager | |
841 | } | |
d4d05625 | 842 | |
843 | // Detection elements | |
ea7ea157 | 844 | AliMpExMap* detElements = module->GetDetElementStore(); |
630711ed | 845 | TIter next(detElements->CreateIterator()); |
846 | AliMUONGeometryDetElement* detElement; | |
847 | ||
848 | while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) ) | |
849 | { | |
d4d05625 | 850 | // Set detection element symbolic name |
14a02207 | 851 | TGeoPNEntry* pnEntryDE |
df22c125 | 852 | = gGeoManager->SetAlignableEntry(GetDESymName(detElement->GetId()), |
853 | detElement->GetVolumePath()); | |
14a02207 | 854 | if ( ! pnEntryDE ) { |
327d1302 | 855 | AliErrorStream() |
b96f7067 | 856 | << "Volume path " |
857 | << detElement->GetVolumePath().Data() | |
858 | << " for detection element " << detElement->GetId() | |
327d1302 | 859 | << " not found in geometry." << endl; |
860 | } | |
861 | else { | |
862 | // Set detection element matrix | |
14a02207 | 863 | pnEntryDE->SetMatrix(new TGeoHMatrix(*detElement->GetGlobalTransformation())); |
327d1302 | 864 | // the matrix will be deleted via TGeoManager |
865 | } | |
d4d05625 | 866 | } |
867 | } | |
868 | } | |
869 | ||
afc8e661 | 870 | //_____________________________________________________________________________ |
ae612121 | 871 | TClonesArray* AliMUONGeometryTransformer::CreateZeroAlignmentData() const |
872 | { | |
873 | /// Create array with zero alignment data | |
874 | ||
875 | // Create array for zero-alignment objects | |
876 | TClonesArray* array = new TClonesArray("AliAlignObjMatrix", 200); | |
877 | TClonesArray& refArray =*array; | |
878 | array->SetOwner(true); | |
879 | ||
880 | // Identity matrix | |
881 | TGeoHMatrix matrix; | |
882 | ||
883 | // Modules | |
884 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { | |
885 | AliMUONGeometryModuleTransformer* module | |
886 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
887 | ||
ae612121 | 888 | Int_t moduleId = module->GetModuleId(); |
889 | ||
890 | // Align object ID | |
ae079791 | 891 | Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId); |
ae612121 | 892 | |
893 | // Create mis align matrix | |
894 | Int_t pos = array->GetEntriesFast(); | |
d4d05625 | 895 | new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, matrix, kTRUE); |
ae612121 | 896 | } |
897 | ||
898 | // Detection elements | |
899 | for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) { | |
900 | AliMUONGeometryModuleTransformer* moduleTransformer | |
901 | = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i); | |
ae612121 | 902 | |
630711ed | 903 | AliMpExMap* detElements = moduleTransformer->GetDetElementStore(); |
904 | TIter next(detElements->CreateIterator()); | |
905 | AliMUONGeometryDetElement* detElement; | |
906 | ||
907 | while ( ( detElement = static_cast<AliMUONGeometryDetElement*>(next()) ) ) | |
908 | { | |
ae612121 | 909 | Int_t detElemId = detElement->GetId(); |
910 | ||
911 | // Align object ID | |
ae079791 | 912 | Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId); |
ae612121 | 913 | |
914 | // Create mis align matrix | |
915 | Int_t pos = array->GetEntriesFast(); | |
d4d05625 | 916 | new (refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, matrix, kTRUE); |
ae612121 | 917 | } |
918 | } | |
919 | ||
920 | return array; | |
921 | } | |
922 | ||
923 | //_____________________________________________________________________________ | |
f384585c | 924 | void AliMUONGeometryTransformer::ClearMisAlignmentData() |
925 | { | |
926 | /// Clear the array of misalignment data | |
927 | ||
928 | if ( ! fMisAlignArray ) return; | |
929 | ||
930 | fMisAlignArray->Delete(); | |
931 | } | |
932 | ||
933 | //_____________________________________________________________________________ | |
afc8e661 | 934 | void AliMUONGeometryTransformer::Global2Local(Int_t detElemId, |
935 | Float_t xg, Float_t yg, Float_t zg, | |
936 | Float_t& xl, Float_t& yl, Float_t& zl) const | |
937 | { | |
938 | /// Transform point from the global reference frame (ALIC) | |
939 | /// to the local reference frame of the detection element specified | |
940 | /// by detElemId. | |
f7006443 | 941 | |
afc8e661 | 942 | const AliMUONGeometryModuleTransformer* kTransformer |
943 | = GetModuleTransformerByDEId(detElemId); | |
944 | ||
945 | if (kTransformer) | |
946 | kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl); | |
947 | } | |
948 | ||
949 | //_____________________________________________________________________________ | |
950 | void AliMUONGeometryTransformer::Global2Local(Int_t detElemId, | |
951 | Double_t xg, Double_t yg, Double_t zg, | |
952 | Double_t& xl, Double_t& yl, Double_t& zl) const | |
953 | { | |
954 | /// Transform point from the global reference frame (ALIC) | |
955 | /// to the local reference frame of the detection element specified | |
956 | /// by detElemId. | |
f7006443 | 957 | |
afc8e661 | 958 | const AliMUONGeometryModuleTransformer* kTransformer |
959 | = GetModuleTransformerByDEId(detElemId); | |
960 | ||
961 | if (kTransformer) | |
962 | kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl); | |
963 | } | |
964 | ||
965 | //_____________________________________________________________________________ | |
966 | void AliMUONGeometryTransformer::Local2Global(Int_t detElemId, | |
967 | Float_t xl, Float_t yl, Float_t zl, | |
968 | Float_t& xg, Float_t& yg, Float_t& zg) const | |
969 | { | |
970 | /// Transform point from the local reference frame of the detection element | |
971 | /// specified by detElemId to the global reference frame (ALIC). | |
972 | ||
973 | const AliMUONGeometryModuleTransformer* kTransformer | |
974 | = GetModuleTransformerByDEId(detElemId); | |
975 | ||
976 | if (kTransformer) | |
977 | kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg); | |
978 | } | |
979 | ||
980 | //_____________________________________________________________________________ | |
981 | void AliMUONGeometryTransformer::Local2Global(Int_t detElemId, | |
982 | Double_t xl, Double_t yl, Double_t zl, | |
983 | Double_t& xg, Double_t& yg, Double_t& zg) const | |
984 | { | |
985 | /// Transform point from the local reference frame of the detection element | |
986 | /// specified by detElemId to the global reference frame (ALIC). | |
987 | ||
988 | const AliMUONGeometryModuleTransformer* kTransformer | |
989 | = GetModuleTransformerByDEId(detElemId); | |
990 | ||
991 | if (kTransformer) | |
992 | kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg); | |
993 | } | |
994 | ||
995 | //_____________________________________________________________________________ | |
996 | const AliMUONGeometryModuleTransformer* | |
997 | AliMUONGeometryTransformer::GetModuleTransformer(Int_t index, Bool_t warn) const | |
998 | { | |
a9aad96e | 999 | /// Return the geometry module transformer specified by index |
afc8e661 | 1000 | |
1001 | return GetModuleTransformerNonConst(index, warn); | |
1002 | } | |
1003 | ||
1004 | //_____________________________________________________________________________ | |
1005 | const AliMUONGeometryModuleTransformer* | |
1006 | AliMUONGeometryTransformer::GetModuleTransformerByDEId(Int_t detElemId, | |
1007 | Bool_t warn) const | |
1008 | { | |
a9aad96e | 1009 | /// Return the geometry module transformer specified by detection element ID |
afc8e661 | 1010 | |
1011 | // Get module index | |
ea7ea157 | 1012 | Int_t index = AliMpDEManager::GetGeomModuleId(detElemId); |
afc8e661 | 1013 | |
1014 | return GetModuleTransformer(index, warn); | |
1015 | } | |
317aa7dc | 1016 | |
a7d4e65b | 1017 | //_____________________________________________________________________________ |
1018 | const AliMUONGeometryDetElement* | |
1019 | AliMUONGeometryTransformer::GetDetElement(Int_t detElemId, Bool_t warn) const | |
1020 | { | |
a9aad96e | 1021 | /// Return detection element with given detElemId |
a7d4e65b | 1022 | |
1023 | const AliMUONGeometryModuleTransformer* kTransformer | |
1024 | = GetModuleTransformerByDEId(detElemId, warn); | |
1025 | ||
1026 | if (!kTransformer) return 0; | |
1027 | ||
1028 | return kTransformer->GetDetElement(detElemId, warn); | |
1029 | } | |
1030 | ||
317aa7dc | 1031 | //_____________________________________________________________________________ |
1032 | Bool_t AliMUONGeometryTransformer::HasDE(Int_t detElemId) const | |
1033 | { | |
1034 | /// Return true if detection element with given detElemId is defined | |
1035 | ||
1036 | const AliMUONGeometryModuleTransformer* kTransformer | |
1037 | = GetModuleTransformerByDEId(detElemId, false); | |
1038 | ||
1039 | if (!kTransformer) return false; | |
1040 | ||
1041 | return ( kTransformer->GetDetElement(detElemId, false) != 0 ); | |
1042 | } | |
1043 | ||
1044 |