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