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