75071763608adb4a495f9d77060a90316d053192
[u/mrichter/AliRoot.git] / MUON / AliMUONSt12QuadrantSegmentation.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 // -------------------------------------
19 // Class AliMUONSt12QuadrantSegmentation
20 // -------------------------------------
21 // Segmentation for MUON quadrants of stations 1 and 2 using 
22 // the mapping package
23 // Author: Ivana Hrivnacova, IPN Orsay
24  
25 #include <TError.h>
26 #include <TF1.h>
27 #include <TObjArray.h>
28 #include <TVector2.h>
29 #include <TSystem.h>
30
31 #include "AliLog.h"
32
33 #include "AliMpPad.h"
34 #include "AliMpArea.h"
35 #include "AliMpSectorReader.h"
36 #include "AliMpSector.h"
37 #include "AliMpVPadIterator.h"
38 #include "AliMpSectorSegmentation.h"
39 #include "AliMpFiles.h"
40 #include "AliMpNeighboursPadIterator.h"
41
42 #include "AliMUONSt12QuadrantSegmentation.h"
43 #include "AliMUONConstants.h"
44
45 /// \cond CLASSIMP
46 ClassImp(AliMUONSt12QuadrantSegmentation)
47 /// \endcond
48
49 //______________________________________________________________________________
50 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(
51                                        AliMpVSegmentation* segmentation,
52                                        AliMpStationType stationType,
53                                        AliMpPlaneType planeType) 
54 : AliMUONVGeometryDESegmentation(),
55   fStationType(stationType),
56   fPlaneType(planeType),
57   fSector(0),
58   fSectorSegmentation(0),
59   fSectorIterator(0),
60   fWireD(0),
61   fChamber(0),
62   fId(0),
63   fRmin(0.),
64   fRmax(0.),
65   fZ(0.),
66   fIx(0),
67   fIy(0),
68   fX(0.),
69   fY(0.),
70   fZone(0),
71   fXhit(0.),
72   fYhit(0.),
73   fIxt(0),
74   fIyt(0),
75   fIwt(0),
76   fXt(0.),
77   fYt(0.),
78   fCorrA(0)
79 {
80 /// Standard constructor
81
82   fSectorSegmentation = dynamic_cast<AliMpSectorSegmentation*>(segmentation);
83   if (fSectorSegmentation)
84     fSector = fSectorSegmentation->GetSector();
85   else 
86     AliFatal("Wrong mapping segmentation type");
87     
88   // Anod pitch
89   if ( stationType == kStation1 )  
90     fWireD = AliMUONConstants::PitchSt1();
91   else if ( stationType == kStation2 )   
92     fWireD = AliMUONConstants::Pitch();
93   else  
94     AliFatal("Wrong station type");
95
96   fCorrA = new TObjArray(3);
97   fCorrA->AddAt(0,0);
98   fCorrA->AddAt(0,1);
99   fCorrA->AddAt(0,2);
100
101   AliDebug(1, Form("ctor this = %p", this) ); 
102 }
103
104 //______________________________________________________________________________
105 AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation() 
106 : AliMUONVGeometryDESegmentation(),
107   fStationType(kStation1),
108   fPlaneType(kBendingPlane),
109   fSector(0),
110   fSectorSegmentation(0),
111   fSectorIterator(0),
112   fWireD(0),
113   fChamber(0),
114   fId(0),
115   fRmin(0.),
116   fRmax(0.),
117   fZ(0.),
118   fIx(0),
119   fIy(0),
120   fX(0.),
121   fY(0.),
122   fZone(0),
123   fXhit(0.),
124   fYhit(0.),
125   fIxt(0),
126   fIyt(0),
127   fIwt(0),
128   fXt(0.),
129   fYt(0.),
130   fCorrA(0) 
131 {
132 /// Default Constructor
133
134   AliDebug(1, Form("default (empty) ctor this = %p", this));
135 }
136
137 //______________________________________________________________________________
138 AliMUONSt12QuadrantSegmentation::~AliMUONSt12QuadrantSegmentation() 
139 {
140 /// Destructor
141
142   AliDebug(1, Form("dtor this = %p", this));
143
144   delete fSector;
145   delete fSectorSegmentation;  
146   delete fSectorIterator;  
147
148
149 //
150 // private methods
151 //
152
153 //______________________________________________________________________________
154 void AliMUONSt12QuadrantSegmentation::UpdateCurrentPadValues(const AliMpPad& pad)
155 {
156 /// Updates current pad values.
157
158   fIx = pad.GetIndices().GetFirst();
159   fIy = pad.GetIndices().GetSecond();
160   fX = pad.Position().X();
161   fY = pad.Position().Y();
162   fZone = fSectorSegmentation->Zone(pad);
163 }  
164
165
166 //
167 // public methods
168 //
169
170 //______________________________________________________________________________
171 void AliMUONSt12QuadrantSegmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/)
172 {
173 /// Set pad size Dx*Dy 
174
175   AliFatal("Not uniform pad size.");
176 }
177
178 //______________________________________________________________________________
179 void AliMUONSt12QuadrantSegmentation::SetDAnod(Float_t d)
180 {
181 /// Set anod pitch
182
183   fWireD = d;
184 }
185
186 #include "AliMpMotifMap.h"
187 //______________________________________________________________________________
188 Bool_t  AliMUONSt12QuadrantSegmentation::HasPad(Float_t x, Float_t y, Float_t /*z*/)
189
190 /// Returns true if a pad exists in the given position
191
192   // fSector->GetMotifMap()->Print();
193
194   AliMpPad pad = fSectorSegmentation
195                ->PadByPosition(TVector2(x,y), false);
196
197   return pad.IsValid();
198 }  
199
200
201 //______________________________________________________________________________
202 Bool_t  AliMUONSt12QuadrantSegmentation::HasPad(Int_t ix, Int_t iy)
203 {
204 /// Returns true if a pad with given indices exists
205
206   AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), false);
207
208   return pad.IsValid();
209 }  
210
211
212 //______________________________________________________________________________
213 AliMUONGeometryDirection  AliMUONSt12QuadrantSegmentation::GetDirection()
214 {
215 /// Returns the direction with a constant pad size  
216 /// (Direction or coordinate where the resolution is the best)
217
218   switch ( fSector->GetDirection() ) {
219     case kX: return kDirX;
220     case kY: return kDirY;
221     default: return kDirUndefined;
222   }  
223 }  
224
225 //______________________________________________________________________________
226 const AliMpVSegmentation*  
227 AliMUONSt12QuadrantSegmentation::GetMpSegmentation() const
228 {
229 /// Returns the mapping segmentation
230 /// (provides access to electronics info)
231
232   return fSectorSegmentation;
233 }  
234
235 //______________________________________________________________________________
236 Float_t AliMUONSt12QuadrantSegmentation::GetAnod(Float_t xhit) const
237 {
238 /// Anod wire coordinate closest to xhit
239 /// Returns for a hit position xhit the position of the nearest anode wire    
240 /// From AliMUONSegmentationV01.
241
242   Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5
243                          : Int_t(xhit/fWireD) - 0.5;
244   return fWireD*wire;
245
246 }
247
248 //______________________________________________________________________________
249 void  AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/, 
250                                       Int_t& ix, Int_t& iy)
251 {                                       
252 ///  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
253
254   GetPadI(x, y, ix, iy);
255 }
256                        
257 //______________________________________________________________________________
258 void  AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y,
259                                       Int_t& ix, Int_t& iy)
260 {                                       
261 /// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
262 /// If there is no pad, ix = 0, iy = 0 are returned.
263
264   AliMpPad pad = fSectorSegmentation->PadByPosition(TVector2(x,y), true);
265
266   ix = pad.GetIndices().GetFirst();
267   iy = pad.GetIndices().GetSecond();
268 }
269                        
270 //______________________________________________________________________________
271 void  AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy, 
272                                       Float_t& x, Float_t& y, Float_t& z)
273 {                                       
274 /// Transform from pad to real coordinates
275
276   z = fZ;
277   GetPadC(ix, iy, x , y);
278 }
279
280 //______________________________________________________________________________
281 void  AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy, 
282                                       Float_t& x, Float_t& y)
283 {                                       
284 /// Transform from pad to real coordinates
285 /// If there is no pad, x = 0., y = 0. are returned.
286
287   AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), true);
288
289   x = pad.Position().X();
290   y = pad.Position().Y();
291 }
292
293
294 //______________________________________________________________________________
295 void AliMUONSt12QuadrantSegmentation::Init(Int_t chamber)
296 {
297 /// Initialize segmentation
298
299  // find Npx, Npy and save this info
300   
301   // reference to chamber
302  fRmin=AliMUONConstants::Rmin(0);
303  fRmax=AliMUONConstants::Rmax(0);  
304  fZ = 0;
305  fId=chamber;
306 }
307  
308 //______________________________________________________________________________
309 Float_t AliMUONSt12QuadrantSegmentation::Dpx() const
310 {
311 /// Get pad size in x
312
313   AliFatal( "Not uniform pad size.");
314   return 0.;
315 }
316
317 //______________________________________________________________________________
318 Float_t AliMUONSt12QuadrantSegmentation::Dpy() const
319 {
320 /// Get pad size in y
321
322   AliFatal("Not uniform pad size.");
323   return 0.;
324 }
325  
326 //______________________________________________________________________________
327 Float_t AliMUONSt12QuadrantSegmentation::Dpx(Int_t isector) const
328 {
329 /// Pad size in x by sector
330
331   return fSectorSegmentation->PadDimensions(isector).X()*2.0;
332
333
334 //______________________________________________________________________________
335 Float_t AliMUONSt12QuadrantSegmentation::Dpy(Int_t isector) const
336 {
337 /// Pad size in x, y by Sector 
338
339   return fSectorSegmentation->PadDimensions(isector).Y()*2.0;
340 }
341
342 //______________________________________________________________________________
343 Int_t AliMUONSt12QuadrantSegmentation::Npx() const
344 {
345 /// Maximum number of Pads in x
346 /// hard coded for the time being
347
348   return fSectorSegmentation->MaxPadIndexX();
349 }
350
351 //______________________________________________________________________________
352 Int_t AliMUONSt12QuadrantSegmentation::Npy() const
353 {
354 /// Maximum number of Pads in y
355 /// hard coded for the time being
356
357   return fSectorSegmentation->MaxPadIndexY();
358 }
359
360 //______________________________________________________________________________
361 void  AliMUONSt12QuadrantSegmentation::SetPad(Int_t ix, Int_t iy)
362 {
363 /// Set pad position.
364 /// Sets virtual pad coordinates, needed for evaluating pad response 
365 /// outside the tracking program.
366 /// From AliMUONSegmentationV01.
367
368   GetPadC(ix, iy, fX, fY);
369   fZone = Sector(ix, iy);
370 }
371
372 //______________________________________________________________________________
373 void  AliMUONSt12QuadrantSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
374 {
375 /// Set hit position
376 /// Sets virtual hit position, needed for evaluating pad response 
377 /// outside the tracking program 
378 /// From AliMUONSegmentationV01.
379
380   fXhit = xhit;
381   fYhit = yhit;
382 }
383     
384 //______________________________________________________________________________
385 void  AliMUONSt12QuadrantSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, 
386                                        Float_t dx, Float_t dy) 
387 {                                        
388 /// Iterate over pads - initialiser
389
390   // Sets the current pad to that located in the hit position
391  
392   SetHit(GetAnod(xhit), yhit, 0.); 
393   
394   // Enable iterating in one dimension
395   if (dx == 0.)  dx = 0.01;
396   if (dy == 0.)  dy = 0.01;
397   
398   // Delete previous iterator
399   delete  fSectorIterator;
400   
401   fSectorIterator 
402     = fSectorSegmentation
403         ->CreateIterator(AliMpArea(TVector2(fXhit,fYhit),TVector2(dx,dy)));
404
405   AliDebug(1,Form("CreateIterator area=%e,%e +- %e,%e %s",
406                   fXhit,fYhit,dx,dy,PlaneTypeName(fPlaneType).Data()));
407   
408   fSectorIterator->First();             
409
410   if (! fSectorIterator->IsDone())
411     UpdateCurrentPadValues(fSectorIterator->CurrentItem());
412 }
413  
414 //______________________________________________________________________________
415 void  AliMUONSt12QuadrantSegmentation::NextPad()
416 {
417 /// Iterate over pads - stepper
418
419   fSectorIterator->Next();                              
420
421   if (! fSectorIterator->IsDone())
422     UpdateCurrentPadValues(fSectorIterator->CurrentItem());
423 }
424
425 //______________________________________________________________________________
426 Int_t AliMUONSt12QuadrantSegmentation::MorePads()
427 {
428 /// Iterate over pads - condition
429
430   if (fSectorIterator->IsDone())
431     return 0;
432   else
433     return 1;  
434 }
435
436 //______________________________________________________________________________
437 Float_t AliMUONSt12QuadrantSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, 
438                                                    Float_t x, Float_t y, Int_t* /*dummy*/)
439 {                                          
440 /// Returns the square of the distance between 1 pad
441 /// labelled by its channel numbers and a coordinate
442
443   AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX, iY));
444   
445   if (!pad.IsValid())
446     AliFatal("Cannot locate pad.");
447
448   return (pad.Position() - TVector2(x, y)).Mod2();
449 }
450
451 //______________________________________________________________________________
452 void AliMUONSt12QuadrantSegmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
453                                                    Int_t* /*Nparallel*/, Int_t* /*Offset*/)
454 {                                          
455 /// Number of pads read in parallel and offset to add to x 
456 /// (specific to LYON, but mandatory for display)
457
458   AliFatal( "Not yet implemented.");
459 }
460
461
462 //______________________________________________________________________________
463 void AliMUONSt12QuadrantSegmentation::Neighbours(Int_t iX, Int_t iY, 
464                                         Int_t* Nlist, 
465                                         Int_t Xlist[10], Int_t Ylist[10])
466 {                                         
467 /// Get next neighbours 
468
469   AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX,iY));
470   Int_t &i = *Nlist;
471   i=0;
472   AliMpNeighboursPadIterator iter(fSectorSegmentation, pad, kFALSE);
473
474   for( iter.First(); !iter.IsDone() && i<10; iter.Next()) {
475     Xlist[i] = iter.CurrentItem().GetIndices().GetFirst();
476     Ylist[i] = iter.CurrentItem().GetIndices().GetSecond();
477     i++;
478   }
479 }
480  
481 //______________________________________________________________________________
482 Int_t  AliMUONSt12QuadrantSegmentation::Ix()
483 {
484 /// Current pad cursor during disintegration
485 /// x, y-coordinate
486
487   return fSectorIterator->CurrentItem().GetIndices().GetFirst();
488 }
489
490 //______________________________________________________________________________
491 Int_t  AliMUONSt12QuadrantSegmentation::Iy()
492 {
493 /// Current pad cursor during disintegration
494 /// x, y-coordinate
495
496   return fSectorIterator->CurrentItem().GetIndices().GetSecond();
497 }
498
499 //______________________________________________________________________________
500 Int_t  AliMUONSt12QuadrantSegmentation::ISector()
501 {
502 /// Current sector
503
504   return fZone;
505 }
506
507 //______________________________________________________________________________
508 Int_t AliMUONSt12QuadrantSegmentation::Sector(Int_t ix, Int_t iy)
509 {
510 /// Calculate sector from pad coordinates
511
512   return fSectorSegmentation
513            ->Zone(fSectorSegmentation->PadByIndices(AliMpIntPair(ix, iy)));
514 }
515
516 //______________________________________________________________________________
517 Int_t AliMUONSt12QuadrantSegmentation::Sector(Float_t x, Float_t y)
518 {
519 /// Calculate sector from pad coordinates
520
521   return fSectorSegmentation
522            ->Zone(fSectorSegmentation
523                     ->PadByPosition(TVector2(x,y)));
524 }
525
526 //______________________________________________________________________________
527 void  AliMUONSt12QuadrantSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
528                                                 Float_t& y1, Float_t& y2)
529 {                                                 
530 /// Current integration limits 
531  
532   x1 = fXhit - fX - Dpx(fZone)/2.;
533   x2 = x1 + Dpx(fZone);
534
535   y1 = fYhit - fY - Dpy(fZone)/2.;
536   y2 = y1 + Dpy(fZone);    
537 }
538
539 //______________________________________________________________________________
540 Int_t AliMUONSt12QuadrantSegmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/)
541 {
542 /// Signal Generation Condition during Stepping
543 /// -  0: don't generate signal
544 /// -  1: generate signal 
545 ///
546 ///  Comments:                                                                  \n 
547 ///
548 ///  Crossing of pad boundary and mid plane between neighbouring wires is checked.
549 ///  To correctly simulate the dependence of the spatial resolution on the angle 
550 ///  of incidence signal must be generated for constant steps on 
551 ///  the projection of the trajectory along the anode wire.
552 ///
553 ///  Signal will be generated if particle crosses pad boundary or
554 ///  boundary between two wires. 
555 ///
556 /// From AliMUONSegmentationV01
557
558   Int_t ixt, iyt;
559   GetPadI(x, y, ixt, iyt);
560   Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1;
561   
562   if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
563     return 1;
564   } 
565   else {
566     return 0;
567   }
568 }
569
570 //______________________________________________________________________________
571 void  AliMUONSt12QuadrantSegmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/)
572 {
573 /// Initialise signal generation at coord (x,y,z)
574 /// Initialises pad and wire position during stepping.
575 /// From AliMUONSegmentationV01
576
577   fXt = x;
578   fYt = y;
579   GetPadI(x, y, fIxt, fIyt);
580   fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ;
581 }                   
582     
583 //______________________________________________________________________________
584 void AliMUONSt12QuadrantSegmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const
585 {                                             
586 /// Test points for auto calibration
587 /// Returns test point on the pad plane.
588 /// Used during determination of the segmoid correction of the COG-method
589 /// From AliMUONSegmentationV01
590
591   n=1;
592   x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.);
593   y[0] = x[0];
594 }
595
596 //______________________________________________________________________________
597 void AliMUONSt12QuadrantSegmentation::Draw(const char * /*opt*/)
598 {
599 /// Draw the segmentation zones.
600 /// (Called from AliMUON::BuildGeometry)
601
602   AliWarning("Not yet implemented.");
603 }
604
605 //______________________________________________________________________________
606 void AliMUONSt12QuadrantSegmentation::SetCorrFunc(Int_t isec, TF1* func)
607 {
608 /// Set the correction function.
609 /// From AliMUONSegmentationV01
610
611   fCorrA->AddAt(func, isec);
612 }
613
614 //______________________________________________________________________________
615 TF1* AliMUONSt12QuadrantSegmentation::CorrFunc(Int_t isec) const
616 {
617 /// Get the correction Function.
618 /// From AliMUONSegmentationV01
619
620   return (TF1*) fCorrA->At(isec);
621