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),
68 fTrackList = new TEveTrackList("Cosmic ray");
69 fTrackList->SetTitle("muons");
70 fTrackList->SetMainColor(8);
71 gEve->AddElement(fTrackList);
73 fGraphPicked1 = new TGraph();
74 fGraphPicked1->SetName("Selected points");
75 fGraphPicked1->SetMarkerColor(4);
76 fGraphPicked1->SetMarkerStyle(4);
77 fGraphPicked1->SetMarkerSize(2);
79 fGraphLinear1 = new TGraphErrors();
80 fGraphLinear1->SetName("Fitted points");
81 fGraphLinear1->SetMarkerColor(2);
83 fGraphPicked2 = new TGraph();
84 fGraphPicked2->SetName("Selected points");
85 fGraphPicked2->SetMarkerColor(4);
86 fGraphPicked2->SetMarkerStyle(4);
87 fGraphPicked2->SetMarkerSize(2);
89 fGraphLinear2 = new TGraphErrors();
90 fGraphLinear2->SetName("Fitted points");
91 fGraphLinear2->SetMarkerColor(2);
94 AliEveCosmicRayFitter::~AliEveCosmicRayFitter()
98 if(fLineFitter1) delete fLineFitter1;
99 if(fLineFitter2) delete fLineFitter2;
101 fTrackList->DecDenyDestroy();
105 /**************************************************************************/
106 void AliEveCosmicRayFitter::Start()
108 // Clear existing point selection and maintain connection to the
109 // TEvePointSet signal.
112 if(fConnected == kFALSE)
114 TQObject::Connect("TEvePointSet", "PointSelected(Int_t)",
115 "AliEveCosmicRayFitter", this, "AddFitPoint(Int_t)");
120 /**************************************************************************/
121 void AliEveCosmicRayFitter::Stop()
123 // Stop selection of points.
127 TQObject::Disconnect("TEvePointSet", "AddFitPoint(Int_t)");
132 /**************************************************************************/
134 void AliEveCosmicRayFitter::Reset(Int_t /*n*/, Int_t /*ids*/)
138 TEvePointSet::Reset();
141 if(fLineFitter1) fLineFitter1->Clear();
142 if(fLineFitter2) fLineFitter2->Clear();
145 /**************************************************************************/
147 void AliEveCosmicRayFitter::AddFitPoint(Int_t n)
149 // Add/remove given point depending if exists in the fSPMap.
152 TEvePointSet* ps = dynamic_cast<TEvePointSet*>((TQObject*) gTQSender);
154 std::map<Point_t, Int_t>::iterator g = fSPMap.find(Point_t(ps, n));
155 if(g != fSPMap.end())
157 Int_t idx = g->second;
158 if(idx != fLastPoint)
160 GetPoint(fLastPoint, x, y, z);
161 SetPoint(idx, x, y, z);
168 fSPMap[Point_t(ps, n)] = Size();
169 ps->GetPoint(n, x, y, z);
170 SetNextPoint(x, y, z);
174 ElementChanged(kTRUE, kTRUE);
177 /**************************************************************************/
179 void AliEveCosmicRayFitter::FitTrack()
181 // Fit selected points with TLinearFitter fitter.
183 static const TEveException eH("CosmicRayFitter::FitTrack ");
185 if(fLineFitter1) delete fLineFitter1;
186 if(fLineFitter2) delete fLineFitter2;
187 fLineFitter1 = new TLinearFitter(1, "hyp1");
188 fLineFitter2 = new TLinearFitter(1, "hyp1");
190 AliDebug(2, Form(" Selected %3d points:\n", fLastPoint+1));
192 Double_t *posXpoint = new Double_t[fLastPoint+1];
193 Double_t *posYpoint = new Double_t[fLastPoint+1];
194 Double_t *posZpoint = new Double_t[fLastPoint+1];
195 Double_t *errYpoint = new Double_t[fLastPoint+1];
196 Double_t *errZpoint = new Double_t[fLastPoint+1];
198 for (Int_t i=0; i<=fLastPoint; i++) {
200 GetPoint(i, x, y, z);
204 errYpoint[i] = 10.;//0.05*posYpoint[i];//arbitrary
205 errZpoint[i] = 10.;//0.05*posZpoint[i];//arbitrary
207 AliDebug(2, Form("(%f, %f, %f) \n", posXpoint[i], posYpoint[i], posZpoint[i]));
210 fLineFitter1->AssignData(fLastPoint+1, 1, posXpoint, posYpoint, errYpoint);
211 fLineFitter2->AssignData(fLastPoint+1, 1, posXpoint, posZpoint, errZpoint);
212 Int_t fitResult1 = fLineFitter1->Eval();
213 Int_t fitResult2 = fLineFitter2->Eval();
215 if (fitResult1 || fitResult2)
216 throw(eH + Form(" linear fit result is not ok (%1i, %1i)", fitResult1, fitResult2));
228 fLineFitter1->GetParameters(params1);
229 fLineFitter2->GetParameters(params2);
232 GetPoint(0, x, y, z);
233 y = params1(0) + x*params1(1);
234 z = params2(0) + x*params2(1);
236 rc.fP.Set(1, params1(1), params2(1));
238 TEveTrack* track = new TEveTrack(&rc, fTrackList->GetPropagator());
239 track->SetAttLineAttMarker(fTrackList);
241 TEveTrackPropagator* tp = fTrackList->GetPropagator();
243 tp->InitTrack(rc.fV, 0);
244 tp->GoToBounds(rc.fP);
246 rc.fP.Set(-1, -params1(1), -params2(1));
247 tp->InitTrack(rc.fV, 0);
248 tp->GoToBounds(rc.fP);
249 tp->FillPointSet(track);
252 fTrackList->AddElement(track);
255 /**************************************************************************/
256 void AliEveCosmicRayFitter::DestroyElements()
258 // Virtual method of base class Reve::RenderElement.
259 // It preserves track list to have coomon track propagator attributes.
261 TEveElement::DestroyElements();
262 gEve->AddElement(fTrackList, this);
263 fTrackList->DestroyElements();
266 /**************************************************************************/
267 void AliEveCosmicRayFitter::SumDistance3D(Int_t &, Double_t *, Double_t & sum, Double_t * par, Int_t )
270 // Square sum of distances
274 dynamic_cast<TGraph2D*>((TVirtualFitter::GetFitter())->GetObjectFit() );
277 Double_t * x = gr->GetX();
278 Double_t * y = gr->GetY();
279 Double_t * z = gr->GetZ();
280 Int_t npoints = gr->GetN();
283 for (Int_t i = 0; i < npoints; ++i) {
284 d = Distance3D(x[i],y[i],z[i],par);
286 // printf("%d (%f, %f, %f) dist:%d", i, x[i], y[i], z[i], TMath::Sqrt(d));
288 // printf("Total sum %f\n", sum);
291 /**************************************************************************/
292 Double_t AliEveCosmicRayFitter::Distance3D(Double_t x, Double_t y, Double_t z, Double_t *p)
295 // distance line point is D = | (xp-x0) cross ux |
296 // where ux is direction of line and x0 is a point in the line (like t = 0)
299 using namespace ROOT::Math;
302 XYZVector x0(0., p[0], p[2]);
303 XYZVector x1(1., p[0] + p[1], p[2] + p[3]);
304 XYZVector u = (x1-x0).Unit();
305 Double_t d2 = ((xp-x0).Cross(u)) .Mag2();
309 /**************************************************************************/
310 void AliEveCosmicRayFitter::DrawDebugGraph()
313 // Draw graph of Line fit.
316 static const TEveException eH("CosmicRayFitter::DrawDebugGraph ");
318 if(fLineFitter1 == 0 || fLineFitter2 == 0)
319 throw(eH + "fitter not set.");
323 fLineFitter1->GetParameters(params1);
324 fLineFitter2->GetParameters(params2);
328 Int_t nR = fLastPoint+1;
329 Double_t *x = new Double_t[nR];
330 Double_t *y = new Double_t[nR];
331 Double_t *z = new Double_t[nR];
332 Float_t xx=0., yy=0., zz=0.;
333 for (Int_t i=0; i<nR; i++) {
334 GetPoint(i, xx, yy, zz);
338 AliDebug(2, Form("%d (%f, %f, %f)\n", i, x[i], y[i], z[i]));
341 fGraphPicked1->Set(nR);
342 fGraphLinear1->Set(nR);
343 fGraphPicked2->Set(nR);
344 fGraphLinear2->Set(nR);
347 for (Int_t i=0; i<nR; i++)
349 yCoor = params1(0) + x[i]*params1(1);
350 zCoor = params2(0) + x[i]*params2(1);
351 fGraphPicked1->SetPoint(i, x[i], y[i]);
352 fGraphLinear1->SetPoint(i, x[i], yCoor);
353 fGraphLinear1->SetPointError(i, TMath::Abs(x[i])*0.001, TMath::Abs(yCoor)*0.05);
354 fGraphPicked2->SetPoint(i, x[i], z[i]);
355 fGraphLinear2->SetPoint(i, x[i], zCoor);
356 fGraphLinear2->SetPointError(i, TMath::Abs(x[i])*0.001, TMath::Abs(zCoor)*0.05);
365 TCanvas * canvas = 0;
366 if (gPad) gPad->Clear();
367 else if (gPad==0 || gPad->GetCanvas()->IsEditable() == kFALSE) {
368 canvas = new TCanvas("canvas", "CosmicRayFitter", 800, 400);
372 canvas->SetHighLightColor(2);
373 canvas->Range(0,0,1,1);
374 canvas->SetFillColor(0);
375 canvas->SetBorderMode(0);
376 canvas->SetBorderSize(2);
378 TPad *canvas_1 = new TPad("canvas_1", "canvas_1",0.01,0.01,0.49,0.99);
381 canvas_1->SetFillColor(0);
382 canvas_1->SetBorderSize(2);
383 canvas_1->SetFrameBorderMode(0);
384 fGraphPicked1->Draw("AP");
385 fGraphLinear1->Draw("SAME P");
386 canvas_1->Modified();
389 TPad *canvas_2 = new TPad("canvas_2", "canvas_2",0.51,0.01,0.99,0.99);
392 canvas_2->SetFillColor(0);
393 canvas_2->SetBorderSize(2);
394 canvas_2->SetFrameBorderMode(0);
395 fGraphPicked2->Draw("AP");
396 fGraphLinear2->Draw("SAME P");
397 canvas_2->Modified();