2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
4 /**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
10 #include "AliEveCosmicRayFitter.h"
14 #include "TEveTrack.h"
15 #include "TEveTrackPropagator.h"
16 #include "TEveVSDStructs.h"
17 #include "TEveManager.h"
23 #include "TGraphErrors.h"
24 #include "TLinearFitter.h"
25 #include <Math/Vector3D.h>
27 //______________________________________________________________________
28 // AliEveCosmicRayFitter
30 // Same schema used in AliEveTrackFitter class.
32 // AliEveCosmicRayFitter is a TEvePointSet interface to allow
33 // straight line fit. It creates a set of points by listening to
34 // selection signal of any TEvePointSet object. After selection, the
35 // list is feeded to TVirtualFitter class, which returns straight
36 // line parameters. The fit result is visualized with a TEveLine
39 // Thanks to L. Moneta for the algorithm prepared to make a 3D
46 ClassImp(AliEveCosmicRayFitter)
48 AliEveCosmicRayFitter::AliEveCosmicRayFitter(const Text_t* name, Int_t n_points) :
49 TEvePointSet (name, n_points),
65 fTrackList = new TEveTrackList("Cosmic ray");
66 fTrackList->SetTitle("muons");
67 fTrackList->SetMainColor((Color_t)8);
68 gEve->AddElement(fTrackList);
71 fGraphPicked1 = new TGraph();
72 fGraphPicked1->SetName("Selected points");
73 fGraphPicked1->SetMarkerColor(4);
74 fGraphPicked1->SetMarkerStyle(4);
75 fGraphPicked1->SetMarkerSize(2);
77 fGraphLinear1 = new TGraphErrors();
78 fGraphLinear1->SetName("Fitted points");
79 fGraphLinear1->SetMarkerColor(2);
81 fGraphPicked2 = new TGraph();
82 fGraphPicked2->SetName("Selected points");
83 fGraphPicked2->SetMarkerColor(4);
84 fGraphPicked2->SetMarkerStyle(4);
85 fGraphPicked2->SetMarkerSize(2);
87 fGraphLinear2 = new TGraphErrors();
88 fGraphLinear2->SetName("Fitted points");
89 fGraphLinear2->SetMarkerColor(2);
92 AliEveCosmicRayFitter::~AliEveCosmicRayFitter()
96 if(fLineFitter1) delete fLineFitter1;
97 if(fLineFitter2) delete fLineFitter2;
99 fTrackList->DecDenyDestroy();
103 /**************************************************************************/
104 void AliEveCosmicRayFitter::Start()
106 // Clear existing point selection and maintain connection to the
107 // TEvePointSet signal.
110 if(fConnected == kFALSE)
112 TQObject::Connect("TEvePointSet", "PointSelected(Int_t)",
113 "AliEveCosmicRayFitter", this, "AddFitPoint(Int_t)");
118 /**************************************************************************/
119 void AliEveCosmicRayFitter::Stop()
121 // Stop selection of points.
125 TQObject::Disconnect("TEvePointSet", "AddFitPoint(Int_t)");
130 /**************************************************************************/
132 void AliEveCosmicRayFitter::Reset(Int_t /*n*/, Int_t /*ids*/)
136 TEvePointSet::Reset();
139 if(fLineFitter1) fLineFitter1->Clear();
140 if(fLineFitter2) fLineFitter2->Clear();
143 /**************************************************************************/
145 void AliEveCosmicRayFitter::AddFitPoint(Int_t n)
147 // Add/remove given point depending if exists in the fSPMap.
150 TEvePointSet* ps = dynamic_cast<TEvePointSet*>((TQObject*) gTQSender);
152 std::map<Point_t, Int_t>::iterator g = fSPMap.find(Point_t(ps, n));
153 if(g != fSPMap.end())
155 Int_t idx = g->second;
156 if(idx != fLastPoint)
158 GetPoint(fLastPoint, x, y, z);
159 SetPoint(idx, x, y, z);
166 fSPMap[Point_t(ps, n)] = Size();
167 ps->GetPoint(n, x, y, z);
168 SetNextPoint(x, y, z);
172 ElementChanged(kTRUE, kTRUE);
175 /**************************************************************************/
177 void AliEveCosmicRayFitter::FitTrack()
179 // Fit selected points with TLinearFitter fitter.
181 static const TEveException eH("CosmicRayFitter::FitTrack ");
183 if(fLineFitter1) delete fLineFitter1;
184 if(fLineFitter2) delete fLineFitter2;
185 fLineFitter1 = new TLinearFitter(1, "hyp1");
186 fLineFitter2 = new TLinearFitter(1, "hyp1");
188 AliDebug(2, Form(" Selected %3d points:\n", fLastPoint+1));
190 Double_t *posXpoint = new Double_t[fLastPoint+1];
191 Double_t *posYpoint = new Double_t[fLastPoint+1];
192 Double_t *posZpoint = new Double_t[fLastPoint+1];
193 Double_t *errYpoint = new Double_t[fLastPoint+1];
194 Double_t *errZpoint = new Double_t[fLastPoint+1];
196 for (Int_t i=0; i<=fLastPoint; i++) {
198 GetPoint(i, x, y, z);
202 errYpoint[i] = 10.;//0.05*posYpoint[i];//arbitrary
203 errZpoint[i] = 10.;//0.05*posZpoint[i];//arbitrary
205 AliDebug(2, Form("(%f, %f, %f) \n", posXpoint[i], posYpoint[i], posZpoint[i]));
208 fLineFitter1->AssignData(fLastPoint+1, 1, posXpoint, posYpoint, errYpoint);
209 fLineFitter2->AssignData(fLastPoint+1, 1, posXpoint, posZpoint, errZpoint);
210 Int_t fitResult1 = fLineFitter1->Eval();
211 Int_t fitResult2 = fLineFitter2->Eval();
213 if (fitResult1 || fitResult2)
214 throw(eH + Form(" linear fit result is not ok (%1i, %1i)", fitResult1, fitResult2));
226 fLineFitter1->GetParameters(params1);
227 fLineFitter2->GetParameters(params2);
230 GetPoint(0, x, y, z);
231 y = params1(0) + x*params1(1);
232 z = params2(0) + x*params2(1);
234 rc.fP.Set(1, params1(1), params2(1));
236 TEveTrack* track = new TEveTrack(&rc, fTrackList->GetPropagator());
237 track->SetAttLineAttMarker(fTrackList);
239 TEveTrackPropagator* tp = fTrackList->GetPropagator();
241 tp->InitTrack(rc.fV, rc.fP, 1, 0);
242 tp->GoToBounds(rc.fP);
244 rc.fP.Set(-1, -params1(1), -params2(1));
245 tp->InitTrack(rc.fV, rc.fP, 1, 0);
246 tp->GoToBounds(rc.fP);
247 tp->FillPointSet(track);
250 fTrackList->AddElement(track);
253 /**************************************************************************/
254 void AliEveCosmicRayFitter::DestroyElements()
256 // Virtual method of base class Reve::RenderElement.
257 // It preserves track list to have coomon track propagator attributes.
259 TEveElement::DestroyElements();
260 gEve->AddElement(fTrackList, this);
261 fTrackList->DestroyElements();
265 /**************************************************************************/
266 void AliEveCosmicRayFitter::SumDistance3D(Int_t &, Double_t *, Double_t & sum, Double_t * par, Int_t )
269 // Square sum of distances
273 dynamic_cast<TGraph2D*>((TVirtualFitter::GetFitter())->GetObjectFit() );
276 Double_t * x = gr->GetX();
277 Double_t * y = gr->GetY();
278 Double_t * z = gr->GetZ();
279 Int_t npoints = gr->GetN();
282 for (Int_t i = 0; i < npoints; ++i) {
283 d = Distance3D(x[i],y[i],z[i],par);
285 // printf("%d (%f, %f, %f) dist:%d", i, x[i], y[i], z[i], TMath::Sqrt(d));
287 // printf("Total sum %f\n", sum);
290 /**************************************************************************/
291 Double_t AliEveCosmicRayFitter::Distance3D(Double_t x, Double_t y, Double_t z, Double_t *p)
294 // distance line point is D = | (xp-x0) cross ux |
295 // where ux is direction of line and x0 is a point in the line (like t = 0)
298 using namespace ROOT::Math;
301 XYZVector x0(0., p[0], p[2]);
302 XYZVector x1(1., p[0] + p[1], p[2] + p[3]);
303 XYZVector u = (x1-x0).Unit();
304 Double_t d2 = ((xp-x0).Cross(u)) .Mag2();
308 /**************************************************************************/
309 void AliEveCosmicRayFitter::DrawDebugGraph()
312 // Draw graph of Line fit.
315 static const TEveException eH("CosmicRayFitter::DrawDebugGraph ");
317 if(fLineFitter1 == 0 || fLineFitter2 == 0)
318 throw(eH + "fitter not set.");
322 fLineFitter1->GetParameters(params1);
323 fLineFitter2->GetParameters(params2);
327 Int_t nR = fLastPoint+1;
328 Double_t *x = new Double_t[nR];
329 Double_t *y = new Double_t[nR];
330 Double_t *z = new Double_t[nR];
331 Float_t xx=0., yy=0., zz=0.;
332 for (Int_t i=0; i<nR; i++) {
333 GetPoint(i, xx, yy, zz);
337 AliDebug(2, Form("%d (%f, %f, %f)\n", i, x[i], y[i], z[i]));
340 fGraphPicked1->Set(nR);
341 fGraphLinear1->Set(nR);
342 fGraphPicked2->Set(nR);
343 fGraphLinear2->Set(nR);
346 for (Int_t i=0; i<nR; i++)
348 yCoor = params1(0) + x[i]*params1(1);
349 zCoor = params2(0) + x[i]*params2(1);
350 fGraphPicked1->SetPoint(i, x[i], y[i]);
351 fGraphLinear1->SetPoint(i, x[i], yCoor);
352 fGraphLinear1->SetPointError(i, TMath::Abs(x[i])*0.001, TMath::Abs(yCoor)*0.05);
353 fGraphPicked2->SetPoint(i, x[i], z[i]);
354 fGraphLinear2->SetPoint(i, x[i], zCoor);
355 fGraphLinear2->SetPointError(i, TMath::Abs(x[i])*0.001, TMath::Abs(zCoor)*0.05);
364 TCanvas * canvas = 0;
365 if (gPad) gPad->Clear();
366 else if (gPad==0 || gPad->GetCanvas()->IsEditable() == kFALSE) {
367 canvas = new TCanvas("canvas", "CosmicRayFitter", 800, 400);
371 canvas->SetHighLightColor(2);
372 canvas->Range(0,0,1,1);
373 canvas->SetFillColor(0);
374 canvas->SetBorderMode(0);
375 canvas->SetBorderSize(2);
377 TPad *canvas_1 = new TPad("canvas_1", "canvas_1",0.01,0.01,0.49,0.99);
380 canvas_1->SetFillColor(0);
381 canvas_1->SetBorderSize(2);
382 canvas_1->SetFrameBorderMode(0);
383 fGraphPicked1->Draw("AP");
384 fGraphLinear1->Draw("SAME P");
385 canvas_1->Modified();
388 TPad *canvas_2 = new TPad("canvas_2", "canvas_2",0.51,0.01,0.99,0.99);
391 canvas_2->SetFillColor(0);
392 canvas_2->SetBorderSize(2);
393 canvas_2->SetFrameBorderMode(0);
394 fGraphPicked2->Draw("AP");
395 fGraphLinear2->Draw("SAME P");
396 canvas_2->Modified();