- Adapted comments for Doxygen
[u/mrichter/AliRoot.git] / MUON / AliMUONSt345SlatSegmentationV2.cxx
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
16 /* $Id$ */
17
18 #include "AliMUONSt345SlatSegmentationV2.h"
19 #include "AliMUONConstants.h"
20
21 #include "AliMpArea.h"
22 #include "AliMpSlat.h"
23 #include "AliMpSlatSegmentation.h"
24 #include "AliMpPCB.h" 
25 // FIXME: we should not need access to PCB at this level
26 // if the Dpx, Dpy, Sector interface would not be used.
27 // Investigate instead to direct use of AliMpVSegmentation and AliMpPad
28 // from the clusterFinder ? // :aphecetc:20050722 
29 // or, or ... have the AliMpSlat handles the notion of zone, finally
30 // (where "zone" in mapping is equivalent to "sector" here), and thus
31 // let AliMpSlat offer the interface to get information similar to what
32 // Dpx, Dpy, Sector offer now to the clustering. That indeed should be
33 // handled directly at the level of AliMpVSegmentation...
34 #include "AliMpVPadIterator.h"
35
36 #include "AliLog.h"
37
38 #include "Riostream.h"
39
40 /// \cond CLASSIMP
41 ClassImp(AliMUONSt345SlatSegmentationV2)
42 /// \endcond
43
44 namespace
45 {
46   Float_t FMAX(1E9);
47 }
48
49 //_____________________________________________________________________________
50 AliMUONSt345SlatSegmentationV2::AliMUONSt345SlatSegmentationV2()
51 : AliMUONVGeometryDESegmentation(),
52 fDetElemId(-1),
53 fPlaneType(kBendingPlane),
54 fSlat(0),
55 fSlatSegmentation(0),
56 fPadIterator(0),
57 fXhit(FMAX),
58 fYhit(FMAX)
59 {
60 /// Default ctor
61
62         AliDebug(1,Form("this=%p default (empty) ctor",this));
63 }
64
65 //_____________________________________________________________________________
66 AliMUONSt345SlatSegmentationV2::AliMUONSt345SlatSegmentationV2(
67                                    AliMpVSegmentation* segmentation,
68                                    Int_t detElemId, AliMpPlaneType bendingOrNonBending)
69 : AliMUONVGeometryDESegmentation(),
70 fDetElemId(detElemId),
71 fPlaneType(bendingOrNonBending),
72 fSlat(0),
73 fSlatSegmentation(0),
74 fPadIterator(0),
75 fXhit(FMAX),
76 fYhit(FMAX)
77
78 /// Normal ctor.
79
80   fSlatSegmentation = dynamic_cast<AliMpSlatSegmentation*>(segmentation);
81   if (fSlatSegmentation)
82     fSlat = fSlatSegmentation->Slat();
83   else 
84     AliFatal("Wrong mapping segmentation type");
85                 
86   AliDebug(1,Form("this=%p detElemId=%3d %s fSlatSegmentation=%p",this,detElemId,
87                                                                         ( (bendingOrNonBending==kBendingPlane)?"Bending":"NonBending" ),
88                                                                         fSlatSegmentation));
89 }
90
91 //_____________________________________________________________________________
92 AliMUONSt345SlatSegmentationV2::~AliMUONSt345SlatSegmentationV2()
93 {
94 /// Destructor
95
96         AliDebug(1,Form("dtor this=%p",this));
97   delete fPadIterator;
98 }
99
100 //_____________________________________________________________________________
101 TF1*
102 AliMUONSt345SlatSegmentationV2::CorrFunc(Int_t /*isec*/) const
103 {
104 /// Not implemented
105
106   AliFatal("Not Implemented");
107   return 0x0;
108 }
109
110 //_____________________________________________________________________________
111 Float_t 
112 AliMUONSt345SlatSegmentationV2::Distance2AndOffset(Int_t /*iX*/, Int_t /*iY*/, 
113                                   Float_t /*x*/, Float_t /*y*/, Int_t* /*dummy*/){
114 /// Not implemented
115
116   AliFatal("Not Implemented");
117   return 0.0;
118 }
119
120 //_____________________________________________________________________________
121 void
122 AliMUONSt345SlatSegmentationV2::Draw(Option_t* /*opt*/)
123 {
124 /// Not implemented
125
126   AliFatal("Not Implemented");
127 }
128
129 //_____________________________________________________________________________
130 Float_t
131 AliMUONSt345SlatSegmentationV2::Dpx() const
132 {
133 /// Not implemented
134
135   AliFatal("Not Implemented");
136   return 0.0;
137 }
138
139 //_____________________________________________________________________________
140 Float_t
141 AliMUONSt345SlatSegmentationV2::Dpy() const
142 {
143 /// Not implemented
144
145   AliFatal("Not Implemented");
146   return 0.0;
147 }
148
149 //_____________________________________________________________________________
150 Float_t
151 AliMUONSt345SlatSegmentationV2::Dpx(int ipcb) const
152 {
153 /// Get pad size in x
154
155         AliMpPCB* pcb = fSlat->GetPCB(ipcb);
156         if (!pcb) 
157   {
158     AliFatal("pcb is null!");
159   }
160         return pcb->PadSizeX();
161 }
162
163 //_____________________________________________________________________________
164 Float_t
165 AliMUONSt345SlatSegmentationV2::Dpy(int ipcb) const
166 {
167 /// Get pad size in y
168
169         AliMpPCB* pcb = fSlat->GetPCB(ipcb);
170         if (!pcb) 
171   {
172     AliFatal("pcb is null!");
173   }
174         return pcb->PadSizeY();
175 }
176
177 //_____________________________________________________________________________
178 void
179 AliMUONSt345SlatSegmentationV2::FirstPad(Float_t xhit, Float_t yhit,Float_t /*zhit*/,
180                                          Float_t dx, Float_t dy)
181 {
182 /// OK. We will do it in 2 steps. First get the area over which to
183 /// iterate, based on hit coordinates and (dx,dy). This first step
184 /// has nothing to do with segmentation in the first place, but with
185 /// how we simulate the fact that at some point the charge is shared
186 /// amongst several pads.
187 /// The second step is the actual pad iteration and is handled by 
188 /// a specific class (which has to do only with iteration...)
189 ///
190 /// \todo FIXME: this method should not be here in the first place, IMHO.
191         
192   // Find the wire position (center of charge distribution)
193   Float_t xwire = GetAnod(xhit);
194   fXhit = xwire;
195   fYhit = yhit;
196         
197   Double_t x01 = xwire - dx;
198   Double_t x02 = xwire + dx;
199   Double_t y01 = yhit - dy;
200   Double_t y02 = yhit + dy;
201         
202   Double_t xext = x02 - x01;
203   Double_t yext = y02 - y01;
204         
205   // we do not check area here, as we assume the iterator
206   // will do it, and will possibly truncate it if needed.
207   // Note that we convert the area position to a reference frame
208   // located in the lower-left corner of the slat, instead of its
209   // center.
210 //  AliMpArea area(TVector2((x01+x02)/2.0+fSlat->DX(),
211 //                                                                                                      (y01+y02)/2.0+fSlat->DY()),
212 //                                                               TVector2(xext/2.0,yext/2.0));
213   AliMpArea area(TVector2((x01+x02)/2.0,(y01+y02)/2.0),
214                                                                  TVector2(xext/2.0,yext/2.0));
215         
216   delete fPadIterator;
217         
218   fPadIterator = fSlatSegmentation->CreateIterator(area);
219         
220   fPadIterator->First();
221         
222   fCurrentPad = fPadIterator->CurrentItem();
223         
224   if ( !fCurrentPad.IsValid() ) 
225         {
226                 AliError(Form("Cannot get a valid pad for (xhit,yhit,dx,dy)=(%e,%e,%e,%e)",xhit,yhit,dx,dy));
227         }
228         
229   AliDebug(4,Form("xhit,yhit,dx,dy=%e,%e,%e,%e ix,iy=%3d,%3d slat=%s",
230                                                                         xhit,yhit,dx,dy,
231                                                                         fCurrentPad.GetIndices().GetFirst(),
232                                                                         fCurrentPad.GetIndices().GetSecond(),fSlat->GetID()));            
233 }
234
235 //_____________________________________________________________________________
236 Float_t
237 AliMUONSt345SlatSegmentationV2::GetAnod(Float_t xhit) const
238 {
239 /// Gets the x-coordinate of the wire which is the closest to xhit.
240         
241   Int_t n = Int_t(xhit/AliMUONConstants::Pitch());
242   Float_t wire = (xhit>0) ? n+0.5 : n-0.5;
243   return AliMUONConstants::Pitch()*wire;
244 }
245
246 //_____________________________________________________________________________
247 AliMUONGeometryDirection
248 AliMUONSt345SlatSegmentationV2::GetDirection()
249 {
250 /// Not implemented
251
252   //AliWarning("Not Implemented");
253   return kDirUndefined;
254 }
255
256 //______________________________________________________________________________
257 const AliMpVSegmentation*  
258 AliMUONSt345SlatSegmentationV2::GetMpSegmentation() const
259 {
260 /// Returns the mapping segmentation
261 /// (provides access to electronics info)
262
263   return fSlatSegmentation;
264 }  
265
266
267 //_____________________________________________________________________________
268 void 
269 AliMUONSt345SlatSegmentationV2::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
270                                          Int_t* /*Nparallel*/, Int_t* /*Offset*/)
271 {
272 /// Not implemented
273
274   AliFatal("Not Implemented");
275 }
276
277 //_____________________________________________________________________________
278 void
279 AliMUONSt345SlatSegmentationV2::GetPadC(Int_t ix, Int_t iy, 
280                                         Float_t& x, Float_t& y, Float_t& z)
281 {                                        
282 /// Transform from pad to real coordinates
283
284   z = 0;
285   GetPadC(ix,iy,x,y);
286 }
287
288 //_____________________________________________________________________________
289 void
290 AliMUONSt345SlatSegmentationV2::GetPadC(Int_t ix, Int_t iy, 
291                                         Float_t& x, Float_t& y)
292 {
293 /// Transform from pad to real coordinates
294
295   AliMpPad pad = 
296   fSlatSegmentation->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
297   x = pad.Position().X();
298   y = pad.Position().Y();
299 }
300
301
302 //_____________________________________________________________________________
303 void
304 AliMUONSt345SlatSegmentationV2::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
305 Int_t& ix, Int_t& iy)
306 {
307 ///  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
308
309   GetPadI(x,y,ix,iy);
310 }
311
312 //_____________________________________________________________________________
313 void
314 AliMUONSt345SlatSegmentationV2::GetPadI(Float_t x, Float_t y,
315                                         Int_t& ix, Int_t& iy)
316 {
317 ///  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
318
319   AliMpPad pad = fSlatSegmentation->PadByPosition(TVector2(x,y), kTRUE);
320         
321   if ( pad != AliMpPad::Invalid() )
322         {
323                 ix = pad.GetIndices().GetFirst();
324                 iy = pad.GetIndices().GetSecond();
325         }
326   else
327         {
328                 ix = iy = -1;
329         }
330 }
331
332 //_____________________________________________________________________________
333 void 
334 AliMUONSt345SlatSegmentationV2::GiveTestPoints(Int_t& /*n*/, 
335                                     Float_t* /*x*/, Float_t* /*y*/) const
336 {
337 /// Not implemented
338
339   AliFatal("Not Implemented");
340 }
341
342 //_____________________________________________________________________________
343 Bool_t
344 AliMUONSt345SlatSegmentationV2::HasPad(Float_t x, Float_t y, Float_t z)
345 {
346 /// Returns true if a pad exists in the given position
347
348   Int_t ix, iy;
349   GetPadI(x,y,z,ix,iy);
350   return HasPad(ix,iy);
351 }
352
353 //_____________________________________________________________________________
354 Bool_t
355 AliMUONSt345SlatSegmentationV2::HasPad(Int_t ix, Int_t iy)
356 {
357 /// Returns true if a pad with given indices exists
358
359   return fSlatSegmentation->HasPad(AliMpIntPair(ix,iy));
360 }
361
362 //_____________________________________________________________________________
363 void  
364 AliMUONSt345SlatSegmentationV2::IntegrationLimits(Float_t& x1, Float_t& x2,
365                                                   Float_t& y1, Float_t& y2)
366 {
367 ///  Returns integration limits for current pad
368         
369         //   x1 = fXhit - fX - Dpx(fSector)/2.;
370         //   x2 = x1 + Dpx(fSector);
371         //   y1 = fYhit - fY - Dpy(fSector)/2.;
372         //   y2 = y1 + Dpy(fSector);    
373         
374   Float_t x = fCurrentPad.Position().X();
375   Float_t y = fCurrentPad.Position().Y();
376         
377   Float_t padsizex = fCurrentPad.Dimensions().X() * 2.0;
378   Float_t padsizey = fCurrentPad.Dimensions().Y() * 2.0;
379         
380   x1 = fXhit - x - padsizex/2.0;
381   x2 = x1 + padsizex;
382   y1 = fYhit - y - padsizey/2.0;
383   y2 = y1 + padsizey;
384         
385   AliDebug(4,Form("xhit,yhit=%e,%e x,y=%e,%e, x1,x2,y1,y2=%e,%e,%e,%e",fXhit,fYhit,x,y,x1,x2,y1,y2));
386 }
387
388 //_____________________________________________________________________________
389 Int_t
390 AliMUONSt345SlatSegmentationV2::ISector()
391 {
392 /// \todo FIXME: remove the usage of ISector from all the code.
393
394   return -10;
395 }
396
397 //_____________________________________________________________________________
398 Int_t
399 AliMUONSt345SlatSegmentationV2::Ix()
400 {
401 /// Current pad cursor during disintegration
402 /// x, y-coordinate
403
404   if ( fPadIterator )
405         {
406                 return fPadIterator->CurrentItem().GetIndices().GetFirst();
407         }
408   else
409         {
410                 return -1;
411         }
412 }
413
414 //_____________________________________________________________________________
415 Int_t
416 AliMUONSt345SlatSegmentationV2::Iy()
417 {
418 /// Current pad cursor during disintegration
419 /// x, y-coordinate
420
421   if ( fPadIterator ) 
422         {
423                 return fPadIterator->CurrentItem().GetIndices().GetSecond();
424         }
425   else
426         {
427                 return -1;
428         }
429 }
430
431 //_____________________________________________________________________________
432 Int_t
433 AliMUONSt345SlatSegmentationV2::MorePads()
434 {
435 /// Iterate over pads - condition
436
437   return (fPadIterator && !fPadIterator->IsDone());
438 }
439
440 //_____________________________________________________________________________
441 void 
442 AliMUONSt345SlatSegmentationV2::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
443                                            Int_t Xlist[10], Int_t Ylist[10])
444 {
445 /// Find pad at (ix,iy) for which we'll search neighbours.
446
447   AliMpPad pad = 
448         fSlatSegmentation->PadByIndices(AliMpIntPair(iX,iY),kTRUE);
449         
450   // Define the region to look into : a region slightly bigger
451   // than the pad itself (5% bigger), in order to catch first neighbours.
452
453   AliMpArea area(pad.Position(),pad.Dimensions()*1.05); 
454                 
455   AliMpVPadIterator* it = fSlatSegmentation->CreateIterator(area);
456   it->First();
457   Int_t n = 0;
458   while ( !it->IsDone() && n < 10 )
459         {
460                 AliMpPad p = it->CurrentItem();
461                 if ( p != pad ) // skip self
462                 {
463                         Xlist[n] = p.GetIndices().GetFirst();
464                         Ylist[n] = p.GetIndices().GetSecond();
465                         ++n;
466                 }
467                 it->Next();
468         }
469         delete it;
470   *Nlist = n;
471 }
472
473 //_____________________________________________________________________________
474 void
475 AliMUONSt345SlatSegmentationV2::NextPad()
476 {
477 /// Iterate over pads - stepper
478
479   if ( fPadIterator )
480         {
481                 fPadIterator->Next();
482                 fCurrentPad = fPadIterator->CurrentItem();
483         }
484   else
485         {
486                 AliError("PadIterator not initialized. Please use First() first ;-)");
487         }
488 }
489
490 //_____________________________________________________________________________
491 Int_t
492 AliMUONSt345SlatSegmentationV2::Npx() const
493 {
494 /// Maximum number of Pads in x
495
496   return fSlatSegmentation->MaxPadIndexX()+1;
497 }
498
499 //_____________________________________________________________________________
500 Int_t
501 AliMUONSt345SlatSegmentationV2::Npy() const
502 {
503 /// Maximum number of Pads in y
504
505   return fSlatSegmentation->MaxPadIndexY()+1;
506 }
507
508 //_____________________________________________________________________________
509 void
510 AliMUONSt345SlatSegmentationV2::Print(Option_t* /*opt*/) const
511 {
512 /// Printing
513
514   cout << "DetElemId=" << fDetElemId << " PlaneType=" 
515   << fPlaneType << " Npx,Npy=" << Npx() << "," << Npy() << " fSlat=" << fSlat 
516   << " fSlatSegmentation=" << fSlatSegmentation
517   << " fSlatSegmentation->Slat()=" << fSlatSegmentation->Slat() << endl;
518 }
519
520 //_____________________________________________________________________________
521 Int_t
522 AliMUONSt345SlatSegmentationV2::Sector(Int_t ix, Int_t /*iy*/)
523 {
524 /// Calculate sector from pad coordinates
525
526   return fSlat->FindPCBIndex(ix);
527 }
528
529 //_____________________________________________________________________________
530 Int_t
531 AliMUONSt345SlatSegmentationV2::Sector(Float_t x, Float_t y)
532 {
533 /// Calculate sector from pad coordinates
534
535   return fSlat->FindPCBIndex(x,y);
536 }
537
538 //_____________________________________________________________________________
539 void
540 AliMUONSt345SlatSegmentationV2::SetCorrFunc(Int_t /*isec*/,TF1* /*func*/)
541 {
542 /// Not implemented
543
544   AliFatal("Not Implemented");
545 }
546
547 //_____________________________________________________________________________
548 void
549 AliMUONSt345SlatSegmentationV2::SetDAnod(float /*d*/)
550 {
551 /// Not implemented
552
553   AliFatal("Not Implemented");
554 }
555
556 //_____________________________________________________________________________
557 void
558 AliMUONSt345SlatSegmentationV2::SetHit(Float_t x, Float_t y, Float_t)
559 {
560 /// Set hit position
561 /// Sets virtual hit position, needed for evaluating pad response 
562 /// outside the tracking program 
563
564   fXhit = x;
565   fYhit = y;
566         
567   //
568   // insure we're within the slat limits. If not, issue a simple
569   // warning, as this might be correct (due to clustering/fitting algorithm
570   // that is allowed to go a little bit outside limits).
571   // That should only be considered an error in case the point is way
572   // outside (but by how much is the question you'll have to determine
573   // by yourself...)
574   //
575   if ( fXhit < -fSlat->DX() || fXhit > fSlat->DX() ||
576        fYhit < -fSlat->DY() || fYhit > fSlat->DY() )
577         {
578     Double_t dx = - fSlat->DX() + TMath::Abs(fXhit);
579     Double_t dy = - fSlat->DY() + TMath::Abs(fYhit);
580     dx = ( dx > 0 ? dx : 0);
581     dy = ( dy > 0 ? dy : 0);
582                 AliWarning(Form("Hit outside slat %s limits (x,y)hit = (%e,%e). "
583                     "Outside by (%e,%e) cm. Might be ok though.",
584                     fSlat->GetID(),fXhit,fYhit,dx,dy));
585         }  
586 }
587
588 //_____________________________________________________________________________
589 void
590 AliMUONSt345SlatSegmentationV2::SetPad(Int_t ix, Int_t iy)
591 {
592 /// Set pad position.
593 /// Sets virtual pad coordinates, needed for evaluating pad response 
594 /// outside the tracking program.
595
596   fCurrentPad = 
597         fSlatSegmentation->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
598   if ( !fCurrentPad.IsValid() )
599         {
600                 AliError(Form("Setting current pad to invalid ! (ix,iy)=(%4d,%4d)",ix,iy));
601         }
602 }
603
604 //_____________________________________________________________________________
605 void
606 AliMUONSt345SlatSegmentationV2::SetPadSize(float /*p1*/,float /*p2*/)
607 {
608 /// Not implemented
609
610   AliFatal("Not Implemented");
611 }
612
613 //_____________________________________________________________________________
614 Int_t 
615 AliMUONSt345SlatSegmentationV2::SigGenCond(Float_t /*x*/, Float_t /*y*/, Float_t /*z*/)
616 {
617 /// Not implemented
618
619   AliFatal("Not Implemented");
620   return 0;
621 }
622
623 //_____________________________________________________________________________
624 void 
625 AliMUONSt345SlatSegmentationV2::SigGenInit(Float_t,Float_t,Float_t)
626 {
627 /// Not implemented
628
629   AliFatal("Not Implemented");
630 }