+ assert( fNofYNeighbour != NULL );
+
+ int idCentralB=0,idCentralNB=0 ;
+ float padCenterXB;
+ float padCenterYNB;
+ float diffX,diffY;
+ float minPadArea;
+ float halfPadLengthX,halfPadLengthY;
+ bool *isMergedY = new bool[fCentralCountB];
+ bool *isMergedX = new bool[fCentralCountNB];
+ float outsideSpacePoint = 1000000.0 ; /// A space point outside the detector
+
+ // MERGE Bending Plane hits, which are placed side by side
+ for(int i=0;i<fCentralCountB-1;i++){
+ isMergedY[i] = false;
+ if(fRecY[i] != outsideSpacePoint){
+ for(int j=i+1;j<fCentralCountB;j++){
+
+ if(fCentralChargeB[i]==fCentralChargeB[j]){
+ fRecY[j] = outsideSpacePoint;
+ continue;
+ }
+ else if(
+ (
+ fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
+ )
+ &&
+ (
+ fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
+ ||
+ fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
+ )
+ &&
+ fRecY[j] != outsideSpacePoint
+ &&
+ fRecY[i] != outsideSpacePoint
+ ){
+
+ if(fAvgChargeY[i] > fAvgChargeY[j]){
+ fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
+ )/(fAvgChargeY[i] + fAvgChargeY[j]);
+ fRecY[j] = outsideSpacePoint;
+ }
+ else{
+ fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
+ )/(fAvgChargeY[i] + fAvgChargeY[j]);
+ fRecY[i] = outsideSpacePoint;
+
+ }// search for higher charge
+ }//pad position
+ }//j for loop
+ }//if fRecY[i] != outsideSpacePoint
+ }// i for loop
+ isMergedY[fCentralCountB-1] = false;
+
+ // MERGE Non Bending Plane hits, which are placed side by side
+ for(int i=0;i<fCentralCountNB-1;i++){
+ isMergedX[i] = false;
+ if(fRecX[i] != outsideSpacePoint){
+ for(int j=i+1;j<fCentralCountNB;j++){
+
+ if(fCentralChargeNB[i]==fCentralChargeNB[j]){
+ fRecX[j] = outsideSpacePoint;
+ continue;
+ }
+ else if(
+ (
+ fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
+ )
+ &&
+ (
+ fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
+ ||
+ fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
+ )
+ &&
+ fRecX[j] != outsideSpacePoint
+ &&
+ fRecX[i] != outsideSpacePoint
+ ){
+
+ if(fAvgChargeX[i] > fAvgChargeX[j]){
+ fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
+ )/(fAvgChargeX[i] + fAvgChargeX[j]);
+ fRecX[j] = outsideSpacePoint;
+ }
+ else{
+ fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
+ )/(fAvgChargeX[i] + fAvgChargeX[j]);
+ fRecX[i] = outsideSpacePoint;
+ }// search for higher charge
+ }//pad position
+ }//j for loop
+ }//if fRecX[i] != outsideSpacePoint
+ }// i for loop
+ isMergedX[fCentralCountNB-1] = false;
+
+ // Merge bending Plane hits with Non Bending
+ for(int b=0;b<fCentralCountB;b++){
+ if(fRecY[b]!=outsideSpacePoint){
+ idCentralB = fCentralChargeB[b];
+ padCenterXB = fPadData[idCentralB].fRealX;
+
+ halfPadLengthX = fPadData[idCentralB].fHalfPadSize ;
+
+ for(int nb=0;nb<fCentralCountNB;nb++){
+ if(fRecX[nb]!=outsideSpacePoint){
+ idCentralNB = fCentralChargeNB[nb];
+
+ padCenterYNB = fPadData[idCentralNB].fRealY;
+
+ halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
+
+ if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
+ diffX = fabsf(fRecX[nb]) - fabsf(padCenterXB);
+ else
+ diffX = fabsf(padCenterXB) - fabsf(fRecX[nb]);
+
+ if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
+ diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
+ else
+ diffY = fabsf(fRecY[b]) - fabsf(padCenterYNB);
+
+ if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
+
+ isMergedY[b] = true;
+ isMergedX[nb] = true;
+
+ if(fNofYNeighbour[b]==2){
+ if(fPadData[idCentralB].fDetElemId<104)
+ fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204)
+ fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ else
+ fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ }
+
+ if(fPadData[idCentralNB].fDetElemId<204)
+ fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
+ else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
+ fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
+
+
+ // First check that we have not overflowed the buffer.
+ if((*fRecPointsCount) == fMaxRecPointsCount){
+ HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
+ " Output buffer is too small.",
+ (*fRecPointsCount),fMaxRecPointsCount
+ );
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return true;
+ }
+
+ AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
+ (fPadData[idCentralB].fDetElemId / 100) - 1,
+ fPadData[idCentralB].fDetElemId
+ );
+ fRecPoints[(*fRecPointsCount)].fFlags = idflags;
+ fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
+ fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
+ fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
+
+ if (fGenerateClusterInfo)
+ {
+ if (fClusterCount >= fMaxClusters)
+ {
+ HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return false;
+ }
+
+ fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
+
+ // Increment the cluster ID and warp it around at 0x03FFFFFF since
+ // the bottom 5 bits are filled with the source DDL number and the
+ // sign bit in fClusters[fClusterCount].fId must be positive.
+ fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
+
+ fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
+ fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
+ fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
+ fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
+ fClusters[fClusterCount].fChargeB = fTotChargeY[b];
+ fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
+ fClusterCount++;
+ }
+
+ if (fGenerateChannelInfo)
+ {
+ // 3 by 3 pad structure around the central pad for the 2 planes.
+ int pad[2][3][3] = {{
+ {0, 0, 0},
+ {0, idCentralB, 0},
+ {0, 0, 0}
+ },{
+ {0, 0, 0},
+ {0, idCentralNB, 0},
+ {0, 0, 0}
+ }};
+
+ // Find the pad index numbers for the central pads and the pads surrounding them.
+ // All these pads would have contributed to the cluster as long as their charge is != 0.
+ if (fPadData[idCentralB].fIY > 0)
+ pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
+ if (fPadData[idCentralB].fIY < 236)
+ pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
+ if (fPadData[idCentralB].fIX > 0)
+ {
+ int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
+ pad[0][1][0] = idLeft;
+ if (fPadData[idLeft].fIY > 0)
+ pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
+ if (fPadData[idLeft].fIY < 236)
+ pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
+ }
+ if (fPadData[idCentralB].fIX < 335)
+ {
+ int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
+ pad[0][1][2] = idRight;
+ if (fPadData[idRight].fIY > 0)
+ pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
+ if (fPadData[idRight].fIY < 236)
+ pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
+ }
+
+ if (fPadData[idCentralNB].fIX > 0)
+ pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
+ if (fPadData[idCentralNB].fIX < 335)
+ pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
+ if (fPadData[idCentralNB].fIY > 0)
+ {
+ int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
+ pad[1][0][1] = idLower;
+ if (fPadData[idLower].fIX > 0)
+ pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
+ if (fPadData[idLower].fIX < 335)
+ pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
+ }
+ if (fPadData[idCentralNB].fIY < 236)
+ {
+ int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
+ pad[1][2][1] = idUpper;
+ if (fPadData[idUpper].fIX > 0)
+ pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
+ if (fPadData[idUpper].fIX < 335)
+ pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
+ }
+
+ AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
+
+ // Now generate the pad structures from all the pad indices found above.
+ for (int i = 0; i < 2; i++)
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 3; k++)
+ {
+ AliHLTMUONPad& p = fPadData[pad[i][j][k]];
+ // Skip pads that have zero charge because they would not have
+ // contributed to the cluster.
+ if (p.fCharge <= 0) continue;
+
+ UShort_t manuId; UChar_t channelId; UShort_t adc;
+ AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
+
+ fChannels[fChannelCount].fClusterId = clusterId;
+ fChannels[fChannelCount].fBusPatch = p.fBusPatch;
+ fChannels[fChannelCount].fManu = manuId;
+ fChannels[fChannelCount].fChannelAddress = channelId;
+ fChannels[fChannelCount].fSignal = adc;
+ fChannels[fChannelCount].fRawDataWord = p.fRawData;
+ fChannelCount++;
+ }
+ }
+
+ HLTDebug("Part 1 : Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
+ fRecPoints[(*fRecPointsCount)].fX,
+ fRecPoints[(*fRecPointsCount)].fY,
+ fRecPoints[(*fRecPointsCount)].fZ
+ );
+ (*fRecPointsCount)++;
+ }//if lies wihtin 5.0 mm
+ }// condn over fRecX ! = 0.0
+ }// loop over NB side
+ }// condn on fRecY[b] != 0.0
+ }// loop over B side;
+
+ //Hit only in bending plane and in zone 1 which has not merged and which has number of channels > 2 are considered as valid hits
+ for(int b=0;b<fCentralCountB;b++){
+ if(fRecY[b]!=outsideSpacePoint and !isMergedY[b] and fNofBChannel[b]>2){
+ idCentralB = fCentralChargeB[b];
+
+ minPadArea = (fPadData[idCentralB].fDetElemId < 204) ? 10.0*2.0*0.315*10.0*2.0*0.21 : 10.0*2.0*0.375*10.0*2.0*0.25 ;
+
+ if(TMath::Abs(400.0*fPadData[idCentralB].fHalfPadSize*fPadData[idCentralB].fPadSizeXY - minPadArea)> 1.0e-5) continue;
+
+ if(fNofYNeighbour[b]==2){
+ if(fPadData[idCentralB].fDetElemId<104)
+ fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204)
+ fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ else
+ fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
+ }
+
+ padCenterXB = fPadData[idCentralB].fRealX;
+ // if(fPadData[idCentralB].fDetElemId<204)
+ // padCenterXB += 0.095*sin(10.5*(padCenterXB - fPadData[idCentralB].fRealX)) ;
+ // else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
+ // padCenterXB += 0.085*sin(9.0*(padCenterXB - fPadData[idCentralB].fRealX)) ;
+
+ // First check that we have not overflowed the buffer.
+ if((*fRecPointsCount) == fMaxRecPointsCount){
+ HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
+ " Output buffer is too small.",
+ (*fRecPointsCount),fMaxRecPointsCount
+ );
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return true;
+ }
+
+ AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
+ (fPadData[idCentralB].fDetElemId / 100) - 1,
+ fPadData[idCentralB].fDetElemId
+ );
+ fRecPoints[(*fRecPointsCount)].fFlags = idflags;
+ fRecPoints[(*fRecPointsCount)].fX = padCenterXB;
+ fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
+ fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
+
+ if (fGenerateClusterInfo)
+ {
+ if (fClusterCount >= fMaxClusters)
+ {
+ HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return false;
+ }
+
+ fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
+
+ // Increment the cluster ID and warp it around at 0x03FFFFFF since
+ // the bottom 5 bits are filled with the source DDL number and the
+ // sign bit in fClusters[fClusterCount].fId must be positive.
+ fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
+
+ fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
+ fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
+ fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
+ fClusters[fClusterCount].fNchannelsNB = fNofBChannel[b];
+ fClusters[fClusterCount].fChargeB = fTotChargeY[b];
+ fClusters[fClusterCount].fChargeNB = fTotChargeY[b];
+ fClusterCount++;
+ }
+
+ if (fGenerateChannelInfo)
+ {
+ // 3 by 3 pad structure around the central pad for the 2 planes.
+ int pad[2][3][3] = {{
+ {0, 0, 0},
+ {0, idCentralB, 0},
+ {0, 0, 0}
+ },{
+ {0, 0, 0},
+ {0, 0 , 0},
+ {0, 0, 0}
+ }};
+
+ // Find the pad index numbers for the central pads and the pads surrounding them.
+ // All these pads would have contributed to the cluster as long as their charge is != 0.
+ if (fPadData[idCentralB].fIY > 0)
+ pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
+ if (fPadData[idCentralB].fIY < 236)
+ pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
+ if (fPadData[idCentralB].fIX > 0)
+ {
+ int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
+ pad[0][1][0] = idLeft;
+ if (fPadData[idLeft].fIY > 0)
+ pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
+ if (fPadData[idLeft].fIY < 236)
+ pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
+ }
+ if (fPadData[idCentralB].fIX < 335)
+ {
+ int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
+ pad[0][1][2] = idRight;
+ if (fPadData[idRight].fIY > 0)
+ pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
+ if (fPadData[idRight].fIY < 236)
+ pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
+ }
+
+ // For hits only in bending plane no need to copy the information to the non-bending side
+ // for(int i=0;i<3;i++)
+ // for(int j=0;j<3;j++)
+ // pad[1][i][j] = pad[0][i][j];
+
+
+ AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
+
+ // Now generate the pad structures from all the pad indices found above.
+ for (int i = 0; i < 1; i++)
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 3; k++)
+ {
+ AliHLTMUONPad& p = fPadData[pad[i][j][k]];
+ // Skip pads that have zero charge because they would not have
+ // contributed to the cluster.
+ if (p.fCharge <= 0) continue;
+
+ UShort_t manuId; UChar_t channelId; UShort_t adc;
+ AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
+
+ fChannels[fChannelCount].fClusterId = clusterId;
+ fChannels[fChannelCount].fBusPatch = p.fBusPatch;
+ fChannels[fChannelCount].fManu = manuId;
+ fChannels[fChannelCount].fChannelAddress = channelId;
+ fChannels[fChannelCount].fSignal = adc;
+ fChannels[fChannelCount].fRawDataWord = p.fRawData;
+ fChannelCount++;
+ }
+ }
+
+ HLTDebug("Part 2 : Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
+ fRecPoints[(*fRecPointsCount)].fX,
+ fRecPoints[(*fRecPointsCount)].fY,
+ fRecPoints[(*fRecPointsCount)].fZ
+ );
+ (*fRecPointsCount)++;
+
+ }// condn on fRecY[b] != 0.0
+ }// loop over B side;
+
+
+ //Hit only in non-bending plane and in zone 1 which has not merged and which has number of channels > 2 are considered as valid hits
+ for(int nb=0;nb<fCentralCountNB;nb++){
+
+ idCentralNB = fCentralChargeNB[nb];
+ if(fRecX[nb]!=outsideSpacePoint and !isMergedX[nb] and fNofNBChannel[nb]>2){
+
+ minPadArea = (fPadData[idCentralNB].fDetElemId < 204) ? 10.0*2.0*0.315*10.0*2.0*0.21 : 10.0*2.0*0.375*10.0*2.0*0.25 ;
+
+ if(TMath::Abs(400.0*fPadData[idCentralNB].fHalfPadSize*fPadData[idCentralNB].fPadSizeXY - minPadArea)> 1.0e-5) continue;
+
+ padCenterYNB = fPadData[idCentralNB].fRealY;
+
+
+ // if(fPadData[idCentralNB].fDetElemId<104)
+ // padCenterYNB += 0.02*sin(14.5*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
+ // else if(fPadData[idCentralNB].fDetElemId>=200 && fPadData[idCentralNB].fDetElemId<204)
+ // padCenterYNB += 0.02*sin(14.0*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
+ // else
+ // padCenterYNB += 0.025*sin(12.0*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
+
+
+ if(fPadData[idCentralNB].fDetElemId<204)
+ fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
+ else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
+ fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
+
+
+ // First check that we have not overflowed the buffer.
+ if((*fRecPointsCount) == fMaxRecPointsCount){
+ HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
+ " Output buffer is too small.",
+ (*fRecPointsCount),fMaxRecPointsCount
+ );
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return true;
+ }
+
+ AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
+ (fPadData[idCentralNB].fDetElemId / 100) - 1,
+ fPadData[idCentralNB].fDetElemId
+ );
+ fRecPoints[(*fRecPointsCount)].fFlags = idflags;
+ fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
+ fRecPoints[(*fRecPointsCount)].fY = padCenterYNB;
+ fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralNB].fRealZ;
+
+ if (fGenerateClusterInfo)
+ {
+ if (fClusterCount >= fMaxClusters)
+ {
+ HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
+ delete [] isMergedY;
+ delete [] isMergedX;
+ return false;
+ }
+
+ fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
+
+ // Increment the cluster ID and warp it around at 0x03FFFFFF since
+ // the bottom 5 bits are filled with the source DDL number and the
+ // sign bit in fClusters[fClusterCount].fId must be positive.
+ fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
+
+ fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
+ fClusters[fClusterCount].fDetElemId = fPadData[idCentralNB].fDetElemId;
+ fClusters[fClusterCount].fNchannelsB = fNofNBChannel[nb];
+ fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
+ fClusters[fClusterCount].fChargeB = fTotChargeX[nb];
+ fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
+ fClusterCount++;
+ }
+
+ if (fGenerateChannelInfo)
+ {
+ // 3 by 3 pad structure around the central pad for the 2 planes.
+ int pad[2][3][3] = {{
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0}
+ },{
+ {0, 0, 0},
+ {0, idCentralNB, 0},
+ {0, 0, 0}
+ }};
+
+ // Find the pad index numbers for the central pads and the pads surrounding them.
+ // All these pads would have contributed to the cluster as long as their charge is != 0.
+
+ if (fPadData[idCentralNB].fIX > 0)
+ pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
+ if (fPadData[idCentralNB].fIX < 335)
+ pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
+ if (fPadData[idCentralNB].fIY > 0)
+ {
+ int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
+ pad[1][0][1] = idLower;
+ if (fPadData[idLower].fIX > 0)
+ pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
+ if (fPadData[idLower].fIX < 335)
+ pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
+ }
+ if (fPadData[idCentralNB].fIY < 236)
+ {
+ int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
+ pad[1][2][1] = idUpper;
+ if (fPadData[idUpper].fIX > 0)
+ pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
+ if (fPadData[idUpper].fIX < 335)
+ pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
+ }
+
+ // For hits only in non-bending plane no need to copy the information to the bending side
+ // for(int i=0;i<3;i++)
+ // for(int j=0;j<3;j++)
+ // pad[0][i][j] = pad[1][i][j];
+
+
+ AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
+
+ // Now generate the pad structures from all the pad indices found above.
+ for (int i = 1; i < 2; i++)
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 3; k++)
+ {
+ AliHLTMUONPad& p = fPadData[pad[i][j][k]];
+ // Skip pads that have zero charge because they would not have
+ // contributed to the cluster.
+ if (p.fCharge <= 0) continue;
+
+ UShort_t manuId; UChar_t channelId; UShort_t adc;
+ AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
+
+ fChannels[fChannelCount].fClusterId = clusterId;
+ fChannels[fChannelCount].fBusPatch = p.fBusPatch;
+ fChannels[fChannelCount].fManu = manuId;
+ fChannels[fChannelCount].fChannelAddress = channelId;
+ fChannels[fChannelCount].fSignal = adc;
+ fChannels[fChannelCount].fRawDataWord = p.fRawData;
+ fChannelCount++;
+ }
+ }
+
+ HLTDebug("Part 3 : Reconstructed hit (X,Y,Z) : (%f,%f,%f), detelemId : %d",
+ fRecPoints[(*fRecPointsCount)].fX,
+ fRecPoints[(*fRecPointsCount)].fY,
+ fRecPoints[(*fRecPointsCount)].fZ,
+ fPadData[idCentralNB].fDetElemId
+ );
+ (*fRecPointsCount)++;
+ }//if lies wihtin 5.0 mm
+ }// condn over fRecX ! = 0.0
+
+ delete [] isMergedY;
+ delete [] isMergedX;
+
+ return true;
+}
+
+bool AliHLTMUONHitReconstructor::MergeSlatRecHits()
+{
+ // Merge reconstructed hits first over same plane then bending plane with non-bending plane
+
+ assert( fRecX != NULL );
+ assert( fRecY != NULL );
+ assert( fAvgChargeX != NULL );
+ assert( fAvgChargeY != NULL );
+ assert( fTotChargeX != NULL );
+ assert( fTotChargeY != NULL );
+ assert( fNofBChannel != NULL );
+ assert( fNofNBChannel != NULL );
+ assert( fNofYNeighbour != NULL );