New classes for the neural tracking algorithm (from A. Pulvirenti)
authorbarbera <barbera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 Jan 2002 09:24:46 +0000 (09:24 +0000)
committerbarbera <barbera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 Jan 2002 09:24:46 +0000 (09:24 +0000)
ITS/AliITSglobalRecPoint.cxx [new file with mode: 0644]
ITS/AliITSglobalRecPoint.h [new file with mode: 0644]
ITS/AliITSneuralTrack.cxx [new file with mode: 0644]
ITS/AliITSneuralTrack.h [new file with mode: 0644]
ITS/AliITSneuralTracker.cxx [new file with mode: 0644]
ITS/AliITSneuralTracker.h [new file with mode: 0644]
ITS/ITSLinkDef.h
ITS/ITSneuralCompleteEval.C [new file with mode: 0644]
ITS/ITSneuralTracking.C [new file with mode: 0644]
ITS/ITSstoreFindableTracks.C [new file with mode: 0644]
ITS/Makefile

diff --git a/ITS/AliITSglobalRecPoint.cxx b/ITS/AliITSglobalRecPoint.cxx
new file mode 100644 (file)
index 0000000..a800531
--- /dev/null
@@ -0,0 +1,173 @@
+#include <stdlib.h>
+#include <iostream.h>
+
+#include <TROOT.h>
+#include <TObject.h>
+#include <TMath.h>
+#include <TString.h>
+
+#include "AliITSglobalRecPoint.h"
+
+
+ClassImp(AliITSglobalRecPoint)
+//
+//
+//
+AliITSglobalRecPoint::AliITSglobalRecPoint()
+{
+       // Default constructor:
+       // sets to zero all members
+       fLayer = 0;
+       
+       fGX = fGSX = 0.0;
+       fGY = fGSY = 0.0;
+       fGZ = fGSZ = 0.0;
+       
+       fR2 = fR3 = fPhi = fTheta = 0.0;
+       
+       fLabel[0] = fLabel[1] = fLabel[2] = -1;
+       fKalmanLabel = 0;
+       fSign = 0;
+       fModule = 0;
+       fPosInModule = 0;
+       
+       fUsed = 0;
+}
+//
+//
+//
+AliITSglobalRecPoint::AliITSglobalRecPoint(Double_t gx, Double_t gy, 
+       Double_t gz, Double_t gsx, Double_t gsy, Double_t gsz, Int_t l) : 
+       fGX(gx), fGY(gy), fGZ(gz), fGSX(gsx), fGSY(gsy), fGSZ(gsz), fLayer(l)
+{
+       fR2 = TMath::Sqrt(fGX*fGX + fGY*fGY);
+       fR3 = TMath::Sqrt(fGX*fGX + fGY*fGY + fGZ*fGZ); 
+       fPhi = TMath::ATan2(fGY, fGX);
+       if (fPhi < 0.0) fPhi = 2.0 * TMath::Pi() + fPhi;
+       fTheta = TMath::ATan2(fR2, fGZ);
+       
+       fLabel[0] = fLabel[1] = fLabel[2] = -1;
+       fUsed = 0;
+       fKalmanLabel = 0;
+       fSign = 0;
+       fModule = 0;
+       fPosInModule = 0;
+}
+//
+//
+/*
+Double_t AliITSglobalRecPoint::GetGlobalSigmaR2()
+{      
+       // Square sigma of the 2-D radius:
+       // = X^2 * Sx^2 + Y^2 * Sy^2
+       
+       Double_t answer = fGX*fGX*fGSigmaX + fGY*fGY*fGSigmaY;
+       return answer / (fR2 * fR2);
+}
+//
+//
+//
+Double_t AliITSglobalRecPoint::GetGlobalSigmaR3()
+{
+       // Square sigma of the 3-D radius:
+       // = (X^2 * Sx^2 + Y^2 * Sy^2 + Z^2 * Sz^2) / R^2
+       // R in 3-D, r in 2-D
+       
+       Double_t answer = fGX*fGX*fGSigmaX + fGY*fGY*fGSigmaY + fGZ*fGZ*fGSigmaZ;
+       return answer / (fR3 * fR3);
+}
+//
+//
+//
+Double_t AliITSglobalRecPoint::GetGlobalSigmaTheta()
+{
+       // Square sigma of theta:
+       // = (Z^2 * (X^2 * Sx^2 + Y^2 * Sy^2) + r^4 * Sz^2) / (R^4 * r^2)
+       // R in 3-D, r in 2-D
+       
+       Double_t answer = fGZ*fGZ*(fGX*fGX*fGSigmaX + fGY*fGY*fGSigmaY) + fR2*fR2*fR2*fR2*fGSigmaZ;
+       return answer / (fR3*fR3*fR3*fR3*fR2*fR2);
+}
+//
+//
+//
+Double_t AliITSglobalRecPoint::GetGlobalSigmaPhi()
+{
+       // Square sigma of phi:
+       // = (Y^2 * Sx^2 + X^2 * Sy^2) / r^4
+       // R in 3-D, r in 2-D
+       
+       Double_t answer = fGY*fGY*fGSigmaX + fGX*fGX*fGSigmaY;
+       return answer / (fR2 * fR2 * fR2 * fR2);
+}
+//
+//
+//
+Bool_t AliITSglobalRecPoint::SharesID(AliITSRecPoint* pt)
+{
+       // Controls if there is a track index shared by two points
+       
+       Bool_t ok = kFALSE;
+       Int_t i, j;
+       for (i = 0; i < 3; i++) {
+               if (fTracks[i] < 0) continue;
+               for (j = 0; j < 3; j++) {
+                       if (pt->fTracks[j] < 0) continue;
+                       ok = ok || (fTracks[i] == pt->fTracks[j]);
+               }
+       }
+       return ok;
+}
+*/
+//
+//
+Double_t AliITSglobalRecPoint::DPhi(AliITSglobalRecPoint *p)
+{
+       // Absolute value of the difference
+       // between 'phi' coordinates of two points
+       // controlled in order to avoid that, for
+       // reasons of initial values, it come > 180. degrees
+       
+       Double_t phi = TMath::Abs(fPhi - p->fPhi);
+       if (phi > TMath::Pi())
+               phi = 2.0 * TMath::Pi() - phi;
+       return phi;
+}
+//
+//
+//
+Double_t AliITSglobalRecPoint::DTheta(AliITSglobalRecPoint *p)
+{
+       // Absolute value of the difference
+       // between 'theta' coordinates of two points
+       
+       return TMath::Abs(fTheta - p->fTheta);
+}
+//
+//
+//
+Int_t AliITSglobalRecPoint::Compare(const TObject *O) const
+{
+       // Criterion for sorting:
+       // p1 < p2 if p1.phi < p2.phi;
+       
+       // Casting to convert the given argument to rec-point
+       AliITSglobalRecPoint *you = (AliITSglobalRecPoint*)O;
+       
+       // Comparation
+       if (fLayer < you->fLayer)
+               return -1;
+       else if (fLayer > you->fLayer)
+               return 1;
+       else {
+               if (fPhi < you->fPhi)
+                       return -1;
+               else if (fPhi > you->fPhi)
+                       return 1;
+               else
+                       return 0;
+       }
+}
+//
+//
+//
diff --git a/ITS/AliITSglobalRecPoint.h b/ITS/AliITSglobalRecPoint.h
new file mode 100644 (file)
index 0000000..c430ae0
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef ALIITSGLOBALRECPOINT_H
+#define ALIITSGLOBALRECPOINT_H
+
+class AliITSglobalRecPoint : public TObject {
+
+       public:
+                       
+               AliITSglobalRecPoint();
+      AliITSglobalRecPoint(Double_t gx, Double_t gy, Double_t gz, Double_t gsx, Double_t gsy, Double_t gsz, Int_t l);
+               
+               virtual ~AliITSglobalRecPoint() { }
+               
+               // difference in azymuthal angle
+               Double_t DPhi  (AliITSglobalRecPoint *p); 
+               // difference in polar angle
+               Double_t DTheta(AliITSglobalRecPoint *p); 
+               // checks if the pt contains a given positive label
+               Bool_t   HasID (Int_t ID)      
+               { if (ID < 0) return kFALSE; else return (fLabel[0]==ID || fLabel[1]==ID || fLabel[2]==ID); }
+               // checks if the pt shares at least a positive label with another one
+               Bool_t   SharesID(AliITSglobalRecPoint *p) 
+               { return (HasID(p->fLabel[0]) || HasID(p->fLabel[1]) || HasID(p->fLabel[2])); }
+               
+               // Parameters for sorting
+               Bool_t  IsSortable() const { return kTRUE; }
+               Int_t   Compare(const TObject *O) const;
+               
+       public:
+                       
+               Double_t fGX, fGY, fGZ; // (x,y,z) in the global reference
+                       
+               Double_t fR2;    // = sqrt(x^2 + y^2)
+               Double_t fR3;    // = sqrt(x^2 + y^2 + z^2)
+               Double_t fPhi;   // = atan(y/x)
+               Double_t fTheta; // = acos(z/r3)
+               
+               Double_t fGSX; //
+               Double_t fGSY; // sigmas of global coords
+               Double_t fGSZ; //
+               
+               Int_t fModule;      // ITS module containing the point
+               Int_t fPosInModule; // position in TClonesArray of TreeR
+               Int_t fLayer;       // ITS layer containing the point
+               Int_t fLabel[3];    // Generated tracks containing the point
+               Int_t fKalmanLabel; // Kalman recognized track containing the point
+               
+               Int_t fSign;        //   0 if the point doesn't belong to a Kalman track
+                                   // + 1 if the point belongs to a Kalman good track
+                                   // - 1 if the point belongs to a Kalman fake track
+               
+               Int_t fUsed;        // a flag to avoid point recycling
+               
+               ClassDef(AliITSglobalRecPoint, 1) // AliITSglobalRecPoints class
+};
+
+#endif
diff --git a/ITS/AliITSneuralTrack.cxx b/ITS/AliITSneuralTrack.cxx
new file mode 100644 (file)
index 0000000..d803132
--- /dev/null
@@ -0,0 +1,266 @@
+#include <fstream.h>
+#include <stdlib.h>
+
+#include <TObject.h>
+#include <TROOT.h>
+#include <TMath.h>
+#include <TString.h>
+
+#include "AliITSglobalRecPoint.h"
+#include "AliITSneuralTracker.h"
+
+#include "AliITSneuralTrack.h"
+
+
+
+ClassImp(AliITSneuralTrack)
+//
+//
+//
+AliITSneuralTrack::AliITSneuralTrack()
+{
+       Int_t i;
+       for (i = 0; i < 6; i++) fPoint[i] = 0;
+}
+//
+//
+//
+AliITSneuralTrack::~AliITSneuralTrack() 
+{
+       Int_t i;
+       for (i = 0; i < 6; i++) delete fPoint[i];
+}
+//
+//
+//
+Int_t AliITSneuralTrack::CheckMe(Bool_t verbose)
+{
+       Int_t l, stored = 0;
+       TString empty("Not filled slots: ");
+       for (l = 0; l < 6; l++) {
+               if (fPoint[l]) 
+                       stored++;
+               else {
+                       empty += l;
+                       empty += ' ';
+               }
+       }
+               
+       if (stored < 6 && verbose) Warning("", empty);
+       return stored;
+}
+//
+//
+//
+Int_t AliITSneuralTrack::EvaluateTrack(Bool_t verbose, Int_t min, Int_t* &good)
+{
+       Int_t i, j, k = 0, count[18], id[18];
+       for (i = 0; i < 6; i++) {
+               for (j = 0; j < 3; j++) {
+                       if (fPoint[i])
+                               id[k] = fPoint[i]->fLabel[j];
+                       else
+                               id[k] = -1;
+                       count[k] = 0;
+                       k++;
+               }
+       }
+       for (i = 0; i < 18; i++) {
+               for (j = i+1; j < 18; j++) {
+                       if (id[i] == id[j] || id[j] < 0) id[j] = -1;
+               }
+       }
+       for (i = 0; i < 18; i++) {
+               if (id[i] < 0) continue;
+               for (j = 0; j < 6; j++) {
+                       if (fPoint[j] && fPoint[j]->HasID(id[i])) count[i]++;
+               }
+       }
+       Int_t index[18], best;
+       TMath::Sort(18, count, index);
+       best = id[index[0]];
+       if (verbose) {
+               if (count[index[0]]<min) cout << "\t";
+               cout << best << " " << count[index[0]] << endl;
+       }
+               
+       if (good) delete [] good;
+       good = new Int_t[6];
+       for (i = 0; i < 6; i++) {
+               good[i] = 0;
+               if (!fPoint[i])
+                       good[i] = -1;
+               else if (fPoint[i] && fPoint[i]->HasID(best))
+                       good[i] = 1;
+               else if (fPoint[i]->fLabel[0] < 0 && fPoint[i]->fLabel[1] < 0 && fPoint[i]->fLabel[2] < 0)
+                       good[i] = -1;
+       }
+       
+       if (count[index[0]] < min) best = -best;
+       
+       return best;
+       
+       
+       
+       /*
+       if (good) delete [] good;
+       good = new Int_t[6];
+       Int_t count = CheckMe(verbose);
+       
+       if (count < min) return -9999999;
+       
+       Int_t i, l, max = 0, best = 0;
+       for (l = 0; l < 6; l++) {
+               for (i = 0; i < 3; i++) {
+                       if (fPoint[l].fLabel[i] > max) max = fPoint[l].fLabel[i];
+               }
+       }
+       
+       count = max + 1;
+       Int_t *counter = new Int_t[count];
+       for (i = 0; i < count; i++) counter[i] = 0;
+       
+       for (l = 0; l < 6; l++) {
+               for (i = 0; i < 3; i++) {
+                       if (fPoint[l].fLabel[i] >= 0) 
+                               counter[fPoint[l].fLabel[i]]++;
+               }
+       }
+       
+       for (i = 0; i < count; i++) {
+               if (counter[i] > counter[best]) best = i;
+       }
+       
+       for (l = 0; l < 6; l++) {
+               good[l] = 0;
+               if (fPoint[l].fLabel[0] == best || fPoint[l].fLabel[1] == best || fPoint[l].fLabel[2] == best)
+                       good[l] = 1;
+               else if (fPoint[l].fLabel[0] < 0 && fPoint[l].fLabel[1] < 0 && fPoint[l].fLabel[2] < 0)
+                       good[l] = -1;
+       }
+       
+       if (counter[best] < min) best = -best;
+       delete counter;
+       return best;
+       */
+}
+//
+//
+//
+void AliITSneuralTrack::GetCoords(Double_t* &x, Double_t* &y, Double_t* &z)
+{
+       if (x) delete [] x; x = new Double_t[6];
+       if (y) delete [] y; y = new Double_t[6];
+       if (z) delete [] z; z = new Double_t[6];
+       
+       Int_t i;
+       
+       for (i = 0; i < 6; i++) {
+               x[i] = y[i] = z[i] = 0.0;
+               if (!fPoint[i]) continue;
+               x[i] = fPoint[i]->fGX;
+               y[i] = fPoint[i]->fGY;
+               z[i] = fPoint[i]->fGZ;
+       }
+}
+//
+//
+//
+void AliITSneuralTrack::CopyPoint(AliITSglobalRecPoint *p)
+{
+       Int_t layer = p->fLayer;
+       if (layer < 0 || layer > 6) {
+               Error("", Form("Wrong layer [%d]", layer));
+               return;
+       }
+       
+       fPoint[layer] = new AliITSglobalRecPoint;
+       fPoint[layer]->fGX = p->fGX;
+       fPoint[layer]->fGY = p->fGY;
+       fPoint[layer]->fGZ = p->fGZ;
+       fPoint[layer]->fGSX = p->fGSX;
+       fPoint[layer]->fGSY = p->fGSY;
+       fPoint[layer]->fGSZ = p->fGSZ;
+       fPoint[layer]->fLayer = layer;
+       fPoint[layer]->fLabel[0] = p->fLabel[0];
+       fPoint[layer]->fLabel[1] = p->fLabel[1];
+       fPoint[layer]->fLabel[2] = p->fLabel[2];
+}
+//
+//
+//
+void AliITSneuralTrack::Print(Option_t *option, Int_t min)
+{
+       Int_t *vuoto = 0;
+       TString opt(option);
+       opt.ToUpper();
+       Int_t id = EvaluateTrack(0, min, vuoto);
+       if (opt.Contains("A")) {
+               cout << "\nEvaluated ID for this track: ";
+               cout.width(8);
+               if (id >= 0) {
+                       cout << id;
+                       cout << " [good]";
+               }
+               else {
+                       cout << -id;
+                       cout << " [fake]";
+               }
+       }
+       cout << endl << endl;
+}
+//
+//
+//
+void AliITSneuralTrack::Kinks(Int_t &pos, Int_t &neg, Int_t &incr, Int_t &decr)
+{
+       Int_t i;
+       Double_t dphi, dphi_old = 0.0;
+       pos = neg = incr = decr = 0;
+       for (i = 1; i < 6; i++) {
+               dphi = fPoint[i]->fPhi - fPoint[i-1]->fPhi;
+               if (dphi > 0.0) pos++; else neg++;
+               if (TMath::Abs(dphi) > dphi_old) incr++; else decr++;
+               dphi_old = TMath::Abs(dphi);
+       }
+}
+//
+//
+//
+Double_t AliITSneuralTrack::FitXY(Double_t VX, Double_t VY)
+{
+       Int_t i;
+       Double_t X, Y, D, R;
+       Double_t rx(0.0), ry(0.0), x2(0.0), y2(0.0), xy(0.0);
+       for (i = 0; i < 6; i++) {
+               X = fPoint[i]->fGX - VX;
+               Y = fPoint[i]->fGY - VY;
+               R = X * X + Y * Y;
+               rx += R * X;
+               ry += R * Y;
+               x2 += X * X;
+               y2 += Y * Y;
+               xy += X * Y;
+       }
+  
+       D = 2 * (x2 * y2 - xy * xy);
+       if (D == 0.0) 
+               return 1000.0;
+       else {
+               X = (rx * y2 - ry * xy) / D;
+               Y = (ry * x2 - rx * xy) / D;
+               fFitRadius  = TMath::Sqrt(X * X + Y * Y);
+               fFitXC = X + VX;
+               fFitYC = Y + VY;
+       }
+  
+       fSqChi = 0.0;
+       for (i = 0; i < 6; i++) {
+               X = fPoint[i]->fGX - fFitXC;
+               Y = fPoint[i]->fGY - fFitYC;
+               fSqChi += ((X * X + Y * Y) / (fFitRadius * fFitRadius)) * ((X * X + Y * Y) / (fFitRadius * fFitRadius));
+       }
+       fSqChi /= 6.0;
+       fSqChi = TMath::Sqrt(fSqChi);
+       return fSqChi;
+}
diff --git a/ITS/AliITSneuralTrack.h b/ITS/AliITSneuralTrack.h
new file mode 100644 (file)
index 0000000..26fceb0
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef ALIITSNEURALTRACK_H
+#define ALIITSNEURALTRACK_H
+
+class AliITSglobalRecPoint;
+
+class AliITSneuralTrack : public TObject {
+       
+       friend class AliITSneuralTracker;
+
+public:
+                AliITSneuralTrack();
+       virtual ~AliITSneuralTrack();
+       
+       Double_t GetSqChi() {return fSqChi;}
+       Double_t GetR(Double_t &Xc, Double_t &Yc)
+               {Xc=fFitXC; Yc=fFitYC; return fFitRadius;}
+               
+       Int_t  CheckMe(Bool_t verbose);
+       Int_t  EvaluateTrack(Bool_t verbose, Int_t min, Int_t* &good);
+               
+       void GetCoords(Double_t* &x, Double_t* &y, Double_t* &z);
+       void CopyPoint(AliITSglobalRecPoint *p);
+       void Print(Option_t *option, Int_t min);
+       void Kinks(Int_t &pos, Int_t &neg, Int_t &decr, Int_t &incr);
+                       
+       AliITSglobalRecPoint* GetPoint(Int_t i) { return fPoint[i]; }
+               
+private:
+       
+       Double_t FitXY(Double_t VX, Double_t VY); //!
+               
+       Double_t fFitXC;
+       Double_t fFitYC;
+       Double_t fFitRadius;
+       Double_t fFitTanL;
+       Double_t fSqChi;
+       
+       AliITSglobalRecPoint *fPoint[6]; 
+       
+       ClassDef(AliITSneuralTrack, 1)
+};
+
+#endif
diff --git a/ITS/AliITSneuralTracker.cxx b/ITS/AliITSneuralTracker.cxx
new file mode 100644 (file)
index 0000000..4779b4a
--- /dev/null
@@ -0,0 +1,694 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: Alberto Pulvirenti.                                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ *                                                                        *
+ * track finder for ITS stand-alone with neural network algorithm         *
+ * This class defines a Hopfield MFT neural network simulation            *
+ * which reads all recpoints from an event and produces a tree with       *
+ * the points belonging to recognized tracks                              *
+ * the TTree obtained as the output file will be saved in a .root file    * 
+ * and it must be read by groups of six entries at a time                 *
+ **************************************************************************/
+
+
+#include <fstream.h>
+#include <stdlib.h>
+
+#include <TROOT.h>
+#include <TFile.h>
+#include <TObjArray.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TRandom.h>
+#include <TVector3.h>
+
+#include "AliRun.h"
+#include "AliITS.h"
+#include "AliITSgeom.h"
+#include "AliITSgeomMatrix.h"
+#include "AliITSRecPoint.h"
+#include "AliITSglobalRecPoint.h"
+#include "AliITSneuralTrack.h"
+#include "AliITSneuralTracker.h"
+
+ClassImp(AliITSneuralTracker)
+
+
+// ====================================================================================================
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AliITSneuralTracker <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// ====================================================================================================
+
+AliITSneuralTracker::AliITSneuralTracker() 
+{
+       //
+       // Default constructor (not for use)
+       //
+       Int_t i = 0;
+       fCurvCut = 0;
+       for (i = 0; i < 6; i++) {
+               fPoints[i] = 0;
+               if (i < 5) fNeurons[i] = 0;
+       }
+       fTracks = 0;
+}
+//---------------------------------------------------------------------------------------------------------
+AliITSneuralTracker::AliITSneuralTracker (Int_t nsecs, Int_t ncurv, Double_t *curv, Double_t theta)
+{ 
+       // Argumented constructor
+       // ----------------------
+       // gets the number of azymuthal sectors,
+       // the number of curvature cut steps and their cut values, 
+       // and then the polar angle cut.
+       // Be careful not to put 'ncurv' greater than the dimension of the 
+       // 'curv' array (--> segmentation fault)
+       
+       fSectorNum   = nsecs;
+       fSectorWidth = 2.0 * TMath::Pi()/(Double_t)nsecs;
+               
+       fCurvNum = ncurv;
+       fCurvCut = new Double_t[ncurv];
+       Int_t i;
+       for (i = 0; i < ncurv; i++) fCurvCut[i] = curv[i];
+       
+       fThetaCut = theta;
+       fThetaNum = (Int_t)(TMath::Pi() / theta) + 1;
+       if (fThetaNum < 1) fThetaNum = 1;
+               
+       cout << "\nClass AliITSneuralTracker invoked with " << fSectorNum << " phi secs.";
+       cout << " and " << fThetaNum << " theta secs.\n" << endl;
+       
+       Int_t k, j;
+       for (k = 0; k < 6; k++) {
+               fPoints[k] = new TObjArray**[fSectorNum];
+               for (i = 0; i < fSectorNum; i++) {
+                       fPoints[k][i] = new TObjArray*[fThetaNum];
+                       for (j = 0; j < fThetaNum; j++) fPoints[k][i][j] = new TObjArray(0);
+               }
+               if (k < 6) fNeurons[k] = new TObjArray(0);
+       }
+       
+       fTracks = new TObjArray(1);
+}
+//---------------------------------------------------------------------------------------------------------
+AliITSneuralTracker::~AliITSneuralTracker() 
+{
+       // Destructor
+       // ----------
+       // clears the TObjArrays and all heap objects
+       
+       Int_t lay, sec, k;
+       delete [] fCurvCut;
+       
+       for (lay = 0; lay < 6; lay++) {
+               for (sec = 0; sec < fSectorNum; sec++) {
+                       for (k = 0; k < fThetaNum; k++) {
+                               fPoints[lay][sec][k]->Delete();
+                       }
+               }
+               delete [] fPoints[lay];
+               if (lay < 5) {
+                       fNeurons[lay]->Delete();
+                       delete fNeurons[lay];
+               }
+       }
+       
+       fTracks->Delete();
+}
+//---------------------------------------------------------------------------------------------------------
+Int_t AliITSneuralTracker::ReadFile(const Text_t *fname, Int_t evnum)
+{
+       // File reader
+       // -----------
+       // Reads a ROOT file in order to retrieve recpoints.
+       // the 'evnum' argument can have two meanings:
+       // if it is >= 0 it represents the event number to retrieve the correct gAlice
+       // if it is < 0, instead, this means that the open file contains 
+       // a 'TreeP' tree, with all points which remained unused 
+       // after the Kalman tracking procedure (produced via the ITSafterKalman.C macro)
+       // the return value is the number of collected points 
+       // (then, if errors occur, the method returns 0)
+       
+       TFile *file = new TFile(fname, "read");
+       TTree *tree = 0;
+       Int_t i, nentries, total, sector, mesh;
+       
+       if (evnum < 0) {
+               tree = (TTree*)file->Get("TreeP0");
+               if (!tree) {
+                       Error("", "Specifying evnum < 0, I expect to find a 'TreeP' tree in the file, but there isn't any");
+                       return 0;
+               }
+               AliITSglobalRecPoint *p = 0;
+               tree->SetBranchAddress("Points", &p);
+               nentries = (Int_t)tree->GetEntries();
+               total = 0; 
+               for (i = 0; i < nentries; i++) {
+                       tree->GetEntry(i);
+                       AliITSglobalRecPoint *q = new AliITSglobalRecPoint(*p);
+                       sector = (Int_t)(q->fPhi / fSectorWidth);
+                       mesh = (Int_t)(q->fTheta / fThetaCut);
+                       q->fUsed = 0;
+                       fPoints[q->fLayer][sector][mesh]->AddLast(q);
+                       total++;
+               }
+               return total;
+       }
+       
+       if (gAlice) { delete gAlice; gAlice = 0; }
+       gAlice = (AliRun*)file->Get("gAlice");
+       if (!gAlice) {
+               Error("", "gAlice is NULL, maybe wrong filename...");
+               return 0;
+       }
+
+       Int_t nparticles = (Int_t)gAlice->GetEvent(evnum);
+       if (!nparticles) {
+               Error("", "No particles found");
+               return 0;
+       }
+
+       AliITS *its = (AliITS*)gAlice->GetModule("ITS");
+       if (!its) {
+               Error("", "No ITS found");
+               return 0;
+       }
+
+       AliITSgeom *geom = (AliITSgeom*)its->GetITSgeom();
+       if (!geom) {
+               Error("", "AliITSgeom is NULL");
+               return 0;
+       }
+
+       tree = gAlice->TreeR();
+       if (!tree) {
+               Error("", "TreeR() returned NULL");
+               return 0;
+       }
+
+       nentries = (Int_t)tree->GetEntries();
+       if (!nentries) {
+               Error("", "TreeR is empty");
+               return 0;
+       }
+
+       // Reading objects initialization
+       Int_t k, entry, lay, lad, det;
+       Double_t l[3], g[3], ll[3][3], gg[3][3];
+       
+       TObjArray *recsArray = its->RecPoints();
+       AliITSRecPoint *recp;
+       AliITSglobalRecPoint *pnt = 0;
+       
+       total = 0;
+       for(entry = 0; entry < nentries; entry++) {
+               if (entry > geom->GetLastSSD()) continue;
+               its->ResetRecPoints();
+               tree->GetEvent(entry);
+               TObjArrayIter recs(recsArray);
+               AliITSgeomMatrix *gm = geom->GetGeomMatrix(entry);
+               geom->GetModuleId(entry, lay, lad, det);
+               lay--;
+               while ((recp = (AliITSRecPoint*)recs.Next())) {
+                       // conversion to global coordinate system
+                       for (i = 0; i < 3; i++) {
+                               l[i] = g[i] = 0.0;
+                               for (k = 0; k < 3; k++) {
+                                       ll[i][k] = 0.0;
+                                       gg[i][k] = 0.0;
+                               }
+                       }
+                       // local to global conversions of coords
+                       l[0] = recp->fX;
+                       l[1] = 0.0;
+                       l[2] = recp->fZ;
+                       gm->LtoGPosition(l, g);
+                       // local to global conversions of sigmas
+                       ll[0][0] = recp->fSigmaX2;
+                       ll[2][2] = recp->fSigmaZ2;
+                       gm->LtoGPositionError(ll, gg);
+                       // instantiation of a new global rec-point
+                       pnt = new AliITSglobalRecPoint(g[0], g[1], g[2], gg[0][0], gg[1][1], gg[2][2], lay);
+                       // copy of owner track labels
+                       for (i = 0; i < 3; i++) pnt->fLabel[i] = recp->fTracks[i];
+                       sector = (Int_t)(pnt->fPhi / fSectorWidth);
+                       mesh = (Int_t)(pnt->fTheta / fThetaCut);
+                       pnt->fUsed = 0;
+                       fPoints[lay][sector][mesh]->AddLast(pnt);
+                       total++;
+               }
+       }
+       
+       return total;
+}
+//---------------------------------------------------------------------------------------------------------
+void AliITSneuralTracker::Go(const char* filesave, Bool_t flag)
+{
+       // Global working method
+       // ---------------------
+       // It's the method which calls all other ones,
+       // in order to analyze the whole ITS points ensemble
+       // It's the only method to use, besides the parameter setters,
+       // so, all other methods are defined as private
+       // (see header file)
+       // the flag meaning is explained in the 'Initialize' method
+       
+       Int_t i; 
+       for (i = 0; i < fSectorNum; i++) DoSector(i, flag);
+       cout << endl << "Saving results in file " << filesave << "..." << flush;
+       TFile *f = new TFile(filesave, "recreate");
+       fTracks->Write();
+       cout << "done" << endl;
+       f->Close();
+}
+
+//=========================================================================================================
+// * * *   P R I V A T E   S E C T I O N   * * *
+//=========================================================================================================
+
+Int_t AliITSneuralTracker::Initialize(Int_t secnum, Int_t curvnum, Bool_t flag)
+{
+       // Network initializer
+       // -------------------
+       // Fills the neuron arrays, following the cut criteria for the selected step
+       // (secnum = sector to analyze, curvnum = curvature cut step to use)
+       // It also sets the initial random activation.
+       // In order to avoid a large number of 'new' operations, all existing neurons
+       // are reset and initialized with the new values, and are created new unit only if
+       // it turns out to be necessary
+       // the 'flag' argument is used to decide if the lower edge in the intevral
+       // of the accepted curvatures is given by zero (kFALSE) or by the preceding used cut (kTRUE)
+       // (if this is the first step, anyway, the minimum is always zero)
+       
+       Int_t l, m, k, neurons = 0;
+       
+       for (l = 0; l < 5; l++) fNeurons[l]->Delete();
+       
+       AliITSneuron *unit = 0;
+       Double_t abscurv, max = fCurvCut[curvnum], min = 0.0;
+       if (flag && curvnum > 0) min = fCurvCut[curvnum - 1];
+       AliITSglobalRecPoint *inner = 0, *outer = 0;
+       for (l = 0; l < 5; l++) {
+               for (m = 0; m < fThetaNum; m++) {
+                       TObjArrayIter inners(fPoints[l][secnum][m]);
+                       while ((inner = (AliITSglobalRecPoint*)inners.Next())) {
+                               if (inner->fUsed > 0) continue; // points can't be recycled
+                               for (k = m-1; k <= m+1; k++) {
+                                       if (k < 0 || k >= fThetaNum) continue; // to avoid seg faults 
+                                       TObjArrayIter outers(fPoints[l+1][secnum][k]);
+                                       while ((outer = (AliITSglobalRecPoint*)outers.Next())) {
+                                               if (outer->fUsed > 0) continue;  // points can't be recycled
+                                               if (inner->DTheta(outer) > fThetaCut) continue;
+                                               unit = new AliITSneuron;
+                                               unit->fInner = inner;
+                                               unit->fOuter = outer;
+                                               CalcParams(unit);
+                                               abscurv = TMath::Abs(unit->fCurv);
+                                               if (unit->fDiff > fDiff || abscurv < min || abscurv > max) {
+                                                       delete unit;
+                                                       continue;
+                                               }
+                                               unit->fActivation = gRandom->Rndm() * (fMax - fMin) + fMin;
+                                               fNeurons[l]->AddLast(unit);
+                                               neurons++;
+                                       } // end loop on candidates for outer point for neurons
+                               }
+                       } // end loop on candidates inner points for neuron
+               }
+       } // end loop on layers
+       return neurons;
+}
+//---------------------------------------------------------------------------------------------------------
+Bool_t AliITSneuralTracker::Update()
+{
+       // Updating cycle
+       // --------------
+       // Performs an updating cycle, by summing all the
+       // gain and cost contribution for each neuron and
+       // updating its activation.
+       // An asynchronous method is followed, with the order
+       // according that the neurons have been created
+       // Time wasting is avoided by dividing the neurons 
+       // into different arrays, depending on the layer of their inner point.
+       // The return value answers the question: "The network has stabilized?"
+       
+       Int_t j, l;
+       Double_t actOld, actNew, argNew, totDiff = 0.0;
+       Double_t sumInh, sumExc, units = 0.0;
+       AliITSneuron *me = 0, *it = 0;
+       for (l = 0; l < 5; l++) {
+               TObjArrayIter meIter(fNeurons[l]);
+               while ((me = (AliITSneuron*)meIter.Next())) {
+                       units++;
+                       TObjArrayIter inhIter(fNeurons[l]);
+                       
+                       // inhibition (search only for neurons starting in the same layer)
+                       sumInh = 0.0;
+                       while((it = (AliITSneuron*)inhIter.Next())) {
+                               if (it->fOuter == me->fOuter || it->fInner == me->fInner)       
+                                       sumInh += it->fActivation;
+                       }
+                       
+                       // excitation (search only for neurons 
+                       // which start in the previous or next layers)
+                       sumExc = 0.0;
+                       for (j = l - 1; j <= l + 1; j += 2) {
+                               if (j < 0 || j >= 5) continue;
+                               TObjArrayIter itIter(fNeurons[j]);
+                               while ((it = (AliITSneuron*)itIter.Next())) {
+                                       if (it->fInner == me->fOuter || it->fOuter == me->fInner && it->fCurv * me->fCurv > 0.0) {
+                                               sumExc += Weight(me, it) * it->fActivation;
+                                       }
+                               }
+                       } // end search for excitories
+                       
+                       actOld = me->fActivation;
+                       argNew = fRatio * sumExc - sumInh;
+                       actNew = 1.0 / (1.0 + TMath::Exp(-argNew / fTemp));
+                       me->fActivation = actNew;
+                       // calculation the relative activation variation 
+                       // (for stabilization check)
+                       totDiff += TMath::Abs((actNew - actOld) / actOld);
+               } // end loop over 'me' (updated neuron)
+       } // end loop over layers
+       totDiff /= units;
+       
+       return (totDiff < fVar);
+}
+//---------------------------------------------------------------------------------------------------------
+Int_t AliITSneuralTracker::Save()
+{
+       // Tracki saving method
+       // --------------------
+       // Stores the recognized tracks into the TObjArray 'fTracks'
+       // but doesn't save it into a file until the whole work has ended
+       
+       Int_t l;
+       Double_t test = 0.5;
+       
+       // Before all, for each neuron is found the best active sequences
+       // among the incoming and outgoing other units
+       AliITSneuron *main, *fwd, *back, *start;
+       for (l = 0; l < 5; l++) {
+               TObjArrayIter mainIter(fNeurons[l]);
+               while((main = (AliITSneuron*)mainIter.Next())) {
+                       if (l < 4) {
+                               TObjArrayIter fwdIter(fNeurons[l+1]);
+                               test = 0.5;
+                               while ((fwd = (AliITSneuron*)fwdIter.Next())) {
+                                       if (main->fOuter == fwd->fInner && fwd->fActivation > test) {
+                                               test = fwd->fActivation;
+                                               main->fNext = fwd;
+                                       }
+                               };
+                       }
+                       if (l > 0) {
+                               TObjArrayIter backIter(fNeurons[l-1]);
+                               test = 0.5;
+                               while ((back = (AliITSneuron*)backIter.Next())) {
+                                       if (main->fInner == back->fOuter && back->fActivation > test) {
+                                               test = back->fActivation;
+                                               main->fPrev = back;
+                                       }
+                               };
+                       }
+               }
+       }
+       
+       // Then, are resolved the mismatches in the chains found above 
+       // (when unit->next->prev != unit or unit->prev->next != unit)
+       for (l = 0; l < 5; l++) {
+               TObjArrayIter mainIter(fNeurons[l]);
+               while((main = (AliITSneuron*)mainIter.Next())) {
+                       fwd  = main->fNext;
+                       back = main->fPrev;
+                       if (fwd  != 0 && fwd->fPrev  != main) main->fNext = 0; 
+                       if (back != 0 && back->fNext != main) main->fPrev = 0; 
+               }
+       }
+       
+       Int_t pos, neg, incr, decr, ntracks;
+       AliITSneuralTrack *trk = 0;
+               
+       TObjArrayIter startIter(fNeurons[0]);
+       for (;;) {
+               start = (AliITSneuron*)startIter.Next();
+               if (!start) break;
+               Int_t pts = 0;
+               // with the chain above defined, a track can be followed
+               // like a linked list structure
+               for (main = start; main; main = main->fNext) pts++;
+               // the count will be  > 5 only if the track contains 6 points
+               // (what we want)
+               if (pts < 5) continue;
+               // track storage
+               trk = new AliITSneuralTrack;
+               trk->CopyPoint(start->fInner);
+               for (main = start; main; main = main->fNext) {
+                       //main->fInner->fUsed = kTRUE;
+                       //main->fOuter->fUsed = kTRUE;
+                       trk->CopyPoint(main->fOuter);
+               }
+               trk->Kinks(pos, neg, incr, decr);
+               if (pos != 0 && neg != 0) {
+                       cout << "pos, neg kinks = " << pos << " " << neg << endl;
+                       continue;
+               }
+               if (incr != 0 && decr != 0) {
+                       cout << "increment, decrements in delta phi = " << incr << " " << decr << endl;
+                       continue;
+               }
+               for (main = start; main; main = main->fNext) {
+                       main->fInner->fUsed++;
+                       main->fOuter->fUsed++;
+               }
+               fTracks->AddLast(trk);
+       }
+       ntracks = (Int_t)fTracks->GetEntriesFast();
+       return ntracks;
+}
+//---------------------------------------------------------------------------------------------------------
+void AliITSneuralTracker::DoSector(Int_t sect, Bool_t flag)
+{
+       // Sector recognition
+       // ------------------
+       // This is a private method which works on a single sector
+       // just for an easier readability of the code.
+       // The 'flag' argument is needed to be given to the 'Initialize' method (see it)
+       
+       Int_t curvnum, nTracks = 0, nUnits;
+       Bool_t isStable = kFALSE;
+       for (curvnum = 0; curvnum < fCurvNum; curvnum++) {
+               cout << "\rSector " << sect << ":" << ((curvnum+1)*100)/fCurvNum << "%" << flush;
+               nUnits = Initialize(sect, curvnum, flag);
+               if (!nUnits) continue;
+               do {
+                       isStable = Update();
+               } while (!isStable);
+               nTracks = Save();
+       }
+       cout << "\rTracks stored after sector " << sect << ": " << nTracks << endl;
+}
+//---------------------------------------------------------------------------------------------------------
+Int_t AliITSneuralTracker::CountExits(AliITSneuron *n)
+{
+       // Counter for neurons which enter in 'n' tail
+       
+       Int_t count = 0, l = n->fOuter->fLayer;
+       if (l == 5) return 0;
+       
+       AliITSneuron *test = 0;
+       TObjArrayIter iter(fNeurons[l]);
+       while ((test = (AliITSneuron*)iter.Next())) {
+               if (test->fInner == n->fOuter) count++;
+       }
+       return count;
+}
+//---------------------------------------------------------------------------------------------------------
+Int_t AliITSneuralTracker::CountEnters(AliITSneuron *n)
+{
+       // Counter for neurons which exit from 'n' head
+       
+       Int_t count = 0, l = n->fInner->fLayer;
+       if (l == 0) return 0;
+       
+       AliITSneuron *test = 0;
+       TObjArrayIter iter(fNeurons[l-1]);
+       while ((test = (AliITSneuron*)iter.Next())) {
+               if (test->fOuter == n->fInner) count++;
+       }
+       return count;
+}
+//---------------------------------------------------------------------------------------------------------
+Bool_t AliITSneuralTracker::ResetNeuron(AliITSneuron *n)
+{
+       // A method which resets the neuron's pointers to zero
+       
+       if (!n) return kFALSE;
+       n->fNext = 0;
+       n->fPrev = 0;
+       n->fInner = 0;
+       n->fOuter = 0;
+       // the other datamembers don't need to be reinitialized
+       return kTRUE;
+}
+//---------------------------------------------------------------------------------------------------------
+Bool_t AliITSneuralTracker::SetEdge(AliITSneuron *n, AliITSglobalRecPoint *p, const char what)
+{
+       // Sets the indicated edge point to the neuron
+       // (if the arguments are suitable ones...)
+       
+       if (!n || !p || (what != 'i' && what != 'I' && what != 'o' && what != 'O')) return kFALSE;
+       if (what == 'i' || what == 'I') 
+               n->fInner = p;
+       else
+               n->fOuter = p;
+       return kTRUE;
+}
+//---------------------------------------------------------------------------------------------------------
+Bool_t AliITSneuralTracker::CalcParams(AliITSneuron *n)
+{
+       // This method evaluates the helix parameters from the edged of a neuron
+       // (curvature, phase parameter, tangent of lambda angle)
+       // if the p[arameters assume too strange (and unphysical) values, the 
+       // method return kFALSE, else it return kTRUE;
+       
+       if (!n) return kFALSE;
+       
+       Double_t sign(1.0), det, rc = 0.0;
+       Double_t tanl1, tanl2, l1, l2;
+       // changing the reference frame into the one centered in the vertex
+       Double_t x1 = n->fInner->fGX - fVPos[0];
+       Double_t y1 = n->fInner->fGY - fVPos[1];
+       Double_t z1 = n->fInner->fGZ - fVPos[2];
+       Double_t r1 = x1 * x1 + y1 * y1;
+       Double_t x2 = n->fOuter->fGX - fVPos[0];
+       Double_t y2 = n->fOuter->fGY - fVPos[1];
+       Double_t z2 = n->fOuter->fGZ - fVPos[2];
+       Double_t r2 = x2 * x2 + y2 * y2;
+       // initialization of the XY-plane data (curvature and centre)
+       // (will remain these values if we encounter errors)
+       n->fCurv = n->fCX = n->fCY = n->fTanL = n->fPhase = 0.0;
+       n->fLength = (n->fOuter->fGX - n->fInner->fGX) * (n->fOuter->fGX - n->fInner->fGX);
+       n->fLength += (n->fOuter->fGY - n->fInner->fGY) * (n->fOuter->fGY - n->fInner->fGY);
+       n->fLength += (n->fOuter->fGZ - n->fInner->fGZ) * (n->fOuter->fGZ - n->fInner->fGZ);
+       n->fLength = TMath::Sqrt(n->fLength);
+       // this determinant which is zero when the points are in a line
+       det = 2.0 * (x1 * y2 - x2 * y1);
+       if (det == 0.0)
+               return kFALSE; // it is difficult having perfectly aligned points --- it's more likely to be an error
+       else {
+               n->fCX = (r1*y2 - r2*y1) / det;
+               n->fCY = (r2*x1 - r1*x2) / det;
+               rc = TMath::Sqrt(n->fCX * n->fCX + n->fCY * n->fCY);
+               r1 = TMath::Sqrt(r1);
+               r2 = TMath::Sqrt(r2);
+               sign = (n->fOuter->fPhi >= n->fInner->fPhi) ? 1.0 : -1.0;
+               if (rc > 0.0) {
+                       n->fCurv = sign / rc;
+                       n->fPhase = TMath::ATan2(-n->fCX, -n->fCY);
+                       if (n->fPhase < 0.0) n->fPhase += 2.0 * TMath::Pi(); // angles in 0 --> 2pi
+                       if (r1 <= 2.0 * rc && r2 <= 2.0 * rc) {
+                               l1 = 2.0 * rc * TMath::ASin(r1 / (2.0 * rc));
+                               l2 = 2.0 * rc * TMath::ASin(r2 / (2.0 * rc));
+                               tanl1 = z1 / l1;
+                               tanl2 = z2 / l2;
+                               n->fDiff = TMath::Abs(tanl1 - tanl2);
+                               n->fTanL = 0.5 * (tanl1 + tanl2);
+                       }
+                       else {
+                               n->fTanL = 0.0;
+                               n->fDiff = 100.0;
+                               return kFALSE; // it' even more difficult that the arguments above aren't acceptable for arcsine
+                       }
+               }
+               else
+                       return kFALSE;
+       }
+       return kTRUE;
+}
+//---------------------------------------------------------------------------------------------------------
+Double_t AliITSneuralTracker::Angle(AliITSneuron *n, AliITSneuron *m)
+{
+       // calculates the angle between two segments
+       // but doesn't check if they have a common point.
+       // The calculation is made by the ratio of their scalar product
+       // to the product of their magnitudes
+       
+       Double_t x = (m->fOuter->fGX - m->fInner->fGX) * (n->fOuter->fGX - n->fInner->fGX);
+       Double_t y = (m->fOuter->fGY - m->fInner->fGY) * (n->fOuter->fGY - n->fInner->fGY);
+       Double_t z = (m->fOuter->fGZ - m->fInner->fGZ) * (n->fOuter->fGZ - n->fInner->fGZ);
+               
+       Double_t cosine = (x + y + z) / (n->fLength * m->fLength);
+       
+       if (cosine > 1.0 || cosine < -1.0) {
+               Warning("AliITSneuronV1::Angle", "Strange value of cosine");
+               return 0.0;
+       }
+       
+       return TMath::ACos(cosine);
+}
+//---------------------------------------------------------------------------------------------------------
+Double_t AliITSneuralTracker::Weight(AliITSneuron *n, AliITSneuron *m)
+{
+       // calculation of the excitoy weight
+       
+//     Double_t v1 = TMath::Abs(fTanL - n->fTanL);
+//     Double_t v2 = TMath::Abs(TMath::Abs(fCurv) - TMath::Abs(n->fCurv));
+//     Double_t v3 = TMath::Abs(fPhase - n->fPhase);
+//     Double_t q = (v1 + v2 + v3) / 3.0;
+//     Double_t a = 1.0; // 0.02 / (fDiff + n->fDiff);
+       Double_t b = 1.0 - TMath::Sin(Angle(n, m));
+       return TMath::Power(b, fExp);
+//     return TMath::Exp(q / par1);
+
+}
+//---------------------------------------------------------------------------------------------------------
+// ====================================================================================================
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AliITSneuron <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// ====================================================================================================
+
+AliITSneuron::AliITSneuron()
+{
+       // Default constructor
+       // -------------------
+       // sets all parameters to default (but unuseful) 
+       // (in particular all pointers are set to zero)
+       // There is no alternative constructor, because 
+       // this class should not be used by itself, but 
+       // it is only necessary to allow the neural tracker to work
+       // In fact, all methods which operate on neuron's datamembers
+       // are stored in the AliITSneuralTracker class anyway
+       
+       fActivation = 0.0;
+       
+       fCurv = 0.0;
+       fCX = 0.0;
+       fCY = 0.0;
+       fTanL = 0.0;
+       fPhase = 0.0;
+       fDiff = 0.0;
+       fLength = 0.0;
+       
+       fNext = fPrev = 0;
+       fInner = fOuter = 0;
+}
+//---------------------------------------------------------------------------------------------------------
+AliITSneuron::~AliITSneuron() 
+{
+       // Destructor
+       // ----------
+       // does nothing, because there is no need to affect parameters,
+       // while the AliITSglobalRecPoint pointers can't be deleted,
+       // and the AliITSneuron pointers belong to a TObjArray which will
+       // be cleared when necessary...
+}
+
diff --git a/ITS/AliITSneuralTracker.h b/ITS/AliITSneuralTracker.h
new file mode 100644 (file)
index 0000000..5c5981b
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef AliITSneuralTracker_h
+#define AliITSneuralTracker_h
+
+class TObjArray;
+class AliITSneuron;
+class AliITSneuralTrack;
+class AliITSglobalRecPoint;
+
+///////////////////////////////////////////////////////////////////////
+//
+// AliITSneuralTracker: 
+//
+// neural network MFT algorithm 
+// for track finding in ITS stand alone
+// according to the Denby-Peterson model with adaptments to the 
+// ALICE multiplicity
+// 
+///////////////////////////////////////////////////////////////////////
+
+class AliITSneuralTracker : public TObject {
+
+public:
+       
+       // constructors & destructor
+       AliITSneuralTracker();
+       AliITSneuralTracker(Int_t nsecs, Int_t nc, Double_t *c, Double_t theta);
+       virtual ~AliITSneuralTracker();
+       
+       // file reading and points array population
+       Int_t ReadFile(const Text_t *fname, Int_t evnum);
+       
+       // setters for working parameters (NOT cuts)
+       void SetDiff(Double_t a) {fDiff=a;}                 // helix adaptment parameter
+       void SetExponent(Double_t a) {fExp = a;}            // exponent which selects the high excitory values
+       void SetGainToCostRatio(Double_t a) {fRatio = a;}   // ratio between the gain and cost contributions
+       void SetTemperature(Double_t a) {fTemp = a;}        // temperature parameter in activation function
+       void SetVariationLimit(Double_t a) {fVar = a;}      // stability threshold
+       void SetInitLimits(Double_t a, Double_t b)          // intervals for initial random activations
+               {fMin = (a<=b) ? a : b; fMax = (a<=b)? b : a;}
+       void SetVertex(Double_t x, Double_t y, Double_t z)  // estimated vertex position
+               { fVPos[0] = x; fVPos[1] = y; fVPos[2] = z;}
+       
+       // neuron managin methods
+       Bool_t   SetEdge(AliITSneuron *n, AliITSglobalRecPoint *p, const char what); // sets the neuron's edges
+       Bool_t   CalcParams(AliITSneuron *n);              // calculation of helix parameters for the neuron
+       
+       // neural tracking (the argument is the ROOT file to store results)
+       void Go(const char* filesave, Bool_t flag = kFALSE); 
+                       
+private:
+               
+       // These methods are private to prevent the users to use them in incorrect sequences
+               
+       // neuron management methods (not to be used publically)
+       Bool_t   ResetNeuron(AliITSneuron *n);             // resets all neuron's fields like in the constructor
+       Int_t    CountExits (AliITSneuron *n);             // counter for # of neurons going into n's tail
+       Int_t    CountEnters(AliITSneuron *n);             // counter for # of neurons startins from n's head
+       Double_t Angle(AliITSneuron *n, AliITSneuron *m);  // angle between two neural segments
+       Double_t Weight(AliITSneuron *n, AliITSneuron *m); // synaptic weight between two neural segments
+       
+       // neural network work-flow
+       Int_t  Initialize(Int_t snum, Int_t cnum, Bool_t flag = kFALSE); 
+                                                             // resets (or creates) neurons array for a new neural tracking
+       Bool_t Update();                            // updates the neurons and checks if stabilization has occurred
+       Int_t  Save();                              // saves the found tracks after stabilization
+       void   DoSector(Int_t sect, Bool_t flag);   // complete work on a single sector
+               
+       Int_t     fCurvNum;  //  # of curvature cut steps
+       Double_t *fCurvCut;  //! value of all curvature cuts
+       
+       Int_t     fSectorNum;    // no. of azymuthal sectors
+       Double_t  fSectorWidth;  // width of an azymuthal sector
+       
+       Double_t fVPos[3]; // estimated vertex coords
+       
+       Double_t fMin;      // min initial random activations
+       Double_t fMax;      // max initial random activations
+       Double_t fThetaCut; // polar angle cut
+       Int_t    fThetaNum; // size of theta sectionement
+       Double_t fTemp;     // logistic function parameter
+       Double_t fVar;      // stability threshold (for mean rel. activations)
+       Double_t fRatio;    // ratio between inhibitory and excitory contributions
+       Double_t fExp;      // alignment weight
+       Double_t fDiff;     // max allowed difference between TanL exstimations from the two neuron edges
+       
+       TObjArray ***fPoints[6];  //! Collection of recpoints (sectioned in azym. secs)
+       TObjArray   *fNeurons[6]; //! Collection of neurons
+       TObjArray   *fTracks;     //! Collection of tracks
+       
+       ClassDef(AliITSneuralTracker, 1)
+};
+       
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+class AliITSneuron : public TObject {
+       
+       friend class AliITSneuralTracker;
+       
+public:
+               
+                AliITSneuron();
+       virtual ~AliITSneuron();
+       
+       Bool_t   ContainsID(Int_t ID) 
+               { return (fInner->HasID(ID) && fOuter->HasID(ID)); }
+       
+private:
+               
+       Double_t fActivation; // Activation value
+
+       Double_t fCurv;    // curvature [= 1 / R]
+       Double_t fCX;      // curvature centre (X) in changed RF
+       Double_t fCY;      // curvature centre (X) in changed RF
+       Double_t fTanL;    // tan(dip angle) = C / freq
+       Double_t fPhase;   // 'phase' parameter
+       Double_t fDiff;    // difference between tan(lambda) estimated by the two different points
+       Double_t fLength;  // segment length
+       
+       AliITSneuron *fNext; // best outgoing unit
+       AliITSneuron *fPrev; // best incoming unit
+       
+       AliITSglobalRecPoint *fInner; // inner point 
+       AliITSglobalRecPoint *fOuter; // outer point
+};
+
+       
+#endif
index 4771f98460a24c722889f0be2ed55d40ae721d6b..0868e42226e2809f022992dd76b4733f7f1d4edc 100644 (file)
 #pragma link C++ class  AliCascadeVertexer+;
 
 #pragma link C++ class  AliITSVertex+;
+
+// Classes for neural tracking
+#pragma link C++ class AliITSglobalRecPoint+;
+#pragma link C++ class AliITSneuron+;
+#pragma link C++ class AliITSneuralTrack+;
+#pragma link C++ class AliITSneuralTracker+;
+
 #endif
diff --git a/ITS/ITSneuralCompleteEval.C b/ITS/ITSneuralCompleteEval.C
new file mode 100644 (file)
index 0000000..cb43acc
--- /dev/null
@@ -0,0 +1,233 @@
+// Neural performance evaluation
+//
+// before using this macro, you should have make run the macro
+// 'ITSstoreFindableTracks.C' in order to have a file named following
+// the rule to append '_fnd' to the name 
+// (e.g.   galice.root --> galice_fnd.root)
+// and have in it a tree with some tracks statistics useful for evaluation
+// of performance with the same event without loosing too much time...
+
+void ITSneuralCompleteEval
+(Int_t nsecs, const char *filename, Bool_t low = kFALSE, 
+ Bool_t draw = kTRUE, const char *save = 0)
+{
+       Int_t N, M;
+       Float_t *edge = 0;
+       if (!low) {
+               N = 7;
+               edge = new Float_t[8];
+               edge[0] = 0.0;
+               edge[1] = 0.5;
+               edge[2] = 1.0;
+               edge[3] = 1.5;
+               edge[4] = 2.0;
+               edge[5] = 3.0;
+               edge[6] = 4.0;
+               edge[7] = 5.0;
+       }
+       else {
+               N = 5;
+               edge = new Float_t[6];
+               edge[0] = 0.0;
+               edge[1] = 0.2;
+               edge[2] = 0.4;
+               edge[3] = 0.6;
+               edge[4] = 0.8;
+               edge[5] = 1.0;
+       }
+       
+       Float_t find[2] = {0.0, 0.0}, find1[2] = {0.0, 0.0};
+       Float_t good[2] = {0.0, 0.0}, good1[2] = {0.0, 0.0};
+       Float_t fake[2] = {0.0, 0.0}, fake1[2] = {0.0, 0.0};
+       
+       // histos filled with neural results
+       TH1D *hgood[2], *hfake[2], *hfind[2];
+       TH1D *hgood1[2], *hfake1[2], *hfind1[2];
+       TH1D *hg[2], *hf[2];
+       if (draw) {
+               hgood[0] = new TH1D("hgood0", "Good found tracks", N, edge);
+               hfake[0] = new TH1D("hfake0", "Fake found tracks", N, edge);
+               hfind[0] = new TH1D("hfound0", "Findable tracks", N, edge);
+               hgood[1] = new TH1D("hgood1", "Good found tracks", N, edge);
+               hfake[1] = new TH1D("hfake1", "Fake found tracks", N, edge);
+               hfind[1] = new TH1D("hfound1", "Findable tracks", N, edge);
+       
+               hgood[0]->Sumw2(); 
+               hfake[0]->Sumw2(); 
+               hfind[0]->Sumw2(); 
+               hgood[1]->Sumw2(); 
+               hfake[1]->Sumw2(); 
+               hfind[1]->Sumw2(); 
+               
+               // histos for evaluating percentual efficiency
+               hg[0] = new TH1D("hg0", "Efficiency (%) for #geq 5 right pts.", N, edge);
+               hf[0] = new TH1D("hf0", "Fake probability (%) for #geq 5 right pts.", N, edge);
+               hg[1] = new TH1D("hg1", "Efficiency (%) for 6 right pts.", N, edge);
+               hf[1] = new TH1D("hf1", "Fake probability (%) for 6 right pts.", N, edge);
+       }
+       
+       TFile *ffind;
+       TTree *tree;
+       
+       if (low) {
+               ffind = new TFile(Form("%s.root", filename), "READ");
+               tree  = (TTree*)ffind->Get("TreeF");
+       }
+       else {
+               ffind = new TFile(Form("%s_fnd.root", filename), "READ");
+               tree  = (TTree*)ffind->Get("tree");
+       }
+       
+       TFile *ftracks = new TFile(Form("%s_%d.root", filename, nsecs), "READ");
+       
+       
+       Double_t pt;
+       Int_t i, j, count, prim, *none = 0, div;
+       Int_t entries = tree->GetEntries(), label, min[] = {5,6};
+       tree->SetBranchAddress("pt", &pt);
+       tree->SetBranchAddress("count", &count);
+       tree->SetBranchAddress("prim", &prim);
+       
+       AliITSneuralTrack *trk = 0;
+       div = low ? 50 : 500;
+       for(i = 1;;i++) {
+               trk = (AliITSneuralTrack*)ftracks->Get(Form("AliITSneuralTrack;%d", i));
+               if (i%div == 0) cout << "\rEvaluating found track " << i << flush;
+               if (!trk) break;
+               for (j = 0; j < 2; j++) {
+                       label = trk->EvaluateTrack(0, min[j], none);
+                       tree->GetEntry(abs(label));
+                       if (count >= min[j]) {
+                               if (label > 0) {
+                                       if (draw) hgood[j]->Fill(pt);
+                                       good[j]++;
+                                       if (pt >= 1.0) good1[j]++;
+                               }
+                               else {
+                                       if (draw) hfake[j]->Fill(pt);
+                                       fake[j]++;
+                                       if (pt >= 1.0) fake1[j]++;
+                               }
+                       }
+               }
+       }
+       cout << endl;
+               
+       div = low ? 200 : 20000;
+       
+       for (i = 0; i < entries; i++) {
+               if (i%div == 0) cout << "\rEvaluating findable track no. " << i << flush;
+               tree->GetEntry(i);
+               for (j = 0; j < 2; j++) {
+                       if (count >= min[j]) {
+                               find[j]++;
+                               if (draw) hfind[j]->Fill(pt);
+                               if (pt >= 1.0) find1[j]++;
+                       }
+               }
+       }
+       cout << endl;
+       cout << hgood[0]->GetEntries() << " " << hgood[1]->GetEntries() << endl;
+       cout << hfake[0]->GetEntries() << " " << hfake[1]->GetEntries() << endl;
+       cout << hfind[0]->GetEntries() << " " << hfind[1]->GetEntries() << endl << endl;
+       
+       if (draw) {
+               TCanvas *canv[2];
+               canv[0] = new TCanvas("c_0", "Tracking efficiency (soft)", 0, 0, 600, 500);
+               canv[1] = new TCanvas("c_1", "Tracking efficiency (hard)", 630, 0, 600, 500);
+               
+               TLine *line1 = new TLine(1,100.0,edge[N],100.0); line1->SetLineStyle(4);
+               TLine *line2 = new TLine(1,90,edge[N],90); line2->SetLineStyle(4);
+                       
+               Bool_t good_drawn;
+               for (i = 0; i < 2; i++) {
+                       canv[i]->cd();
+                       good_drawn = kFALSE;
+                       if (hgood[i]->GetEntries() > 0.0) {
+                               good_drawn = kTRUE;
+                               hg[i]->Divide(hgood[i], hfind[i], 100.0, 1.0);
+                               hg[i]->SetMaximum(120);
+                               hg[i]->SetMinimum(0);
+                               hg[i]->SetMarkerStyle(21);
+                               hg[i]->SetMarkerSize(1);
+                               hg[i]->SetStats(kFALSE);
+                               hg[i]->GetXaxis()->SetTitle("pt (GeV/c)");
+                               hg[i]->Draw("PE1");
+                       }
+                       if (hfake[i]->GetEntries() > 0.0) {
+                               hf[i]->Divide(hfake[i], hfind[i], 100.0, 1.0);
+                               hf[i]->SetMaximum(120);
+                               hf[i]->SetMinimum(0);
+                               hf[i]->SetMarkerStyle(25);
+                               hf[i]->SetMarkerSize(1);
+                               hf[i]->SetStats(kFALSE);
+                               if (good_drawn)
+                                       hf[i]->Draw("PE1SAME");
+                               else
+                                       hf[i]->Draw("PE1");
+                       }
+                       line1->Draw("histosame");
+                       line2->Draw("histosame");
+                       canv[i]->Update();
+               }
+               canv[0]->SaveAs(Form("%s_soft.eps", filename));
+               canv[1]->SaveAs(Form("%s_hard.eps", filename));
+               cout << endl;
+       }
+       
+       Float_t sgood[2] = {0.0, 0.0}, sgood1[2] = {0.0, 0.0};
+       Float_t sfake[2] = {0.0, 0.0}, sfake1[2] = {0.0, 0.0};
+       for (i = 0; i < 2; i++) {
+               sgood[i] = error(good[i], find[i]);
+               sgood1[i] = error(good1[i], find1[i]);
+               sfake[i] = error(fake[i], find[i]);
+               sfake1[i] = error(fake1[i], find1[i]);
+               
+               good[i] = good[i] * 100.0 / find[i];
+               fake[i] = fake[i] * 100.0 / find[i];
+               good1[i] = good1[i] * 100.0 / find1[i];
+               fake1[i] = fake1[i] * 100.0 / find1[i];
+       }
+       
+       if (save) {
+               fstream data(save, ios::app);
+               data.setf(ios::fixed);
+               data.precision(1);
+               data << good1[0] << " " << fake1[0] << " ";
+               data << good1[1] << " " << fake1[1] << endl;
+               data.close();
+       }
+       else {
+               cout.setf(ios::fixed);
+               cout.precision(1);
+               cout << "*****************************************" << endl;
+               cout << "* Tracks with at least 5 correct points *" << endl;
+               cout << "*****************************************" << endl;
+               cout << "(all particles)" << endl;
+               cout << "Efficiency: " << good[0] << " +/- " << sgood[0] << "%" << endl;
+               cout << "Fake prob.: " << fake[0] << " +/- " << sfake[0] << "%" << endl;
+               if (!low) {
+                       cout << "(pt >= 1 GeV/c)" << endl;
+                       cout << "Efficiency: " << good1[0] << " +/- " << sgood1[0] << "%" << endl;
+                       cout << "Fake prob.: " << fake1[0] << " +/- " << sfake1[0] << "%" << endl;
+               }
+               cout << endl;
+               cout << "************************************" << endl;
+               cout << "* Tracks with all 6 correct points *" << endl;
+               cout << "************************************" << endl;
+               cout << "(all particles)" << endl;
+               cout << "Efficiency: " << good[1] << " +/- " << sgood[1] << "%" << endl;
+               cout << "Fake prob.: " << fake[1] << " +/- " << sfake[1] << "%" << endl;
+               if (!low) {
+                       cout << "(pt >= 1 GeV/c)" << endl;
+                       cout << "Efficiency: " << good1[1] << " +/- " << sgood1[1] << "%" << endl;
+                       cout << "Fake prob.: " << fake1[1] << " +/- " << sfake1[1] << "%" << endl;
+               }
+               cout << endl;
+       }
+}
+
+Double_t error(Double_t x, Double_t y) {
+       Double_t radq = x + x * x / y;
+       return 100.0 * sqrt(radq) / y;
+}
diff --git a/ITS/ITSneuralTracking.C b/ITS/ITSneuralTracking.C
new file mode 100644 (file)
index 0000000..d8f1a7c
--- /dev/null
@@ -0,0 +1,111 @@
+// ARGUMENTS:
+// 1. number of azymuthal sectors (it's better not to go under 8 or over 40)
+// 2. the ROOT file to read (WITHOUT exstension)
+// 3. event number
+// 4. if specified a string, a fstream named like the argument is opened and
+//    the elapsed CPU time is stored (not useful)
+
+// the macro will save a file named, for example "galice_<nsecs>.root"
+// containing may AliITSneuralTrack objects
+
+void ITSneuralTracking
+(Int_t nsecs = 12, const char* rfile = "galice", Int_t event = 0, const char* save = 0)
+{
+       TStopwatch timer;
+       Double_t CONVERT = TMath::Pi() / 180.0;
+       const char* wfile = Form("%s_%d.root", rfile, nsecs);
+       cout << "Reading file " << rfile << ".root and saving in " << wfile << endl;
+       
+// ==================================
+// ==== CURVATURE CUT DEFINITION ====
+// ==================================
+
+       // These values define the curvature cuts for all steps 
+       // within a sector.
+       // For a greater clarity, the cuts are indicated in units
+       // of transverse momentum (GeV/c) but these value have no
+       // exact physical meaning, but are useful to understand
+       // well what means a choice in the value of a certain 
+       // curvature constraint
+       // NOTE: becareful to make sure that the 'ncuts' variable
+       //       have the same value of the dimension of the allocated arrays
+       
+       Int_t ncuts;
+       Double_t *p, *cut;
+       
+       ncuts = 5;
+       p = new Double_t[5];
+       cut = new Double_t[5];  
+       p[0] = 2.0;
+       p[1] = 1.0;
+       p[2] = 0.7;
+       p[3] = 0.5;
+       p[4] = 0.3;
+       
+       for (Int_t i = 0; i < ncuts; i++) cut[i] = 0.003 * 0.2 / p[i];
+       
+
+// ==========================
+// ==== OTHER PARAMETERS ====
+// ==========================
+           
+       Bool_t   flag   = kFALSE; // for now, don't change this line, please...
+       
+       Double_t diff   = 0.02;   // helicoidal cut 
+       Double_t dtheta = 1.0;    // delta-theta cut
+       Double_t temp   = 1.0;    // temperature parameter
+       Double_t var    = 0.0001; // stabilization threshold
+       
+       Double_t exp    = 7.0;    // straight-line excitator
+       Double_t gtoc   = 3.0;    // gain/cost contribution ratio
+       
+       Double_t min    = 0.4;    // minimum in random activation initialization
+       Double_t max    = 0.6;    // maximum in random activation initialization
+       
+       
+// =========================
+// ==== NEURAL TRACKING ====
+// =========================
+       
+       AliITSneuralTracker *ANN = new AliITSneuralTracker(nsecs, ncuts, cut, CONVERT*dtheta);
+               
+       TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(Form("%s.root", rfile));
+       if (!file) file = new TFile(Form("%s.root", rfile),"UPDATE");
+
+       //Double_t Xv = -0.001097;
+       //Double_t Yv = -0.00347647;
+       //Double_t Zv =  0.000631345;
+       //ANN->SetVertex(Xv, Yv, Zv);
+       // You should find the vertex with VertexMacro.C
+       // and then put by hand the found values with
+       // the above method.
+       
+       Int_t points = ANN->ReadFile(Form("%s.root", rfile), event);
+               
+       ANN->SetTemperature(temp);
+       ANN->SetVariationLimit(var);
+       ANN->SetGainToCostRatio(gtoc);
+       ANN->SetExponent(exp);
+       ANN->SetInitLimits(min, max);
+       ANN->SetDiff(diff);
+       
+       cout << points << " points found " << endl << endl;
+       
+       TStopwatch timer;
+       timer.Start();
+       
+       ANN->Go(wfile, flag);
+       
+       timer.Stop();
+       cout << endl;
+       timer.Print();
+       
+       if (save) {
+               fstream ksave(save, ios::app);
+               ksave << nsecs << " " << timer->CpuTime() << endl;
+               ksave.close();
+       }
+       
+//     delete gAlice;
+//     gAlice = 0;
+}
diff --git a/ITS/ITSstoreFindableTracks.C b/ITS/ITSstoreFindableTracks.C
new file mode 100644 (file)
index 0000000..585c740
--- /dev/null
@@ -0,0 +1,85 @@
+void ITSstoreFindableTracks(const char *nfile = "galice", Int_t evnum = 0)
+{
+       TFile *froot = new TFile(Form("%s.root", nfile), "READ");
+       
+       gAlice = (AliRun*)froot->Get("gAlice");
+       if (!gAlice) {
+               cout << "gAlice not found in file!!!" << endl;
+               return;
+       }
+       
+       AliITS *ITS = (AliITS*)gAlice->GetModule("ITS");
+       
+       Int_t nparts = gAlice->GetEvent(evnum);
+       cout << "Tracks saved in event " << evnum << ": " << nparts << endl;
+       
+       TClonesArray *recPoints = ITS->RecPoints();
+       TTree        *treeRec   = gAlice->TreeR();
+   Int_t         ntracks   = gAlice->GetNtrack(); //FCA correction
+       Int_t         nmodules  = treeRec->GetEntries();
+       Int_t         modmin[6];
+       Int_t         modmax[6];
+       
+       Int_t layer, nlads, ndets;
+       AliITSgeom *gm = ITS->GetITSgeom();
+       for (layer = 0; layer < 6; layer++) {
+               nlads  = gm->GetNladders(layer+1);
+               ndets  = gm->GetNdetectors(layer+1);
+               modmin[layer] = gm->GetModuleIndex(layer+1, 1, 1);
+               modmax[layer] = gm->GetModuleIndex(layer+1, nlads, ndets);
+       }
+       
+       Int_t track, *goodITS[6];
+       for (layer = 0; layer < 6; layer++) {
+               goodITS[layer] = new Int_t[ntracks];
+               for(track = 0; track < ntracks; track++) goodITS[layer][track] = 0;
+       }
+   
+       Int_t irec, index, npoints = 0;
+       for (Int_t layer = 1; layer <= 6; layer++) {
+               for (Int_t mod = modmin[layer-1]; mod <= modmax[layer-1]; mod++) {
+                       ITS->ResetRecPoints();
+                       treeRec->GetEvent(mod);
+                       cout << "\rLayer " << layer << ", module: " << mod << flush;
+                       TObjArrayIter *iter = (TObjArrayIter*)recPoints->MakeIterator();
+                       while ((recp = (AliITSRecPoint*)iter.Next())) {
+                               for (index = 0; index < 3; index++) {
+                                       track = recp->GetLabel(index);
+                                       if(track < 0) continue;
+                                       if(track > ntracks) {
+                                               cerr << " Error on track number \n";
+                                               continue;
+                                       }
+                                       goodITS[layer-1][track] = 1;
+                               } //loop over tracks
+                       } //loop over points
+               } //loop over modules
+               cout << endl;
+       } //loop over layers
+       
+       // histos filled with neural results
+       TFile     *fnew = new TFile(Form("%s_fnd.root", nfile), "RECREATE");
+       TParticle *part = 0;
+       TTree     *tree = new TTree("tree", "Tree of tracks");
+       
+       Int_t count = 0, prim = 0;
+       Double_t pt = 0.0;
+       tree->Branch("count", &count, "count/I");
+       tree->Branch("prim", &prim, "prim/I");
+       tree->Branch("pt", &pt, "pt/D");
+       
+       for(track = 0; track < ntracks; track++) {
+               prim = 0;
+               count = 0;
+               part = gAlice->Particle(track);
+               if (!(track % 10000)) cout << "\rStoring track " << track << flush;
+               if (part->GetFirstMother() == -1) prim = 1;
+               for (layer = 0; layer < 6; layer++) count += goodITS[layer][track];
+               pt = part->Pt();
+               tree->Fill();
+       }
+       
+       fnew->cd();
+       tree->Write("tree", TObject::kOverwrite);
+       fnew->Close();
+}
index fd070188b66cf360dd9635b65ebc6e33c8f65aae..7402c52306fd62a619498e581d3302ddecf44218 100644 (file)
@@ -45,7 +45,9 @@ SRCS          = AliITS.cxx AliITSv1.cxx AliITSv3.cxx AliITSv5.cxx \
                AliITSPid.cxx AliITStrackV2Pid.cxx  \
                AliITSVertex.cxx \
                AliV0vertex.cxx AliV0vertexer.cxx \
-               AliCascadeVertex.cxx AliCascadeVertexer.cxx
+               AliCascadeVertex.cxx AliCascadeVertexer.cxx \
+               AliITSglobalRecPoint.cxx AliITSneuralTrack.cxx \
+               AliITSneuralTracker.cxx 
 #              AliITSAlignmentTrack.cxx AliITSAlignmentModule.cxx \
 
 # Fortran sources