+//_____________________________________________________________________________
+void AliTRDclusterizerV1::Transform(AliTRDdataArrayI* digitsIn,
+ AliTRDdataArrayF* digitsOut,
+ Int_t idet, Int_t nRowMax,
+ Int_t nColMax, Int_t nTimeTotal,
+ Float_t ADCthreshold)
+{
+
+ //
+ // Apply gain factor
+ // Apply tail cancellation: Transform digitsIn to digitsOut
+ //
+
+
+ AliTRDRecParam* recParam = AliTRDRecParam::Instance();
+ if (!recParam)
+ {
+ printf("<AliTRDclusterizerV1::Transform> ");
+ printf("ERROR getting instance of AliTRDRecParam");
+ return;
+ }
+ AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+
+ Double_t *inADC = new Double_t[nTimeTotal]; // adc data before tail cancellation
+ Double_t *outADC = new Double_t[nTimeTotal]; // adc data after tail cancellation
+
+ if (fVerbose > 0) {
+ printf("<AliTRDclusterizerV1::Transform> ");
+ printf("Tail cancellation (nExp = %d) for detector %d.\n",
+ recParam->GetTCnexp(),idet);
+ }
+
+ for (Int_t iRow = 0; iRow < nRowMax; iRow++ ) {
+ for (Int_t iCol = 0; iCol < nColMax; iCol++ ) {
+ for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
+ //
+ // add gain
+ //
+ Double_t gain = calibration->GetGainFactor(idet, iCol, iRow);
+ if (gain==0) {
+ AliError("Not a valid gain\n");
+ }
+ inADC[iTime] = digitsIn->GetDataUnchecked(iRow, iCol, iTime);
+
+ inADC[iTime] /= gain;
+ outADC[iTime] = inADC[iTime];
+ }
+
+ // Apply the tail cancelation via the digital filter
+ if (recParam->TCOn())
+ {
+ DeConvExp(inADC,outADC,nTimeTotal,recParam->GetTCnexp());
+ }
+
+ for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
+ // Store the amplitude of the digit if above threshold
+ if (outADC[iTime] > ADCthreshold) {
+ if (fVerbose > 1)
+ {
+ printf(" iRow = %d, iCol = %d, iTime = %d, adc = %f\n"
+ ,iRow,iCol,iTime,outADC[iTime]);
+ }
+ digitsOut->SetDataUnchecked(iRow,iCol,iTime,outADC[iTime]);
+ }
+
+ }
+
+ }
+
+ }
+
+ delete [] inADC;
+ delete [] outADC;
+
+ return;
+
+}
+
+
+//_____________________________________________________________________________
+void AliTRDclusterizerV1::DeConvExp(Double_t *source, Double_t *target,
+ Int_t n, Int_t nexp)
+{
+ //
+ // Tail Cancellation by Deconvolution for PASA v4 TRF
+ //
+
+ Double_t rates[2];
+ Double_t coefficients[2];
+
+ // initialize (coefficient = alpha, rates = lambda)
+
+ Double_t R1 = 1.0;
+ Double_t R2 = 1.0;
+ Double_t C1 = 0.5;
+ Double_t C2 = 0.5;
+
+ if (nexp == 1) { // 1 Exponentials
+ R1 = 1.156;
+ R2 = 0.130;
+ C1 = 0.066;
+ C2 = 0.000;
+ }
+ if (nexp == 2) { // 2 Exponentials
+ R1 = 1.156;
+ R2 = 0.130;
+ C1 = 0.114;
+ C2 = 0.624;
+ }
+
+ coefficients[0] = C1;
+ coefficients[1] = C2;
+
+ Double_t Dt = 0.100;
+
+ rates[0] = TMath::Exp(-Dt/(R1));
+ rates[1] = TMath::Exp(-Dt/(R2));
+
+ Int_t i, k;
+ Double_t reminder[2];
+ Double_t correction, result;
+
+ /* attention: computation order is important */
+ correction=0.0;
+
+ for ( k=0; k<nexp; k++ ) reminder[k]=0.0;
+
+ for ( i=0; i<n; i++ ) {
+ result = ( source[i] - correction ); // no rescaling
+ target[i] = result;
+
+ for ( k=0; k<nexp; k++ ) reminder[k] = rates[k] *
+ ( reminder[k] + coefficients[k] * result);
+ correction=0.0;
+ for ( k=0; k<nexp; k++ ) correction += reminder[k];
+ }
+
+}