#ifndef ALIITSALIGNMILLE_H
#define ALIITSALIGNMILLE_H
#include <TString.h>
#include <TObject.h>
#include "AliTrackPointArray.h"
#define ITSMILLENDETELEM 2198
#define ITSMILLENPARCH 6
#define ITSMILLENLOCAL 5
#define ITSMILLENSTDEV 3
class AliMillepede;
class AliAlignObjParams;
class TGeoManager;
class TGeoHMatrix;
class AliITSAlignMilleModule;
class AliTrackFitterRieman;
class AliITSAlignMilleData;
class AliITSAlignMille:public TObject
{
public:
AliITSAlignMille(const Char_t *configFilename="AliITSAlignMille.conf", Bool_t initmille=kTRUE);
virtual ~AliITSAlignMille();
Int_t GetModuleIndex(const Char_t *symname);
Int_t GetModuleIndex(UShort_t voluid);
UShort_t GetModuleVolumeID(const Char_t *symname);
UShort_t GetModuleVolumeID(Int_t index);
void SetCurrentModule(Int_t index);
void SetCurrentSensitiveModule(Int_t index);
void SetGeometryFileName(const Char_t* filename="geometry.root")
{ fGeometryFileName = filename; }
const Char_t* GetGeometryFileName() {return fGeometryFileName.Data();}
const Char_t* GetPreAlignmentFileName() {return fPreAlignmentFileName.Data();}
void PrintCurrentModuleInfo();
void Print(Option_t*) const;
Bool_t IsConfigured() const {return fIsConfigured;}
void SetRequiredPoint(Char_t* where, Int_t ndet, Int_t updw, Int_t nreqpts);
void SetMinNPtsPerTrack(Int_t pts=3) {fMinNPtsPerTrack=pts;}
Int_t ProcessTrack(AliTrackPointArray *track);
AliTrackPointArray *PrepareTrack(const AliTrackPointArray *track);
void InitTrackParams(int meth=1);
Bool_t InitRiemanFit();
AliTrackFitterRieman *GetRiemanFitter() const {return fRieman;}
Int_t InitModuleParams();
Int_t CheckCurrentTrack();
Bool_t CheckVolumeID(UShort_t voluid) const;
Int_t IsDefined(UShort_t voluid) const;
Int_t IsContained(UShort_t voluid) const;
Int_t CalcIntersectionPoint(const Double_t *lpar, const Double_t *gpar);
Int_t CalcDerivatives(Int_t paridx, Bool_t islpar);
const Double_t* GetLocalIntersectionPoint() const {return fPintLoc;}
const Double_t* GetGlobalIntersectionPoint() const {return fPintGlo;}
void SetInitTrackParamsMeth(Int_t meth=1) {fInitTrackParamsMeth=meth;}
AliTrackPointArray *SortTrack(const AliTrackPointArray *atp);
void SetTemporaryExcludedModule(Int_t index) {fTempExcludedModule=index;}
void FixParameter(Int_t param, Double_t value);
void AddConstraint(Double_t *factor, Double_t value );
void InitGlobalParameters(Double_t *par);
void SetLocalDerivative(Int_t index, Double_t value)
{fLocalDerivatives[index] = value;}
void SetGlobalDerivative(Int_t index, Double_t value)
{fGlobalDerivatives[index] = value;}
void LocalFit(Int_t iTrack, Double_t *lTrackParam, Int_t lSingleFit);
void GlobalFit(Double_t *parameters,Double_t *errors,Double_t *pulls);
void PrintGlobalParameters();
Double_t GetParError(Int_t iPar);
Int_t AddLocalEquation(AliITSAlignMilleData &m);
void SetLocalEquations(const AliITSAlignMilleData *m, Int_t neq);
AliTrackPointArray *GetCurrentTrack() const {return fTrack;}
const AliTrackPoint *GetCurrentCluster() const {return &fCluster;}
void SetCurrentTrack(AliTrackPointArray * const atp) {fTrack=atp;}
void SetCurrentCluster(const AliTrackPoint &atp) {fCluster=atp;}
Int_t GetNModules() const {return fNModules;}
Int_t GetCurrentModuleIndex() const {return fCurrentModuleIndex;}
TGeoHMatrix *GetCurrentModuleHMatrix() const {return fCurrentModuleHMatrix;}
const Double_t *GetCurrentModuleTranslation() const {return fCurrentModuleTranslation;}
Int_t GetCurrentModuleInternalIndex() const {return fCurrentModuleInternalIndex;}
const Int_t *GetModuleIndexArray() const {return fModuleIndex;}
const Int_t *GetProcessedPoints() const {return fProcessedPoints;}
Int_t GetTotBadLocEqPoints() const {return fTotBadLocEqPoints;}
AliITSAlignMilleModule *GetMilleModule(UShort_t voluid) const;
AliITSAlignMilleModule *GetCurrentModule() const;
const UShort_t *GetModuleVolumeIDArray() const {return fModuleVolumeID;}
const Double_t *GetMeasLoc() const { return fMeasLoc;}
const Double_t *GetSigmaLoc() const { return fSigmaLoc;}
Double_t GetBField() const {return fBField;}
const Double_t *GetLocalInitParam() const {return fLocalInitParam;}
Double_t GetLocalDX() const {return fDerivativeXLoc;}
Double_t GetLocalDZ() const {return fDerivativeZLoc;}
Double_t GetParSigTranslations() const {return fParSigTranslations;}
Double_t GetParSigRotations() const {return fParSigRotations;}
Int_t GetPreAlignmentQualityFactor(Int_t index) const;
void SetBug(Int_t bug) {fBug=bug;}
private:
Int_t LoadConfig(const Char_t *cfile="AliITSAlignMille.conf");
Int_t LoadSuperModuleFile(const Char_t *cfile="ITSMilleSuperModules.root");
void ResetLocalEquation();
void InitGeometry();
Int_t ApplyToGeometry();
void Init(Int_t nGlobal, Int_t nLocal, Int_t nStdDev);
AliMillepede *fMillepede;
static Int_t fgNParCh;
static Int_t fgNDetElem;
Double_t fStartFac;
Double_t fResCutInitial;
Double_t fResCut;
Int_t fNGlobal;
Int_t fNLocal;
Int_t fNStdDev;
Bool_t fIsMilleInit;
Double_t fParSigTranslations;
Double_t fParSigRotations;
AliTrackPointArray *fTrack;
AliTrackPoint fCluster;
Double_t *fGlobalDerivatives;
Double_t fLocalDerivatives[ITSMILLENLOCAL];
Double_t fLocalInitParam[ITSMILLENLOCAL];
Double_t fModuleInitParam[ITSMILLENPARCH];
Double_t fPintLoc[3];
Double_t fPintLoc0[3];
Double_t fPintGlo[3];
Double_t fMeasLoc[3];
Double_t fMeasGlo[3];
Double_t fSigmaLoc[3];
Double_t fSigmaXfactor;
Double_t fSigmaZfactor;
AliAlignObjParams *fTempAlignObj;
Double_t fDerivativeXLoc;
Double_t fDerivativeZLoc;
Int_t fMinNPtsPerTrack;
Int_t fInitTrackParamsMeth;
Int_t *fProcessedPoints;
Int_t fTotBadLocEqPoints;
AliTrackFitterRieman *fRieman;
Bool_t fRequirePoints;
Int_t fNReqLayUp[6];
Int_t fNReqLayDown[6];
Int_t fNReqLay[6];
Int_t fNReqDetUp[3];
Int_t fNReqDetDown[3];
Int_t fNReqDet[3];
Int_t fTempExcludedModule;
TString fGeometryFileName;
TString fPreAlignmentFileName;
TGeoManager *fGeoManager;
Int_t fCurrentModuleIndex;
Int_t fCurrentModuleInternalIndex;
Int_t fCurrentSensVolIndex;
Double_t fCurrentModuleTranslation[3];
Int_t fNModules;
Int_t fModuleIndex[ITSMILLENDETELEM*2];
UShort_t fModuleVolumeID[ITSMILLENDETELEM*2];
Bool_t fFreeParam[ITSMILLENDETELEM*2][ITSMILLENPARCH];
Bool_t fUseLocalShifts;
Bool_t fUseSuperModules;
Bool_t fUsePreAlignment;
Bool_t fUseSortedTracks;
Bool_t fBOn;
Double_t fBField;
Int_t fNSuperModules;
TGeoHMatrix *fCurrentModuleHMatrix;
Bool_t fIsConfigured;
Int_t fPreAlignQF[ITSMILLENDETELEM*2];
Double_t fSensVolSigmaXfactor[ITSMILLENDETELEM*2];
Double_t fSensVolSigmaZfactor[ITSMILLENDETELEM*2];
Int_t fBug;
AliITSAlignMilleModule *fMilleModule[ITSMILLENDETELEM*2];
AliITSAlignMilleModule *fSuperModule[ITSMILLENDETELEM*2];
AliITSAlignMille(const AliITSAlignMille& rhs);
AliITSAlignMille& operator=(const AliITSAlignMille& rhs);
ClassDef(AliITSAlignMille, 0)
};
#endif