ROOT logo
//*--- Author: Jochen Markert

// from ROOT
#include "TF2.h"
#include "TRandom.h"

// form hydra
#include "hcategory.h"
#include "hgeantkine.h"
#include "hgeantmdc.h"
#include "hgeomtransform.h"
#include "hgeomvector.h"
#include "hlocation.h"
#include "hmdccal1.h"
#include "hmdccal1sim.h"
#include "hmdccal2.h" //?
#include "hmdccal2sim.h" //?
#include "hmdccal2par.h"
#include "hmdccal2parsim.h"
#include "hmdcgetcontainers.h"
#include "hmdcgeomobj.h"
#include "hmagnetpar.h"
#include "hmdcdigitpar.h"
#include "hmdcseg.h"
#include "hmdcidealclasses.h"
#include "hmdcsizescells.h"
#include "hmdctaskset.h"
#include "hmdctrackgdef.h"
#include "hmdctrackgfieldpar.h"
#include "hmdctrkcand.h"
#include "hmdcidealclasses.h"
#include "hmetamatch2.h"
#include "hrootsource.h"
#include "hruntimedb.h"
#include "hmdcdetector.h"
#include "htaskset.h"
#include "htofdetector.h"
#include "hspectrometer.h"

#include "hkaldef.h"
#include "hkaldetcradle.h"
#include "hkalinput.h"
#include "hkalgeomtools.h"
#include "hkalmdchit.h"

#include <iostream>
#include <vector>
using namespace std;

ClassImp (HKalInput)

//_HADES_CLASS_DESCRIPTION
///////////////////////////////////////////////////////////////////////////////
//    HKalInput is a helper class to fill a TObjArray of hits in sector
//    coordinate system to be used in the Kalman filter. Input can be provided
//    from HMdcTrkCand (real tracking) or HMdcTrkCandIdeal (ideal tracking from
//    from GEANT hit points). It will fill 4 (2x2) hits from inner/outer segment.
//    Errors for real tracking are taken from HMdcSeg, for ideal tracking 200/100 mu
//    in x/y. The errors can be scaled by a factor. The geometrical transformations
//    are performed via HMdcSizesCells, thus the container has to initialized
//    before usage.
//
//-----------------------------------------------------------------------
//    HOWTO use the HKalMdcInput class::
//    before Event loop:
//
//    // assume Spectrometer setup + Hades creation is performed ....
//
//    HKalDetCradle *pCradleHades = new HKalDetCradle();
//    HKalMdcInput *input = new HKalMdcInput(refID, pCradleHades);   // fill the input hits
//    input->setPrint(0);                       // debug print (off == 0)
//
//    TObjArray allhits;                        // array of hits to be fed into kalman
//    Int_t measDim = 2;                        // dimension of hit vector (default = 2)
//    Double_t scaleErr = 1.;                   // scaling factor for errors (default = 1.)
//
//    Inside eventloop:
//
//        //-----------------------------------------------------------------------
//        // Run Kalman filter on hits.
//        Int_t nrHits = 0;
//        input->resetIterMdcTrkCand();
//	  	  while( (nrHits = input->nextMdcTrackCand(allhits, measDim, scaleErr)) )
//        {
//	       // ..... kalman
//
//	      }
//-----------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////

//  -----------------------------------
//  Ctors and Dtor
//  -----------------------------------

HKalInput::HKalInput() : TObject() {
    // It is recommended to use the constructor
    // HKalInput(Int_t refID, HKalDetCradle *detCradle)
    // instead where the object will be initialized correctly.
    // This empty constructor sets all pointers to NULL. To use the object
    // the following still has to be done afterwards:
    // Do spectrometer setup + Hades creation ....
    // To set the pointer to detector cradle:
    // setDetectorCradle(detCradle)  // set pointer to detector cradle
    // To get pointer to categories, HMdcSizesCells, magnet and B-field
    // parameters:
    // init(refID)                   // gets categories

    pCradleHades = NULL;
    fSizesCells  = NULL;
    pField       = NULL;
    pMagnet      = NULL;
    setPrint(kFALSE);
}

HKalInput::HKalInput(HKalDetCradle *detCradle) : TObject() {
    // Assumes spectrometer setup + Hades creation have been performed ....
    // This constructor sets all needed class members.
    // refID:     runtime ID
    // detCradle: pointer to Hades detector cradle

    pCradleHades = NULL;
    fSizesCells  = NULL;
    pField       = NULL;
    pMagnet      = NULL;
    setDetectorCradle(detCradle);
    setPrint(kFALSE);
}

HKalInput::~HKalInput() {
    delete pCradleHades;
}

//  -----------------------------------
//  Implementation of public methods
//  -----------------------------------

void HKalInput::calcSegPoints(const HMdcSeg *seg, Double_t& x1,  Double_t& y1, Double_t& z1, Double_t& x2, Double_t& y2, Double_t& z2) {
    // calculates 2 coordinate points from segment.

    Double_t teta = seg->getTheta();
    Double_t phi  = seg->getPhi();
    Double_t z    = seg->getZ();
    Double_t r    = seg->getR();
    Double_t pi2  = acos(-1.)/2.;

    Double_t X = r * cos(phi + pi2);
    Double_t Y = r * sin(phi + pi2);
    Double_t Z = z;

    x1 = X;
    y1 = Y;
    z1 = Z;
    x2 = X + cos(phi) * sin(teta);
    y2 = Y + sin(phi) * sin(teta);
    z2 = Z + cos(teta);
}


void HKalInput::clearCategories() {
    // Clear the categories (for macros in MakeCode style).

    if(kineCat)            kineCat           ->Clear();
    if(mdcTrkCandCat)      mdcTrkCandCat     ->Clear();
    if(mdcTrkCandCat)      mdcTrkCandCat     ->Clear();
    if(mdcSegCat)          mdcSegCat         ->Clear();
    if(mdcHitCat)          mdcHitCat         ->Clear();
    if(mdcTrkCandIdealCat) mdcTrkCandIdealCat->Clear();
    if(mdcSegIdealCat)     mdcSegIdealCat    ->Clear();
    if(mdcHitIdealCat)     mdcHitIdealCat    ->Clear();
}

void HKalInput::getCategories() {
    // Retries the pointer to needed input categories. Creates
    // iterators.

    geantMdcCat         = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcGeantRaw);
    kineCat             = (HCategory*)gHades->getCurrentEvent()->getCategory(catGeantKine);

    mdcTrkCandCat       = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcTrkCand);
    mdcSegCat           = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcSeg);
    mdcHitCat           = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcHit);

    mdcTrkCandIdealCat  = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcTrkCandIdeal);
    mdcSegIdealCat      = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcSegIdeal);
    mdcHitIdealCat      = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcHitIdeal);

    mdcCal1Cat          = (HCategory*)gHades->getCurrentEvent()->getCategory(catMdcCal1);

    metaMatchCat        = (HCategory*)gHades->getCurrentEvent()->getCategory(catMetaMatch);

    if(kineCat) iterKine = (HIterator *) kineCat->MakeIterator("native");
    else        iterKine = NULL;

    if(mdcTrkCandCat) iterMdcTrkCand = (HIterator *) mdcTrkCandCat->MakeIterator("native");
    else              iterMdcTrkCand = NULL;

    if(mdcTrkCandIdealCat) iterMdcTrkCandIdeal = (HIterator *) mdcTrkCandIdealCat->MakeIterator("native");
    else                   iterMdcTrkCandIdeal = NULL;

    if(metaMatchCat)  iterMetaMatch  = (HIterator *) metaMatchCat->MakeIterator("native");
    else              iterMetaMatch  = NULL;

}

Bool_t HKalInput::init(Int_t refID) {
    Bool_t bSuccess;
    if(!gHades) {
        Error("init()", "Hades object does not exist!");
        exit(1);
    }

    getCategories();                   // get Pointer to categories
    bSuccess  = initSizesCells(refID);             // init HMdcSizesCells
    if(!bSuccess) {
        Warning("init()", "Could not initialize SizesCells.");
    }
    bSuccess &= initBField(refID);                 // init Bfield parameters
    if(!bSuccess) {
        Warning("init()", "Could not initialize B-field.");
    }
    mdcGetContainers = HMdcGetContainers::getObject();
    return bSuccess;
}

Bool_t HKalInput::initBField(Int_t refID) {
    // Initialize HMdcTrackGFieldPar and HMagnetPar for run refID.
    // If the container already exists it will not
    // be created a second time.

    HRuntimeDb* rtdb = gHades->getRuntimeDb();
    if(!pField) {
        pField =  (HMdcTrackGFieldPar*)(rtdb->getContainer("MdcTrackGFieldPar"));
    }
    if(!pMagnet) {
        pMagnet = (HMagnetPar*)( rtdb->getContainer("MagnetPar"));
    }
    return (pField && pMagnet);
}


Bool_t HKalInput::initSizesCells(Int_t refID) {
    // Initialize HMdcSizesCells for run refID.
    // If the container already exists it will not
    // be created a second time.

    fSizesCells = HMdcSizesCells::getExObject();  // check if is already there

    if(!fSizesCells) {
        fSizesCells = HMdcSizesCells::getObject();

        return fSizesCells->initContainer();
    } else {
        return kTRUE;
    }
}

HMdcSizesCells* HKalInput::getSizesCells() {
    if(!fSizesCells) {
        Error("getSizesCells()","HMdcSizesCells is NULL!");
        exit(1);
    }
    return fSizesCells;
}

HMdcTrkCand* HKalInput::nextMdcTrackCand(TObjArray &allhits, Int_t measDim, Double_t scaleErr) {
    // Fills 4 hits in sector coordinates system to allhits array.
    // Loops over HMdcTrkCand Category for the next for hits. The
    // iterator for the category has to be reset by hand at the begin
    // of each event. Return 0 if no next candidate has been found.
    // The errors of the hits will be taken from HMdcSeg and can be scaled
    // by scaleErr.
    //
    // allhits: array with HKalMdcHit objects (return value. Existing content of array will be deleted.)
    // measDim: dimension of measurement vector
    // scaleErr: scale errX and errY by this factor

    if(fSizesCells == NULL){
        Error("nextMdcTrackCand()","HMdcSizeCells is NULL!");
        exit(1);
    }
    if(pCradleHades == NULL) {
        Error("nextMdcTrackCand()","DetectorCadle is NULL!");
        exit(1);
    }
    Int_t nrhits = 0;

    HMetaMatch2 *pMetaMatch = NULL;
    HMdcTrkCand *mdcTrkCand = NULL;

    if(!iterMetaMatch) return NULL;


    // This is the SEGment class of MDC. This data container
    // holds the information about a straight track let between
    // a pair of MDCs.

    Int_t   indexSeg    [2];   // index in catMdcSeg for inner/outer seg
    HMdcSeg *mdcSeg     [2];   // segment pointer for inner/outer seg
    Int_t   mdcSegIndHit[4];

    Double_t coordHit   [3];
    Double_t coordErrHit[3];
    Double_t coordErrLay[3];

    // Collecting track candidates.
    for(Int_t ihit = 0; ihit < 4; ihit ++) mdcSegIndHit[ihit] = -1;

    allhits.Clear();
    while ((pMetaMatch = (HMetaMatch2*)(iterMetaMatch->Next())) != 0) {
        mdcTrkCand = (HMdcTrkCand*)mdcTrkCandCat->getObject(pMetaMatch->getTrkCandInd());

        for(Int_t io = 0; io < 2; io ++) { // loop inner/outer segment
            mdcSeg[io]     = 0;

            indexSeg   [io] =  mdcTrkCand->getSegInd(io);
            if(indexSeg[io] != -1) {
                mdcSeg[io] = (HMdcSeg*) mdcSegCat->getObject(indexSeg[io]);
                for(Int_t nhits = 0; nhits < 2; nhits ++) { // loop hits in segment
                    if(mdcSeg[io]) {
                        mdcSegIndHit[io * 2 + nhits] = mdcSeg[io]->getHitInd(nhits);
#if kalDebug > 2
                        cout<<io * 2 + nhits<<" "<< mdcSegIndHit[io * 2 + nhits]<<endl;
#endif
                    } else {
                        if(bPrint) {
                            Warning("nextMdcTrackCand()", "zero segment!");
                        }
                        mdcSegIndHit[io * 2 + nhits] = -1;
                    }
                }
            }
        }
        if(!mdcSeg[0] || !mdcSeg[1]) continue;

        // If a Hit doesn't exist -1 is returned.
#if kalDebug > 2
        cout<<"filling sec "<<(Int_t)mdcSeg[0]->getSec()<<endl;
#endif
        Int_t sec,mod;
        //-------inner segment----------------------------
        HMdcHit* locHit; // temp hit pointer
        for(Int_t io = 0; io < 2; io ++) {              // loop inner/outer segment
            for(Int_t nhits = 0; nhits < 2; nhits ++) { // loop hits in segment
                locHit = (HMdcHit*)mdcHitCat->getObject(mdcSegIndHit[io * 2 + nhits]);
                if(!locHit) {
#if kalDebug > 0
                    if(bPrint) {
                        cout<<"nextMdcTrackCand(), No hit in segment "<<io<<"."<<endl;
                    }
#endif
                    continue;
                }
                locHit->getSecMod(sec, mod);
                const HKalMdcMeasLayer* hitdmeas = pCradleHades->getMdcLayerAt(sec, mod, 0);

                // Get HMdcHit coordinates and errors in local Mdc coordinate system.
                coordHit   [0] = locHit->getX();
                coordHit   [1] = locHit->getY();
		coordHit   [2] = 0;
#if kalDebug > 3
		cout<<"io = "<<io<<" hit = "<<nhits<<", x = "<<locHit->getX()<<", y = "<<locHit->getY()<<endl;
#endif
                (*fSizesCells)[sec][mod].transFrom(coordHit[0], coordHit[1], coordHit[2]);

                coordErrLay[0] = locHit->getErrX() * scaleErr;
                coordErrLay[1] = locHit->getErrY() * scaleErr;
                coordErrLay[2] = 0.03;

		if(locHit->getErrX() == 0. || locHit->getErrY() == 0.) {
#if kalDebug > 0
		    Warning("nextMdcTrackCand()", "Measurement errors are zero.");
#endif
                    coordErrLay[0] = 0.2;
                    coordErrLay[1] = 0.1;
                }
                if(measDim > 2) {
                    HGeomVector errLay(coordErrLay[0], coordErrLay[1], coordErrLay[2]);
                    HGeomVector errSec = (*fSizesCells)[sec][mod].getSecTrans()->getRotMatrix() * errLay;
                    coordErrHit[0] = TMath::Abs(errSec.getX());
                    coordErrHit[1] = TMath::Abs(errSec.getY());
                    coordErrHit[2] = TMath::Abs(errSec.getZ());
                } else {
                    coordErrHit[0] = coordErrLay[0];
                    coordErrHit[1] = coordErrLay[1];
                    coordErrHit[2] = coordErrLay[2];
                }

                allhits.Add(new HKalMdcHit(&coordHit[0], &coordErrHit[0], *hitdmeas, measDim, TVector3(&coordHit[0]), Kalman::kSegHit));
                nrhits++;
            }
	}
        return mdcTrkCand;
    } // end loop over

    return mdcTrkCand;
}

HMdcTrkCand* HKalInput::nextWireTrack(TObjArray &allhits, Int_t minLayInSeg, Int_t minLayOutSeg) {
    // Fills drift chamber wire hits with the drift time as measurement vector
    // to allhits array.
    // Loops over HMdcTrkCandIdeal Category for the next four hits. The
    // iterator for the category has to be reset by hand at the begin
    // of each event. Return 0 if no next candidate has been found.
    //
    // output:
    // allhits: array with HKalMdcHit objects (Existing content of array will be deleted!)
    // input:
    // minLayInSeg:   minimum number of layers in the inner segment needed to fill allhits
    // minLayOutSeg:  minimum number of layers in the outer segment needed

    Int_t             indexSeg[2];   // index in catMdcSeg for inner/outer seg
    Int_t             mdcSegNlay[2];

    HMdcSeg     *mdcSeg[2];
    HMdcTrkCand *mdcTrkCand = 0;
    HMetaMatch2 *pMetaMatch = NULL;

    if(fSizesCells == NULL) {
        Error("nextWireTrack()","HMdcSizeCells is NULL!");
        exit(1);
    }
    if(pCradleHades == NULL) {
        Error("nextWireTrack()","DetectorCradle is NULL!");
        exit(1);
    }

    if(!iterMetaMatch) return NULL;

    HLocation loccal;
    loccal.set(4,0,0,0,0);

    HMdcCal2ParSim *cal2sim = (HMdcCal2ParSim*)gHades->getRuntimeDb()->getContainer("MdcCal2ParSim");
    HMdcCal2Par    *cal2    = (HMdcCal2Par   *)gHades->getRuntimeDb()->getContainer("MdcCal2Par");

    allhits.Clear();


    while ((pMetaMatch = (HMetaMatch2*)(iterMetaMatch->Next())) != 0) {
        mdcTrkCand = (HMdcTrkCand*)mdcTrkCandCat->getObject(pMetaMatch->getTrkCandInd());

        for(Int_t io = 0; io < 2; io ++) { // loop inner/outer segment
            mdcSegNlay[io] = 0;
            mdcSeg[io]     = 0;

            indexSeg   [io] =  mdcTrkCand->getSegInd(io);
            if(indexSeg[io] !=-1){
                mdcSeg[io] = (HMdcSeg*) mdcSegCat->getObject(indexSeg[io]);
                if(!mdcSeg[io]){ cout<<"zero segment!"; continue;}
                mdcSegNlay[io] = mdcSeg[io]->getNLayers();
            }
        }
        if(!mdcSeg[0] || !mdcSeg[1]) continue;

        // Skip if there were not enough hits in each segment.
        if(mdcSegNlay[0] >= minLayInSeg && mdcSegNlay[1] >= minLayOutSeg) {
#if kalDebug > 2
            cout<<"filling sec "<<(Int_t)mdcSeg[0]->getSec()<<endl;
#endif

            // Used for time of flight correction of drift time.
            Double_t sumTof [4]={ 0., 0., 0., 0. };
            Double_t sumErr [4]={ 0., 0., 0., 0. };

            for(Int_t io = 0; io < 2; io ++) {              // loop inner/outer segment

                HMdcSeg *seg = mdcSeg[io];

                for(Int_t l = 0; l < 12; l++) { // segment = 2 modules = 2x6 layers
                    // input selection
                    Int_t nCell = seg->getNCells(l); // number of cells per layer
                    loccal[0]   = seg->getSec();
                    Int_t ioseg = seg->getIOSeg(); // 0=inner,1=outer

                    if(nCell > 0) {
                        TObjArray hits;
                        Int_t    nComp = 0; // Number of competing hits in a layer.

                        //nCell = 1; //?
                        for(Int_t i = 0; i < nCell; i++) {
                            if(ioseg == 0)  {
                                (l < 6) ? loccal[1] = 0 : loccal[1] = 1;
                            } else if(ioseg == 1) {
                                (l < 6) ? loccal[1] = 2 : loccal[1] = 3;
                            }
                            (l < 6) ? loccal[2] = l : loccal[2] = l - 6;

                            // input selection
                            Int_t cell = seg->getCell(l,i);  // get cell number
                            loccal[3] = cell;

                            HMdcCal1Sim *cal1 = (HMdcCal1Sim*)mdcCal1Cat->getObject(loccal);

                            if(cal1->getStatus1() < 0) continue; // Check if hit is valid.

                            Double_t x1, y1, z1, x2, y2, z2 = 0.;

			    HMdcHit* locHit1 = (HMdcHit*)mdcHitCat->getObject(mdcSeg[io]->getHitInd(0));
			    HMdcHit* locHit2 = (HMdcHit*)mdcHitCat->getObject(mdcSeg[io]->getHitInd(1));
			    if(locHit1 && locHit2) {
				x1 = locHit1->getX();
				y1 = locHit1->getY();
				z1 = 0;
				Int_t sec1, mod1;
				locHit1->getSecMod(sec1, mod1);
				(*fSizesCells)[sec1][mod1].transFrom(x1, y1, z1);

				x2 = locHit2->getX();
				y2 = locHit2->getY();
				z2 = 0;
				Int_t sec2, mod2;
				locHit2->getSecMod(sec2, mod2);
				(*fSizesCells)[sec2][mod2].transFrom(x2, y2, z2);
			    } else {
				calcSegPoints(seg, x1, y1, z1, x2, y2, z2);
			    }


                            HMdcSizesCellsLayer &fSizesCellsLayer = (*fSizesCells)[loccal[0]][loccal[1]][loccal[2]];
                            HMdcSizesCellsCell  &fSizesCellsCell  = (*fSizesCells)[loccal[0]][loccal[1]][loccal[2]][loccal[3]];

                            TVector3 layerHit;

                            Double_t alpha, mindist;
                            if(!fSizesCellsLayer.getImpact(x1, y1, z1, x2, y2, z2, loccal[3], alpha, mindist)) {
                                if(bPrint) {
                                    Warning("nextWireTrack()", Form("No impact found with cell %i. Measurement discarded.", loccal[3]));
                                }
                                continue;
                            }
                            // Speed of signal on wire in ns/mm
                            Float_t signalSpeed = ((HMdcDigitPar*)gHades->getRuntimeDb()->getContainer("MdcDigitPar"))->getSignalSpeed();

                            // Path length of signal along the wire in mm.
                            Double_t xWire      = fSizesCellsLayer.getSignPath(x1, y1, z1, x2, y2, z2, cell);
                            // Amount of time that the signal travels on the wire.
                            Double_t tWireOffset = xWire * signalSpeed;

                            // Offset from time of flight subtracted later.
                            Float_t t1  = cal1->getTime1() - tWireOffset;

                            Double_t timeSimErr = cal2sim->
                                calcTimeErr(loccal[0], loccal[1], alpha, mindist);

                            Double_t dist       = cal2->
                                calcDistance  (loccal[0], loccal[1], alpha, t1);

                            //?
                            //Double_t sigTof[4] = { 1.23, 1.25, 1.5, 1.46 }; //? ns
                            Double_t sigTof[4] = { 2.69, 2.72, 2.07, 2.09 }; //? ns apr12
                            Double_t vd[4]     = { 1./24., 1./24., 1./25., 1./25.5 }; //? mm/ns
                            Double_t errTof    = vd[loccal[1]] * sigTof[loccal[1]];

                            Double_t distErr = 0.;

                            HGeomVector &wire1 = fSizesCellsCell.getWirePnt1();
                            TVector3 wirePoint1(wire1.X(), wire1.Y(), wire1.Z());
                            HGeomVector &wire2 = fSizesCellsCell.getWirePnt2();
                            TVector3 wirePoint2(wire2.X(), wire2.Y(), wire2.Z());

                            Int_t iflag;
                            Double_t length;
                            TVector3 pcaFinal, pcaWire;
                            HKalGeomTools::Track2ToLine(pcaFinal, pcaWire, iflag,
                                                        mindist, length,
                                                        TVector3(x1,y1,z1),
                                                        TVector3(x2,y2,z2),
                                                        wirePoint1, wirePoint2);

                            // Make virtual plane.
                            // origin: PCA on wire
                            // u axis: along wire
                            // v axis: from origin to PCA on track
                            //TVector3 u = (wirePoint2 - wirePoint1).Unit();
			    //TVector3 v = (pcaFinal - pcaWire).Unit();



			    if(locHit1 && locHit2) {
				const HGeomRotation& transRotLaySysRSec =
				    fSizesCellsLayer.getRotLaySysRSec(cell).getRotMatrix();
				HGeomRotation transRotSecToRotLay = transRotLaySysRSec.inverse();
				HGeomVector transVecRotLayToSec =
				    fSizesCellsLayer.getRotLaySysRSec(cell).getTransVector();

				//Double_t Rxx = transRotSecToRotLay.getElement(0,0);
				//Double_t Rxy = transRotSecToRotLay.getElement(0,1);
				//Double_t Rxz = transRotSecToRotLay.getElement(0,2);
				Double_t Ryx = transRotSecToRotLay.getElement(1,0);
				Double_t Ryy = transRotSecToRotLay.getElement(1,1);
				Double_t Ryz = transRotSecToRotLay.getElement(1,2);
				Double_t Rzx = transRotSecToRotLay.getElement(2,0);
				Double_t Rzy = transRotSecToRotLay.getElement(2,1);
				Double_t Rzz = transRotSecToRotLay.getElement(2,2);

				Double_t tx  = transVecRotLayToSec.getX();
				Double_t ty  = transVecRotLayToSec.getY();
				Double_t tz  = transVecRotLayToSec.getZ();

				Double_t errx1 = locHit1->getErrX();
				Double_t erry1 = locHit1->getErrY();
				Double_t errz1 = 0.03;
				HGeomVector errLay1(errx1, erry1, errz1);
				HGeomVector errSec1 = (*fSizesCells)[loccal[0]][loccal[1]].getSecTrans()->getRotMatrix() * errLay1;
				errx1 = errSec1.getX();
				erry1 = errSec1.getY();
				errz1 = errSec1.getZ();

				Double_t errx2 = locHit2->getErrX();
				Double_t erry2 = locHit2->getErrY();
				Double_t errz2 = 0.03;
				HGeomVector errLay2(errx2, erry2, errz2);
				HGeomVector errSec2 = (*fSizesCells)[loccal[0]][loccal[1]].getSecTrans()->getRotMatrix() * errLay2;
				errx2 = errSec2.getX();
				erry2 = errSec2.getY();
				errz2 = errSec2.getZ();

				Double_t yWire = fSizesCellsCell.getWirePos();
                                // What could possibly go wrong?
				distErr = TMath::Sqrt(errx2*errx2*TMath::Power(-((( 2*Ryx*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))+2*Rzx*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+( Rzx*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))-Ryx*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.) +
						      erry2*erry2*TMath::Power(-((( 2*Ryy*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))+2*Rzy*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+( Rzy*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))-Ryy*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.) +
						      errz2*errz2*TMath::Power(-((( 2*Ryz*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))+2*Rzz*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+( Rzz*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))-Ryz*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.) +
						      errx1*errx1*TMath::Power(-(((-2*Ryx*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))-2*Rzx*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+(-Rzx*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))+Ryx*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))-Rzx*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+Ryx*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.) +
						      erry1*erry1*TMath::Power(-(((-2*Ryy*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))-2*Rzy*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+(-Rzy*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))+Ryy*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))-Rzy*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+Ryy*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.) +
						      errz1*errz1*TMath::Power(-(((-2*Ryz*(Ryx*(-x1+x2)+Ryy*(-y1-y2)+Ryz*(-z1-z2))-2*Rzz*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))*(-(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2))))/(2.*TMath::Power(TMath::Power((Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2)),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.),1.5)))+(-Rzz*(Ryx*(-tx+x1)+Ryy*(-ty+y1)-yWire+Ryz*(-tz+z1))+Ryz*(Rzx*(-tx+x1)+Rzy*(-ty+y1)+Rzz*(-tz+z1))-Rzz*(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2))+Ryz*(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2)))/TMath::Sqrt(TMath::Power(Ryx*(-x1+x2)+Ryy*(-y1+y2)+Ryz*(-z1+z2),2.)+TMath::Power(Rzx*(-x1+x2)+Rzy*(-y1+y2)+Rzz*(-z1+z2),2.)),2.));
			    } else {
				distErr = cal2->calcDistanceErr(loccal[0], loccal[1],
								alpha, t1)  + errTof;
			    }

			    const Int_t measDim = 1;
                            // Measurement vector is drift radius.
                            Double_t coord   [measDim];
			    coord[0] = mindist;

			    Double_t coordErr[measDim];
                            coordErr[0] = distErr;

			    Double_t yw, zw = 0.;
			    fSizesCellsLayer.getYZinWireSys(pcaFinal.x(), pcaFinal.y(), pcaFinal.z(),
							    loccal[3], yw, zw);
			    if(yw < 0) coord[0] *= -1.;


                            const HKalMdcMeasLayer *hitmeas =
                                pCradleHades->getMdcLayerAt(loccal[0],
                                                            loccal[1],
                                                            loccal[2]);

                            // Find intersection of segment points with
                            // the measurement layer.
                            TVector3 pos1(x1, y1, z1);
                            TVector3 pos2(x2, y2, z2);
                            TVector3 dir = pos2 - pos1;
                            TVector3 pointIntersect;
                            hitmeas->findIntersection(pointIntersect,
                                                      pos1, dir);

			    Double_t weight = 1. / nCell;
                            if(dist >= 0.) {
                                HKalMdcHit *newhit =
                                    new HKalMdcHit(&coord[0], &coordErr[0],
                                                   *hitmeas, measDim,
                                                   pointIntersect,
                                                   Kalman::kWireHit,
                                                   weight, loccal[3]);
                                newhit->setDriftTime(t1, timeSimErr);
                                //newhit->setImpactAngle(alpha);
                                newhit->setImpactAngle(cal1->getAngle1());
                                newhit->setTime1(cal1->getTime1());
                                newhit->setTime2(cal1->getTime2());
                                newhit->setTimeWireOffset(tWireOffset);
				newhit->setTimeTofCal1(cal1->getTof1());
                                allhits.Add(newhit);
                                nComp++;

                                // Get the time of flight correction by a
                                // weighted least squares estimation:
                                // take the mean difference of the measured
                                // time t1 and the expected drift time timeSim.
                                // These differences are calculated for each
                                // mdc module and weighted by the variances of
                                // the calculated drift time error.
                                Double_t timeSim   =
                                    cal2sim->calcTime(loccal[0], loccal[1],
                                                      alpha, mindist);
                                sumTof[loccal[1]] += (t1 - timeSim) /
                                    (timeSimErr*timeSimErr);
                                sumErr[loccal[1]] += 1. /
                                    (timeSimErr*timeSimErr); // Normalization of weights.
                            }
                        } // for loop over number cells in layer

                        // Weight needs to be corrected if not all cells in a
                        // layer have been added as hit.
                        if(nComp != nCell) {
                            // Competing hits from a measurement layer are
                            // weighted equally.
                            Double_t weight = 1. / (Double_t)nComp;
                            Int_t iLast = allhits.GetEntries() - 1;
                            for(Int_t i = iLast; i > iLast - nComp; i--) {
                                ((HKalMdcHit*)allhits.At(i))->setWeight(weight);
                            }
                        }
                    } // if nCell > 0
                } // end loop over layers
            } // end loop over inner/outer segments

            // Time of flight correction for each module.
            Double_t tTof[4];
            for(Int_t i = 0; i < 4; i++) {
                if(sumErr[i] != 0.) {
                    tTof[i] = sumTof[i] / sumErr[i];
                } else {
                    tTof[i] = 0.;
                }
            }

            // Correct drift time by Tof.
            for(Int_t i = 0; i < allhits.GetEntries(); i++) {
                HKalMdcHit *hit = (HKalMdcHit*)allhits.At(i);
                if(hit) {
                    hit->setDriftTime(TMath::Max(hit->getDriftTime() -
                                                 tTof[hit->getModule()], 0.),
                                      hit->getDriftTimeErr());
                    hit->setTimeTof(tTof[hit->getModule()]);
                } else {
                    cout<<"null pointer at index"<<i<<" of "<<allhits.GetEntries()<<endl;
                }
            }
            return mdcTrkCand;
        }
    } // loop through ideal candidates
    return mdcTrkCand;
}

//? remove
HMdcTrkCand* HKalInput::nextWireTrackNoComp(TObjArray &allhits, Int_t minLayInSeg, Int_t minLayOutSeg) {
    // Fills drift chamber wire hits with the drift time as measurement vector
    // to allhits array.
    // If there are two competing hits in an MDC layer, only the one with the
    // smaller drift time will be used.
    // Loops over HMdcTrkCandIdeal Category for the next four hits. The
    // iterator for the category has to be reset by hand at the begin
    // of each event. Return 0 if no next candidate has been found.
    //
    // output:
    // allhits: array with HKalMdcHit objects (Existing content of array will be deleted!)
    // input:
    // minLayInSeg:   minimum number of layers in the inner segment needed to fill allhits
    // minLayOutSeg:  minimum number of layers in the outer segment needed

    Int_t             indexSeg[2];   // index in catMdcSeg for inner/outer seg
    Int_t             mdcSegNlay[2];

    HMdcSeg     *mdcSeg[2];
    HMdcTrkCand *mdcTrkCand = 0;
    HMetaMatch2 *pMetaMatch = NULL;

    if(fSizesCells == NULL) {
        Error("nextWireTrack()","HMdcSizeCells is NULL!");
        exit(1);
    }
    if(pCradleHades == NULL) {
        Error("nextWireTrack()","DetectorCradle is NULL!");
        exit(1);
    }

    if(!iterMetaMatch) return NULL;

    HLocation loccal;
    loccal.set(4,0,0,0,0);

    HMdcCal2ParSim *cal2sim = (HMdcCal2ParSim*)gHades->getRuntimeDb()->getContainer("MdcCal2ParSim");
    HMdcCal2Par    *cal2    = (HMdcCal2Par   *)gHades->getRuntimeDb()->getContainer("MdcCal2Par");

    allhits.Clear();


    while ((pMetaMatch = (HMetaMatch2*)(iterMetaMatch->Next())) != 0) {
        mdcTrkCand = (HMdcTrkCand*)mdcTrkCandCat->getObject(pMetaMatch->getTrkCandInd());

        for(Int_t io = 0; io < 2; io ++) { // loop inner/outer segment
            mdcSegNlay[io] = 0;
            mdcSeg[io]     = 0;

            indexSeg   [io] =  mdcTrkCand->getSegInd(io);
            if(indexSeg[io] !=-1){
                mdcSeg[io] = (HMdcSeg*) mdcSegCat->getObject(indexSeg[io]);
                if(!mdcSeg[io]){ cout<<"zero segment!"; continue;}
                mdcSegNlay[io] = mdcSeg[io]->getNLayers();
            }
        }
        if(!mdcSeg[0] || !mdcSeg[1]) continue;

        // Skip if there were not enough hits in each segment.
        if(mdcSegNlay[0] >= minLayInSeg && mdcSegNlay[1] >= minLayOutSeg) {
#if kalDebug > 2
            cout<<"filling sec "<<(Int_t)mdcSeg[0]->getSec()<<endl;
#endif

            // Used for time of flight correction of drift time.
            Double_t sumTof [4]={ 0., 0., 0., 0. };
            Double_t sumErr [4]={ 0., 0., 0., 0. };

            for(Int_t io = 0; io < 2; io ++) {              // loop inner/outer segment

                HMdcSeg *seg = mdcSeg[io];

                for(Int_t l = 0; l < 12; l++) { // segment = 2 modules = 2x6 layers
                    // input selection
                    Int_t nCell = seg->getNCells(l); // number of cells per layer
                    loccal[0]   = seg->getSec();
                    Int_t ioseg = seg->getIOSeg(); // 0=inner,1=outer

                    if(nCell > 0) {
                        TObjArray hits;
                        Int_t    nComp = 0; // Number of competing hits in a layer.

                        // Search for the cell with the lowest drift time.
                        Int_t bestCell = -1;
                        Double_t bestTime = -1.;
                        for(Int_t i = 0; i < nCell; i++) {
                            if(ioseg == 0)  {
                                (l < 6) ? loccal[1] = 0 : loccal[1] = 1;
                            } else if(ioseg == 1) {
                                (l < 6) ? loccal[1] = 2 : loccal[1] = 3;
                            }
                            (l < 6) ? loccal[2] = l : loccal[2] = l - 6;

                            // input selection
                            Int_t cell = seg->getCell(l,i);  // get cell number
                            loccal[3] = cell;

                            HMdcCal1Sim *cal1 = (HMdcCal1Sim*)mdcCal1Cat->getObject(loccal);

                            if(cal1->getStatus1() < 0) continue; // Check if hit is valid.

                            if(bestTime < 0.) {
                                bestTime = cal1->getTime1();
                                bestCell = 1;
                            }

                            if(cal1->getTime1() < bestTime) {
                                bestTime = cal1->getTime1();
                                bestCell = i;
                            }
                        }

                        if(bestCell > 0) {

                            Int_t cell = seg->getCell(l,bestCell);  // get cell number
                            loccal[3] = cell;

                            HMdcCal1Sim *cal1 = (HMdcCal1Sim*)mdcCal1Cat->getObject(loccal);

                            if(cal1->getStatus1() < 0) continue; // Check if hit is valid.

                            Double_t x1, y1, z1, x2, y2, z2 = 0.;
                            calcSegPoints(seg, x1, y1, z1, x2, y2, z2);

                            HMdcSizesCellsLayer &fSizesCellsLayer = (*fSizesCells)[loccal[0]][loccal[1]][loccal[2]];
                            HMdcSizesCellsCell  &fSizesCellsCell  = (*fSizesCells)[loccal[0]][loccal[1]][loccal[2]][loccal[3]];

                            TVector3 layerHit;

                            Double_t alpha, mindist;
                            if(!fSizesCellsLayer.getImpact(x1, y1, z1, x2, y2, z2, loccal[3], alpha, mindist)) {
                                if(bPrint) {
                                    Warning("nextWireTrack()", Form("No impact found with cell %i. Measurement discarded.", loccal[3]));
                                }
                                continue;
                            }
                            // Speed of signal on wire in ns/mm
                            Float_t signalSpeed = ((HMdcDigitPar*)gHades->getRuntimeDb()->getContainer("MdcDigitPar"))->getSignalSpeed();

                            // Path length of signal along the wire in mm.
                            Double_t xWire      = fSizesCellsLayer.getSignPath(x1, y1, z1, x2, y2, z2, cell);
                            // Amount of time that the signal travels on the wire.
                            Double_t tWireOffset = xWire * signalSpeed;

                            // Offset from time of flight subtracted later.
                            Float_t t1  = cal1->getTime1() - tWireOffset;

                            Double_t timeSimErr = cal2sim->calcTimeErr(loccal[0], loccal[1], alpha, mindist);

                            Double_t dist       = cal2->calcDistance  (loccal[0], loccal[1], alpha, t1);
                            Double_t distErr    = cal2->calcDistanceErr(loccal[0], loccal[1], alpha, t1);

                            const Int_t measDim = 1;
                            // Measurement vector is drift radius.
                            Double_t coord   [measDim];
                            coord[0] = dist;
                            Double_t coordErr[measDim];
                            coordErr[0] = distErr;

                            HGeomVector &wire1 = fSizesCellsCell.getWirePnt1();
                            TVector3 wirePoint1(wire1.X(), wire1.Y(), wire1.Z());
                            HGeomVector &wire2 = fSizesCellsCell.getWirePnt2();
                            TVector3 wirePoint2(wire2.X(), wire2.Y(), wire2.Z());

                            Int_t iflag;
                            Double_t length;
                            TVector3 pcaFinal, pcaWire;

                            HKalGeomTools::Track2ToLine(pcaFinal, pcaWire, iflag, mindist, length, TVector3(x1,y1,z1), TVector3(x2,y2,z2), wirePoint1, wirePoint2);

                            // Make virtual plane.
                            // origin: PCA on wire
                            // u axis: along wire
                            // v axis: from origin to PCA on track
                            TVector3 u = (wirePoint2 - wirePoint1).Unit();
                            TVector3 v = (pcaFinal - pcaWire).Unit();

                            const HKalMdcMeasLayer *hitmeas = pCradleHades->getMdcLayerAt(loccal[0], loccal[1], loccal[2]);

                            Double_t weight = 1.;// / nCell;
                            if(dist >= 0.) {
                                HKalMdcHit *newhit = new HKalMdcHit(&coord[0], &coordErr[0], *hitmeas, measDim, pcaFinal, Kalman::kWireHit, weight, loccal[3]);
                                newhit->setDriftTime(t1, timeSimErr);
                                newhit->setImpactAngle(alpha);
                                newhit->setTime1(cal1->getTime1());
                                newhit->setTime2(cal1->getTime2());
                                newhit->setTimeWireOffset(tWireOffset);
                                newhit->setTimeTofCal1(cal1->getTof1());
                                allhits.Add(newhit);
                                nComp++;

                                // Get the time of flight correction by a weighted least squares estimation:
                                // take the mean difference of the measured time t1 and the expected drift
                                // time timeSim. These differences are calculated for each mdc module and weighted
                                // by the variances of the calculated drift time error.
                                Double_t timeSim   = cal2sim->calcTime   (loccal[0], loccal[1], alpha, mindist);
                                sumTof[loccal[1]] += (t1 - timeSim) / (timeSimErr*timeSimErr);
                                sumErr[loccal[1]] += 1. / (timeSimErr*timeSimErr); // Normalization of weights.
                            }
                        } // for loop over number cells in layer

                        // Weight needs to be corrected if not all cells in a layer have been added as hit.
                        if(nComp != nCell) {
                            // Competing hits from a measurement layer are weighted equally.
                            Double_t weight = 1. / (Double_t)nComp;
                            Int_t iLast = allhits.GetEntries() - 1;
                            for(Int_t i = iLast; i > iLast - nComp; i--) {
                                ((HKalMdcHit*)allhits.At(i))->setWeight(weight);
                            }
                        }
                    } // if nCell > 0
                } // end loop over layers
            } // end loop over inner/outer segments

            // Time of flight correction for each module.
            Double_t tTof[4];
            for(Int_t i = 0; i < 4; i++) {
                if(sumErr[i] != 0.) {
                    tTof[i] = sumTof[i] / sumErr[i];
                } else {
                    tTof[i] = 0.;
                }
            }

            // Correct drift time by Tof.
            for(Int_t i = 0; i < allhits.GetEntries(); i++) {
                HKalMdcHit *hit = (HKalMdcHit*)allhits.At(i);
                if(hit) {
                    hit->setDriftTime(TMath::Max(hit->getDriftTime() - tTof[hit->getModule()], 0.), hit->getDriftTimeErr());
                    hit->setTimeTof(tTof[hit->getModule()]);
                } else {
                    cout<<"null pointer at index"<<i<<" of "<<allhits.GetEntries()<<endl;
                }
            }
            return mdcTrkCand;
        }
    } // loop through ideal candidates
    return mdcTrkCand;
}

HGeantKine* HKalInput::getGeantKine(const HMdcTrkCand *cand) {
    if(!cand)          { Error("getGeantKine()","HMdcTrkCand == NULL!"); return NULL; }
    if(!mdcSegCat)     { Error("getGeantKine()","mdcSegCat == NULL!"  ); return NULL; }
    HMdcSegSim* mdcSeg = (HMdcSegSim*) mdcSegCat->getObject(cand->getSegInd(0));
    Int_t ind = mdcSeg->getTrack(0);
    if(ind < 0)        { Error("getGeantKine()","ind < 0!"                 ); return NULL; }
    if(!kineCat)       { Error("getGeantKine()","kineCat == NULL!"         ); return NULL; }

    return (HGeantKine* )kineCat->getObject(ind-1);
}

HGeantKine* HKalInput::getGeantKine(const HMdcTrkCandIdeal *cand) {
    if(!cand)          {Error("getGeantKine()","HMdcTrkCandIdeal == NULL!"); return NULL;}
    if(!mdcSegIdealCat){Error("getGeantKine()","mdcSegIdealCat == NULL!"  ); return NULL;}
    HMdcSegIdeal* mdcSeg = (HMdcSegIdeal*) mdcSegIdealCat->getObject(cand->getSegInd(0));
    Int_t ind = mdcSeg->getTrack(0);
    if(ind < 0)        {Error("getGeantKine()","ind < 0!"                 ); return NULL;}
    if(!kineCat)       {Error("getGeantKine()","kineCat == NULL!"         ); return NULL;}

    return (HGeantKine* )kineCat->getObject(ind-1);
}

void HKalInput::getGeantMdcRawpoints(TObjArray &allhits, HGeantKine *kine, Bool_t midplane) {
    // Return TObjArray with pointer to HGeantMdc objects for the track.
    // if midplane == kTRUE  fill only points for layer == 6.
    // if midplane == KFALSE fill only points for layer < 6.

    if(!kine)         {Error("getGeantMdcRawpoints()","HGeantKine == NULL!"); return ;}

    allhits.Clear();

    HGeantMdc* geantMdc;
    kine->resetMdcIter();
    while( (geantMdc = (HGeantMdc*)kine->nextMdcHit()) != 0) {
        if( midplane && geantMdc->getLayer() != 6) continue;  // only hits for modules
        if(!midplane && geantMdc->getLayer() == 6) continue;  // only hits for layers
        allhits.Add(geantMdc);
    }
}

void HKalInput::getPosAndDir(TVector3 &pos, TVector3 &dir, HGeantMdc *geantMdc, Bool_t sectorCoord) {
    // Return pos and dir from HGeantMdc.
    // if sectorCoord == kTRUE the points will be transformed
    // to sector coordinate system.

    if(!geantMdc) { Error("getPosAndDir()","HGeantMdc == NULL!"); return ;}

    Double_t point   [3];
    Double_t pointDir[3];

    Float_t x,y,tof,p,th,ph;
    geantMdc->getHit(x,y,tof,p);

    point[0] = x;
    point[1] = y;
    point[2] = 0;

    geantMdc->getIncidence(th,ph);
    Double_t theta = th * TMath::DegToRad();    // 0 -360 deg
    Double_t phi   = ph * TMath::DegToRad();    // 0 -180 deg
    Double_t sinTh = sin(theta);
    pointDir[0]    = sinTh * cos(phi)         * 1000; // just for precision * 1000
    pointDir[1]    = sinTh * sin(phi)         * 1000;
    pointDir[2]    = sqrt(1. - sinTh * sinTh) * 1000;

    pointDir[0]   += point[0];
    pointDir[1]   += point[1];
    pointDir[2]   += point[2];

    Int_t s = geantMdc->getSector();
    Int_t m = geantMdc->getModule();
    Int_t l = geantMdc->getLayer();

    if(sectorCoord){
        HGeomTransform trans;

        if(l == 6) { // midplane
            ((*fSizesCells)[s][m]).transFrom(point   [0],point   [1],point   [2]); // transform to sector coordinate system
            ((*fSizesCells)[s][m]).transFrom(pointDir[0],pointDir[1],pointDir[2]); // transform to sector coordinate system
        } else {
            if(mdcGetContainers->getSecTransGeantLayer(trans, s, m, l)) {
                HGeomVector layPoint(point[0], point[1], point[2]);
                HGeomVector transPoint = trans.transFrom(layPoint); // transform to sector coordinate system
                point[0] = transPoint.X();
                point[1] = transPoint.Y();
                point[2] = transPoint.Z();

                layPoint.setXYZ(pointDir[0], pointDir[1], pointDir[2]);
                transPoint = trans.transFrom(layPoint); // transform to sector coordinate system
                pointDir[0] = transPoint.X();
                pointDir[1] = transPoint.Y();
                pointDir[2] = transPoint.Z();
            } else {
                Error("getPosAndDir()", "Transformation matrix not found.");
                exit(1);
            }
        }
    }

    pos.SetX(point[0]);
    pos.SetY(point[1]);
    pos.SetZ(point[2]);

    dir.SetX(pointDir[0]);
    dir.SetY(pointDir[1]);
    dir.SetZ(pointDir[2]);

    dir -= pos;

    if(sectorCoord) {
        // Project Geant point on measurement layer.
	const HKalMdcMeasLayer *measLay = pCradleHades->getMdcLayerAt(s, m, l);
#if kalDebug > 3
	cout<<"Distance Geant point to plane: "<<measLay->distanceToPlane(pos)<<endl;
#endif
        TVector3 posNoShift = pos;
        measLay->findIntersection(pos, posNoShift, dir);
    }
}

void HKalInput::getMdcSegs(const HMdcTrkCand *cand, HMdcSeg **segs) {
    if(!cand)      {Error("getGeantKine()","HMdcTrkCand == NULL!"); return ;}
    if(!mdcSegCat) {Error("getGeantKine()","mdcSegCat == NULL!"  ); return ;}

    segs[0]     = (HMdcSeg*) mdcSegCat->getObject(cand->getSegInd(0));
    if(cand->getSegInd(1)!=-1){
        segs[1] = (HMdcSeg*) mdcSegCat->getObject(cand->getSegInd(1));
    } else {
        segs[1] = NULL;
    }
}

void HKalInput::getMdcSegs(const HMdcTrkCandIdeal *cand, HMdcSegIdeal **segs) {
    if(!cand)          {Error("getGeantKine()","HMdcTrkCand == NULL!");      return ;}
    if(!mdcSegIdealCat){Error("getGeantKine()","mdcSegIdealCat == NULL!"  ); return ;}

    segs[0]     = (HMdcSegIdeal*) mdcSegIdealCat->getObject(cand->getSegInd(0));
    if(cand->getSegInd(1)!=-1){
        segs[1] = (HMdcSegIdeal*) mdcSegIdealCat->getObject(cand->getSegInd(1));
    } else {
        segs[1] = NULL;
    }
}
 hkalinput.cc:1
 hkalinput.cc:2
 hkalinput.cc:3
 hkalinput.cc:4
 hkalinput.cc:5
 hkalinput.cc:6
 hkalinput.cc:7
 hkalinput.cc:8
 hkalinput.cc:9
 hkalinput.cc:10
 hkalinput.cc:11
 hkalinput.cc:12
 hkalinput.cc:13
 hkalinput.cc:14
 hkalinput.cc:15
 hkalinput.cc:16
 hkalinput.cc:17
 hkalinput.cc:18
 hkalinput.cc:19
 hkalinput.cc:20
 hkalinput.cc:21
 hkalinput.cc:22
 hkalinput.cc:23
 hkalinput.cc:24
 hkalinput.cc:25
 hkalinput.cc:26
 hkalinput.cc:27
 hkalinput.cc:28
 hkalinput.cc:29
 hkalinput.cc:30
 hkalinput.cc:31
 hkalinput.cc:32
 hkalinput.cc:33
 hkalinput.cc:34
 hkalinput.cc:35
 hkalinput.cc:36
 hkalinput.cc:37
 hkalinput.cc:38
 hkalinput.cc:39
 hkalinput.cc:40
 hkalinput.cc:41
 hkalinput.cc:42
 hkalinput.cc:43
 hkalinput.cc:44
 hkalinput.cc:45
 hkalinput.cc:46
 hkalinput.cc:47
 hkalinput.cc:48
 hkalinput.cc:49
 hkalinput.cc:50
 hkalinput.cc:51
 hkalinput.cc:52
 hkalinput.cc:53
 hkalinput.cc:54
 hkalinput.cc:55
 hkalinput.cc:56
 hkalinput.cc:57
 hkalinput.cc:58
 hkalinput.cc:59
 hkalinput.cc:60
 hkalinput.cc:61
 hkalinput.cc:62
 hkalinput.cc:63
 hkalinput.cc:64
 hkalinput.cc:65
 hkalinput.cc:66
 hkalinput.cc:67
 hkalinput.cc:68
 hkalinput.cc:69
 hkalinput.cc:70
 hkalinput.cc:71
 hkalinput.cc:72
 hkalinput.cc:73
 hkalinput.cc:74
 hkalinput.cc:75
 hkalinput.cc:76
 hkalinput.cc:77
 hkalinput.cc:78
 hkalinput.cc:79
 hkalinput.cc:80
 hkalinput.cc:81
 hkalinput.cc:82
 hkalinput.cc:83
 hkalinput.cc:84
 hkalinput.cc:85
 hkalinput.cc:86
 hkalinput.cc:87
 hkalinput.cc:88
 hkalinput.cc:89
 hkalinput.cc:90
 hkalinput.cc:91
 hkalinput.cc:92
 hkalinput.cc:93
 hkalinput.cc:94
 hkalinput.cc:95
 hkalinput.cc:96
 hkalinput.cc:97
 hkalinput.cc:98
 hkalinput.cc:99
 hkalinput.cc:100
 hkalinput.cc:101
 hkalinput.cc:102
 hkalinput.cc:103
 hkalinput.cc:104
 hkalinput.cc:105
 hkalinput.cc:106
 hkalinput.cc:107
 hkalinput.cc:108
 hkalinput.cc:109
 hkalinput.cc:110
 hkalinput.cc:111
 hkalinput.cc:112
 hkalinput.cc:113
 hkalinput.cc:114
 hkalinput.cc:115
 hkalinput.cc:116
 hkalinput.cc:117
 hkalinput.cc:118
 hkalinput.cc:119
 hkalinput.cc:120
 hkalinput.cc:121
 hkalinput.cc:122
 hkalinput.cc:123
 hkalinput.cc:124
 hkalinput.cc:125
 hkalinput.cc:126
 hkalinput.cc:127
 hkalinput.cc:128
 hkalinput.cc:129
 hkalinput.cc:130
 hkalinput.cc:131
 hkalinput.cc:132
 hkalinput.cc:133
 hkalinput.cc:134
 hkalinput.cc:135
 hkalinput.cc:136
 hkalinput.cc:137
 hkalinput.cc:138
 hkalinput.cc:139
 hkalinput.cc:140
 hkalinput.cc:141
 hkalinput.cc:142
 hkalinput.cc:143
 hkalinput.cc:144
 hkalinput.cc:145
 hkalinput.cc:146
 hkalinput.cc:147
 hkalinput.cc:148
 hkalinput.cc:149
 hkalinput.cc:150
 hkalinput.cc:151
 hkalinput.cc:152
 hkalinput.cc:153
 hkalinput.cc:154
 hkalinput.cc:155
 hkalinput.cc:156
 hkalinput.cc:157
 hkalinput.cc:158
 hkalinput.cc:159
 hkalinput.cc:160
 hkalinput.cc:161
 hkalinput.cc:162
 hkalinput.cc:163
 hkalinput.cc:164
 hkalinput.cc:165
 hkalinput.cc:166
 hkalinput.cc:167
 hkalinput.cc:168
 hkalinput.cc:169
 hkalinput.cc:170
 hkalinput.cc:171
 hkalinput.cc:172
 hkalinput.cc:173
 hkalinput.cc:174
 hkalinput.cc:175
 hkalinput.cc:176
 hkalinput.cc:177
 hkalinput.cc:178
 hkalinput.cc:179
 hkalinput.cc:180
 hkalinput.cc:181
 hkalinput.cc:182
 hkalinput.cc:183
 hkalinput.cc:184
 hkalinput.cc:185
 hkalinput.cc:186
 hkalinput.cc:187
 hkalinput.cc:188
 hkalinput.cc:189
 hkalinput.cc:190
 hkalinput.cc:191
 hkalinput.cc:192
 hkalinput.cc:193
 hkalinput.cc:194
 hkalinput.cc:195
 hkalinput.cc:196
 hkalinput.cc:197
 hkalinput.cc:198
 hkalinput.cc:199
 hkalinput.cc:200
 hkalinput.cc:201
 hkalinput.cc:202
 hkalinput.cc:203
 hkalinput.cc:204
 hkalinput.cc:205
 hkalinput.cc:206
 hkalinput.cc:207
 hkalinput.cc:208
 hkalinput.cc:209
 hkalinput.cc:210
 hkalinput.cc:211
 hkalinput.cc:212
 hkalinput.cc:213
 hkalinput.cc:214
 hkalinput.cc:215
 hkalinput.cc:216
 hkalinput.cc:217
 hkalinput.cc:218
 hkalinput.cc:219
 hkalinput.cc:220
 hkalinput.cc:221
 hkalinput.cc:222
 hkalinput.cc:223
 hkalinput.cc:224
 hkalinput.cc:225
 hkalinput.cc:226
 hkalinput.cc:227
 hkalinput.cc:228
 hkalinput.cc:229
 hkalinput.cc:230
 hkalinput.cc:231
 hkalinput.cc:232
 hkalinput.cc:233
 hkalinput.cc:234
 hkalinput.cc:235
 hkalinput.cc:236
 hkalinput.cc:237
 hkalinput.cc:238
 hkalinput.cc:239
 hkalinput.cc:240
 hkalinput.cc:241
 hkalinput.cc:242
 hkalinput.cc:243
 hkalinput.cc:244
 hkalinput.cc:245
 hkalinput.cc:246
 hkalinput.cc:247
 hkalinput.cc:248
 hkalinput.cc:249
 hkalinput.cc:250
 hkalinput.cc:251
 hkalinput.cc:252
 hkalinput.cc:253
 hkalinput.cc:254
 hkalinput.cc:255
 hkalinput.cc:256
 hkalinput.cc:257
 hkalinput.cc:258
 hkalinput.cc:259
 hkalinput.cc:260
 hkalinput.cc:261
 hkalinput.cc:262
 hkalinput.cc:263
 hkalinput.cc:264
 hkalinput.cc:265
 hkalinput.cc:266
 hkalinput.cc:267
 hkalinput.cc:268
 hkalinput.cc:269
 hkalinput.cc:270
 hkalinput.cc:271
 hkalinput.cc:272
 hkalinput.cc:273
 hkalinput.cc:274
 hkalinput.cc:275
 hkalinput.cc:276
 hkalinput.cc:277
 hkalinput.cc:278
 hkalinput.cc:279
 hkalinput.cc:280
 hkalinput.cc:281
 hkalinput.cc:282
 hkalinput.cc:283
 hkalinput.cc:284
 hkalinput.cc:285
 hkalinput.cc:286
 hkalinput.cc:287
 hkalinput.cc:288
 hkalinput.cc:289
 hkalinput.cc:290
 hkalinput.cc:291
 hkalinput.cc:292
 hkalinput.cc:293
 hkalinput.cc:294
 hkalinput.cc:295
 hkalinput.cc:296
 hkalinput.cc:297
 hkalinput.cc:298
 hkalinput.cc:299
 hkalinput.cc:300
 hkalinput.cc:301
 hkalinput.cc:302
 hkalinput.cc:303
 hkalinput.cc:304
 hkalinput.cc:305
 hkalinput.cc:306
 hkalinput.cc:307
 hkalinput.cc:308
 hkalinput.cc:309
 hkalinput.cc:310
 hkalinput.cc:311
 hkalinput.cc:312
 hkalinput.cc:313
 hkalinput.cc:314
 hkalinput.cc:315
 hkalinput.cc:316
 hkalinput.cc:317
 hkalinput.cc:318
 hkalinput.cc:319
 hkalinput.cc:320
 hkalinput.cc:321
 hkalinput.cc:322
 hkalinput.cc:323
 hkalinput.cc:324
 hkalinput.cc:325
 hkalinput.cc:326
 hkalinput.cc:327
 hkalinput.cc:328
 hkalinput.cc:329
 hkalinput.cc:330
 hkalinput.cc:331
 hkalinput.cc:332
 hkalinput.cc:333
 hkalinput.cc:334
 hkalinput.cc:335
 hkalinput.cc:336
 hkalinput.cc:337
 hkalinput.cc:338
 hkalinput.cc:339
 hkalinput.cc:340
 hkalinput.cc:341
 hkalinput.cc:342
 hkalinput.cc:343
 hkalinput.cc:344
 hkalinput.cc:345
 hkalinput.cc:346
 hkalinput.cc:347
 hkalinput.cc:348
 hkalinput.cc:349
 hkalinput.cc:350
 hkalinput.cc:351
 hkalinput.cc:352
 hkalinput.cc:353
 hkalinput.cc:354
 hkalinput.cc:355
 hkalinput.cc:356
 hkalinput.cc:357
 hkalinput.cc:358
 hkalinput.cc:359
 hkalinput.cc:360
 hkalinput.cc:361
 hkalinput.cc:362
 hkalinput.cc:363
 hkalinput.cc:364
 hkalinput.cc:365
 hkalinput.cc:366
 hkalinput.cc:367
 hkalinput.cc:368
 hkalinput.cc:369
 hkalinput.cc:370
 hkalinput.cc:371
 hkalinput.cc:372
 hkalinput.cc:373
 hkalinput.cc:374
 hkalinput.cc:375
 hkalinput.cc:376
 hkalinput.cc:377
 hkalinput.cc:378
 hkalinput.cc:379
 hkalinput.cc:380
 hkalinput.cc:381
 hkalinput.cc:382
 hkalinput.cc:383
 hkalinput.cc:384
 hkalinput.cc:385
 hkalinput.cc:386
 hkalinput.cc:387
 hkalinput.cc:388
 hkalinput.cc:389
 hkalinput.cc:390
 hkalinput.cc:391
 hkalinput.cc:392
 hkalinput.cc:393
 hkalinput.cc:394
 hkalinput.cc:395
 hkalinput.cc:396
 hkalinput.cc:397
 hkalinput.cc:398
 hkalinput.cc:399
 hkalinput.cc:400
 hkalinput.cc:401
 hkalinput.cc:402
 hkalinput.cc:403
 hkalinput.cc:404
 hkalinput.cc:405
 hkalinput.cc:406
 hkalinput.cc:407
 hkalinput.cc:408
 hkalinput.cc:409
 hkalinput.cc:410
 hkalinput.cc:411
 hkalinput.cc:412
 hkalinput.cc:413
 hkalinput.cc:414
 hkalinput.cc:415
 hkalinput.cc:416
 hkalinput.cc:417
 hkalinput.cc:418
 hkalinput.cc:419
 hkalinput.cc:420
 hkalinput.cc:421
 hkalinput.cc:422
 hkalinput.cc:423
 hkalinput.cc:424
 hkalinput.cc:425
 hkalinput.cc:426
 hkalinput.cc:427
 hkalinput.cc:428
 hkalinput.cc:429
 hkalinput.cc:430
 hkalinput.cc:431
 hkalinput.cc:432
 hkalinput.cc:433
 hkalinput.cc:434
 hkalinput.cc:435
 hkalinput.cc:436
 hkalinput.cc:437
 hkalinput.cc:438
 hkalinput.cc:439
 hkalinput.cc:440
 hkalinput.cc:441
 hkalinput.cc:442
 hkalinput.cc:443
 hkalinput.cc:444
 hkalinput.cc:445
 hkalinput.cc:446
 hkalinput.cc:447
 hkalinput.cc:448
 hkalinput.cc:449
 hkalinput.cc:450
 hkalinput.cc:451
 hkalinput.cc:452
 hkalinput.cc:453
 hkalinput.cc:454
 hkalinput.cc:455
 hkalinput.cc:456
 hkalinput.cc:457
 hkalinput.cc:458
 hkalinput.cc:459
 hkalinput.cc:460
 hkalinput.cc:461
 hkalinput.cc:462
 hkalinput.cc:463
 hkalinput.cc:464
 hkalinput.cc:465
 hkalinput.cc:466
 hkalinput.cc:467
 hkalinput.cc:468
 hkalinput.cc:469
 hkalinput.cc:470
 hkalinput.cc:471
 hkalinput.cc:472
 hkalinput.cc:473
 hkalinput.cc:474
 hkalinput.cc:475
 hkalinput.cc:476
 hkalinput.cc:477
 hkalinput.cc:478
 hkalinput.cc:479
 hkalinput.cc:480
 hkalinput.cc:481
 hkalinput.cc:482
 hkalinput.cc:483
 hkalinput.cc:484
 hkalinput.cc:485
 hkalinput.cc:486
 hkalinput.cc:487
 hkalinput.cc:488
 hkalinput.cc:489
 hkalinput.cc:490
 hkalinput.cc:491
 hkalinput.cc:492
 hkalinput.cc:493
 hkalinput.cc:494
 hkalinput.cc:495
 hkalinput.cc:496
 hkalinput.cc:497
 hkalinput.cc:498
 hkalinput.cc:499
 hkalinput.cc:500
 hkalinput.cc:501
 hkalinput.cc:502
 hkalinput.cc:503
 hkalinput.cc:504
 hkalinput.cc:505
 hkalinput.cc:506
 hkalinput.cc:507
 hkalinput.cc:508
 hkalinput.cc:509
 hkalinput.cc:510
 hkalinput.cc:511
 hkalinput.cc:512
 hkalinput.cc:513
 hkalinput.cc:514
 hkalinput.cc:515
 hkalinput.cc:516
 hkalinput.cc:517
 hkalinput.cc:518
 hkalinput.cc:519
 hkalinput.cc:520
 hkalinput.cc:521
 hkalinput.cc:522
 hkalinput.cc:523
 hkalinput.cc:524
 hkalinput.cc:525
 hkalinput.cc:526
 hkalinput.cc:527
 hkalinput.cc:528
 hkalinput.cc:529
 hkalinput.cc:530
 hkalinput.cc:531
 hkalinput.cc:532
 hkalinput.cc:533
 hkalinput.cc:534
 hkalinput.cc:535
 hkalinput.cc:536
 hkalinput.cc:537
 hkalinput.cc:538
 hkalinput.cc:539
 hkalinput.cc:540
 hkalinput.cc:541
 hkalinput.cc:542
 hkalinput.cc:543
 hkalinput.cc:544
 hkalinput.cc:545
 hkalinput.cc:546
 hkalinput.cc:547
 hkalinput.cc:548
 hkalinput.cc:549
 hkalinput.cc:550
 hkalinput.cc:551
 hkalinput.cc:552
 hkalinput.cc:553
 hkalinput.cc:554
 hkalinput.cc:555
 hkalinput.cc:556
 hkalinput.cc:557
 hkalinput.cc:558
 hkalinput.cc:559
 hkalinput.cc:560
 hkalinput.cc:561
 hkalinput.cc:562
 hkalinput.cc:563
 hkalinput.cc:564
 hkalinput.cc:565
 hkalinput.cc:566
 hkalinput.cc:567
 hkalinput.cc:568
 hkalinput.cc:569
 hkalinput.cc:570
 hkalinput.cc:571
 hkalinput.cc:572
 hkalinput.cc:573
 hkalinput.cc:574
 hkalinput.cc:575
 hkalinput.cc:576
 hkalinput.cc:577
 hkalinput.cc:578
 hkalinput.cc:579
 hkalinput.cc:580
 hkalinput.cc:581
 hkalinput.cc:582
 hkalinput.cc:583
 hkalinput.cc:584
 hkalinput.cc:585
 hkalinput.cc:586
 hkalinput.cc:587
 hkalinput.cc:588
 hkalinput.cc:589
 hkalinput.cc:590
 hkalinput.cc:591
 hkalinput.cc:592
 hkalinput.cc:593
 hkalinput.cc:594
 hkalinput.cc:595
 hkalinput.cc:596
 hkalinput.cc:597
 hkalinput.cc:598
 hkalinput.cc:599
 hkalinput.cc:600
 hkalinput.cc:601
 hkalinput.cc:602
 hkalinput.cc:603
 hkalinput.cc:604
 hkalinput.cc:605
 hkalinput.cc:606
 hkalinput.cc:607
 hkalinput.cc:608
 hkalinput.cc:609
 hkalinput.cc:610
 hkalinput.cc:611
 hkalinput.cc:612
 hkalinput.cc:613
 hkalinput.cc:614
 hkalinput.cc:615
 hkalinput.cc:616
 hkalinput.cc:617
 hkalinput.cc:618
 hkalinput.cc:619
 hkalinput.cc:620
 hkalinput.cc:621
 hkalinput.cc:622
 hkalinput.cc:623
 hkalinput.cc:624
 hkalinput.cc:625
 hkalinput.cc:626
 hkalinput.cc:627
 hkalinput.cc:628
 hkalinput.cc:629
 hkalinput.cc:630
 hkalinput.cc:631
 hkalinput.cc:632
 hkalinput.cc:633
 hkalinput.cc:634
 hkalinput.cc:635
 hkalinput.cc:636
 hkalinput.cc:637
 hkalinput.cc:638
 hkalinput.cc:639
 hkalinput.cc:640
 hkalinput.cc:641
 hkalinput.cc:642
 hkalinput.cc:643
 hkalinput.cc:644
 hkalinput.cc:645
 hkalinput.cc:646
 hkalinput.cc:647
 hkalinput.cc:648
 hkalinput.cc:649
 hkalinput.cc:650
 hkalinput.cc:651
 hkalinput.cc:652
 hkalinput.cc:653
 hkalinput.cc:654
 hkalinput.cc:655
 hkalinput.cc:656
 hkalinput.cc:657
 hkalinput.cc:658
 hkalinput.cc:659
 hkalinput.cc:660
 hkalinput.cc:661
 hkalinput.cc:662
 hkalinput.cc:663
 hkalinput.cc:664
 hkalinput.cc:665
 hkalinput.cc:666
 hkalinput.cc:667
 hkalinput.cc:668
 hkalinput.cc:669
 hkalinput.cc:670
 hkalinput.cc:671
 hkalinput.cc:672
 hkalinput.cc:673
 hkalinput.cc:674
 hkalinput.cc:675
 hkalinput.cc:676
 hkalinput.cc:677
 hkalinput.cc:678
 hkalinput.cc:679
 hkalinput.cc:680
 hkalinput.cc:681
 hkalinput.cc:682
 hkalinput.cc:683
 hkalinput.cc:684
 hkalinput.cc:685
 hkalinput.cc:686
 hkalinput.cc:687
 hkalinput.cc:688
 hkalinput.cc:689
 hkalinput.cc:690
 hkalinput.cc:691
 hkalinput.cc:692
 hkalinput.cc:693
 hkalinput.cc:694
 hkalinput.cc:695
 hkalinput.cc:696
 hkalinput.cc:697
 hkalinput.cc:698
 hkalinput.cc:699
 hkalinput.cc:700
 hkalinput.cc:701
 hkalinput.cc:702
 hkalinput.cc:703
 hkalinput.cc:704
 hkalinput.cc:705
 hkalinput.cc:706
 hkalinput.cc:707
 hkalinput.cc:708
 hkalinput.cc:709
 hkalinput.cc:710
 hkalinput.cc:711
 hkalinput.cc:712
 hkalinput.cc:713
 hkalinput.cc:714
 hkalinput.cc:715
 hkalinput.cc:716
 hkalinput.cc:717
 hkalinput.cc:718
 hkalinput.cc:719
 hkalinput.cc:720
 hkalinput.cc:721
 hkalinput.cc:722
 hkalinput.cc:723
 hkalinput.cc:724
 hkalinput.cc:725
 hkalinput.cc:726
 hkalinput.cc:727
 hkalinput.cc:728
 hkalinput.cc:729
 hkalinput.cc:730
 hkalinput.cc:731
 hkalinput.cc:732
 hkalinput.cc:733
 hkalinput.cc:734
 hkalinput.cc:735
 hkalinput.cc:736
 hkalinput.cc:737
 hkalinput.cc:738
 hkalinput.cc:739
 hkalinput.cc:740
 hkalinput.cc:741
 hkalinput.cc:742
 hkalinput.cc:743
 hkalinput.cc:744
 hkalinput.cc:745
 hkalinput.cc:746
 hkalinput.cc:747
 hkalinput.cc:748
 hkalinput.cc:749
 hkalinput.cc:750
 hkalinput.cc:751
 hkalinput.cc:752
 hkalinput.cc:753
 hkalinput.cc:754
 hkalinput.cc:755
 hkalinput.cc:756
 hkalinput.cc:757
 hkalinput.cc:758
 hkalinput.cc:759
 hkalinput.cc:760
 hkalinput.cc:761
 hkalinput.cc:762
 hkalinput.cc:763
 hkalinput.cc:764
 hkalinput.cc:765
 hkalinput.cc:766
 hkalinput.cc:767
 hkalinput.cc:768
 hkalinput.cc:769
 hkalinput.cc:770
 hkalinput.cc:771
 hkalinput.cc:772
 hkalinput.cc:773
 hkalinput.cc:774
 hkalinput.cc:775
 hkalinput.cc:776
 hkalinput.cc:777
 hkalinput.cc:778
 hkalinput.cc:779
 hkalinput.cc:780
 hkalinput.cc:781
 hkalinput.cc:782
 hkalinput.cc:783
 hkalinput.cc:784
 hkalinput.cc:785
 hkalinput.cc:786
 hkalinput.cc:787
 hkalinput.cc:788
 hkalinput.cc:789
 hkalinput.cc:790
 hkalinput.cc:791
 hkalinput.cc:792
 hkalinput.cc:793
 hkalinput.cc:794
 hkalinput.cc:795
 hkalinput.cc:796
 hkalinput.cc:797
 hkalinput.cc:798
 hkalinput.cc:799
 hkalinput.cc:800
 hkalinput.cc:801
 hkalinput.cc:802
 hkalinput.cc:803
 hkalinput.cc:804
 hkalinput.cc:805
 hkalinput.cc:806
 hkalinput.cc:807
 hkalinput.cc:808
 hkalinput.cc:809
 hkalinput.cc:810
 hkalinput.cc:811
 hkalinput.cc:812
 hkalinput.cc:813
 hkalinput.cc:814
 hkalinput.cc:815
 hkalinput.cc:816
 hkalinput.cc:817
 hkalinput.cc:818
 hkalinput.cc:819
 hkalinput.cc:820
 hkalinput.cc:821
 hkalinput.cc:822
 hkalinput.cc:823
 hkalinput.cc:824
 hkalinput.cc:825
 hkalinput.cc:826
 hkalinput.cc:827
 hkalinput.cc:828
 hkalinput.cc:829
 hkalinput.cc:830
 hkalinput.cc:831
 hkalinput.cc:832
 hkalinput.cc:833
 hkalinput.cc:834
 hkalinput.cc:835
 hkalinput.cc:836
 hkalinput.cc:837
 hkalinput.cc:838
 hkalinput.cc:839
 hkalinput.cc:840
 hkalinput.cc:841
 hkalinput.cc:842
 hkalinput.cc:843
 hkalinput.cc:844
 hkalinput.cc:845
 hkalinput.cc:846
 hkalinput.cc:847
 hkalinput.cc:848
 hkalinput.cc:849
 hkalinput.cc:850
 hkalinput.cc:851
 hkalinput.cc:852
 hkalinput.cc:853
 hkalinput.cc:854
 hkalinput.cc:855
 hkalinput.cc:856
 hkalinput.cc:857
 hkalinput.cc:858
 hkalinput.cc:859
 hkalinput.cc:860
 hkalinput.cc:861
 hkalinput.cc:862
 hkalinput.cc:863
 hkalinput.cc:864
 hkalinput.cc:865
 hkalinput.cc:866
 hkalinput.cc:867
 hkalinput.cc:868
 hkalinput.cc:869
 hkalinput.cc:870
 hkalinput.cc:871
 hkalinput.cc:872
 hkalinput.cc:873
 hkalinput.cc:874
 hkalinput.cc:875
 hkalinput.cc:876
 hkalinput.cc:877
 hkalinput.cc:878
 hkalinput.cc:879
 hkalinput.cc:880
 hkalinput.cc:881
 hkalinput.cc:882
 hkalinput.cc:883
 hkalinput.cc:884
 hkalinput.cc:885
 hkalinput.cc:886
 hkalinput.cc:887
 hkalinput.cc:888
 hkalinput.cc:889
 hkalinput.cc:890
 hkalinput.cc:891
 hkalinput.cc:892
 hkalinput.cc:893
 hkalinput.cc:894
 hkalinput.cc:895
 hkalinput.cc:896
 hkalinput.cc:897
 hkalinput.cc:898
 hkalinput.cc:899
 hkalinput.cc:900
 hkalinput.cc:901
 hkalinput.cc:902
 hkalinput.cc:903
 hkalinput.cc:904
 hkalinput.cc:905
 hkalinput.cc:906
 hkalinput.cc:907
 hkalinput.cc:908
 hkalinput.cc:909
 hkalinput.cc:910
 hkalinput.cc:911
 hkalinput.cc:912
 hkalinput.cc:913
 hkalinput.cc:914
 hkalinput.cc:915
 hkalinput.cc:916
 hkalinput.cc:917
 hkalinput.cc:918
 hkalinput.cc:919
 hkalinput.cc:920
 hkalinput.cc:921
 hkalinput.cc:922
 hkalinput.cc:923
 hkalinput.cc:924
 hkalinput.cc:925
 hkalinput.cc:926
 hkalinput.cc:927
 hkalinput.cc:928
 hkalinput.cc:929
 hkalinput.cc:930
 hkalinput.cc:931
 hkalinput.cc:932
 hkalinput.cc:933
 hkalinput.cc:934
 hkalinput.cc:935
 hkalinput.cc:936
 hkalinput.cc:937
 hkalinput.cc:938
 hkalinput.cc:939
 hkalinput.cc:940
 hkalinput.cc:941
 hkalinput.cc:942
 hkalinput.cc:943
 hkalinput.cc:944
 hkalinput.cc:945
 hkalinput.cc:946
 hkalinput.cc:947
 hkalinput.cc:948
 hkalinput.cc:949
 hkalinput.cc:950
 hkalinput.cc:951
 hkalinput.cc:952
 hkalinput.cc:953
 hkalinput.cc:954
 hkalinput.cc:955
 hkalinput.cc:956
 hkalinput.cc:957
 hkalinput.cc:958
 hkalinput.cc:959
 hkalinput.cc:960
 hkalinput.cc:961
 hkalinput.cc:962
 hkalinput.cc:963
 hkalinput.cc:964
 hkalinput.cc:965
 hkalinput.cc:966
 hkalinput.cc:967
 hkalinput.cc:968
 hkalinput.cc:969
 hkalinput.cc:970
 hkalinput.cc:971
 hkalinput.cc:972
 hkalinput.cc:973
 hkalinput.cc:974
 hkalinput.cc:975
 hkalinput.cc:976
 hkalinput.cc:977
 hkalinput.cc:978
 hkalinput.cc:979
 hkalinput.cc:980
 hkalinput.cc:981
 hkalinput.cc:982
 hkalinput.cc:983
 hkalinput.cc:984
 hkalinput.cc:985
 hkalinput.cc:986
 hkalinput.cc:987
 hkalinput.cc:988
 hkalinput.cc:989
 hkalinput.cc:990
 hkalinput.cc:991
 hkalinput.cc:992
 hkalinput.cc:993
 hkalinput.cc:994
 hkalinput.cc:995
 hkalinput.cc:996
 hkalinput.cc:997
 hkalinput.cc:998
 hkalinput.cc:999
 hkalinput.cc:1000
 hkalinput.cc:1001
 hkalinput.cc:1002
 hkalinput.cc:1003
 hkalinput.cc:1004
 hkalinput.cc:1005
 hkalinput.cc:1006
 hkalinput.cc:1007
 hkalinput.cc:1008
 hkalinput.cc:1009
 hkalinput.cc:1010
 hkalinput.cc:1011
 hkalinput.cc:1012
 hkalinput.cc:1013
 hkalinput.cc:1014
 hkalinput.cc:1015
 hkalinput.cc:1016
 hkalinput.cc:1017
 hkalinput.cc:1018
 hkalinput.cc:1019
 hkalinput.cc:1020
 hkalinput.cc:1021
 hkalinput.cc:1022
 hkalinput.cc:1023
 hkalinput.cc:1024
 hkalinput.cc:1025
 hkalinput.cc:1026
 hkalinput.cc:1027
 hkalinput.cc:1028
 hkalinput.cc:1029
 hkalinput.cc:1030
 hkalinput.cc:1031
 hkalinput.cc:1032
 hkalinput.cc:1033
 hkalinput.cc:1034
 hkalinput.cc:1035
 hkalinput.cc:1036
 hkalinput.cc:1037
 hkalinput.cc:1038
 hkalinput.cc:1039
 hkalinput.cc:1040
 hkalinput.cc:1041
 hkalinput.cc:1042
 hkalinput.cc:1043
 hkalinput.cc:1044
 hkalinput.cc:1045
 hkalinput.cc:1046
 hkalinput.cc:1047
 hkalinput.cc:1048
 hkalinput.cc:1049
 hkalinput.cc:1050
 hkalinput.cc:1051
 hkalinput.cc:1052
 hkalinput.cc:1053
 hkalinput.cc:1054
 hkalinput.cc:1055
 hkalinput.cc:1056
 hkalinput.cc:1057
 hkalinput.cc:1058
 hkalinput.cc:1059
 hkalinput.cc:1060
 hkalinput.cc:1061
 hkalinput.cc:1062
 hkalinput.cc:1063
 hkalinput.cc:1064
 hkalinput.cc:1065
 hkalinput.cc:1066
 hkalinput.cc:1067
 hkalinput.cc:1068
 hkalinput.cc:1069
 hkalinput.cc:1070
 hkalinput.cc:1071
 hkalinput.cc:1072
 hkalinput.cc:1073
 hkalinput.cc:1074
 hkalinput.cc:1075
 hkalinput.cc:1076
 hkalinput.cc:1077
 hkalinput.cc:1078
 hkalinput.cc:1079
 hkalinput.cc:1080
 hkalinput.cc:1081
 hkalinput.cc:1082
 hkalinput.cc:1083
 hkalinput.cc:1084
 hkalinput.cc:1085
 hkalinput.cc:1086
 hkalinput.cc:1087
 hkalinput.cc:1088
 hkalinput.cc:1089
 hkalinput.cc:1090
 hkalinput.cc:1091
 hkalinput.cc:1092
 hkalinput.cc:1093
 hkalinput.cc:1094
 hkalinput.cc:1095
 hkalinput.cc:1096
 hkalinput.cc:1097
 hkalinput.cc:1098
 hkalinput.cc:1099
 hkalinput.cc:1100
 hkalinput.cc:1101
 hkalinput.cc:1102
 hkalinput.cc:1103
 hkalinput.cc:1104
 hkalinput.cc:1105
 hkalinput.cc:1106
 hkalinput.cc:1107
 hkalinput.cc:1108
 hkalinput.cc:1109
 hkalinput.cc:1110
 hkalinput.cc:1111
 hkalinput.cc:1112
 hkalinput.cc:1113
 hkalinput.cc:1114
 hkalinput.cc:1115
 hkalinput.cc:1116
 hkalinput.cc:1117
 hkalinput.cc:1118
 hkalinput.cc:1119