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"
31 #include "AliMUONGeometryStore.h"
35 #include <Riostream.h>
36 #include <TObjString.h>
39 const Float_t AliMUONGeometrySegmentation::fgkMaxDistance = 1.0e6;
41 ClassImp(AliMUONGeometrySegmentation)
43 //______________________________________________________________________________
44 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation(
45 const AliMUONGeometryModuleTransformer* transformer)
48 fCurrentDetElement(0),
49 fCurrentSegmentation(0),
50 fkModuleTransformer(transformer),
55 /// Standard constructor
57 fDESegmentations = new AliMUONGeometryStore(false);
59 fDENames = new AliMUONGeometryStore(true);
61 AliDebug(1, Form("ctor this = %p", this) );
64 //______________________________________________________________________________
65 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation()
68 fCurrentDetElement(0),
69 fCurrentSegmentation(0),
70 fkModuleTransformer(0),
75 /// Default Constructor
77 AliDebug(1, Form("default (empty) ctor this = %p", this));
80 //______________________________________________________________________________
81 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation(
82 const AliMUONGeometrySegmentation& rhs)
85 /// Protected copy constructor
87 AliFatal("Copy constructor is not implemented.");
90 #include <Riostream.h>
91 //______________________________________________________________________________
92 AliMUONGeometrySegmentation::~AliMUONGeometrySegmentation()
96 AliDebug(1, Form("dtor this = %p", this));
98 delete fDESegmentations;
106 //______________________________________________________________________________
107 AliMUONGeometrySegmentation&
108 AliMUONGeometrySegmentation::operator=(const AliMUONGeometrySegmentation& rhs)
110 /// Protected assignment operator
112 // check assignement to self
113 if (this == &rhs) return *this;
115 AliFatal("Assignment operator is not implemented.");
124 //______________________________________________________________________________
125 Bool_t AliMUONGeometrySegmentation::OwnNotify(Int_t detElemId, Bool_t warn) const
127 /// Update current detection element and segmentation,
128 /// and checks if they exist.
129 /// Return true if success.
131 if (detElemId != fCurrentDetElemId) {
133 // Find detection element and its segmentation
134 AliMUONGeometryDetElement* detElement
135 = fkModuleTransformer->GetDetElement(detElemId, warn);
138 AliError(Form("Detection element %d not defined", detElemId));
142 AliMUONVGeometryDESegmentation* segmentation
143 = (AliMUONVGeometryDESegmentation*) fDESegmentations->Get(detElemId, warn);
146 AliError(Form("Segmentation for detection element %d not defined",
151 fCurrentDetElemId = detElemId;
152 fCurrentDetElement = detElement;
153 fCurrentSegmentation = segmentation;
163 //______________________________________________________________________________
164 void AliMUONGeometrySegmentation::Add(Int_t detElemId, const TString& detElemName,
165 AliMUONVGeometryDESegmentation* segmentation)
167 /// Add detection element segmentation
169 fDESegmentations->Add(detElemId, segmentation);
170 fDENames->Add(detElemId, new TObjString(detElemName));
174 //______________________________________________________________________________
175 const AliMUONVGeometryDESegmentation*
176 AliMUONGeometrySegmentation::GetDESegmentation(Int_t detElemId, Bool_t warn) const
178 /// Return the DE segmentation
180 if (!OwnNotify(detElemId, warn)) return 0;
182 return fCurrentSegmentation;
185 //______________________________________________________________________________
186 AliMUONGeometryDirection
187 AliMUONGeometrySegmentation::GetDirection(Int_t detElemId) const
189 /// Return direction with a constant pad size
190 /// (Direction or coordinate where the resolution is the best)
192 if (!OwnNotify(detElemId)) return kDirUndefined;
194 return fCurrentSegmentation->GetDirection();
197 //______________________________________________________________________________
198 TString AliMUONGeometrySegmentation::GetDEName(Int_t detElemId) const
200 /// Return name of the given detection element
202 TObjString* deName = (TObjString*)fDENames->Get(detElemId, false);
205 return deName->GetString();
208 << "Detection element " << detElemId << " not defined. " << endl;
213 //______________________________________________________________________________
214 void AliMUONGeometrySegmentation::Print(Option_t* opt) const
216 // Print DE segmentations
218 std::cout << "fDESegmentations (class "
219 << fDESegmentations->Class()->GetName() << ") entries="
220 << fDESegmentations->GetNofEntries()
222 fDESegmentations->Print(opt);
225 //______________________________________________________________________________
226 void AliMUONGeometrySegmentation::SetPadSize(Float_t p1, Float_t p2)
228 /// Set pad size Dx*Dy to all detection element segmentations
230 for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
231 AliMUONVGeometryDESegmentation* segmentation
232 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
233 segmentation->SetPadSize(p1, p2);
237 //______________________________________________________________________________
238 void AliMUONGeometrySegmentation::SetDAnod(Float_t d)
240 /// Set anod pitch to all detection element segmentations
242 for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
243 AliMUONVGeometryDESegmentation* segmentation
244 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
245 segmentation->SetDAnod(d);
249 //______________________________________________________________________________
250 Float_t AliMUONGeometrySegmentation::GetAnod(Int_t detElemId, Float_t xhit) const
252 /// Anod wire coordinate closest to xhit
253 /// Returns for a hit position xhit the position of the nearest anode wire
254 /// !!! xhit is understand a a distance, not as a position in the space
257 if (!OwnNotify(detElemId)) return 0;
259 return fCurrentSegmentation->GetAnod(xhit);
262 //______________________________________________________________________________
263 Bool_t AliMUONGeometrySegmentation::GetPadI(Int_t detElemId,
264 Float_t xg, Float_t yg, Float_t zg,
265 Int_t& ix, Int_t& iy)
267 /// Return pad coordinates (ix,iy) for given real coordinates (x,y)
269 if (!OwnNotify(detElemId)) return false;
272 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
274 if (!fCurrentSegmentation->HasPad(xl, yl, zl)) return false;
276 fCurrentSegmentation->GetPadI(xl, yl, zl, ix, iy);
280 //______________________________________________________________________________
282 AliMUONGeometrySegmentation::HasPad(Int_t detElemId, Int_t ix, Int_t iy)
284 // Tells if a given pad exists in a given detector element
286 if (!OwnNotify(detElemId)) return false;
288 return fCurrentSegmentation->HasPad(ix,iy);
291 //______________________________________________________________________________
293 AliMUONGeometrySegmentation::HasPad(Int_t detElemId,
294 Float_t& xg, Float_t& yg, Float_t& zg)
296 // Tells if a given pad exists in a given detector element
298 if (!OwnNotify(detElemId)) return false;
301 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
303 return fCurrentSegmentation->HasPad(xl, yl, zl);
306 //______________________________________________________________________________
308 AliMUONGeometrySegmentation::GetPadC(Int_t detElemId,
310 Float_t& xg, Float_t& yg, Float_t& zg)
312 /// Transform from pad to real coordinates
314 if (!OwnNotify(detElemId)) return false;
316 if (!fCurrentSegmentation->HasPad(ix, iy)) {
317 xg = yg = zg = fgkMaxDistance;
322 fCurrentSegmentation->GetPadC(ix, iy, xl , yl, zl);
324 fkModuleTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
328 //______________________________________________________________________________
329 void AliMUONGeometrySegmentation::Init(Int_t chamber)
331 /// Initialize segmentation.
332 /// Check that all detection elements have segmanetation set
334 // Loop over detection elements
335 AliMUONGeometryStore* detElements = fkModuleTransformer->GetDetElementStore();
337 for (Int_t i=0; i<detElements->GetNofEntries(); i++) {
339 // Get detction element Id
340 Int_t detElemId = detElements->GetEntry(i)->GetUniqueID();
342 // Check segmentation
343 if (! fDESegmentations->Get(detElemId) ) {
344 AliError(Form("Detection element %d has not a segmentation set.",
345 detElements->GetEntry(i)->GetUniqueID()));
348 // Initialize DE Segmentation
349 ((AliSegmentation*)fDESegmentations->Get(detElemId))->Init(chamber);
354 //______________________________________________________________________________
355 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId) const
357 /// Get pad size in x
359 if (!OwnNotify(detElemId)) return 0.;
361 return fCurrentSegmentation->Dpx();
364 //______________________________________________________________________________
365 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId) const
367 /// Get pad size in y
369 if (!OwnNotify(detElemId)) return 0.;
371 return fCurrentSegmentation->Dpy();
374 //______________________________________________________________________________
375 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId, Int_t isector) const
377 /// Pad size in x by sector
379 if (!OwnNotify(detElemId)) return 0.;
381 return fCurrentSegmentation->Dpx(isector);
384 //______________________________________________________________________________
385 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId, Int_t isector) const
387 /// Pad size in x, y by Sector
389 if (!OwnNotify(detElemId)) return 0.;
391 return fCurrentSegmentation->Dpy(isector);
394 //______________________________________________________________________________
395 Int_t AliMUONGeometrySegmentation::Npx(Int_t detElemId) const
397 /// Maximum number of Pads in x
399 if (!OwnNotify(detElemId)) return 0;
401 return fCurrentSegmentation->Npx();
404 //______________________________________________________________________________
405 Int_t AliMUONGeometrySegmentation::Npy(Int_t detElemId) const
407 /// Maximum number of Pads in y
409 if (!OwnNotify(detElemId)) return 0;
411 return fCurrentSegmentation->Npy();
414 //______________________________________________________________________________
415 void AliMUONGeometrySegmentation::SetPad(Int_t detElemId, Int_t ix, Int_t iy)
417 /// Set pad position.
418 /// Sets virtual pad coordinates, needed for evaluating pad response
419 /// outside the tracking program.
420 /// From AliMUONGeometrySegmentationV01.
422 if (!OwnNotify(detElemId)) return;
424 fCurrentSegmentation->SetPad(ix, iy);
427 //______________________________________________________________________________
428 void AliMUONGeometrySegmentation::SetHit(Int_t detElemId,
429 Float_t xghit, Float_t yghit, Float_t zghit)
432 /// Sets virtual hit position, needed for evaluating pad response
433 /// outside the tracking program
434 /// From AliMUONGeometrySegmentationV01.
436 if (!OwnNotify(detElemId)) return;
439 fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl);
441 fCurrentSegmentation->SetHit(xl, yl, zl);
444 //______________________________________________________________________________
445 void AliMUONGeometrySegmentation::FirstPad(Int_t detElemId,
446 Float_t xghit, Float_t yghit, Float_t zghit,
447 Float_t dx, Float_t dy)
449 /// Iterate over pads - initialiser
451 if (!OwnNotify(detElemId)) return;
453 AliDebug(1,Form("xghit, yghit, zghit, dx, dy = %e,%e,%e,%e, %e",
454 xghit, yghit, zghit, dx, dy));
457 fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl);
459 fCurrentSegmentation->FirstPad(xl, yl, zl, dx, dy);
462 //______________________________________________________________________________
463 void AliMUONGeometrySegmentation::NextPad(Int_t detElemId)
465 /// Iterate over pads - stepper
467 if (!OwnNotify(detElemId)) return;
469 fCurrentSegmentation->NextPad();
472 //______________________________________________________________________________
473 Int_t AliMUONGeometrySegmentation::MorePads(Int_t detElemId)
475 /// Iterate over pads - condition
477 if (!OwnNotify(detElemId)) return 0;
479 return fCurrentSegmentation->MorePads();
482 //______________________________________________________________________________
483 Float_t AliMUONGeometrySegmentation::Distance2AndOffset(Int_t detElemId,
485 Float_t xg, Float_t yg, Float_t zg,
488 /// Return the square of the distance between 1 pad
489 /// labelled by its channel numbers and a coordinate
491 if (!OwnNotify(detElemId)) return 0.;
494 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
496 return fCurrentSegmentation->Distance2AndOffset(ix, iy, xl, yl, dummy);
499 //______________________________________________________________________________
500 void AliMUONGeometrySegmentation::GetNParallelAndOffset(Int_t detElemId,
502 Int_t* nparallel, Int_t* offset)
504 /// Number of pads read in parallel and offset to add to x
505 /// (specific to LYON, but mandatory for display)
508 if (!OwnNotify(detElemId)) return;
510 fCurrentSegmentation->GetNParallelAndOffset(ix, iy, nparallel, offset);
514 //______________________________________________________________________________
515 void AliMUONGeometrySegmentation::Neighbours(Int_t detElemId,
518 Int_t xlist[10], Int_t ylist[10])
520 /// Get next neighbours
522 if (!OwnNotify(detElemId)) return;
524 fCurrentSegmentation->Neighbours(ix, iy, nlist, xlist, ylist);
527 //______________________________________________________________________________
528 Int_t AliMUONGeometrySegmentation::Ix()
530 /// Current pad cursor during disintegration
533 return fCurrentSegmentation->Ix();
536 //______________________________________________________________________________
537 Int_t AliMUONGeometrySegmentation::Iy()
539 /// Current pad cursor during disintegration
542 return fCurrentSegmentation->Iy();
545 //______________________________________________________________________________
546 Int_t AliMUONGeometrySegmentation::DetElemId()
548 /// Current pad cursor during disintegration
551 return fCurrentDetElemId;
554 //______________________________________________________________________________
555 Int_t AliMUONGeometrySegmentation::ISector()
559 return fCurrentSegmentation->ISector();
562 //______________________________________________________________________________
563 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId, Int_t ix, Int_t iy)
565 /// Calculate sector from pad coordinates
567 if (!OwnNotify(detElemId)) return 0;
569 return fCurrentSegmentation->Sector(ix, iy);
572 //______________________________________________________________________________
573 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId,
574 Float_t xg, Float_t yg, Float_t zg)
576 /// Calculate sector from pad coordinates
578 if (!OwnNotify(detElemId)) return 0;
581 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
583 return fCurrentSegmentation->Sector(xl, yl);
586 //______________________________________________________________________________
587 void AliMUONGeometrySegmentation::IntegrationLimits(Int_t detElemId,
588 Float_t& x1, Float_t& x2,
589 Float_t& y1, Float_t& y2)
591 /// Current integration limits
593 if (!OwnNotify(detElemId)) return;
595 fCurrentSegmentation->IntegrationLimits(x1, x2, y1, y2);
598 //______________________________________________________________________________
599 Int_t AliMUONGeometrySegmentation::SigGenCond(Int_t detElemId,
600 Float_t xg, Float_t yg, Float_t zg)
602 /// Signal Generation Condition during Stepping
603 /// 0: don't generate signal \n
604 /// 1: generate signal \n
607 /// Crossing of pad boundary and mid plane between neighbouring wires is checked.
608 /// To correctly simulate the dependence of the spatial resolution on the angle
609 /// of incidence signal must be generated for constant steps on
610 /// the projection of the trajectory along the anode wire.
612 /// Signal will be generated if particle crosses pad boundary or
613 /// boundary between two wires.
615 if (!OwnNotify(detElemId)) return 0;
618 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
620 return fCurrentSegmentation->SigGenCond(xl, yl, zl);
623 //______________________________________________________________________________
624 void AliMUONGeometrySegmentation::SigGenInit(Int_t detElemId,
625 Float_t xg, Float_t yg, Float_t zg)
627 /// Initialise signal generation at coord (x,y,z)
628 /// Initialise pad and wire position during stepping.
629 /// From AliMUONGeometrySegmentationV01
631 if (!OwnNotify(detElemId)) return;
634 fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl);
636 if (!fCurrentSegmentation->HasPad(xl, yl, zl)) {
638 << "No pad at " << detElemId
639 << " global position: " << xg << " " << yg << " " << zg
640 << " local position: " << xl << " " << yl << " " << zl << endl;
644 fCurrentSegmentation->SigGenInit(xl, yl, zl);
647 //______________________________________________________________________________
648 void AliMUONGeometrySegmentation::GiveTestPoints(Int_t /*detElemId*/,
650 Float_t* /*xg*/, Float_t* /*yg*/) const
652 /// Test points for auto calibration
653 /// Return test point on the pad plane.
654 /// Used during determination of the segmoid correction of the COG-method
655 /// From AliMUONGeometrySegmentationV01
657 // Requires change of interface
658 // to convert points from local to global we need z coordinate
659 AliError("Not implemented.");
662 //______________________________________________________________________________
663 void AliMUONGeometrySegmentation::Draw(const char* opt)
665 /// Draw the segmentation zones for all detElemId
667 for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
668 AliMUONVGeometryDESegmentation* segmentation
669 = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
670 segmentation->Draw(opt);
674 //______________________________________________________________________________
675 void AliMUONGeometrySegmentation::Draw(Int_t detElemId, const char* opt)
677 /// Draw the segmentation zones for a given detElemId.
679 if (!OwnNotify(detElemId)) return;
681 fCurrentSegmentation->Draw(opt);
684 //______________________________________________________________________________
685 void AliMUONGeometrySegmentation::SetCorrFunc(Int_t detElemId,
686 Int_t isec, TF1* func)
688 /// Set the correction function.
689 /// From AliMUONGeometrySegmentationV01
691 if (!OwnNotify(detElemId)) return;
693 fCurrentSegmentation->SetCorrFunc(isec, func);
696 //______________________________________________________________________________
697 TF1* AliMUONGeometrySegmentation::CorrFunc(Int_t detElemId, Int_t isec) const
699 /// Get the correction Function.
700 /// From AliMUONGeometrySegmentationV01
702 if (!OwnNotify(detElemId)) return 0;
704 return fCurrentSegmentation->CorrFunc(isec);