1 /**************************************************************************
\r
2 * This file is property of and copyright by the ALICE HLT Project *
\r
3 * ALICE Experiment at CERN, All rights reserved. *
\r
5 * Primary Authors: Svein Lindal <slindal@fys.uio.no > *
\r
6 * for The ALICE HLT Project. *
\r
8 * Permission to use, copy, modify and distribute this software and its *
\r
9 * documentation strictly for non-commercial purposes is hereby granted *
\r
10 * without fee, provided that the above copyright notice appears in all *
\r
11 * copies and that both the copyright notice and this permission notice *
\r
12 * appear in the supporting documentation. The authors make no claims *
\r
13 * about the suitability of this software for any purpose. It is *
\r
14 * provided "as is" without express or implied warranty. *
\r
15 **************************************************************************/
\r
17 /// @file AliHLTEvePhos.cxx
\r
18 /// @author Svein Lindal <slindal@fys.uio.no>
\r
19 /// @brief Muon processor for the HLT EVE display
\r
21 #include "AliHLTEveMuon.h"
\r
22 #include "AliHLTMUONDataBlockReader.h"
\r
23 #include "AliHLTHOMERBlockDesc.h"
\r
24 #include "TCanvas.h"
\r
25 #include "TEveStraightLineSet.h"
\r
26 #include "TEvePointSet.h"
\r
27 #include "AliEveHLTEventManager.h"
\r
28 #include "TEveManager.h"
\r
31 #include "TEveVSDStructs.h"
\r
32 #include "TGeoGlobalMagField.h"
\r
33 #include "AliMUONTrack.h"
\r
34 #include "AliMUONTrackParam.h"
\r
35 #include "AliMUONESDInterface.h"
\r
36 #include "AliMUONVTrackReconstructor.h"
\r
37 #include "AliEveMUONTrack.h"
\r
38 #include "AliHLTMUONConstants.h"
\r
39 #include "AliHLTMUONUtils.h"
\r
40 #include "AliMUONVCluster.h"
\r
41 #include "AliMUONVClusterStore.h"
\r
42 #include "AliMUONConstants.h"
\r
43 #include "TEveTrackPropagator.h"
\r
45 using namespace std;
\r
47 class AliHLTMUONUtils;
\r
48 class AliEveMuonTrack;
\r
50 ClassImp(AliHLTEveMuon);
\r
52 AliHLTEveMuon::AliHLTEveMuon() :
\r
53 AliHLTEveBase("Muon"),
\r
54 fFullTrackList(NULL),
\r
59 SetMaxHistograms(6);
\r
62 AliHLTEveMuon::~AliHLTEveMuon()
\r
66 delete fFullTrackList;
\r
67 fFullTrackList = NULL;
\r
79 void AliHLTEveMuon::ProcessBlock(AliHLTHOMERBlockDesc * block) {
\r
80 //See header file for documentation
\r
81 if ( (block->GetDataType().CompareTo("RECHITS") == 0) || (block->GetDataType().CompareTo("TRIGRECS") == 0) ) {
\r
83 fClusters = CreateClusters();
\r
84 AddElement(fClusters);
\r
86 ProcessClusters( block, fClusters );
\r
88 }else if(block->GetDataType().CompareTo("MANTRACK") == 0){
\r
91 fTracks = CreateTrackSet();
\r
92 AddElement(fTracks);
\r
95 ProcessTracks( block, fTracks );
\r
97 }else if(block->GetDataType().CompareTo("TRACKS") == 0){
\r
99 if ( !fFullTrackList ) {
\r
100 fFullTrackList = CreateFullTrackList();
\r
101 AddElement(fFullTrackList);
\r
104 ProcessFullTracks( block, fFullTrackList );
\r
106 } else if(block->GetDataType().CompareTo("ROOTHIST") == 0) {
\r
107 ProcessHistogram(block);
\r
112 TEvePointSet * AliHLTEveMuon::CreateClusters() {
\r
113 //See header file for documentation
\r
114 TEvePointSet * ps = new TEvePointSet("MUON RecHits");
\r
115 ps->SetMainColor(kBlue);
\r
116 ps->SetMarkerStyle(20);
\r
120 TEveStraightLineSet * AliHLTEveMuon::CreateTrackSet() {
\r
122 TEveStraightLineSet * lineset = new TEveStraightLineSet("MUON Tracks");
\r
123 lineset->SetMainColor(kRed);
\r
124 lineset->SetLineWidth(3);
\r
128 TEveTrackList * AliHLTEveMuon::CreateFullTrackList(){
\r
130 TEveTrackList * lineset = new TEveTrackList("MUON Full Tracks");
\r
131 lineset->SetMainColor(kBlue);
\r
135 void AliHLTEveMuon::ProcessHistogram(AliHLTHOMERBlockDesc * block ) {
\r
136 //See header file for documentation
\r
138 fCanvas = CreateCanvas("MUON QA", "MUON QA");
\r
139 fCanvas->Divide(3, 2);
\r
141 AddHistogramsToCanvas(block, fCanvas, fHistoCount);
\r
144 void AliHLTEveMuon::UpdateElements() {
\r
145 //See header file for documentation
\r
146 if(fCanvas) fCanvas->Update();
\r
147 if(fClusters) fClusters->ResetBBox();
\r
148 if(fTracks) fTracks->ElementChanged();
\r
151 void AliHLTEveMuon::ResetElements(){
\r
152 //See header file for documentation
\r
155 if ( fClusters ) fClusters->Reset();
\r
157 fTracks->Destroy();
\r
160 if ( fFullTrackList ){
\r
161 fFullTrackList->Destroy();
\r
162 fFullTrackList = NULL;
\r
168 void AliHLTEveMuon::ProcessClusters(AliHLTHOMERBlockDesc * block, TEvePointSet * clusters) {
\r
169 //See header file for documentation
\r
170 unsigned long size = block->GetSize();
\r
173 buffer = (Int_t *)block->GetData();
\r
174 //cout<<"block size : "<<size<<", buffer : "<<buffer<<", DataType : "<<block->GetDataType()<<endl;
\r
176 if(block->GetDataType().CompareTo("RECHITS") == 0){
\r
178 AliHLTMUONRecHitsBlockReader trackblock((char*)buffer, size);
\r
179 const AliHLTMUONRecHitStruct* hit = trackblock.GetArray();
\r
181 for(AliHLTUInt32_t ientry = 0; ientry < trackblock.Nentries(); ientry++){
\r
182 if(hit->fX!=0.0 && hit->fY!=0.0 && hit->fZ!=0.0)
\r
183 clusters->SetNextPoint(hit->fX,hit->fY,hit->fZ);
\r
190 // if(!strcmp((BlockType(ULong64_t(reader->GetBlockDataType(i)))).Data(),"TRIGRECS")){
\r
192 AliHLTMUONTriggerRecordsBlockReader trigblock(buffer, size);
\r
193 const AliHLTMUONTriggerRecordStruct* trigrec = trigblock.GetArray();
\r
194 for(AliHLTUInt32_t ientry = 0; ientry < trigblock.Nentries(); ientry++){
\r
196 const AliHLTMUONRecHitStruct* hit = &trigrec->fHit[0];
\r
197 for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
\r
199 if(hit->fX!=0.0 && hit->fY!=0.0 && hit->fZ!=0.0)
\r
200 clusters->SetNextPoint(hit->fX,hit->fY,hit->fZ);
\r
202 }// trig chamber loop
\r
209 void AliHLTEveMuon::ProcessTracks(AliHLTHOMERBlockDesc * block, TEveStraightLineSet * tracks) {
\r
210 //See header file for documentation
\r
211 unsigned long size = block->GetSize();
\r
212 Int_t * buffer = (Int_t *)block->GetData();
\r
213 AliHLTMUONRecHitStruct hit1,hit2;
\r
214 hit1.fX = hit1.fY = hit1.fZ = hit2.fX = hit2.fY = hit2.fZ = 0;
\r
215 Int_t ch1=0, ch2=0;
\r
216 Float_t x0=0.0,y0=0.0,z0=0.0;
\r
217 Float_t x3=0.0,y3=0.0,z3=0.0;
\r
218 if(block->GetDataType().CompareTo("MANTRACK") == 0){
\r
219 AliHLTMUONMansoTracksBlockReader mantrackblock(buffer, size);
\r
220 const AliHLTMUONMansoTrackStruct* mtrack = mantrackblock.GetArray();
\r
221 for(AliHLTUInt32_t ientry = 0; ientry < mantrackblock.Nentries(); ientry++){
\r
222 const AliHLTMUONRecHitStruct* hit = &mtrack->fHit[0];
\r
223 for(AliHLTUInt32_t ch = 0; ch < 4; ch++){
\r
224 // cout << setw(10) << left << ch + 7 << setw(0);
\r
225 // cout << setw(13) << left << hit->fX << setw(0);
\r
226 // cout << setw(13) << left << hit->fY << setw(0);
\r
227 // cout << hit->fZ << setw(0) << endl;
\r
228 if(hit->fZ != 0.0){
\r
229 if(ch==0 || ch==1){
\r
230 hit1 = *hit; ch1 = ch+6;
\r
232 hit2 = *hit; ch2 = ch+6;
\r
236 }// trig chamber loop
\r
237 // printf("ch : %d, (X,Y,Z) : (%f,%f,%f)\n",ch1,hit1.fX,hit1.fY,hit1.fZ);
\r
238 // printf("ch : %d, (X,Y,Z) : (%f,%f,%f)\n",ch2,hit2.fX,hit2.fY,hit2.fZ);
\r
240 z3 = AliMUONConstants::DefaultChamberZ(ch2+4);
\r
241 y3 = hit1.fY - (hit1.fZ-z3)*(hit1.fY - hit2.fY)/(hit1.fZ - hit2.fZ) ;
\r
242 x3 = hit1.fX - (hit1.fZ-z3)*(hit1.fX - hit2.fX)/(hit1.fZ - hit2.fZ) ;
\r
244 z0 = AliMUONConstants::DefaultChamberZ(ch1);
\r
245 y0 = hit1.fY - (hit1.fZ-z0)*(hit1.fY - hit2.fY)/(hit1.fZ - hit2.fZ) ;
\r
246 x0 = hit1.fX - (hit1.fZ-z0)*(hit1.fX - hit2.fX)/(hit1.fZ - hit2.fZ) ;
\r
249 tracks->AddLine(x0,y0,z0,x3,y3,z3);
\r
252 // cout<<"NofManso Tracks : "<<mantrackblock.Nentries()<<endl;
\r
256 int AliHLTEveMuon::MakeMUONTrack(AliMUONTrack *muonTrack, const AliHLTMUONTrackStruct *muonHLTTrack)
\r
258 // See header for documentation
\r
259 AliHLTUInt32_t clusterIndex = 0; // for the cluster unique ID.
\r
260 AliHLTMUONParticleSign sign;
\r
262 AliHLTMUONUtils::UnpackTrackFlags(
\r
263 muonHLTTrack->fFlags, sign, hitset
\r
266 // add track parameters at vertex
\r
267 TVector3 mom(muonHLTTrack->fPx, muonHLTTrack->fPy, muonHLTTrack->fPz);
\r
268 AliMUONTrackParam paramAtVtx;
\r
269 if (mom.Mag() != 0)
\r
270 paramAtVtx.SetInverseBendingMomentum(muonHLTTrack->fInverseBendingMomentum);
\r
272 paramAtVtx.SetInverseBendingMomentum(0.);
\r
273 paramAtVtx.SetNonBendingSlope(TMath::Tan(muonHLTTrack->fThetaX));
\r
274 paramAtVtx.SetBendingSlope(TMath::Tan(muonHLTTrack->fThetaY));
\r
275 paramAtVtx.SetZ(muonHLTTrack->fZ);
\r
276 paramAtVtx.SetBendingCoor(muonHLTTrack->fY);
\r
277 paramAtVtx.SetNonBendingCoor(muonHLTTrack->fX);
\r
278 muonTrack->SetTrackParamAtVertex(¶mAtVtx);
\r
280 //printf("(X,Y,Z) : (%8.3f,%8.3f,%8.3f)\n",muonHLTTrack->fX,muonHLTTrack->fY,muonHLTTrack->fZ);
\r
284 AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
\r
285 if (!cStore) return -1;
\r
286 AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);
\r
287 AliMUONTrackParam trackParam;
\r
288 for (int i = 0; i < 16; i++)
\r
290 if (not hitset[i]) continue;
\r
292 AliHLTUInt8_t chamber;
\r
293 AliHLTUInt16_t detElemId;
\r
294 AliHLTMUONUtils::UnpackRecHitFlags((muonHLTTrack->fHit[i]).fFlags, chamber, detElemId);
\r
296 cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
\r
297 cluster->SetXYZ((muonHLTTrack->fHit[i]).fX, (muonHLTTrack->fHit[i]).fY, (muonHLTTrack->fHit[i]).fZ);
\r
298 cluster->SetErrXY( // Use nominal values.
\r
299 AliHLTMUONConstants::DefaultNonBendingReso(),
\r
300 AliHLTMUONConstants::DefaultBendingReso()
\r
302 cluster->SetCharge(-1.); // Indicate no total charge calculated.
\r
303 cluster->SetChi2(-1.); // Indicate no fit made.
\r
304 trackParam.SetZ(cluster->GetZ());
\r
305 muonTrack->AddTrackParamAtCluster(trackParam, *cluster, kTRUE);
\r
309 // compute track parameters at each cluster
\r
311 AliMUONTrackParam *firstTrackParam = (AliMUONTrackParam*) muonTrack->GetTrackParamAtCluster()->First();
\r
312 trackParam = (*firstTrackParam);
\r
313 if (!AliMUONESDInterface::GetTracker()) AliMUONESDInterface::ResetTracker();
\r
314 if (!AliMUONESDInterface::GetTracker()->RefitTrack(*muonTrack, kFALSE) &&
\r
315 muonTrack->GetGlobalChi2() < AliMUONTrack::MaxChi2()) {
\r
316 *firstTrackParam = trackParam;
\r
317 muonTrack->UpdateCovTrackParamAtCluster();
\r
321 muonTrack->SetGlobalChi2(muonHLTTrack->fChi2);
\r
326 Int_t AliHLTEveMuon::ProcessFullTracks(AliHLTHOMERBlockDesc * block, TEveTrackList * fullTracks) {
\r
328 // See header for documentation
\r
332 Double_t b[3], x[3];
\r
333 x[0] = 0.0 ; x[1] = 0.0 ; x[2] = -950.0;
\r
334 TGeoGlobalMagField::Instance()->Field(x,b);
\r
335 //" Field at (0.0, 0.0, -950.0) [at the middle of dipole magnet]
\r
336 //should be (6.79, 0.03, -0.17) or similar value with change of sign"
\r
337 if(TMath::AreEqualAbs(b[0],0.0,1.0e-5) and TMath::AreEqualAbs(b[1],0.0,1.0e-5) and TMath::AreEqualAbs(b[2],0.0,1.0e-5)){
\r
338 printf("At (X,Y,Z) : (%6.2lf,%6.2lf,%6.2lf) Field (Bx,By,Bz) is (%6.2lf,%6.2lf,%6.2lf)\n",
\r
339 x[0],x[1],x[2],b[0],b[1],b[2]);
\r
340 cerr<<"Magnetic field is not properly set, MUON tracking will not possble"<<endl;
\r
348 unsigned long size = block->GetSize();
\r
349 Int_t * buffer = (Int_t *)block->GetData();
\r
351 AliHLTMUONTracksBlockReader muontrackblock(buffer, size);
\r
352 const AliHLTMUONTrackStruct* mtrack = muontrackblock.GetArray();
\r
353 //cout<<"NofTracks : "<<muontrackblock.Nentries()<<endl;
\r
354 for(AliHLTUInt32_t ientry = 0; ientry < muontrackblock.Nentries(); ientry++){
\r
356 AliMUONTrack *muonTrack = new AliMUONTrack();
\r
357 MakeMUONTrack(muonTrack,mtrack);
\r
358 if(muonTrack->GetNClusters()==0){
\r
363 rt.fLabel = ientry;
\r
364 AliEveMUONTrack* track = new AliEveMUONTrack(&rt, fullTracks->GetPropagator());
\r
365 track->MakeMUONTrack(muonTrack);
\r
366 //track->SetTitle(Form("HLT Track : %d, pt : %lf",ientry,TMath::Sqrt(((mtrack->fPx * mtrack->fPx) + (mtrack->fPy * mtrack->fPy)))));
\r
367 track->SetName(Form("HLT Track : %d, pt : %lf",ientry,TMath::Sqrt(((mtrack->fPx * mtrack->fPx) + (mtrack->fPy * mtrack->fPy)))));
\r
368 fullTracks->AddElement(track);
\r