2 //////////////////////////////////////////////////////////////////////////
4 // The main AliEVE drawing module for the MUON detector //
6 //////////////////////////////////////////////////////////////////////////
8 #include "EventAlieve.h"
9 #include "Reve/PointSet.h"
10 #include "Reve/RGTopFrame.h"
13 #include "AliRunLoader.h"
16 #include "AliMpDEIterator.h"
17 #include "AliMpSectorSegmentation.h"
18 #include "AliMpSector.h"
19 #include "AliMUONGeometryTransformer.h"
20 #include "AliMUONSegmentation.h"
21 #include "AliMUONSegFactory.h"
22 #include "AliMpStationType.h"
23 #include "AliMpDEManager.h"
24 #include "AliMUONConstants.h"
25 #include "AliMUONDigit.h"
26 #include "AliMUONRawCluster.h"
27 #include "AliMUONTrack.h"
28 #include "AliMUONTrackParam.h"
30 #include "MUONModule.h"
32 #include <TPolyLine3D.h>
33 #include <TMarker3DBox.h>
37 using namespace Alieve;
42 /**************************************************************************/
43 MUONModule::MUONModule(const Text_t* n, const Text_t* t, Color_t col) :
44 Reve::RenderElement(col),
49 fShowDigits(0), fShowClusters(0), fShowTracks(0),
54 // Default constructor
59 /**************************************************************************/
60 MUONModule::MUONModule(Int_t id, Int_t cath, MUONDigitsInfo* info, Bool_t dig, Bool_t clus, Color_t col ) :
61 Reve::RenderElement(col),
62 QuadSet(Form("M-DetElemId %d C%1d",id,cath)),
66 fShowDigits(dig), fShowClusters(clus), fShowTracks(0),
74 if (!fShowDigits && !fShowClusters) fShowTracks = 1;
76 if (fShowClusters) SetName(Form("M-DetElemId %d",id));
78 if (id/100 >= 11 && cath == 1) SetName(Form("M-DetElemId %d X",id));
79 if (id/100 >= 11 && cath == 2) SetName(Form("M-DetElemId %d Y",id));
80 if (id == -1 && cath == -1) SetName(Form("M-Chambers"));
81 if (id > -1 && cath == -1) SetName(Form("M-Track %d",id));
82 if (cath == -2) SetName(Form("M-Chamber %2d",id));
83 if (cath == -3) SetName(Form("M-Pads %d X",id));
84 if (cath == -4) SetName(Form("M-Pads %d Y",id));
90 /**************************************************************************/
91 MUONModule::MUONModule(const MUONModule &mmod) :
92 Reve::RenderElement(),
93 QuadSet(Form("M-DetElemId %d C%1d",mmod.fID,mmod.fCath)),
97 fShowDigits(mmod.fShowDigits),
98 fShowClusters(mmod.fShowClusters),
99 fShowTracks(mmod.fShowTracks),
100 fFrameCol(mmod.fFrameCol),
101 fDetElemId(mmod.fDetElemId)
109 /**************************************************************************/
110 MUONModule& MUONModule::operator=(const MUONModule &mmod)
113 // Assignment operator
121 fShowDigits = mmod.fShowDigits;
122 fShowClusters = mmod.fShowClusters;
123 fShowTracks = mmod.fShowTracks;
124 fFrameCol = mmod.fFrameCol;
125 fDetElemId = mmod.fDetElemId;
133 /**************************************************************************/
134 void MUONModule::SetID(Int_t id, Int_t cath)
137 // Select a single detector element id
140 static const Exc_t eH("MUOModule::SetID ");
143 throw(eH + "MUONDigitsInfo not set.");
152 /**************************************************************************/
153 void MUONModule::InitModule()
156 // Initialize and draw selected items
161 if (fShowDigits) LoadQuadsDigits();
162 if (fShowClusters) LoadQuadsClusters();
165 LoadQuadsTracks(fID);
166 } else if (fCath == -2 || fCath == -3 || fCath == -4) {
167 if (fCath == -2) LoadQuadsChambers(fID,fID);
168 if (fCath == -3) LoadQuadsChambers(fID,fID,-1,1);
169 if (fCath == -4) LoadQuadsChambers(fID,fID,-1,2);
176 /**************************************************************************/
177 void MUONModule::LoadQuadsChambers(Int_t chamber1, Int_t chamber2, Int_t id, Int_t cat)
183 //printf("Draw chambers: %d %d %d %d %d \n",chamber1,chamber2,id,cat,fCath);
187 AliRunLoader *runLoader = Alieve::Event::AssertRunLoader();
188 runLoader->LoadgAlice();
190 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
192 const AliMUONGeometryTransformer* kGeomTransformer = pMUON->GetGeometryTransformer();
193 AliMUONSegmentation* segmentation = pMUON->GetSegmentation();
194 AliMpSegFactory segFactory;
196 Float_t xg1, xg2, yg1, yg2, zg1, zg2;
198 for (fChamber = chamber1; fChamber <= chamber2; fChamber++) {
203 for ( it.First(fChamber-1); ! it.IsDone(); it.Next() ) {
205 Int_t detElemId = it.CurrentDE();
207 if (id > 0 && id != detElemId) continue;
209 //printf("Detector element ID for chamber %d (tracking): %d \n",fChamber,detElemId);
211 AliMpSectorSegmentation * seg = (AliMpSectorSegmentation *) segmentation->GetMpSegmentation(detElemId, 0);
212 const AliMpSector * sector = seg->GetSector();
214 // get sector measurements
215 TVector2 position = sector->Position();
216 TVector2 dimension = sector->Dimensions(); // half length
218 //printf("Sector position: \n"); position.Print();
219 //printf("Sector dimensions: \n"); dimension.Print();
221 Float_t xlocal1 = position.Px(); // FIXME: not really needed as it's 0 ?
222 Float_t ylocal1 = position.Py(); // FIXME: not really needed as it's 0 ?
223 Float_t xlocal2 = dimension.Px() * 2.;
224 Float_t ylocal2 = dimension.Px() * 2.;
226 //printf("Local position and dimension: xp = %f , yp = %f xd = %f yd = %f \n",xlocal1,ylocal1,xlocal2,ylocal2);
228 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
229 kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg2, yg2, zg2);
231 //printf("Global position: xpg = %f , ypg = %f zpg = %f \n",xg1,yg1,zg1);
232 //printf("Global dimension: xdg = %f , ydg = %f zdg = %f \n",xg2,yg2,zg2);
235 if (fCath != -3 && fCath != -4) {
236 fQuads.push_back(Reve::Quad(fFrameCol));
237 p = fQuads.back().vertices;
239 p[0] = xg1; p[1] = yg1; p[2] = zg1;
240 p[3] = xg1; p[4] = yg1; p[5] = zg1;
241 p[6] = xg1+xg2; p[7] = yg1; p[8] = zg1;
242 p[9] = xg1+xg2; p[10] = yg1; p[11] = zg1;
245 p[0] = zg1; p[1] = yg1; p[2] = xg1;
246 p[3] = zg1; p[4] = yg1; p[5] = xg1;
247 p[6] = zg1; p[7] = yg1; p[8] = xg1+xg2;
248 p[9] = zg1; p[10] = yg1; p[11] = xg1+xg2;
250 Float_t xprev = xg1+xg2;
253 Float_t dstep = TMath::Pi()/2.0 / (Float_t)nstep;
255 for (Int_t istep = 1; istep < (nstep+1); istep++) {
258 Float_t x = xg1 + xg2 * TMath::Cos(d);
259 Float_t y = yg1 + yg2 * TMath::Sin(d);
261 fQuads.push_back(Reve::Quad(fFrameCol));
262 p = fQuads.back().vertices;
264 p[0] = xprev; p[1] = yprev; p[2] = zg1;
265 p[3] = xprev; p[4] = yprev; p[5] = zg1;
266 p[6] = x; p[7] = y; p[8] = zg1;
267 p[9] = x; p[10] = y; p[11] = zg1;
270 p[0] = zg1; p[1] = yprev; p[2] = xprev;
271 p[3] = zg1; p[4] = yprev; p[5] = xprev;
272 p[6] = zg1; p[7] = y; p[8] = x;
273 p[9] = zg1; p[10] = y; p[11] = x;
280 fQuads.push_back(Reve::Quad(fFrameCol));
281 p = fQuads.back().vertices;
283 p[0] = xprev; p[1] = yprev; p[2] = zg1;
284 p[3] = xprev; p[4] = yprev; p[5] = zg1;
285 p[6] = xg1; p[7] = yg1; p[8] = zg1;
286 p[9] = xg1; p[10] = yg1; p[11] = zg1;
289 p[0] = zg1; p[1] = yprev; p[2] = xprev;
290 p[3] = zg1; p[4] = yprev; p[5] = xprev;
291 p[6] = zg1; p[7] = yg1; p[8] = xg1;
292 p[9] = zg1; p[10] = yg1; p[11] = xg1;
293 } // end fCath != -3 , -4
301 for ( it.First(fChamber-1); ! it.IsDone(); it.Next() ) {
303 Int_t detElemId = it.CurrentDE();
305 if (id > 0 && id != detElemId) continue;
307 //AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
309 //printf("Detector element ID for chamber %d (trigger, stationType %s): %d \n",fChamber,StationTypeName(stationType).Data(),detElemId);
311 if ( segmentation->HasDE(detElemId) ) {
312 const AliMpVSegmentation* seg1 = segmentation->GetMpSegmentation(detElemId, 0);
314 // Create mapping segmentation if old trigger segmentation
315 // (not using mapping)
316 seg1 = segFactory.CreateMpSegmentation(detElemId, 0);
320 Float_t deltax = seg1->Dimensions().X();
321 Float_t deltay = seg1->Dimensions().Y();
322 Float_t xlocal1 = -deltax;
323 Float_t ylocal1 = -deltay;
324 Float_t xlocal2 = +deltax;
325 Float_t ylocal2 = +deltay;
327 //printf("Local corners: x1 = %f , y1 = %f x2 = %f y2 = %f \n",xlocal1,ylocal1,xlocal2,ylocal2);
329 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
330 kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg2, yg2, zg2);
332 //printf("Global corner 1: xg1 = %f , yg1 = %f zg1 = %f \n",xg1,yg1,zg1);
333 //printf("Global corner 2: xg2 = %f , yg2 = %f zg2 = %f \n",xg2,yg2,zg2);
335 if (fCath != -3 && fCath != -4) {
336 fQuads.push_back(Reve::Quad(fFrameCol));
337 Float_t* p = fQuads.back().vertices;
338 // the tilting direction now known...
340 p[0] = xg1; p[1] = yg1; p[2] = zg1;
341 p[3] = xg1; p[4] = yg2; p[5] = zg1;
342 p[6] = xg2; p[7] = yg2; p[8] = zg2;
343 p[9] = xg2; p[10] = yg1; p[11] = zg2;
346 p[0] = zg1; p[1] = yg1; p[2] = xg1;
347 p[3] = zg1; p[4] = yg2; p[5] = xg1;
348 p[6] = zg2; p[7] = yg2; p[8] = xg2;
349 p[9] = zg2; p[10] = yg1; p[11] = xg2;
351 if (fCath == -3 || fCath == -4) {
352 // draw all pads in the trigger chambers
355 for (Int_t ic = 1; ic <= 2; ic++) {
357 if (ic != cat) continue;
359 const AliMpVSegmentation* seg3 = segmentation->GetMpSegmentation(detElemId, ic-1);
360 Int_t maxX = seg3->MaxPadIndexX();
361 Int_t maxY = seg3->MaxPadIndexY();
362 //printf("detElemId %d ic %d maxX %d maxY %d \n",detElemId,ic,maxX,maxY);
363 for (Int_t ix = 0; ix <= maxX; ix++) {
364 for (Int_t iy = 0; iy <= maxY; iy++) {
366 AliMpPad pad = seg3->PadByIndices(AliMpIntPair(ix,iy),kFALSE);
368 if (!pad.IsValid()) continue;
370 // get the pad position and dimensions
371 xlocal1 = pad.Position().X();
372 ylocal1 = pad.Position().Y();
373 xlocal2 = pad.Dimensions().X();
374 ylocal2 = pad.Dimensions().Y();
376 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
377 // (no transformation for pad dimensions)
382 if (ic == 1) pcolor = 5;
383 if (ic == 2) pcolor = 5;
385 fQuads.push_back(Reve::Quad());
386 fQuads.back().ColorFromIdx(pcolor);
387 Float_t* p = fQuads.back().vertices;
388 // the tilting direction now known...
390 p[0] = zg1; p[1] = yg1-yg2; p[2] = xg1-xg2;
391 p[3] = zg1; p[4] = yg1+yg2; p[5] = xg1-xg2;
392 p[6] = zg1; p[7] = yg1+yg2; p[8] = xg1+xg2;
393 p[9] = zg1; p[10] = yg1-yg2; p[11] = xg1+xg2;
398 } // end "cathode" loop
401 } // end fCath == -3 , -4
410 } // end chamber loop
414 /**************************************************************************/
415 void MUONModule::LoadQuadsDigits()
421 if (fDetElemId > 0 && fDetElemId != fID) return;
425 AliRunLoader *runLoader = Alieve::Event::AssertRunLoader();
426 runLoader->LoadgAlice();
428 AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
430 const AliMUONGeometryTransformer* kGeomTransformer = pMUON->GetGeometryTransformer();
434 /* D I S P L A Y D I G I T S */
436 // Display X-Y strips for the trigger chambers
438 Float_t adcmax = 1024; // default
439 if (fChamber<11) adcmax = 4096;
441 TClonesArray *digits;
443 digits = fInfo->GetDigits(fChamber);
444 ndigits = digits->GetEntriesFast();
448 Int_t fCathode = fCath;
450 for (Int_t id = 0; id < ndigits; id++) {
451 mdig = (AliMUONDigit*)digits->UncheckedAt(id);
452 if (mdig->Cathode() != fCathode-1) continue;
454 // get all needed parameters
455 Int_t ix=mdig->PadX();
456 Int_t iy=mdig->PadY();
457 Int_t detElemId=mdig->DetElemId();
458 Int_t charge = mdig->Signal();
459 Int_t index = Int_t(TMath::Log(charge)/(TMath::Log(adcmax)/22));
460 Int_t color = 261+index;
461 Int_t colorTrigger = 2;
462 if (color > 282) color = 282;
464 if (detElemId != fID) continue;
466 const AliMpVSegmentation* seg2 = pMUON->GetSegmentation()->GetMpSegmentation(detElemId,fCathode-1);
468 AliMpPad pad = seg2->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
470 //printf("Dig ix %d iy %d \n",ix,iy);
472 // time delay information
473 if (fChamber > 10) { // trigger chamber
475 Int_t n = mdig->Ntracks();
476 for (Int_t icharge = 0; icharge < n; icharge++) {
477 sumCharge = sumCharge+mdig->TrackCharge(icharge);
479 assert(sumCharge==mdig->Signal());
480 Int_t testCharge = sumCharge-(Int_t(sumCharge/n))*n;
481 if(sumCharge <= n || testCharge > 0) {
488 // get the pad position and dimensions
489 Float_t xlocal1 = pad.Position().X();
490 Float_t ylocal1 = pad.Position().Y();
491 Float_t xlocal2 = pad.Dimensions().X();
492 Float_t ylocal2 = pad.Dimensions().Y();
494 Float_t xg1, xg2, yg1, yg2, zg1;
496 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
497 // (no transformation for pad dimensions)
502 color = colorTrigger;
505 fQuads.push_back(Reve::Quad());
506 fQuads.back().ColorFromIdx(color);
507 Float_t* p = fQuads.back().vertices;
508 // the tilting direction now known...
510 p[0] = xg1-xg2; p[1] = yg1-yg2; p[2] = zg1;
511 p[3] = xg1-xg2; p[4] = yg1+yg2; p[5] = zg1;
512 p[6] = xg1+xg2; p[7] = yg1+yg2; p[8] = zg1;
513 p[9] = xg1+xg2; p[10] = yg1-yg2; p[11] = zg1;
516 p[0] = zg1; p[1] = yg1-yg2; p[2] = xg1-xg2;
517 p[3] = zg1; p[4] = yg1+yg2; p[5] = xg1-xg2;
518 p[6] = zg1; p[7] = yg1+yg2; p[8] = xg1+xg2;
519 p[9] = zg1; p[10] = yg1-yg2; p[11] = xg1+xg2;
522 printf("coordinates.............................. \n");
523 for (Int_t j = 0; j < 12; j++) {
525 if ((j+1)%3 == 0) printf("\n");
530 } // end loop over digits
532 LoadQuadsChambers(fChamber,fChamber,fID,fCath);
536 /**************************************************************************/
537 void MUONModule::LoadQuadsClusters()
547 LoadQuadsChambers(fChamber,fChamber,fID);
549 /* D I S P L A Y C L U S T E R S */
551 TClonesArray *clusters;
553 clusters = fInfo->GetClusters(fChamber);
554 if (clusters == 0) return;
555 nclusters = clusters->GetEntriesFast();
557 //Float_t zpos = AliMUONConstants::DefaultChamberZ(fChamber-1);
559 AliMUONRawCluster *cls;
560 for (Int_t iCls = 0; iCls < nclusters; iCls++) {
562 cls = (AliMUONRawCluster*)clusters->UncheckedAt(iCls);
564 if (cls->GetDetElemId() != fID) continue;
566 Float_t x = cls->GetX(0);
567 Float_t y = cls->GetY(0);
568 Float_t z = cls->GetZ(0);
570 Float_t dx = 1.0/2.0;
571 Float_t dy = 1.0/2.0;
572 Float_t r = TMath::Sqrt(dx*dx+dy*dy);
574 // just an empty square
575 fQuads.push_back(Reve::Quad(5));
576 Float_t* p = fQuads.back().vertices;
578 //p[0] = x-dx; p[1] = y-dy; p[2] = z;
579 //p[3] = x-dx; p[4] = y+dy; p[5] = z;
580 //p[6] = x+dx; p[7] = y+dy; p[8] = z;
581 //p[9] = x+dx; p[10] = y-dy; p[11] = z;
584 p[0] = z; p[1] = y-dy; p[2] = x-dx;
585 p[3] = z; p[4] = y+dy; p[5] = x-dx;
586 p[6] = z; p[7] = y+dy; p[8] = x+dx;
587 p[9] = z; p[10] = y-dy; p[11] = x+dx;
590 Float_t dstep = 2.0*TMath::Pi() / (Float_t)nstep;
592 for (Int_t istep = 1; istep < (nstep+1); istep++) {
595 Float_t xc = x + r * TMath::Cos(d);
596 Float_t yc = y + r * TMath::Sin(d);
598 fQuads.push_back(Reve::Quad(5));
599 Float_t* p = fQuads.back().vertices;
601 p[0] = z; p[1] = y; p[2] = x;
602 p[3] = z; p[4] = y; p[5] = x;
603 p[6] = z; p[7] = yc; p[8] = xc;
604 p[9] = z; p[10] = yc; p[11] = xc;
612 /**************************************************************************/
613 void MUONModule::LoadQuadsTracks(Int_t id)
619 /* D I S P L A Y T R A C K S */
621 TClonesArray * trackParamAtHit = 0;
622 TClonesArray *tracks;
624 tracks = fInfo->GetTracks();
625 if (tracks == 0) return;
626 ntracks = tracks->GetEntriesFast();
630 AliMUONTrack *recTrack = (AliMUONTrack*)tracks->At(id);
636 AliMUONTrackParam *trackParam = recTrack->GetTrackParamAtVertex();
637 xRec0 = trackParam->GetNonBendingCoor();
638 yRec0 = trackParam->GetBendingCoor();
639 zRec0 = trackParam->GetZ();
641 Int_t nTrackHits = recTrack->GetNTrackHits();
642 for (Int_t iHit = 0; iHit < nTrackHits; iHit++){
643 trackParamAtHit = recTrack->GetTrackParamAtHit();
644 trackParam = (AliMUONTrackParam*) trackParamAtHit->At(iHit);
645 xRec = trackParam->GetNonBendingCoor();
646 yRec = trackParam->GetBendingCoor();
647 zRec = trackParam->GetZ();
649 fQuads.push_back(Reve::Quad());
650 fQuads.back().ColorFromIdx(4);
651 p = fQuads.back().vertices;
653 p[0] = zRec0; p[1] = yRec0; p[2] = xRec0;
654 p[3] = zRec0; p[4] = yRec0; p[5] = xRec0;
655 p[6] = zRec; p[7] = yRec; p[8] = xRec;
656 p[9] = zRec; p[10] = yRec; p[11] = xRec;
662 } // end loop rec. hits