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 muon_trackRefs.C
/// \brief Macro to visualise trackRef in MUON spectrometer 
/// (both tracker and trigger).
///
/// Use muon_trackRefs(Bool_t showSimClusters) in order to run it
///
/// Needs that alieve_init() is already called
///
/// \author P. Pillot, L. Aphecetche; Subatech

#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TClonesArray.h>
#include <TTree.h>
#include <TParticle.h>
#include <TMath.h>
#include <TROOT.h>
#include <TEveManager.h>
#include <TEveUtil.h>
#include <TEveTrack.h>
#include <TEvePointSet.h>
#include <TEveVSDStructs.h>
#include <TEveTrackPropagator.h>

#include <AliMUONClusterStoreV2.h>
#include <AliMUONRawClusterV2.h>
#include <AliMUONVCluster.h>
#include <AliMUONConstants.h>
#include <AliMUONRecoParam.h>
#include <AliMUONCDB.h>
#include <AliStack.h>
#include <AliTrackReference.h>
#include <AliRunLoader.h>
#include <AliEveMagField.h>
#include <AliEveTrack.h>
#include <AliEveEventManager.h>
#endif

//______________________________________________________________________________
void muon_trackRef_propagator_setup(TEveTrackPropagator* trkProp, Bool_t showVertex)
{
  // set magnetic field
  trkProp->SetMagFieldObj(new AliEveMagField);
  trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
  
  // set propagation range
  trkProp->SetMaxR(500.);
  trkProp->SetMaxZ(-AliMUONConstants::DefaultChamberZ(13)+3.5);
  
  // go through pathmarks
  trkProp->SetFitDaughters(kFALSE);
  trkProp->SetFitReferences(kTRUE);
  trkProp->SetFitDecay(kTRUE);
  trkProp->SetFitCluster2Ds(kFALSE);
  
  // Render first vertex if required
  if (showVertex)
  {
    trkProp->SetRnrFV(kTRUE);
    trkProp->RefFVAtt().SetMarkerSize(0.5);
    trkProp->RefFVAtt().SetMarkerColor(kRed);
  }
}

//______________________________________________________________________________
Bool_t isReconstructible(Bool_t* chHit)
{
  // load recoParam from OCDB
  static AliMUONRecoParam* gRecoParam = 0x0;
  static UInt_t gRequestedStationMask = 0;
  static Bool_t gRequest2ChInSameSt45 = kFALSE;
  if (!gRecoParam)
  {
    gRecoParam = AliMUONCDB::LoadRecoParam();
    if (!gRecoParam) exit(-1);
    // compute the mask of requested stations
    gRequestedStationMask = 0;
    for (Int_t i = 0; i < 5; i++) if (gRecoParam->RequestStation(i)) gRequestedStationMask |= ( 1 << i );
    // get whether a track need 2 chambers hit in the same station (4 or 5) or not to be reconstructible
    gRequest2ChInSameSt45 = !gRecoParam->MakeMoreTrackCandidates();
  }
  
  // check which chambers are hit
  UInt_t presentStationMask(0);
  Int_t nChHitInSt4 = 0, nChHitInSt5 = 0;
  for (Int_t ich=0; ich<10; ich++)
  {
    if (!chHit[ich]) continue;
    Int_t ist = ich/2;
    presentStationMask |= ( 1 << ist );
    if (ist == 3) nChHitInSt4++;
    if (ist == 4) nChHitInSt5++;
  }
  
  // at least one cluster per requested station
  if ((gRequestedStationMask & presentStationMask) != gRequestedStationMask) return kFALSE;
  
  // 2 chambers hit in the same station (4 or 5)
  if (gRequest2ChInSameSt45) return (nChHitInSt4 == 2 || nChHitInSt5 == 2);
  // or 2 chambers hit in station 4 & 5 together
  else return (nChHitInSt4+nChHitInSt5 >= 2);
}

//______________________________________________________________________________
void add_muon_trackRefs(AliStack* stack, TTree* treeTR, TEveTrackList* reco, TEveTrackList* other,
			TEvePointSet* RecoClusters, TEvePointSet* OtherClusters)
{
  TClonesArray* trackRefs = 0;
  treeTR->SetBranchAddress("TrackReferences", &trackRefs);
  Int_t nSimTracks = stack->GetNtrack();
  AliMUONClusterStoreV2 clusters;
  TClonesArray clustersTrigger("AliMUONRawClusterV2", 10);
  
  // loop over simulated track
  for (Int_t itr = 0; itr < nSimTracks; itr++)
  {
    treeTR->GetEntry(stack->TreeKEntry(itr));
    Int_t nTrackRefs = trackRefs->GetEntriesFast();
    if (nTrackRefs <= 0) continue;
    
    TEveTrack* track = 0x0;
    Bool_t chHit[10];
    for (Int_t ich=0; ich<10; ich++) chHit[ich] = kFALSE;
    
    // loop over simulated track hits
    for (Int_t itrR = 0; itrR < nTrackRefs; ++itrR)
    {
      AliTrackReference* atr = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(itrR));
      
      // skip trackRefs not in MUON
      if (atr->DetectorId() != AliTrackReference::kMUON) continue;
      
      // record chamber hit
      Int_t detElemId = atr->UserId();
      Int_t chamberId = detElemId / 100 - 1;
      if (chamberId < 0) continue;
      if (chamberId < 10) chHit[chamberId] = kTRUE;
      
      // produce eve track if not already done
      if (!track)
      {
	TParticle* p = stack->Particle(itr);
	track = new AliEveTrack(p, itr, 0x0);
	track->SetName(Form("%s [%d]", p->GetName(), itr));
	track->SetStdTitle();
	track->SetSourceObject(p);
	
	clusters.Clear();
	clustersTrigger.Clear("C");
      }
      
      // add path mark
      track->AddPathMark(TEvePathMark(TEvePathMark::kReference,
				      TEveVector(atr->X(),  atr->Y(),  atr->Z()),
				      TEveVector(atr->Px(), atr->Py(), atr->Pz()),
				      atr->GetTime()));
      
      // produce clusters if required
      if (RecoClusters || OtherClusters)
      {
	// from tracker
	if (chamberId < 10)
	{
	  // produce a new cluster on that DE or update existing one
	  AliMUONVCluster* cl = 0x0;
	  Int_t clNum = -1;
	  do cl = clusters.FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, ++clNum));
	  while (cl && cl->GetNDigits() == 2);
	  if (cl) {
	    cl->SetXYZ((cl->GetX() + atr->X()) / 2., (cl->GetY() + atr->Y()) / 2., (cl->GetZ() + atr->Z()) / 2.);
	  }
	  else
	  {
	    cl = clusters.Add(chamberId, detElemId, clNum);
	    cl->SetXYZ(atr->X(), atr->Y(), atr->Z());
	  }
	  cl->AddDigitId((UInt_t)itrR);
	}
	else // from trigger
	{
	  AliMUONVCluster* cl = new(clustersTrigger[clustersTrigger.GetLast()+1]) AliMUONRawClusterV2();
	  cl->SetXYZ(atr->X(), atr->Y(), atr->Z());
	}
      }
    }
    
    if (track)
    {
      track->SortPathMarksByTime();
      // stop track propagation at last path mark
      track->RefPathMarks().back().fType = TEvePathMarkT<double>::EType_e(TEvePathMark::kDecay);
      
      // add the track and trackRefs to proper lists
      if (isReconstructible(chHit)) {
	track->SetPropagator(reco->GetPropagator());
	track->SetAttLineAttMarker(reco);
	reco->AddElement(track);
	
	// trackRefs
	if (RecoClusters)
	{
	  // tracker
	  TIter next(clusters.CreateIterator());
	  gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, RecoClusters));
	  // trigger
	  TIter next2(clustersTrigger.MakeIterator());
	  gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next2, RecoClusters));
	}
      }
      else {
	track->SetPropagator(other->GetPropagator());
	track->SetAttLineAttMarker(other);
	other->AddElement(track);
	
	// trackRefs
	if (OtherClusters)
	{
	  // tracker
	  TIter next(clusters.CreateIterator());
	  gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next, OtherClusters));
	  // trigger
	  TIter next2(clustersTrigger.MakeIterator());
	  gROOT->ProcessLine(Form("add_muon_clusters((TIter*)%p, (TEvePointSet*)%p);",&next2, OtherClusters));
	}
      }
    }
  }
  delete trackRefs;
}

//______________________________________________________________________________
void muon_trackRefs(Bool_t showSimClusters)
{
  // load kinematics and trackRefs
  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
  rl->LoadKinematics();
  AliStack* stack = rl->Stack();
  if (!stack) return;
  rl->LoadTrackRefs();
  TTree* treeTR = rl->TreeTR();  
  if (!treeTR) return;
  
  // track containers
  TEveElementList* trackCont = new TEveElementList("Sim MUON Tracks");
  
  TEveTrackList* reco = new TEveTrackList("reconstructible");
  reco->SetRnrPoints(kFALSE);
  reco->SetRnrLine(kTRUE);
  reco->SetLineColor(kRed);
  reco->SetLineStyle(2);
  muon_trackRef_propagator_setup(reco->GetPropagator(), kTRUE);
  trackCont->AddElement(reco);
  
  TEveTrackList* other = new TEveTrackList("others");
  other->SetRnrPoints(kFALSE);
  other->SetRnrLine(kTRUE);
  other->SetLineColor(kWhite);
  other->SetLineStyle(3);
  muon_trackRef_propagator_setup(other->GetPropagator(), kFALSE);
  trackCont->AddElement(other);
  
  // cluster container
  TEveElementList* clusterCont = 0x0;
  TEvePointSet* RecoClusters = 0x0;
  TEvePointSet* OtherClusters = 0x0;
  if (showSimClusters)
  {
    clusterCont = new TEveElementList("Sim MUON Clusters");
    
    RecoClusters = new TEvePointSet(1000);
    RecoClusters->SetName("Reconstructibles");
    RecoClusters->SetPickable(kFALSE);
    RecoClusters->SetMarkerStyle(2);
    RecoClusters->SetMarkerColor(kRed);
    RecoClusters->SetMarkerSize(0.5);
    clusterCont->AddElement(RecoClusters);
    
    OtherClusters = new TEvePointSet(10000);
    OtherClusters->SetName("Others");
    OtherClusters->SetPickable(kFALSE);
    OtherClusters->SetMarkerStyle(2);
    OtherClusters->SetMarkerColor(kWhite);
    OtherClusters->SetMarkerSize(0.5);
    clusterCont->AddElement(OtherClusters);
    
    TEveUtil::LoadMacro("muon_clusters.C+");
  }
  
  // add tracks to the proper list and propagate them. Add also clusters if required.
  add_muon_trackRefs(stack, treeTR, reco, other, RecoClusters, OtherClusters);
  reco->MakeTracks();
  other->MakeTracks();
  trackCont->SetTitle(Form("N=%d", reco->NumChildren()+other->NumChildren()));
  reco->SetTitle(Form("N=%d",reco->NumChildren()));
  other->SetTitle(Form("N=%d",other->NumChildren()));
  if (showSimClusters)
  {
    clusterCont->SetTitle(Form("N=%d",RecoClusters->GetLastPoint()+OtherClusters->GetLastPoint()+2));
    RecoClusters->SetTitle(Form("N=%d",RecoClusters->GetLastPoint()+1));
    OtherClusters->SetTitle(Form("N=%d",OtherClusters->GetLastPoint()+1));
  }
  
  // add graphic containers
  gEve->DisableRedraw();
  gEve->AddElement(trackCont);
  if (clusterCont) gEve->AddElement(clusterCont);
  gEve->EnableRedraw();
  gEve->Redraw3D();
}
 muon_trackRefs.C:1
 muon_trackRefs.C:2
 muon_trackRefs.C:3
 muon_trackRefs.C:4
 muon_trackRefs.C:5
 muon_trackRefs.C:6
 muon_trackRefs.C:7
 muon_trackRefs.C:8
 muon_trackRefs.C:9
 muon_trackRefs.C:10
 muon_trackRefs.C:11
 muon_trackRefs.C:12
 muon_trackRefs.C:13
 muon_trackRefs.C:14
 muon_trackRefs.C:15
 muon_trackRefs.C:16
 muon_trackRefs.C:17
 muon_trackRefs.C:18
 muon_trackRefs.C:19
 muon_trackRefs.C:20
 muon_trackRefs.C:21
 muon_trackRefs.C:22
 muon_trackRefs.C:23
 muon_trackRefs.C:24
 muon_trackRefs.C:25
 muon_trackRefs.C:26
 muon_trackRefs.C:27
 muon_trackRefs.C:28
 muon_trackRefs.C:29
 muon_trackRefs.C:30
 muon_trackRefs.C:31
 muon_trackRefs.C:32
 muon_trackRefs.C:33
 muon_trackRefs.C:34
 muon_trackRefs.C:35
 muon_trackRefs.C:36
 muon_trackRefs.C:37
 muon_trackRefs.C:38
 muon_trackRefs.C:39
 muon_trackRefs.C:40
 muon_trackRefs.C:41
 muon_trackRefs.C:42
 muon_trackRefs.C:43
 muon_trackRefs.C:44
 muon_trackRefs.C:45
 muon_trackRefs.C:46
 muon_trackRefs.C:47
 muon_trackRefs.C:48
 muon_trackRefs.C:49
 muon_trackRefs.C:50
 muon_trackRefs.C:51
 muon_trackRefs.C:52
 muon_trackRefs.C:53
 muon_trackRefs.C:54
 muon_trackRefs.C:55
 muon_trackRefs.C:56
 muon_trackRefs.C:57
 muon_trackRefs.C:58
 muon_trackRefs.C:59
 muon_trackRefs.C:60
 muon_trackRefs.C:61
 muon_trackRefs.C:62
 muon_trackRefs.C:63
 muon_trackRefs.C:64
 muon_trackRefs.C:65
 muon_trackRefs.C:66
 muon_trackRefs.C:67
 muon_trackRefs.C:68
 muon_trackRefs.C:69
 muon_trackRefs.C:70
 muon_trackRefs.C:71
 muon_trackRefs.C:72
 muon_trackRefs.C:73
 muon_trackRefs.C:74
 muon_trackRefs.C:75
 muon_trackRefs.C:76
 muon_trackRefs.C:77
 muon_trackRefs.C:78
 muon_trackRefs.C:79
 muon_trackRefs.C:80
 muon_trackRefs.C:81
 muon_trackRefs.C:82
 muon_trackRefs.C:83
 muon_trackRefs.C:84
 muon_trackRefs.C:85
 muon_trackRefs.C:86
 muon_trackRefs.C:87
 muon_trackRefs.C:88
 muon_trackRefs.C:89
 muon_trackRefs.C:90
 muon_trackRefs.C:91
 muon_trackRefs.C:92
 muon_trackRefs.C:93
 muon_trackRefs.C:94
 muon_trackRefs.C:95
 muon_trackRefs.C:96
 muon_trackRefs.C:97
 muon_trackRefs.C:98
 muon_trackRefs.C:99
 muon_trackRefs.C:100
 muon_trackRefs.C:101
 muon_trackRefs.C:102
 muon_trackRefs.C:103
 muon_trackRefs.C:104
 muon_trackRefs.C:105
 muon_trackRefs.C:106
 muon_trackRefs.C:107
 muon_trackRefs.C:108
 muon_trackRefs.C:109
 muon_trackRefs.C:110
 muon_trackRefs.C:111
 muon_trackRefs.C:112
 muon_trackRefs.C:113
 muon_trackRefs.C:114
 muon_trackRefs.C:115
 muon_trackRefs.C:116
 muon_trackRefs.C:117
 muon_trackRefs.C:118
 muon_trackRefs.C:119
 muon_trackRefs.C:120
 muon_trackRefs.C:121
 muon_trackRefs.C:122
 muon_trackRefs.C:123
 muon_trackRefs.C:124
 muon_trackRefs.C:125
 muon_trackRefs.C:126
 muon_trackRefs.C:127
 muon_trackRefs.C:128
 muon_trackRefs.C:129
 muon_trackRefs.C:130
 muon_trackRefs.C:131
 muon_trackRefs.C:132
 muon_trackRefs.C:133
 muon_trackRefs.C:134
 muon_trackRefs.C:135
 muon_trackRefs.C:136
 muon_trackRefs.C:137
 muon_trackRefs.C:138
 muon_trackRefs.C:139
 muon_trackRefs.C:140
 muon_trackRefs.C:141
 muon_trackRefs.C:142
 muon_trackRefs.C:143
 muon_trackRefs.C:144
 muon_trackRefs.C:145
 muon_trackRefs.C:146
 muon_trackRefs.C:147
 muon_trackRefs.C:148
 muon_trackRefs.C:149
 muon_trackRefs.C:150
 muon_trackRefs.C:151
 muon_trackRefs.C:152
 muon_trackRefs.C:153
 muon_trackRefs.C:154
 muon_trackRefs.C:155
 muon_trackRefs.C:156
 muon_trackRefs.C:157
 muon_trackRefs.C:158
 muon_trackRefs.C:159
 muon_trackRefs.C:160
 muon_trackRefs.C:161
 muon_trackRefs.C:162
 muon_trackRefs.C:163
 muon_trackRefs.C:164
 muon_trackRefs.C:165
 muon_trackRefs.C:166
 muon_trackRefs.C:167
 muon_trackRefs.C:168
 muon_trackRefs.C:169
 muon_trackRefs.C:170
 muon_trackRefs.C:171
 muon_trackRefs.C:172
 muon_trackRefs.C:173
 muon_trackRefs.C:174
 muon_trackRefs.C:175
 muon_trackRefs.C:176
 muon_trackRefs.C:177
 muon_trackRefs.C:178
 muon_trackRefs.C:179
 muon_trackRefs.C:180
 muon_trackRefs.C:181
 muon_trackRefs.C:182
 muon_trackRefs.C:183
 muon_trackRefs.C:184
 muon_trackRefs.C:185
 muon_trackRefs.C:186
 muon_trackRefs.C:187
 muon_trackRefs.C:188
 muon_trackRefs.C:189
 muon_trackRefs.C:190
 muon_trackRefs.C:191
 muon_trackRefs.C:192
 muon_trackRefs.C:193
 muon_trackRefs.C:194
 muon_trackRefs.C:195
 muon_trackRefs.C:196
 muon_trackRefs.C:197
 muon_trackRefs.C:198
 muon_trackRefs.C:199
 muon_trackRefs.C:200
 muon_trackRefs.C:201
 muon_trackRefs.C:202
 muon_trackRefs.C:203
 muon_trackRefs.C:204
 muon_trackRefs.C:205
 muon_trackRefs.C:206
 muon_trackRefs.C:207
 muon_trackRefs.C:208
 muon_trackRefs.C:209
 muon_trackRefs.C:210
 muon_trackRefs.C:211
 muon_trackRefs.C:212
 muon_trackRefs.C:213
 muon_trackRefs.C:214
 muon_trackRefs.C:215
 muon_trackRefs.C:216
 muon_trackRefs.C:217
 muon_trackRefs.C:218
 muon_trackRefs.C:219
 muon_trackRefs.C:220
 muon_trackRefs.C:221
 muon_trackRefs.C:222
 muon_trackRefs.C:223
 muon_trackRefs.C:224
 muon_trackRefs.C:225
 muon_trackRefs.C:226
 muon_trackRefs.C:227
 muon_trackRefs.C:228
 muon_trackRefs.C:229
 muon_trackRefs.C:230
 muon_trackRefs.C:231
 muon_trackRefs.C:232
 muon_trackRefs.C:233
 muon_trackRefs.C:234
 muon_trackRefs.C:235
 muon_trackRefs.C:236
 muon_trackRefs.C:237
 muon_trackRefs.C:238
 muon_trackRefs.C:239
 muon_trackRefs.C:240
 muon_trackRefs.C:241
 muon_trackRefs.C:242
 muon_trackRefs.C:243
 muon_trackRefs.C:244
 muon_trackRefs.C:245
 muon_trackRefs.C:246
 muon_trackRefs.C:247
 muon_trackRefs.C:248
 muon_trackRefs.C:249
 muon_trackRefs.C:250
 muon_trackRefs.C:251
 muon_trackRefs.C:252
 muon_trackRefs.C:253
 muon_trackRefs.C:254
 muon_trackRefs.C:255
 muon_trackRefs.C:256
 muon_trackRefs.C:257
 muon_trackRefs.C:258
 muon_trackRefs.C:259
 muon_trackRefs.C:260
 muon_trackRefs.C:261
 muon_trackRefs.C:262
 muon_trackRefs.C:263
 muon_trackRefs.C:264
 muon_trackRefs.C:265
 muon_trackRefs.C:266
 muon_trackRefs.C:267
 muon_trackRefs.C:268
 muon_trackRefs.C:269
 muon_trackRefs.C:270
 muon_trackRefs.C:271
 muon_trackRefs.C:272
 muon_trackRefs.C:273
 muon_trackRefs.C:274
 muon_trackRefs.C:275
 muon_trackRefs.C:276
 muon_trackRefs.C:277
 muon_trackRefs.C:278
 muon_trackRefs.C:279
 muon_trackRefs.C:280
 muon_trackRefs.C:281
 muon_trackRefs.C:282
 muon_trackRefs.C:283
 muon_trackRefs.C:284
 muon_trackRefs.C:285
 muon_trackRefs.C:286
 muon_trackRefs.C:287
 muon_trackRefs.C:288
 muon_trackRefs.C:289
 muon_trackRefs.C:290
 muon_trackRefs.C:291
 muon_trackRefs.C:292
 muon_trackRefs.C:293
 muon_trackRefs.C:294
 muon_trackRefs.C:295
 muon_trackRefs.C:296
 muon_trackRefs.C:297
 muon_trackRefs.C:298
 muon_trackRefs.C:299
 muon_trackRefs.C:300
 muon_trackRefs.C:301
 muon_trackRefs.C:302
 muon_trackRefs.C:303
 muon_trackRefs.C:304
 muon_trackRefs.C:305
 muon_trackRefs.C:306
 muon_trackRefs.C:307
 muon_trackRefs.C:308
 muon_trackRefs.C:309
 muon_trackRefs.C:310
 muon_trackRefs.C:311
 muon_trackRefs.C:312
 muon_trackRefs.C:313
 muon_trackRefs.C:314
 muon_trackRefs.C:315
 muon_trackRefs.C:316
 muon_trackRefs.C:317
 muon_trackRefs.C:318