+ // Perform the actual tracklet fit based on the fit sums
+ // which have been filled in the fit registers.
+
+ // parameters in fitred.asm (fit program)
+ Int_t decPlaces = 5;
+ Int_t rndAdd = 0;
+ if (decPlaces > 1)
+ rndAdd = (1 << (decPlaces-1)) + 1;
+ else if (decPlaces == 1)
+ rndAdd = 1;
+ Int_t ndriftDp = 5; // decimal places for drift time
+ Long64_t shift = ((Long64_t) 1 << 32);
+
+ // calculated in fitred.asm
+ Int_t padrow = ((fRobPos >> 1) << 2) | (fMcmPos >> 2);
+ Int_t yoffs = (((((fRobPos & 0x1) << 2) + (fMcmPos & 0x3)) * 18) << 8) -
+ ((18*4*2 - 18*2 - 1) << 7);
+ yoffs = yoffs << decPlaces; // holds position of ADC channel 1
+ Int_t layer = fDetector % 6;
+ UInt_t scaleY = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 160.0e-4) * shift);
+ UInt_t scaleD = (UInt_t) ((0.635 + 0.03 * layer)/(256.0 * 140.0e-4) * shift);
+
+ Int_t deflCorr = fTrapConfig->GetDmem(0xc022, fDetector, fRobPos, fMcmPos);
+ Int_t ndrift = fTrapConfig->GetDmem(0xc025, fDetector, fRobPos, fMcmPos);
+
+ // local variables for calculation
+ Long64_t mult, temp, denom; //???
+ UInt_t q0, q1, qTotal; // charges in the two windows and total charge
+ UShort_t nHits; // number of hits
+ Int_t slope, offset; // slope and offset of the tracklet
+ Int_t sumX, sumY, sumXY, sumX2; // fit sums from fit registers
+ //int32_t SumY2; // not used in the current TRAP program
+ FitReg_t *fit0, *fit1; // pointers to relevant fit registers
+
+// const uint32_t OneDivN[32] = { // 2**31/N : exactly like in the TRAP, the simple division here gives the same result!
+// 0x00000000, 0x80000000, 0x40000000, 0x2AAAAAA0, 0x20000000, 0x19999990, 0x15555550, 0x12492490,
+// 0x10000000, 0x0E38E380, 0x0CCCCCC0, 0x0BA2E8B0, 0x0AAAAAA0, 0x09D89D80, 0x09249240, 0x08888880,
+// 0x08000000, 0x07878780, 0x071C71C0, 0x06BCA1A0, 0x06666660, 0x06186180, 0x05D17450, 0x0590B210,
+// 0x05555550, 0x051EB850, 0x04EC4EC0, 0x04BDA120, 0x04924920, 0x0469EE50, 0x04444440, 0x04210840};
+
+ for (Int_t cpu = 0; cpu < 4; cpu++) {
+ if (fFitPtr[cpu] == 31)
+ {
+ fMCMT[cpu] = 0x10001000; //??? AliTRDfeeParam::GetTrackletEndmarker();
+ }
+ else
+ {
+ fit0 = &fFitReg[fFitPtr[cpu] ];
+ fit1 = &fFitReg[fFitPtr[cpu]+1]; // next channel
+
+ mult = 1;
+ mult = mult << (32 + decPlaces);
+ mult = -mult;
+
+ // Merging
+ nHits = fit0->fNhits + fit1->fNhits; // number of hits
+ sumX = fit0->fSumX + fit1->fSumX;
+ sumX2 = fit0->fSumX2 + fit1->fSumX2;
+ denom = nHits*sumX2 - sumX*sumX;
+
+ mult = mult / denom; // exactly like in the TRAP program
+ q0 = fit0->fQ0 + fit1->fQ0;
+ q1 = fit0->fQ1 + fit1->fQ1;
+ sumY = fit0->fSumY + fit1->fSumY + 256*fit1->fNhits;
+ sumXY = fit0->fSumXY + fit1->fSumXY + 256*fit1->fSumX;
+
+ slope = nHits*sumXY - sumX * sumY;
+ offset = sumX2*sumY - sumX * sumXY;
+ temp = mult * slope;
+ slope = temp >> 32; // take the upper 32 bits
+ slope = -slope;
+ temp = mult * offset;
+ offset = temp >> 32; // take the upper 32 bits
+
+ offset = offset + yoffs;
+ AliDebug(10, Form("slope = %i, slope * ndrift = %i, deflCorr: %i",
+ slope, slope * ndrift, deflCorr));
+ slope = ((slope * ndrift) >> ndriftDp) + deflCorr;
+ offset = offset - (fFitPtr[cpu] << (8 + decPlaces));
+
+ temp = slope;
+ temp = temp * scaleD;
+ slope = (temp >> 32);
+ temp = offset;
+ temp = temp * scaleY;
+ offset = (temp >> 32);
+
+ // rounding, like in the TRAP
+ slope = (slope + rndAdd) >> decPlaces;
+ offset = (offset + rndAdd) >> decPlaces;
+
+ AliDebug(5, Form("Det: %3i, ROB: %i, MCM: %2i: deflection: %i, min: %i, max: %i",
+ fDetector, fRobPos, fMcmPos, slope,
+ fTrapConfig->GetDmem(0xc030 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos),
+ fTrapConfig->GetDmem(0xc031 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)));
+
+ Bool_t rejected = kFALSE;
+ // deflection range table from DMEM
+ if ((slope < fTrapConfig->GetDmem(0xc030 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)) ||
+ (slope > fTrapConfig->GetDmem(0xc031 + 2*fFitPtr[cpu], fDetector, fRobPos, fMcmPos)))
+ rejected = kTRUE;
+
+ if (rejected && GetApplyCut())
+ {
+ fMCMT[cpu] = 0x10001000; //??? AliTRDfeeParam::GetTrackletEndmarker();
+ }
+ else
+ {
+ if (slope > 63 || slope < -64) { // wrapping in TRAP!
+ AliError(Form("Overflow in slope: %i, tracklet discarded!", slope));
+ fMCMT[cpu] = 0x10001000;
+ continue;
+ }
+
+ slope = slope & 0x7F; // 7 bit
+
+ if (offset > 0xfff || offset < -0xfff)
+ AliWarning("Overflow in offset");
+ offset = offset & 0x1FFF; // 13 bit