New class TrackFitter: interface to AliRieman helix fit.
authoralja <alja@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Dec 2007 20:57:56 +0000 (20:57 +0000)
committeralja <alja@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Dec 2007 20:57:56 +0000 (20:57 +0000)
EVE/Alieve/LinkDef.h
EVE/Alieve/TrackFitter.cxx [new file with mode: 0644]
EVE/Alieve/TrackFitter.h [new file with mode: 0644]
EVE/Alieve/TrackFitterEditor.cxx [new file with mode: 0644]
EVE/Alieve/TrackFitterEditor.h [new file with mode: 0644]

index 1d763ed..363db0e 100644 (file)
@@ -33,6 +33,9 @@
 #pragma link C++ class Alieve::V0List+;
 #pragma link C++ class Alieve::V0ListEditor+;
 
+// Fit
+#pragma link C++ class Alieve::TrackFitter+;
+#pragma link C++ class Alieve::TrackFitterEditor+;
 
 //================================
 // detectors/
diff --git a/EVE/Alieve/TrackFitter.cxx b/EVE/Alieve/TrackFitter.cxx
new file mode 100644 (file)
index 0000000..dab5de7
--- /dev/null
@@ -0,0 +1,254 @@
+// $Header$
+
+#include "TrackFitter.h"
+
+//#include "TClass.h"
+#include "TCanvas.h"
+#include "TGraph.h"
+#include "TGraphErrors.h"
+
+#include "AliCluster.h"
+#include "AliRieman.h"
+#include "AliExternalTrackParam.h"
+
+#include <Reve/Track.h>
+#include <Reve/PODs.h>
+#include <Reve/ReveManager.h>
+
+using namespace Reve;
+using namespace Alieve;
+
+//______________________________________________________________________
+// TrackFitter
+//
+//  TrackFitter is an interface to helix fit. It creates a set of points, listening to signal 
+//  PointCtrlClicked() of any Reve::PointSet. Via editor it fits selected points and creates a 
+//  reconstructed track.
+// 
+
+ClassImp(TrackFitter)
+
+TrackFitter::TrackFitter(const Text_t* name, Int_t n_points, TreeVarType_e tv_type) :
+    Reve::PointSet(name, n_points, tv_type),
+
+    fGraphSelected(0),
+    fGraphFitted(0),
+
+    fRieman(0),
+    fConnected(kFALSE),
+    fTrackList(0)
+{
+  // Constructor.
+
+  SetMarkerColor(3);
+  SetOwnIds(kFALSE);
+
+  fGraphSelected = new TGraph();
+  fGraphSelected->SetName("Selected points");
+  fGraphSelected->SetMarkerColor(4);
+  fGraphSelected->SetMarkerStyle(4);  
+  fGraphSelected->SetMarkerSize(2);
+
+  fGraphFitted = new TGraphErrors();
+  fGraphFitted->SetName("Fitted points");
+  fGraphFitted->SetMarkerColor(2);
+
+  fTrackList = new TrackList("Tracks");
+  fTrackList->SetLineWidth(2);
+  fTrackList->SetLineColor(8);
+  fTrackList->IncDenyDestroy();
+  fTrackList->GetRnrStyle()->SetEditPathMarks(kTRUE);
+  gReve->AddRenderElement(fTrackList, this);
+  UpdateItems();
+}
+
+TrackFitter::~TrackFitter()
+{
+  // Destructor.
+
+  if(fRieman) delete fRieman;
+  fTrackList->DecDenyDestroy();
+  delete fTrackList;
+}
+
+/**************************************************************************/
+void TrackFitter::DestroyElements()
+{
+  // Virtual method of base class Reve::RenderElement.
+  // It preserves track list to have coomon track propagator attributes.
+
+  RenderElement::DestroyElements();
+  gReve->AddRenderElement(fTrackList, this);
+  fTrackList->DestroyElements();
+  UpdateItems();
+}
+
+/**************************************************************************/
+void TrackFitter::Start()
+{
+  // Start selection of points.
+
+  Reset();
+  if(fConnected == kFALSE)
+  {
+    TQObject::Connect("Reve::PointSet", "PointCtrlClicked(Reve::PointSet*,Int_t)",
+                     "Alieve::TrackFitter", this, "AddFitPoint(Reve::PointSet*,Int_t)");
+
+    fConnected = kTRUE;
+  }
+}
+
+void TrackFitter::Stop()
+{
+  // Stop selection of points.
+
+  if(fConnected)
+  {
+    TQObject::Disconnect("Reve::PointSet", "AddFitPoint(Reve::PointSet*,Int_t)");
+    fConnected = kFALSE;
+  }
+}
+
+/**************************************************************************/
+
+void TrackFitter::AddFitPoint(Reve::PointSet* ps, Int_t n)
+{ 
+  // Add/remove given point depending if exists in the fMapPS.
+  Float_t x, y, z;
+
+  std::map<Point_t, Int_t>::iterator g = fMapPS.find(Point_t(ps, n));
+  if(g != fMapPS.end())
+  {
+    Int_t idx = g->second;
+    if(idx != fLastPoint)
+    {
+      GetPoint(fLastPoint, x, y, z);
+      SetPoint(idx, x, y, z);
+    }
+    fMapPS.erase(g);
+    fLastPoint--;
+  }
+  else 
+  {
+    fMapPS[Point_t(ps, n)] = Size();
+    ps->GetPoint(n, x, y, z);
+    SetNextPoint(x, y, z); 
+    SetPointId(ps->GetPointId(n));
+  }
+  ResetBBox();
+  ElementChanged(kTRUE, kTRUE);
+}
+
+/**************************************************************************/
+
+void TrackFitter::FitTrack()
+{
+  // Fit selected points with AliRieman fitter.
+
+  using namespace TMath;
+
+  if(fRieman) delete fRieman;
+  fRieman = new AliRieman(Size());
+
+  Float_t x, y, z;
+  Int_t alphaIdx = 0;
+  GetPoint(alphaIdx, x, y, z);
+  Float_t minR2=x*x + y*y;
+  for (Int_t i=1; i<=fLastPoint; i++)
+  {
+    GetPoint(i, x, y, z);
+    Float_t cR2 = x*x + y*y;
+    if ( minR2 > cR2 )
+    {
+      minR2 = cR2;
+      alphaIdx = i;
+    }
+  }
+  GetPoint(alphaIdx, x, y, z);
+  fAlpha = ATan2(y, x);
+  Float_t sin = Sin(-fAlpha);
+  Float_t cos = Cos(-fAlpha);  
+  for (Int_t i=0; i<=fLastPoint; i++) { 
+    GetPoint(i, x, y, z);
+    fRieman->AddPoint(cos*x - sin*y, cos*y + sin*x, z, 1, 1);
+  }
+  fRieman->Update();
+
+  Double_t r = Sqrt(minR2);
+  Double_t param[5];
+  Double_t cov[15];
+  fRieman->GetExternalParameters(r, param, cov);
+  // curvature to pt
+  param[4] /= TrackRnrStyle::fgDefMagField*TrackRnrStyle::fgkB2C;
+  // sign in tang
+  if(param[4] < 0) param[3] *= -1;
+  AliExternalTrackParam trackParam(r, fAlpha, param, cov);
+  trackParam.Print();
+
+  // make track
+  Double_t V0[3];
+  trackParam.GetXYZAt(r, TrackRnrStyle::fgDefMagField, V0);
+  Double_t P0[3];
+  trackParam.GetPxPyPzAt(r, TrackRnrStyle::fgDefMagField, P0);
+  RecTrack rc;
+  rc.V.Set(V0); 
+  rc.P.Set(P0);
+  rc.sign = trackParam.Charge();
+
+  Track* track = new Track(&rc, fTrackList->GetRnrStyle());
+  track->SetName(Form("track %f", fAlpha));
+  PathMark* pm = new PathMark(PathMark::Daughter);
+  for(Int_t i=0; i==fLastPoint; i++)
+  {
+    GetPoint(i, x, y, z);
+    pm->V.Set(x, y, z);
+    pm->P.Set(P0); 
+    track->AddPathMark(pm);
+  }
+  track->MakeTrack();
+  track->SetAttLineAttMarker(fTrackList); 
+  gReve->AddRenderElement(track, fTrackList);
+}
+
+
+void TrackFitter::Reset(Int_t n, Int_t ids)
+{
+  // Reset selection.
+
+  if(fRieman) fRieman->Reset();
+  PointSet::Reset(n, ids);
+  fMapPS.clear();
+}
+
+/**************************************************************************/
+void TrackFitter::DrawRiemanGraph()
+{
+  // Draw graph of rieman fit.
+
+   static const Exc_t eH("TrackFitter::DrawRiemanGraph ");
+
+  if(fRieman == 0)
+    throw(eH + "fitter not set.");
+
+  Int_t nR = fRieman->GetN();
+  fGraphSelected->Set(nR);
+  fGraphFitted->Set(nR);
+
+  Double_t* x =  fRieman->GetX();  
+  Double_t* y =  fRieman->GetY();
+  Double_t* sy =  fRieman->GetSy();
+  for (Int_t i=0; i<nR; i++)
+  {
+    fGraphSelected->SetPoint(i, x[i], y[i]);
+    fGraphFitted->SetPoint(i, x[i], fRieman->GetYat(x[i]));
+    fGraphFitted->SetPointError(i, 0.1, sy[i]);
+  }
+  
+  if (gPad) gPad->Clear();
+  fGraphSelected->Draw("AP");
+  fGraphFitted->Draw("SAME P");
+  gPad->GetCanvas()->SetTitle(Form("AliRieman alpha: %f", fAlpha));
+  gPad->Modified();
+  gPad->Update();
+}
diff --git a/EVE/Alieve/TrackFitter.h b/EVE/Alieve/TrackFitter.h
new file mode 100644 (file)
index 0000000..4359dc4
--- /dev/null
@@ -0,0 +1,74 @@
+// $Header$
+
+#ifndef ALIEVE_TrackFitter_H
+#define ALIEVE_TrackFitter_H
+
+#include <Reve/PointSet.h>
+#include <TQObject.h>
+#include <map>
+
+class TGraphErrors;
+class TGraph;
+class AliRieman;
+
+namespace Reve 
+{
+class TrackList;
+}
+
+namespace Alieve {
+
+class TrackFitter : public Reve::PointSet
+{
+private:
+  TrackFitter(const TrackFitter&);            // Not implemented
+  TrackFitter& operator=(const TrackFitter&); // Not implemented
+
+  TGraph       *fGraphSelected;  // graph of selected points
+  TGraphErrors *fGraphFitted;    // graph of fitted points
+
+protected:
+  struct Point_t
+  {
+    // inner structure to check duplicates
+    Reve::PointSet* fPS;   // selected pointset
+    Int_t           fIdx;  // location in the point set array
+    Point_t(Reve::PointSet* ps, Int_t i): fPS(ps), fIdx(i){} 
+    bool operator<(const Point_t& o) const
+    { if (fPS != o.fPS) return fPS < o.fPS; return fIdx < o.fIdx; }
+  };
+
+  Float_t    fAlpha;          // transformation agle to local system (where x>>y)
+  AliRieman* fRieman;         // rieman fitter
+
+  Bool_t     fConnected;      // object connected to pointset Ctrl-shift signal 
+  
+  Reve::TrackList* fTrackList; // track list created with rieman fit 
+
+  std::map<Point_t, Int_t> fMapPS; // map of selected points from different PointSet
+public:
+  TrackFitter(const Text_t* name, Int_t n_points=0, TreeVarType_e tv_type=TVT_XYZ);
+  virtual ~TrackFitter();
+  
+  void AddFitPoint(Reve::PointSet*,Int_t);  // slot for PointCtrlClicked() signal
+
+  virtual void  DestroyElements(); // *MENU*
+
+  void       Start();
+  void       Stop();
+  void       FitTrack();
+  virtual    void  Reset(Int_t n_points=0, Int_t n_int_ids=0);
+
+  Bool_t     GetConnected(){ return fConnected; }
+  AliRieman* GetRieman(){ return fRieman; }
+
+  void       DrawRiemanGraph();
+  TGraph*    GetGraphSelected(){ return fGraphSelected; }
+  TGraphErrors* GetGraphFitted(){ return fGraphFitted; }
+
+  ClassDef(TrackFitter, 0); // Interface to AliRieman fit.
+}; // endclass TrackFitter
+
+}
+
+#endif
diff --git a/EVE/Alieve/TrackFitterEditor.cxx b/EVE/Alieve/TrackFitterEditor.cxx
new file mode 100644 (file)
index 0000000..4e767db
--- /dev/null
@@ -0,0 +1,120 @@
+// $Header$
+
+#include "TrackFitterEditor.h"
+#include <Alieve/TrackFitter.h>
+
+#include <TGButton.h>
+
+using namespace Reve;
+using namespace Alieve;
+
+//______________________________________________________________________
+// TrackFitterEditor
+//
+
+ClassImp(TrackFitterEditor)
+
+TrackFitterEditor::TrackFitterEditor(const TGWindow *p, Int_t width, Int_t height,
+            UInt_t options, Pixel_t back) :
+  TGedFrame(p, width, height, options | kVerticalFrame, back),
+  fM(0),
+  fFit(0),
+  fReset(0),
+  fStart(0),
+  fStop(0),
+  fGraph(0)
+{
+  // Constructor.
+
+  MakeTitle("TrackFitter");
+
+  fStart = new TGTextButton(this, "Start");
+  AddFrame(fStart, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 1));
+  fStart->Connect("Clicked()",
+                  "Alieve::TrackFitterEditor", this, "DoStart()");
+
+  fFit = new TGTextButton(this, "Fit");
+  AddFrame(fFit, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 1));
+  fFit->Connect("Clicked()",
+                "Alieve::TrackFitterEditor", this, "DoFit()");
+
+  fReset = new TGTextButton(this, "Reset");
+  AddFrame(fReset, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 1));
+  fReset->Connect("Clicked()",
+                  "Alieve::TrackFitterEditor", this, "DoReset()");
+
+  fStop = new TGTextButton(this, "Stop");
+  AddFrame(fStop, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 4, 1, 1, 1));
+  fStop->Connect("Clicked()",
+                 "Alieve::TrackFitterEditor", this, "DoStop()");
+
+  fGraph = new TGTextButton(this, " RiemanGraph ");
+  AddFrame(fGraph, new TGLayoutHints(kLHintsLeft, 4, 2, 4, 1));
+  fGraph->Connect("Clicked()",
+                 "Alieve::TrackFitterEditor", this, "DoGraph()");
+ }
+
+/**************************************************************************/
+
+void TrackFitterEditor::SetModel(TObject* obj)
+{ 
+  // Set model object.
+
+  fM = dynamic_cast<TrackFitter*>(obj);
+
+  if(fM->GetConnected())
+  {
+    fStart->SetState(kButtonDisabled);
+    fStop->SetState(kButtonUp);
+  }
+  else
+  { 
+    fStop->SetState(kButtonDisabled);
+    fStart->SetState(kButtonEngaged);
+    fStart->SetState(kButtonUp);
+  }
+}
+
+void TrackFitterEditor::DoFit()
+{
+  // Fit slot.
+
+  fM->FitTrack();
+  Update();
+}
+
+void TrackFitterEditor::DoReset()
+{
+  // Reset slot.
+
+  fM->Reset();
+  Update();
+}
+
+void TrackFitterEditor::DoStart()
+{
+  // Start selection slot.
+
+  fM->Start();
+  fStart->SetState(kButtonDisabled);
+  fStop->SetState(kButtonUp);
+}
+
+void TrackFitterEditor::DoStop()
+{
+  // Stop selection slot.
+
+  fM->Stop();
+  fStop->SetState(kButtonDisabled);
+  fStart->SetState(kButtonUp);
+}
+
+/**************************************************************************/
+
+void TrackFitterEditor::DoGraph()
+{
+  // Draw graph slot.
+
+  fM->DrawRiemanGraph();
+  Update();
+}
diff --git a/EVE/Alieve/TrackFitterEditor.h b/EVE/Alieve/TrackFitterEditor.h
new file mode 100644 (file)
index 0000000..bb33ce5
--- /dev/null
@@ -0,0 +1,48 @@
+// $Header$
+
+#ifndef ALIEVE_TrackFitterEditor_H
+#define ALIEVE_TrackFitterEditor_H
+
+#include <TGedFrame.h>
+
+class TGCheckButton;
+class TGNumberEntry;
+class TGColorSelect;
+
+namespace Alieve {
+
+class TrackFitter;
+
+class TrackFitterEditor : public TGedFrame
+{
+private:
+  TrackFitterEditor(const TrackFitterEditor&);            // Not implemented
+  TrackFitterEditor& operator=(const TrackFitterEditor&); // Not implemented
+
+protected:
+  TrackFitter* fM; // fModel dynamic-casted to TrackFitterEditor
+
+  TGTextButton* fFit;   // button to fit selection
+  TGTextButton* fReset; // button to reset selection
+  TGTextButton* fStart; // button to connect to signal
+  TGTextButton* fStop;  // button to disconnect from signal
+  TGTextButton* fGraph; // button to draw graph
+
+public:
+  TrackFitterEditor(const TGWindow* p=0, Int_t width=170, Int_t height=30, UInt_t options = kChildFrame, Pixel_t back=GetDefaultFrameBackground());
+  virtual ~TrackFitterEditor() {}
+
+  virtual void SetModel(TObject* obj);
+
+  void DoStart();
+  void DoFit();
+  void DoReset(); 
+  void DoStop();
+  void DoGraph();
+
+  ClassDef(TrackFitterEditor, 0); // Editor for TrackFitter class.
+}; // endclass TrackFitterEditor
+
+}
+
+#endif