ROOT logo
// $Id$

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/

/// \ingroup evemacros
/// \file esd_muon_tracks.C
/// \brief Macro to visualise ESD tracks from MUON spectrometer 
/// (both tracker and trigger).
///
/// Use esd_muon_tracks(Bool_t showClusters, Bool_t showDigits) in order to run it
///
/// Needs that alieve_init() is already called
///
/// \author P. Pillot, L. Aphecetche; Subatech

#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TStyle.h>
#include <TROOT.h>
#include <TEveManager.h>
#include <TEveUtil.h>
#include <TEveTrack.h>
#include <TEvePointSet.h>
#include <TEveQuadSet.h>
#include <TEveTrackPropagator.h>
#include <TEveVSDStructs.h>

#include <AliMUONESDInterface.h>
#include <AliMUONTrack.h>
#include <AliMUONTrackExtrap.h>
#include <AliMUONTrackParam.h>
#include <AliMUONConstants.h>
#include <AliMUONCDB.h>
#include <AliMUONGeometryTransformer.h>
#include <AliMUONTriggerCircuit.h>
#include <AliMpCDB.h>
#include <AliESDEvent.h>
#include <AliESDMuonTrack.h>
#include <AliEveMagField.h>
#include <AliEveTrack.h>
#include <AliEveEventManager.h>
#endif

//______________________________________________________________________________
void esd_muon_track_propagator_setup(TEveTrackPropagator* trkProp, Bool_t tracker, Bool_t trigger)
{
  // set magnetic field
  if (AliMUONTrackExtrap::IsFieldON())
  {
    trkProp->SetMagFieldObj(new AliEveMagField);
  }
  else
  {
    trkProp->SetMagField(0.0);
  }
  trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
  
  // set propagation range
  trkProp->SetMaxR(1000);
  if (trigger) trkProp->SetMaxZ(-AliMUONConstants::DefaultChamberZ(13)+10.);
  else trkProp->SetMaxZ(-AliMUONConstants::MuonFilterZBeg());
  
  // go through pathmarks
  trkProp->SetFitDaughters(kFALSE);
  trkProp->SetFitReferences(kTRUE);
  trkProp->SetFitDecay(kFALSE);
  trkProp->SetFitCluster2Ds(kFALSE);
  
  // Render the ref pathmarks
  trkProp->SetRnrReferences(kTRUE);
  trkProp->RefPMAtt().SetMarkerSize(0.5);
  if (trigger) trkProp->RefPMAtt().SetMarkerColor(kGreen);
  else trkProp->RefPMAtt().SetMarkerColor(kAzure);
  
  // Render first vertex
  if (tracker)
  {
    trkProp->SetRnrFV(kTRUE);
    if (trigger) trkProp->RefFVAtt().SetMarkerColor(kGreen);
    else trkProp->RefFVAtt().SetMarkerColor(kAzure);
  }
}

//______________________________________________________________________________
void add_esd_muon_tracks(AliESDEvent* esd, AliMUONESDInterface* data,
			 TEveTrackList* match, TEveTrackList* nomatch, TEveTrackList* ghost)
{
  // load trigger circuit
  static AliMUONTriggerCircuit* gTriggerCircuit = 0x0;
  if (!gTriggerCircuit) 
  {
    AliEveEventManager::AssertGeometry();
    AliMUONGeometryTransformer* fMUONGeometryTransformer = new AliMUONGeometryTransformer();
    fMUONGeometryTransformer->LoadGeometryData();
    gTriggerCircuit = new AliMUONTriggerCircuit(fMUONGeometryTransformer);
  }
  
  Int_t nTrack(esd->GetNumberOfMuonTracks());
  TEveRecTrack recTrack;
  TEveTrack* track;
  
  // add ESD tracks to the proper list
  for (Int_t n = 0; n < nTrack; ++n)
  {
    AliESDMuonTrack* emt = esd->GetMuonTrack(n);
    
    // fill general info
    UInt_t trackId = emt->GetUniqueID();
    recTrack.fLabel = emt->GetLabel();
    recTrack.fIndex = (Int_t)trackId;
    
    // fill tracker track specific info
    if ( emt->ContainTrackerData() )
    {
      recTrack.fStatus = emt->GetMatchTrigger();
      recTrack.fSign = emt->Charge();
      recTrack.fV.Set(emt->GetNonBendingCoorAtDCA(),emt->GetBendingCoorAtDCA(),emt->GetZ());
      recTrack.fP.Set(emt->PxAtDCA(),emt->PyAtDCA(),emt->PzAtDCA());
      recTrack.fBeta = ( emt->E() > 0 ) ? emt->P()/emt->E() : 0;
      
      // get proper track list
      TEveTrackList* trackList = nomatch;
      if ( emt->GetMatchTrigger() > 0 ) trackList = match;
      
      // produce eve track
      track = new AliEveTrack(&recTrack,trackList->GetPropagator());
      track->SetName(Form("%cmu",emt->Charge()>0 ? '+':'-'));
      track->SetStdTitle();
      track->SetSourceObject(emt); // WARNING: Change the UniqueID of the object!!
      
      // add path mark
      TIter next(data->FindTrack(trackId)->GetTrackParamAtCluster());
      AliMUONTrackParam* param;
      while ( ( param = static_cast<AliMUONTrackParam*>(next()) ) )
      {
	TEveVector v(param->GetNonBendingCoor(),param->GetBendingCoor(),param->GetZ());
	TEveVector p(param->Px(),param->Py(),param->Pz());
	track->AddPathMark(TEvePathMark(TEvePathMark::kReference,v,p));
      }
      
      // add trigger track if any
      if (emt->ContainTriggerData())
      {
	Double_t x11 = gTriggerCircuit->GetX11Pos(emt->LoCircuit(), emt->LoStripY());
	Double_t y11 = gTriggerCircuit->GetY11Pos(emt->LoCircuit(), emt->LoStripX());
	Double_t z11 = gTriggerCircuit->GetZ11Pos(emt->LoCircuit(), emt->LoStripX());
	Double_t y21 = gTriggerCircuit->GetY21Pos(emt->LoCircuit(), emt->LoStripX()+emt->LoDev()+1);
	Double_t z21 = gTriggerCircuit->GetZ21Pos(emt->LoCircuit(), emt->LoStripX()+emt->LoDev()+1);
	Double_t pz  = -emt->PUncorrected(); // max value
	TEveVector v(x11, y11, z11);
	TEveVector p(pz*x11/z11, pz*(y21-y11)/(z21-z11), pz);
	track->AddPathMark(TEvePathMark(TEvePathMark::kReference,v,p));
      }
      
      // add the track to proper list
      track->SetAttLineAttMarker(trackList);
      trackList->AddElement(track);
    }
    else // fill ghost track specific info
    {
      recTrack.fStatus = 0;
      recTrack.fSign = emt->Charge();
      Double_t z11 = (emt->GetZUncorrected() < -1.) ? emt->GetZUncorrected() : (Double_t)AliMUONConstants::DefaultChamberZ(10);
      recTrack.fV.Set(emt->GetNonBendingCoorUncorrected(),emt->GetBendingCoorUncorrected(),z11);
      recTrack.fP.Set(-TMath::Tan(emt->GetThetaXUncorrected()),-TMath::Tan(emt->GetThetaYUncorrected()),-1.);
      
      // produce eve track
      track = new AliEveTrack(&recTrack,ghost->GetPropagator());
      track->SetName("mu");
      track->SetTitle("Trigger only");
      track->SetSourceObject(emt);
      
      // add the track to proper list
      track->SetAttLineAttMarker(ghost);
      ghost->AddElement(track);
    }
    
  }
  
}

//______________________________________________________________________________
void esd_muon_tracks(Bool_t showClusters, Bool_t showDigits)
{
  // load ESD
  AliESDEvent* esd = AliEveEventManager::AssertESD();
  if (esd->GetNumberOfMuonTracks() == 0 && !gEve->GetKeepEmptyCont()) return;
  
  // load field
  AliEveEventManager::AssertMagField();
  if (!AliMUONESDInterface::GetTracker()) AliMUONESDInterface::ResetTracker(AliMUONCDB::LoadRecoParam());
  
  // load mapping
  AliMpCDB::LoadAll(kFALSE);
  
  // convert ESD objects to MUON objects
  AliMUONESDInterface data;
  data.LoadEvent(*esd);
  
  // track containers
  TEveElementList* trackCont = new TEveElementList("ESD MUON Tracks");
  trackCont->SetTitle(Form("N=%d", esd->GetNumberOfMuonTracks()));
  
  TEveTrackList* match = new TEveTrackList("Matched");
  match->SetRnrPoints(kFALSE);
  match->SetRnrLine(kTRUE);
  match->SetLineColor(kGreen);
  esd_muon_track_propagator_setup(match->GetPropagator(), kTRUE, kTRUE);
  trackCont->AddElement(match);
  
  TEveTrackList* nomatch = new TEveTrackList("Not matched");
  nomatch->SetRnrPoints(kFALSE);
  nomatch->SetRnrLine(kTRUE);
  nomatch->SetLineColor(kAzure);
  esd_muon_track_propagator_setup(nomatch->GetPropagator(), kTRUE, kFALSE);
  trackCont->AddElement(nomatch);
  
  TEveTrackList* ghost = new TEveTrackList("Ghost");
  ghost->SetRnrPoints(kFALSE);
  ghost->SetRnrLine(kTRUE);
  ghost->SetLineColor(kAzure);
  esd_muon_track_propagator_setup(ghost->GetPropagator(), kFALSE, kTRUE);
  trackCont->AddElement(ghost);
  
  // cluster container
  TEvePointSet* clusterList = 0x0;
  if (showClusters && (data.GetNClusters() > 0 || gEve->GetKeepEmptyCont()))
  {
    clusterList = new TEvePointSet(10000);
    clusterList->SetName("ESD MUON Clusters");
    clusterList->SetTitle(Form("N=%d",data.GetNClusters()));
    clusterList->SetPickable(kFALSE);
    clusterList->SetMarkerStyle(5);
    clusterList->SetMarkerColor(kYellow);
    clusterList->SetMarkerSize(2.5);
  }

  // digit containers
  TEveElementList* digitCont = 0x0;
  TEveQuadSet* bending = 0x0;
  TEveQuadSet* nonBending = 0x0;
  if (showDigits && (data.GetNDigits() > 0 || gEve->GetKeepEmptyCont()))
  {
    digitCont = new TEveElementList("ESD MUON Digits");
    digitCont->SetTitle(Form("N=%d",data.GetNDigits()));
    
    bending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
    bending->SetName("Bending");
    bending->SetRenderMode(TEveDigitSet::kRM_Fill);
    bending->SetPickable(kFALSE);
    digitCont->AddElement(bending);
    
    nonBending = new TEveQuadSet(TEveQuadSet::kQT_RectangleXY, kFALSE, 32);
    nonBending->SetName("Non bending");
    nonBending->SetRenderMode(TEveDigitSet::kRM_Line);
    nonBending->SetPickable(kFALSE);
    digitCont->AddElement(nonBending);
  }
  
  // add tracks to the proper list and propagate them
  add_esd_muon_tracks(esd, &data, match, nomatch, ghost);
  match->SetTitle(Form("N=%d",match->NumChildren()));
  nomatch->SetTitle(Form("N=%d",nomatch->NumChildren()));
  ghost->SetTitle(Form("N=%d",ghost->NumChildren()));
  match->MakeTracks();
  nomatch->MakeTracks();
  ghost->MakeTracks();
  
  // add cluster to the container
  if (clusterList)
  {
    TEveUtil::LoadMacro("muon_clusters.C+");
    TIter next(data.CreateClusterIterator());
    gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, clusterList));
  }
  
  // add digits to the containers
  if (digitCont)
  {
    TEveUtil::LoadMacro("muon_digits.C+");
    TIter next(data.CreateDigitIterator());
    gROOT->ProcessLine(Form("add_muon_digits((TIter*)%p, (TEveQuadSet*)%p, (TEveQuadSet*)%p, kFALSE);",
			    &next, bending, nonBending));
    
    // set containers' title
    bending->SetTitle(Form("N=%d",bending->GetPlex()->Size()));
    nonBending->SetTitle(Form("N=%d",nonBending->GetPlex()->Size()));
    
    // automatic scaling
    gStyle->SetPalette(1);
    bending->AssertPalette();
    nonBending->AssertPalette();
  }
  
  // add graphic containers
  gEve->DisableRedraw();
  gEve->AddElement(trackCont);
  if (clusterList) gEve->AddElement(clusterList);
  if (digitCont) gEve->AddElement(digitCont);
  gEve->EnableRedraw();
  gEve->Redraw3D();
}
 esd_muon_tracks.C:1
 esd_muon_tracks.C:2
 esd_muon_tracks.C:3
 esd_muon_tracks.C:4
 esd_muon_tracks.C:5
 esd_muon_tracks.C:6
 esd_muon_tracks.C:7
 esd_muon_tracks.C:8
 esd_muon_tracks.C:9
 esd_muon_tracks.C:10
 esd_muon_tracks.C:11
 esd_muon_tracks.C:12
 esd_muon_tracks.C:13
 esd_muon_tracks.C:14
 esd_muon_tracks.C:15
 esd_muon_tracks.C:16
 esd_muon_tracks.C:17
 esd_muon_tracks.C:18
 esd_muon_tracks.C:19
 esd_muon_tracks.C:20
 esd_muon_tracks.C:21
 esd_muon_tracks.C:22
 esd_muon_tracks.C:23
 esd_muon_tracks.C:24
 esd_muon_tracks.C:25
 esd_muon_tracks.C:26
 esd_muon_tracks.C:27
 esd_muon_tracks.C:28
 esd_muon_tracks.C:29
 esd_muon_tracks.C:30
 esd_muon_tracks.C:31
 esd_muon_tracks.C:32
 esd_muon_tracks.C:33
 esd_muon_tracks.C:34
 esd_muon_tracks.C:35
 esd_muon_tracks.C:36
 esd_muon_tracks.C:37
 esd_muon_tracks.C:38
 esd_muon_tracks.C:39
 esd_muon_tracks.C:40
 esd_muon_tracks.C:41
 esd_muon_tracks.C:42
 esd_muon_tracks.C:43
 esd_muon_tracks.C:44
 esd_muon_tracks.C:45
 esd_muon_tracks.C:46
 esd_muon_tracks.C:47
 esd_muon_tracks.C:48
 esd_muon_tracks.C:49
 esd_muon_tracks.C:50
 esd_muon_tracks.C:51
 esd_muon_tracks.C:52
 esd_muon_tracks.C:53
 esd_muon_tracks.C:54
 esd_muon_tracks.C:55
 esd_muon_tracks.C:56
 esd_muon_tracks.C:57
 esd_muon_tracks.C:58
 esd_muon_tracks.C:59
 esd_muon_tracks.C:60
 esd_muon_tracks.C:61
 esd_muon_tracks.C:62
 esd_muon_tracks.C:63
 esd_muon_tracks.C:64
 esd_muon_tracks.C:65
 esd_muon_tracks.C:66
 esd_muon_tracks.C:67
 esd_muon_tracks.C:68
 esd_muon_tracks.C:69
 esd_muon_tracks.C:70
 esd_muon_tracks.C:71
 esd_muon_tracks.C:72
 esd_muon_tracks.C:73
 esd_muon_tracks.C:74
 esd_muon_tracks.C:75
 esd_muon_tracks.C:76
 esd_muon_tracks.C:77
 esd_muon_tracks.C:78
 esd_muon_tracks.C:79
 esd_muon_tracks.C:80
 esd_muon_tracks.C:81
 esd_muon_tracks.C:82
 esd_muon_tracks.C:83
 esd_muon_tracks.C:84
 esd_muon_tracks.C:85
 esd_muon_tracks.C:86
 esd_muon_tracks.C:87
 esd_muon_tracks.C:88
 esd_muon_tracks.C:89
 esd_muon_tracks.C:90
 esd_muon_tracks.C:91
 esd_muon_tracks.C:92
 esd_muon_tracks.C:93
 esd_muon_tracks.C:94
 esd_muon_tracks.C:95
 esd_muon_tracks.C:96
 esd_muon_tracks.C:97
 esd_muon_tracks.C:98
 esd_muon_tracks.C:99
 esd_muon_tracks.C:100
 esd_muon_tracks.C:101
 esd_muon_tracks.C:102
 esd_muon_tracks.C:103
 esd_muon_tracks.C:104
 esd_muon_tracks.C:105
 esd_muon_tracks.C:106
 esd_muon_tracks.C:107
 esd_muon_tracks.C:108
 esd_muon_tracks.C:109
 esd_muon_tracks.C:110
 esd_muon_tracks.C:111
 esd_muon_tracks.C:112
 esd_muon_tracks.C:113
 esd_muon_tracks.C:114
 esd_muon_tracks.C:115
 esd_muon_tracks.C:116
 esd_muon_tracks.C:117
 esd_muon_tracks.C:118
 esd_muon_tracks.C:119
 esd_muon_tracks.C:120
 esd_muon_tracks.C:121
 esd_muon_tracks.C:122
 esd_muon_tracks.C:123
 esd_muon_tracks.C:124
 esd_muon_tracks.C:125
 esd_muon_tracks.C:126
 esd_muon_tracks.C:127
 esd_muon_tracks.C:128
 esd_muon_tracks.C:129
 esd_muon_tracks.C:130
 esd_muon_tracks.C:131
 esd_muon_tracks.C:132
 esd_muon_tracks.C:133
 esd_muon_tracks.C:134
 esd_muon_tracks.C:135
 esd_muon_tracks.C:136
 esd_muon_tracks.C:137
 esd_muon_tracks.C:138
 esd_muon_tracks.C:139
 esd_muon_tracks.C:140
 esd_muon_tracks.C:141
 esd_muon_tracks.C:142
 esd_muon_tracks.C:143
 esd_muon_tracks.C:144
 esd_muon_tracks.C:145
 esd_muon_tracks.C:146
 esd_muon_tracks.C:147
 esd_muon_tracks.C:148
 esd_muon_tracks.C:149
 esd_muon_tracks.C:150
 esd_muon_tracks.C:151
 esd_muon_tracks.C:152
 esd_muon_tracks.C:153
 esd_muon_tracks.C:154
 esd_muon_tracks.C:155
 esd_muon_tracks.C:156
 esd_muon_tracks.C:157
 esd_muon_tracks.C:158
 esd_muon_tracks.C:159
 esd_muon_tracks.C:160
 esd_muon_tracks.C:161
 esd_muon_tracks.C:162
 esd_muon_tracks.C:163
 esd_muon_tracks.C:164
 esd_muon_tracks.C:165
 esd_muon_tracks.C:166
 esd_muon_tracks.C:167
 esd_muon_tracks.C:168
 esd_muon_tracks.C:169
 esd_muon_tracks.C:170
 esd_muon_tracks.C:171
 esd_muon_tracks.C:172
 esd_muon_tracks.C:173
 esd_muon_tracks.C:174
 esd_muon_tracks.C:175
 esd_muon_tracks.C:176
 esd_muon_tracks.C:177
 esd_muon_tracks.C:178
 esd_muon_tracks.C:179
 esd_muon_tracks.C:180
 esd_muon_tracks.C:181
 esd_muon_tracks.C:182
 esd_muon_tracks.C:183
 esd_muon_tracks.C:184
 esd_muon_tracks.C:185
 esd_muon_tracks.C:186
 esd_muon_tracks.C:187
 esd_muon_tracks.C:188
 esd_muon_tracks.C:189
 esd_muon_tracks.C:190
 esd_muon_tracks.C:191
 esd_muon_tracks.C:192
 esd_muon_tracks.C:193
 esd_muon_tracks.C:194
 esd_muon_tracks.C:195
 esd_muon_tracks.C:196
 esd_muon_tracks.C:197
 esd_muon_tracks.C:198
 esd_muon_tracks.C:199
 esd_muon_tracks.C:200
 esd_muon_tracks.C:201
 esd_muon_tracks.C:202
 esd_muon_tracks.C:203
 esd_muon_tracks.C:204
 esd_muon_tracks.C:205
 esd_muon_tracks.C:206
 esd_muon_tracks.C:207
 esd_muon_tracks.C:208
 esd_muon_tracks.C:209
 esd_muon_tracks.C:210
 esd_muon_tracks.C:211
 esd_muon_tracks.C:212
 esd_muon_tracks.C:213
 esd_muon_tracks.C:214
 esd_muon_tracks.C:215
 esd_muon_tracks.C:216
 esd_muon_tracks.C:217
 esd_muon_tracks.C:218
 esd_muon_tracks.C:219
 esd_muon_tracks.C:220
 esd_muon_tracks.C:221
 esd_muon_tracks.C:222
 esd_muon_tracks.C:223
 esd_muon_tracks.C:224
 esd_muon_tracks.C:225
 esd_muon_tracks.C:226
 esd_muon_tracks.C:227
 esd_muon_tracks.C:228
 esd_muon_tracks.C:229
 esd_muon_tracks.C:230
 esd_muon_tracks.C:231
 esd_muon_tracks.C:232
 esd_muon_tracks.C:233
 esd_muon_tracks.C:234
 esd_muon_tracks.C:235
 esd_muon_tracks.C:236
 esd_muon_tracks.C:237
 esd_muon_tracks.C:238
 esd_muon_tracks.C:239
 esd_muon_tracks.C:240
 esd_muon_tracks.C:241
 esd_muon_tracks.C:242
 esd_muon_tracks.C:243
 esd_muon_tracks.C:244
 esd_muon_tracks.C:245
 esd_muon_tracks.C:246
 esd_muon_tracks.C:247
 esd_muon_tracks.C:248
 esd_muon_tracks.C:249
 esd_muon_tracks.C:250
 esd_muon_tracks.C:251
 esd_muon_tracks.C:252
 esd_muon_tracks.C:253
 esd_muon_tracks.C:254
 esd_muon_tracks.C:255
 esd_muon_tracks.C:256
 esd_muon_tracks.C:257
 esd_muon_tracks.C:258
 esd_muon_tracks.C:259
 esd_muon_tracks.C:260
 esd_muon_tracks.C:261
 esd_muon_tracks.C:262
 esd_muon_tracks.C:263
 esd_muon_tracks.C:264
 esd_muon_tracks.C:265
 esd_muon_tracks.C:266
 esd_muon_tracks.C:267
 esd_muon_tracks.C:268
 esd_muon_tracks.C:269
 esd_muon_tracks.C:270
 esd_muon_tracks.C:271
 esd_muon_tracks.C:272
 esd_muon_tracks.C:273
 esd_muon_tracks.C:274
 esd_muon_tracks.C:275
 esd_muon_tracks.C:276
 esd_muon_tracks.C:277
 esd_muon_tracks.C:278
 esd_muon_tracks.C:279
 esd_muon_tracks.C:280
 esd_muon_tracks.C:281
 esd_muon_tracks.C:282
 esd_muon_tracks.C:283
 esd_muon_tracks.C:284
 esd_muon_tracks.C:285
 esd_muon_tracks.C:286
 esd_muon_tracks.C:287
 esd_muon_tracks.C:288
 esd_muon_tracks.C:289
 esd_muon_tracks.C:290
 esd_muon_tracks.C:291
 esd_muon_tracks.C:292
 esd_muon_tracks.C:293
 esd_muon_tracks.C:294
 esd_muon_tracks.C:295
 esd_muon_tracks.C:296
 esd_muon_tracks.C:297
 esd_muon_tracks.C:298
 esd_muon_tracks.C:299
 esd_muon_tracks.C:300
 esd_muon_tracks.C:301
 esd_muon_tracks.C:302
 esd_muon_tracks.C:303
 esd_muon_tracks.C:304
 esd_muon_tracks.C:305
 esd_muon_tracks.C:306