1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // Class AliMUONGeometrySegmentation
18 // -------------------------------
19 // New class for the module segmentation
20 // composed of the segmentations of detection elements.
21 // Applies transformations defined in geometry.
23 // Author:Ivana Hrivnacova, IPN Orsay
27 #include "AliMUONGeometrySegmentation.h"
28 #include "AliMUONVGeometryDESegmentation.h"
29 #include "AliMUONGeometryModuleTransformer.h"
30 #include "AliMUONGeometryDetElement.h"
32 #include "AliMpExMap.h"
36 #include <Riostream.h>
37 #include <TObjString.h>
40 const Float_t AliMUONGeometrySegmentation::fgkMaxDistance = 1.0e6;
43 ClassImp(AliMUONGeometrySegmentation)
46 //______________________________________________________________________________
47 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation(
48 const AliMUONGeometryModuleTransformer* transformer)
51 fCurrentDetElement(0),
52 fCurrentSegmentation(0),
53 fkModuleTransformer(transformer),
58 /// Standard constructor
60 fDESegmentations = new AliMpExMap(true);
61 fDESegmentations->SetOwner(false);
63 fDENames = new AliMpExMap(true);
65 AliDebug(1, Form("ctor this = %p", this) );
68 //______________________________________________________________________________
69 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation()
72 fCurrentDetElement(0),
73 fCurrentSegmentation(0),
74 fkModuleTransformer(0),
79 /// Default Constructor
81 AliDebug(1, Form("default (empty) ctor this = %p", this));
84 //______________________________________________________________________________
85 AliMUONGeometrySegmentation::~AliMUONGeometrySegmentation()
89 AliDebug(1, Form("dtor this = %p", this));
91 delete fDESegmentations;
99 //______________________________________________________________________________
100 Bool_t AliMUONGeometrySegmentation::OwnNotify(Int_t detElemId, Bool_t warn) const
102 /// Update current detection element and segmentation,
103 /// and checks if they exist.
104 /// Return true if success.
106 if (detElemId != fCurrentDetElemId) {
108 // Find detection element and its segmentation
109 AliMUONGeometryDetElement* detElement
110 = fkModuleTransformer->GetDetElement(detElemId, warn);
113 AliError(Form("Detection element %d not defined", detElemId));
117 AliMUONVGeometryDESegmentation* segmentation
118 = (AliMUONVGeometryDESegmentation*) fDESegmentations->GetValue(detElemId);
121 AliError(Form("Segmentation for detection element %d not defined",
126 fCurrentDetElemId = detElemId;
127 fCurrentDetElement = detElement;
128 fCurrentSegmentation = segmentation;
138 //______________________________________________________________________________
139 void AliMUONGeometrySegmentation::Add(Int_t detElemId, const TString& detElemName,
140 AliMUONVGeometryDESegmentation* segmentation)
142 /// Add detection element segmentation
144 fDESegmentations->Add(detElemId, segmentation);
145 fDENames->Add(detElemId, new TObjString(detElemName));
149 //______________________________________________________________________________
150 const AliMUONVGeometryDESegmentation*
151 AliMUONGeometrySegmentation::GetDESegmentation(Int_t detElemId, Bool_t warn) const
153 /// Return the DE segmentation
155 if (!OwnNotify(detElemId, warn)) return 0;
157 return fCurrentSegmentation;
160 //______________________________________________________________________________
161 AliMUONGeometryDirection
162 AliMUONGeometrySegmentation::GetDirection(Int_t detElemId) const
164 /// Return direction with a constant pad size.
165 /// (Direction or coordinate where the resolution is the best)
167 if (!OwnNotify(detElemId)) return kDirUndefined;
169 return fCurrentSegmentation->GetDirection();
172 //______________________________________________________________________________
173 TString AliMUONGeometrySegmentation::GetDEName(Int_t detElemId) const
175 /// Return name of the given detection element
177 TObjString* deName = (TObjString*)fDENames->GetValue(detElemId);
180 return deName->GetString();
183 << "Detection element " << detElemId << " not defined. " << endl;
188 //______________________________________________________________________________
189 void AliMUONGeometrySegmentation::Print(Option_t* opt) const
191 /// Print DE segmentations
193 std::cout << "fDESegmentations (class "
194 << fDESegmentations->Class()->GetName() << ") entries="
195 << fDESegmentations->GetSize()
197 fDESegmentations->Print(opt);
200 //______________________________________________________________________________
201 void AliMUONGeometrySegmentation::SetPadSize(Float_t p1, Float_t p2)
203 /// Set pad size Dx*Dy to all detection element segmentations
205 for (Int_t i=0; i<fDESegmentations->GetSize(); i++) {
206 AliMUONVGeometryDESegmentation* segmentation
207 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetObject(i);
208 segmentation->SetPadSize(p1, p2);
212 //______________________________________________________________________________
213 void AliMUONGeometrySegmentation::SetDAnod(Float_t d)
215 /// Set anod pitch to all detection element segmentations
217 for (Int_t i=0; i<fDESegmentations->GetSize(); i++) {
218 AliMUONVGeometryDESegmentation* segmentation
219 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetObject(i);
220 segmentation->SetDAnod(d);
224 //______________________________________________________________________________
225 Float_t AliMUONGeometrySegmentation::GetAnod(Int_t detElemId, Float_t xhit) const
227 /// Anod wire coordinate closest to xhit
228 /// Returns for a hit position xhit the position of the nearest anode wire
229 /// !!! xhit is understand a a distance, not as a position in the space
232 if (!OwnNotify(detElemId)) return 0;
234 return fCurrentSegmentation->GetAnod(xhit);
237 //______________________________________________________________________________
238 Bool_t AliMUONGeometrySegmentation::GetPadI(Int_t detElemId,
239 Float_t xg, Float_t yg, Float_t zg,
240 Int_t& ix, Int_t& iy)
242 /// Return pad coordinates (ix,iy) for given real coordinates (x,y)
244 if (!OwnNotify(detElemId)) return false;
247 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
249 if (!fCurrentSegmentation->HasPad(xl, yl, zl)) return false;
251 fCurrentSegmentation->GetPadI(xl, yl, zl, ix, iy);
255 //______________________________________________________________________________
257 AliMUONGeometrySegmentation::HasPad(Int_t detElemId, Int_t ix, Int_t iy)
259 /// Tell if a given pad exists in a given detector element
261 if (!OwnNotify(detElemId)) return false;
263 return fCurrentSegmentation->HasPad(ix,iy);
266 //______________________________________________________________________________
268 AliMUONGeometrySegmentation::HasPad(Int_t detElemId,
269 Float_t& xg, Float_t& yg, Float_t& zg)
271 /// Tell if a given pad exists in a given detector element
273 if (!OwnNotify(detElemId)) return false;
276 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
278 return fCurrentSegmentation->HasPad(xl, yl, zl);
281 //______________________________________________________________________________
283 AliMUONGeometrySegmentation::GetPadC(Int_t detElemId,
285 Float_t& xg, Float_t& yg, Float_t& zg)
287 /// Transform from pad to real coordinates
289 if (!OwnNotify(detElemId)) return false;
291 if (!fCurrentSegmentation->HasPad(ix, iy)) {
292 xg = yg = zg = fgkMaxDistance;
297 fCurrentSegmentation->GetPadC(ix, iy, xl , yl, zl);
299 fkModuleTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
303 //______________________________________________________________________________
304 void AliMUONGeometrySegmentation::Init(Int_t chamber)
306 /// Initialize segmentation.
307 /// Check that all detection elements have segmanetation set
309 // Loop over detection elements
310 AliMpExMap* detElements = fkModuleTransformer->GetDetElementStore();
312 for (Int_t i=0; i<detElements->GetSize(); i++) {
314 // Skip not filled entries
315 if (!detElements->GetObject(i)) continue;
317 // Get detction element Id
318 Int_t detElemId = detElements->GetObject(i)->GetUniqueID();
320 // Check segmentation
321 if (! fDESegmentations->GetValue(detElemId) ) {
323 << "Detection element " << detElemId << " has not a segmentation set."
327 // Initialize DE Segmentation
328 ((AliSegmentation*)fDESegmentations->GetValue(detElemId))->Init(chamber);
333 //______________________________________________________________________________
334 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId) const
336 /// Get pad size in x
338 if (!OwnNotify(detElemId)) return 0.;
340 return fCurrentSegmentation->Dpx();
343 //______________________________________________________________________________
344 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId) const
346 /// Get pad size in y
348 if (!OwnNotify(detElemId)) return 0.;
350 return fCurrentSegmentation->Dpy();
353 //______________________________________________________________________________
354 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId, Int_t isector) const
356 /// Pad size in x by sector
358 if (!OwnNotify(detElemId)) return 0.;
360 return fCurrentSegmentation->Dpx(isector);
363 //______________________________________________________________________________
364 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId, Int_t isector) const
366 /// Pad size in y by Sector
368 if (!OwnNotify(detElemId)) return 0.;
370 return fCurrentSegmentation->Dpy(isector);
373 //______________________________________________________________________________
374 Int_t AliMUONGeometrySegmentation::Npx(Int_t detElemId) const
376 /// Maximum number of Pads in x
378 if (!OwnNotify(detElemId)) return 0;
380 return fCurrentSegmentation->Npx();
383 //______________________________________________________________________________
384 Int_t AliMUONGeometrySegmentation::Npy(Int_t detElemId) const
386 /// Maximum number of Pads in y
388 if (!OwnNotify(detElemId)) return 0;
390 return fCurrentSegmentation->Npy();
393 //______________________________________________________________________________
394 void AliMUONGeometrySegmentation::SetPad(Int_t detElemId, Int_t ix, Int_t iy)
396 /// Set pad position.
397 /// Sets virtual pad coordinates, needed for evaluating pad response
398 /// outside the tracking program.
399 /// From AliMUONGeometrySegmentationV01.
401 if (!OwnNotify(detElemId)) return;
403 fCurrentSegmentation->SetPad(ix, iy);
406 //______________________________________________________________________________
407 void AliMUONGeometrySegmentation::SetHit(Int_t detElemId,
408 Float_t xghit, Float_t yghit, Float_t zghit)
410 /// Set hit position.
411 /// Sets virtual hit position, needed for evaluating pad response
412 /// outside the tracking program
413 /// From AliMUONGeometrySegmentationV01.
415 if (!OwnNotify(detElemId)) return;
418 fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl);
420 fCurrentSegmentation->SetHit(xl, yl, zl);
423 //______________________________________________________________________________
424 void AliMUONGeometrySegmentation::FirstPad(Int_t detElemId,
425 Float_t xghit, Float_t yghit, Float_t zghit,
426 Float_t dx, Float_t dy)
428 /// Iterate over pads - initialiser
430 if (!OwnNotify(detElemId)) return;
432 AliDebug(1,Form("xghit, yghit, zghit, dx, dy = %e,%e,%e,%e, %e",
433 xghit, yghit, zghit, dx, dy));
436 fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl);
438 fCurrentSegmentation->FirstPad(xl, yl, zl, dx, dy);
441 //______________________________________________________________________________
442 void AliMUONGeometrySegmentation::NextPad(Int_t detElemId)
444 /// Iterate over pads - stepper
446 if (!OwnNotify(detElemId)) return;
448 fCurrentSegmentation->NextPad();
451 //______________________________________________________________________________
452 Int_t AliMUONGeometrySegmentation::MorePads(Int_t detElemId)
454 /// Iterate over pads - condition
456 if (!OwnNotify(detElemId)) return 0;
458 return fCurrentSegmentation->MorePads();
461 //______________________________________________________________________________
462 Float_t AliMUONGeometrySegmentation::Distance2AndOffset(Int_t detElemId,
464 Float_t xg, Float_t yg, Float_t zg,
467 /// Return the square of the distance between 1 pad
468 /// labelled by its channel numbers and a coordinate
470 if (!OwnNotify(detElemId)) return 0.;
473 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
475 return fCurrentSegmentation->Distance2AndOffset(ix, iy, xl, yl, dummy);
478 //______________________________________________________________________________
479 void AliMUONGeometrySegmentation::GetNParallelAndOffset(Int_t detElemId,
481 Int_t* nparallel, Int_t* offset)
483 /// Number of pads read in parallel and offset to add to x
484 /// (specific to LYON, but mandatory for display)
487 if (!OwnNotify(detElemId)) return;
489 fCurrentSegmentation->GetNParallelAndOffset(ix, iy, nparallel, offset);
493 //______________________________________________________________________________
494 void AliMUONGeometrySegmentation::Neighbours(Int_t detElemId,
497 Int_t xlist[10], Int_t ylist[10])
499 /// Get next neighbours
501 if (!OwnNotify(detElemId)) return;
503 fCurrentSegmentation->Neighbours(ix, iy, nlist, xlist, ylist);
506 //______________________________________________________________________________
507 Int_t AliMUONGeometrySegmentation::Ix()
509 /// Current pad cursor during disintegration
512 return fCurrentSegmentation->Ix();
515 //______________________________________________________________________________
516 Int_t AliMUONGeometrySegmentation::Iy()
518 /// Current pad cursor during disintegration
521 return fCurrentSegmentation->Iy();
524 //______________________________________________________________________________
525 Int_t AliMUONGeometrySegmentation::DetElemId()
527 /// Current pad cursor during disintegration
530 return fCurrentDetElemId;
533 //______________________________________________________________________________
534 Int_t AliMUONGeometrySegmentation::ISector()
538 return fCurrentSegmentation->ISector();
541 //______________________________________________________________________________
542 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId, Int_t ix, Int_t iy)
544 /// Calculate sector from pad indices
546 if (!OwnNotify(detElemId)) return 0;
548 return fCurrentSegmentation->Sector(ix, iy);
551 //______________________________________________________________________________
552 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId,
553 Float_t xg, Float_t yg, Float_t zg)
555 /// Calculate sector from pad coordinates
557 if (!OwnNotify(detElemId)) return 0;
560 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
562 return fCurrentSegmentation->Sector(xl, yl);
565 //______________________________________________________________________________
566 void AliMUONGeometrySegmentation::IntegrationLimits(Int_t detElemId,
567 Float_t& x1, Float_t& x2,
568 Float_t& y1, Float_t& y2)
570 /// Current integration limits
572 if (!OwnNotify(detElemId)) return;
574 fCurrentSegmentation->IntegrationLimits(x1, x2, y1, y2);
577 //______________________________________________________________________________
578 Int_t AliMUONGeometrySegmentation::SigGenCond(Int_t detElemId,
579 Float_t xg, Float_t yg, Float_t zg)
581 /// Signal Generation Condition during Stepping
582 /// 0: don't generate signal \n
583 /// 1: generate signal \n
586 /// Crossing of pad boundary and mid plane between neighbouring wires is checked.
587 /// To correctly simulate the dependence of the spatial resolution on the angle
588 /// of incidence signal must be generated for constant steps on
589 /// the projection of the trajectory along the anode wire.
591 /// Signal will be generated if particle crosses pad boundary or
592 /// boundary between two wires.
594 if (!OwnNotify(detElemId)) return 0;
597 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
599 return fCurrentSegmentation->SigGenCond(xl, yl, zl);
602 //______________________________________________________________________________
603 void AliMUONGeometrySegmentation::SigGenInit(Int_t detElemId,
604 Float_t xg, Float_t yg, Float_t zg)
606 /// Initialise signal generation at coord (x,y,z)
607 /// Initialise pad and wire position during stepping.
608 /// From AliMUONGeometrySegmentationV01
610 if (!OwnNotify(detElemId)) return;
613 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
615 if (!fCurrentSegmentation->HasPad(xl, yl, zl)) {
617 << "No pad at " << detElemId
618 << " global position: " << xg << " " << yg << " " << zg
619 << " local position: " << xl << " " << yl << " " << zl << endl;
623 fCurrentSegmentation->SigGenInit(xl, yl, zl);
626 //______________________________________________________________________________
627 void AliMUONGeometrySegmentation::GiveTestPoints(Int_t /*detElemId*/,
629 Float_t* /*xg*/, Float_t* /*yg*/) const
631 /// Test points for auto calibration
632 /// Return test point on the pad plane.
633 /// Used during determination of the segmoid correction of the COG-method
634 /// From AliMUONGeometrySegmentationV01
636 // Requires change of interface
637 // to convert points from local to global we need z coordinate
638 AliError("Not implemented.");
641 //______________________________________________________________________________
642 void AliMUONGeometrySegmentation::Draw(const char* opt)
644 /// Draw the segmentation zones for all detElemId
646 for (Int_t i=0; i<fDESegmentations->GetSize(); i++) {
647 AliMUONVGeometryDESegmentation* segmentation
648 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetObject(i);
649 segmentation->Draw(opt);
653 //______________________________________________________________________________
654 void AliMUONGeometrySegmentation::Draw(Int_t detElemId, const char* opt)
656 /// Draw the segmentation zones for a given detElemId.
658 if (!OwnNotify(detElemId)) return;
660 fCurrentSegmentation->Draw(opt);
663 //______________________________________________________________________________
664 void AliMUONGeometrySegmentation::SetCorrFunc(Int_t detElemId,
665 Int_t isec, TF1* func)
667 /// Set the correction function.
668 /// From AliMUONGeometrySegmentationV01
670 if (!OwnNotify(detElemId)) return;
672 fCurrentSegmentation->SetCorrFunc(isec, func);
675 //______________________________________________________________________________
676 TF1* AliMUONGeometrySegmentation::CorrFunc(Int_t detElemId, Int_t isec) const
678 /// Get the correction Function.
679 /// From AliMUONGeometrySegmentationV01
681 if (!OwnNotify(detElemId)) return 0;
683 return fCurrentSegmentation->CorrFunc(isec);