Line data Source code
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 : // $MpId: AliMpSlat.cxx,v 1.6 2006/05/24 13:58:50 ivana Exp $
18 :
19 : #include "AliMpSlat.h"
20 :
21 : #include "AliMpExMapIterator.h"
22 : #include "AliLog.h"
23 : #include "AliMpMotifPosition.h"
24 : #include "AliMpPCB.h"
25 :
26 : #include "Riostream.h"
27 :
28 : #include "TArrayI.h"
29 :
30 : #include <cassert>
31 :
32 : //-----------------------------------------------------------------------------
33 : /// Representation of a slat cathode (bending or non-bending).
34 : ///
35 : /// A slat can be viewed as a "collection" of PCBs of various densities
36 : /// (the density is defined by the size of the pads composing the PCB).
37 : ///
38 : /// All the PCBs have a least the same height, if not the same width. In most
39 : /// of the case, height=width=40 cm, at least for St345 (for trigger,
40 : /// width varies)
41 : //
42 : /// \author Laurent Aphecetche
43 : //-----------------------------------------------------------------------------
44 :
45 : using std::cout;
46 : using std::endl;
47 : /// \cond CLASSIMP
48 18 : ClassImp(AliMpSlat)
49 : /// \endcond
50 :
51 : //_____________________________________________________________________________
52 : AliMpSlat::AliMpSlat(TRootIOCtor* ioCtor)
53 0 : : TObject(),
54 0 : fId(""),
55 0 : fPlaneType(AliMp::kNonBendingPlane),
56 0 : fDX(0),
57 0 : fDY(0),
58 0 : fNofPadsX(0),
59 0 : fMaxNofPadsY(0),
60 0 : fManuMap(ioCtor),
61 0 : fPCBs(),
62 0 : fPositionX(0.),
63 0 : fPositionY(0.),
64 0 : fNofPads(0)
65 0 : {
66 : ///
67 : /// Empty ctor.
68 : ///
69 0 : AliDebug(1,Form("this=%p Empty ctor",this));
70 :
71 0 : fPCBs.SetOwner(kTRUE);
72 0 : fManuMap.SetOwner(kFALSE);
73 0 : }
74 :
75 : //_____________________________________________________________________________
76 : AliMpSlat::AliMpSlat(const char* id, AliMp::PlaneType bendingOrNonBending)
77 858 : : TObject(),
78 858 : fId(id),
79 858 : fPlaneType(bendingOrNonBending),
80 858 : fDX(0),
81 858 : fDY(0),
82 858 : fNofPadsX(0),
83 858 : fMaxNofPadsY(0),
84 858 : fManuMap(),
85 858 : fPCBs(),
86 858 : fPositionX(0.),
87 858 : fPositionY(0.),
88 858 : fNofPads(0)
89 4290 : {
90 : ///
91 : /// Normal ctor
92 : ///
93 4290 : AliDebug(1,Form("this=%p id=%s",this,id));
94 :
95 858 : fPCBs.SetOwner(kTRUE);
96 858 : fManuMap.SetOwner(kFALSE);
97 1716 : }
98 :
99 : //_____________________________________________________________________________
100 : AliMpSlat::~AliMpSlat()
101 3432 : {
102 : ///
103 : /// Dtor.
104 : ///
105 2860 : AliDebug(1,Form("this=%p fId=%s",this,fId.Data()));
106 :
107 572 : fPCBs.Delete();
108 1716 : }
109 :
110 : //_____________________________________________________________________________
111 : void
112 : AliMpSlat::Add(const AliMpPCB& pcbType, const TArrayI& manuList)
113 : {
114 : ///
115 : /// Adds a PCB to this slat. The manuList specifies the ids of the manu
116 : /// that compose the PCB. The manuList ordering is important, as the
117 : /// assumption is that it's ordered counter-clockwise, starting from
118 : /// the lower-left of the PCB.
119 : ///
120 : Int_t ixOffset = 0;
121 9552 : if ( GetSize() )
122 : {
123 3918 : ixOffset = GetPCB(GetSize()-1)->Ixmax()+1;
124 3918 : }
125 : else
126 : {
127 858 : ixOffset = pcbType.Ixmin();
128 : }
129 4776 : Double_t xOffset = DX()*2;
130 4776 : AliMpPCB* pcb = pcbType.Clone(manuList,ixOffset,xOffset);
131 4776 : fPCBs.AddLast(pcb);
132 4776 : fDY = TMath::Max(pcb->DY(),fDY);
133 4776 : fDX += pcb->DX();
134 4776 : fNofPadsX += pcb->GetNofPadsX();
135 4776 : fMaxNofPadsY = TMath::Max(fMaxNofPadsY,pcb->GetNofPadsY());
136 : Int_t n(0);
137 29010 : for ( Int_t i = 0; i < pcb->GetSize(); ++i )
138 : {
139 9729 : AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
140 9729 : Int_t manuID = mp->GetID();
141 : // Before inserting a new key, check if it's already there
142 9729 : TObject* there = fManuMap.GetValue(manuID);
143 9729 : if ( there == 0 )
144 : {
145 9729 : ++n;
146 29187 : AliDebug(1,Form("Adding %d-th manuId=%d (%d) to ManuMap (size=%d)",n,manuID,mp->GetID(),fManuMap.GetSize()));
147 9729 : fManuMap.Add(manuID,(TObject*)mp);
148 9729 : }
149 : else
150 : {
151 0 : AliError(Form("ManuID %d is duplicated for PCB %s",manuID,pcbType.GetID()));
152 : }
153 : }
154 4776 : fPositionX = DX();
155 4776 : fPositionY = DY();
156 4776 : fNofPads += pcb->NofPads();
157 4776 : }
158 :
159 : //_____________________________________________________________________________
160 : Double_t
161 : AliMpSlat::DX() const
162 : {
163 : ///
164 : /// Returns the x-half-size of the slat.
165 : ///
166 23264 : return fDX;
167 : }
168 :
169 : //_____________________________________________________________________________
170 : Double_t
171 : AliMpSlat::DY() const
172 : {
173 : ///
174 : /// Returns the y-half-size of the slat.
175 : ///
176 13712 : return fDY;
177 : }
178 :
179 : //_____________________________________________________________________________
180 : AliMpMotifPosition*
181 : AliMpSlat::FindMotifPosition(Int_t manuID) const
182 : {
183 : ///
184 : /// Returns the motifPosition referenced by it manuID
185 : ///
186 1886430 : return static_cast<AliMpMotifPosition*>(fManuMap.GetValue(manuID));
187 : }
188 :
189 : //_____________________________________________________________________________
190 : AliMpMotifPosition*
191 : AliMpSlat::FindMotifPosition(Int_t ix, Int_t iy) const
192 : {
193 : ///
194 : /// - 1. Find the PCB containing ix (iy not needed for this)
195 : /// - 2. Forward the request to the PCB, using pcb local indices.
196 : //
197 1849244 : const AliMpPCB* pcb = FindPCB(ix);
198 924622 : if ( pcb )
199 : {
200 811188 : return pcb->FindMotifPosition(ix,iy);
201 : }
202 : else
203 : {
204 113434 : return 0;
205 : }
206 924622 : }
207 :
208 : //_____________________________________________________________________________
209 : AliMpMotifPosition*
210 : AliMpSlat::FindMotifPosition(Double_t x, Double_t y) const
211 : {
212 : ///
213 : /// Returns the motifPosition containing position (x,y)
214 : ///
215 1814 : const AliMpPCB* pcb = FindPCB(x,y);
216 907 : if (pcb)
217 : {
218 905 : return pcb->FindMotifPosition(x,y);
219 : }
220 : else
221 : {
222 2 : return 0;
223 : }
224 907 : }
225 :
226 : //_____________________________________________________________________________
227 : AliMpPCB*
228 : AliMpSlat::FindPCB(Int_t ix) const
229 : {
230 : ///
231 : /// Returns the PCB containing x-integer-position ix
232 : ///
233 7270010 : for ( Int_t i = 0; i < GetSize(); ++i )
234 : {
235 3002543 : AliMpPCB* pcb = GetPCB(i);
236 5981278 : if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
237 : {
238 811188 : return pcb;
239 : }
240 2191355 : }
241 113434 : return 0;
242 924622 : }
243 :
244 : //_____________________________________________________________________________
245 : Int_t
246 : AliMpSlat::FindPCBIndex(Int_t ix) const
247 : {
248 : ///
249 : /// Returns the index of the PCB containing x-integer-position ix.
250 : ///
251 0 : for ( Int_t i = 0; i < GetSize(); ++i )
252 : {
253 0 : AliMpPCB* pcb = GetPCB(i);
254 0 : if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
255 : {
256 0 : return i;
257 : }
258 0 : }
259 0 : return -1;
260 0 : }
261 :
262 : //_____________________________________________________________________________
263 : AliMpPCB*
264 : AliMpSlat::FindPCB(Double_t x, Double_t y) const
265 : {
266 : ///
267 : /// Returns the PCB containing position (x,y)
268 : ///
269 8289 : for ( Int_t i = 0; i < GetSize(); ++i )
270 : {
271 3578 : AliMpPCB* pcb = GetPCB(i);
272 : // if ( x >= pcb->Xmin() && x < pcb->Xmax() &&
273 : // y >= pcb->Ymin() && y < pcb->Ymax() )
274 : // {
275 : // return pcb;
276 : // }
277 8279 : if ( x < pcb->Xmin() || x >= pcb->Xmax() ||
278 2252 : y < pcb->Ymin() || y >= pcb->Ymax() )
279 : {
280 2453 : continue;
281 : }
282 1125 : return pcb;
283 : }
284 2 : return 0;
285 1127 : }
286 :
287 : //_____________________________________________________________________________
288 : Int_t
289 : AliMpSlat::FindPCBIndex(Double_t x, Double_t y) const
290 : {
291 : ///
292 : /// Returns the index of the PCB containing position (x,y)
293 : ///
294 0 : for ( Int_t i = 0; i < GetSize(); ++i )
295 : {
296 0 : AliMpPCB* pcb = GetPCB(i);
297 0 : if ( x >= pcb->Xmin() && x < pcb->Xmax() &&
298 0 : y >= pcb->Ymin() && y < pcb->Ymax() )
299 : {
300 0 : return i;
301 : }
302 0 : }
303 0 : return -1;
304 0 : }
305 :
306 : //_____________________________________________________________________________
307 : Int_t
308 : AliMpSlat::FindPCBIndexByMotifPositionID(Int_t manuId) const
309 : {
310 : /// Find the index of the PCB containing a given manu
311 322636 : for ( Int_t i = 0; i< GetSize(); ++i )
312 : {
313 136528 : AliMpPCB* pcb = GetPCB(i);
314 186108 : if ( pcb->HasMotifPositionID(manuId) ) return i;
315 86948 : }
316 0 : return -1;
317 49580 : }
318 :
319 : //_____________________________________________________________________________
320 : void
321 : AliMpSlat::ForcePosition(Double_t x, Double_t y)
322 : {
323 : ///
324 : /// Force the position to be different from (DX(),DY()).
325 : /// Normally only used by triggerSlats (for layers).
326 : /// Beware that this method must be called once all PCB have been added,
327 : /// as the Add() method resets the position.
328 : ///
329 0 : fPositionX = x;
330 0 : fPositionY = y;
331 0 : }
332 :
333 : //_____________________________________________________________________________
334 : void
335 : AliMpSlat::GetAllMotifPositionsIDs(TArrayI& ecn) const
336 : {
337 : ///
338 : /// Return all the manuIds (=MotifPositionIDs) of this slat
339 : ///
340 5268 : Int_t nofElectronicCards(GetNofElectronicCards());
341 2634 : assert(nofElectronicCards>0);
342 2634 : ecn.Set(nofElectronicCards);
343 2634 : TIter next(fManuMap.CreateIterator());
344 : AliMpMotifPosition* mp;
345 : Int_t n(0);
346 281493 : while ( ( mp = static_cast<AliMpMotifPosition*>(next()) ) )
347 : {
348 91197 : ecn.AddAt(mp->GetID(),n);
349 91197 : ++n;
350 : }
351 2634 : assert(n==nofElectronicCards);
352 2634 : }
353 :
354 : //_____________________________________________________________________________
355 : const char*
356 : AliMpSlat::GetID() const
357 : {
358 : ///
359 : /// Returns the name of this slat.
360 : ///
361 0 : return fId.Data();
362 : }
363 :
364 : //_____________________________________________________________________________
365 : Int_t
366 : AliMpSlat::GetMaxNofPadsY() const
367 : {
368 : ///
369 : /// Returns the maximum number of pads to be found in this slat y-direction.
370 : ///
371 3728 : return fMaxNofPadsY;
372 : }
373 :
374 : //_____________________________________________________________________________
375 : Int_t
376 : AliMpSlat::GetMaxPadIndexX() const
377 : {
378 : ///
379 : /// Returns the max ix that is valid for this slat.
380 : ///
381 2240 : AliMpPCB* last = GetPCB(GetSize()-1);
382 1120 : if (last)
383 : {
384 1120 : return last->Ixmax();
385 : }
386 0 : return 0;
387 1120 : }
388 :
389 : //_____________________________________________________________________________
390 : const char*
391 : AliMpSlat::GetName() const
392 : {
393 : ///
394 : /// Returns the name of this slat, which is composed of its ID with
395 : /// the plane type as a suffix.
396 : ///
397 0 : TString name(GetID());
398 0 : if ( fPlaneType == AliMp::kBendingPlane )
399 : {
400 0 : name += ".Bending";
401 : }
402 0 : else if ( fPlaneType == AliMp::kNonBendingPlane )
403 : {
404 0 : name += ".NonBending";
405 : }
406 : else
407 : {
408 0 : name += ".Invalid";
409 : }
410 0 : return name.Data();
411 0 : }
412 :
413 : //_____________________________________________________________________________
414 : Int_t
415 : AliMpSlat::GetNofElectronicCards() const
416 : {
417 : ///
418 : /// Returns the number of manus that compose the readout of this slat.
419 : ///
420 5268 : return fManuMap.GetSize();
421 : }
422 :
423 : //_____________________________________________________________________________
424 : Int_t
425 : AliMpSlat::GetNofPadsX() const
426 : {
427 : ///
428 : /// Returns the number of pad in x-direction.
429 : ///
430 39936 : return fNofPadsX;
431 : }
432 :
433 : //_____________________________________________________________________________
434 : AliMpPCB*
435 : AliMpSlat::GetPCB(Int_t i) const
436 : {
437 : ///
438 : /// Returns the i-th PCB of this slat.
439 : ///
440 6355818 : if ( i >= fPCBs.GetEntriesFast() ) return 0;
441 3177909 : return (AliMpPCB*)fPCBs[i];
442 3177909 : }
443 :
444 : //_____________________________________________________________________________
445 : Int_t
446 : AliMpSlat::GetSize() const
447 : {
448 : ///
449 : /// Returns the number of PCB in this slat.
450 : ///
451 6535422 : return fPCBs.GetEntriesFast();
452 : }
453 :
454 : //_____________________________________________________________________________
455 : void
456 : AliMpSlat::Print(Option_t* option) const
457 : {
458 : ///
459 : /// Prints the slat characteristics.
460 : ///
461 0 : cout << "SLAT " << GetID() << " 1/2 DIM = (" << DX() << "," << DY() << ")"
462 0 : << " POS = " << GetPositionX() << "," << GetPositionY()
463 0 : << " NPADSX = " << GetNofPadsX()
464 0 : << " MAXNPADSY = " << GetMaxNofPadsY()
465 0 : << " NPCBs=" << GetSize() << endl;
466 :
467 0 : TString soption(option);
468 :
469 0 : if ( soption.Contains("P") )
470 : {
471 0 : for ( Int_t i = 0; i < GetSize() ; ++i )
472 : {
473 0 : cout << " ";
474 0 : if ( option )
475 : {
476 0 : fPCBs[i]->Print(option+1);
477 : }
478 : else
479 : {
480 0 : fPCBs[i]->Print();
481 : }
482 : }
483 0 : }
484 :
485 0 : if ( soption.Contains("M") || soption.Contains("L") )
486 : {
487 0 : cout << fManuMap.GetSize() << " ";
488 0 : cout << "Electronic card (manu or local board) Ids : ";
489 0 : TIter next(fManuMap.CreateIterator());
490 : AliMpMotifPosition* mp;
491 0 : while ( ( mp = static_cast<AliMpMotifPosition*>(next())) )
492 : {
493 0 : cout << mp->GetID() << " ";
494 : }
495 0 : cout << endl;
496 0 : }
497 0 : }
|