#include "hmdcsegsim.h"
#include "hades.h"
#include "hmdcdef.h"
#include "hmdccal1sim.h"
#include "hevent.h"
#include "hcategory.h"
#include "hmessagemgr.h"
#include "htool.h"
ClassImp(HMdcSegSim)
void HMdcSegSim::clear()
{
clearSimInfo();
HMdcSeg::Clear();
}
void HMdcSegSim::clearSimInfo(void) {
status = 0;
nTracks = 0;
nNotFakeTracks = -1;
ioSMatchStatus = -1;
for(Int_t i=0;i<5;i++){
listTracks[i] = 0;
nTimes[i] = 0;
nDigiTimes[i] = 0;
trackStatus[i] = 1;
}
}
void HMdcSegSim::setNTracks(Int_t nTr, const Int_t* listTr,const UChar_t* nTm,const UChar_t* nDi) {
if(nTr<=0) nTracks=-1;
else {
Int_t maxTr = (nTr<6) ? nTr:5;
nTracks = 0;
for(Int_t n=0; n<maxTr; n++) {
listTracks[nTracks] = listTr[n];
nTimes[nTracks] = nTm[n];
if(nDi != NULL) nDigiTimes[nTracks] = nDi[n];
nTracks++;
}
}
}
void HMdcSegSim::addTrack(Int_t track, UChar_t nTm,UChar_t nDi) {
if(nTracks>=0 && nTracks < 5) {
listTracks[nTracks] = track;
nTimes[nTracks] = nTm;
nDigiTimes[nTracks] = nDi;
nTracks++;
}
}
Int_t HMdcSegSim::calcNTracks(void) {
nTracks=0;
HCategory *fCalCat=gHades->getCurrentEvent()->getCategory(catMdcCal1);
if(!fCalCat) return -1;
HLocation loc;
loc.set(4,getSec(),0,0,0);
Int_t seg=getIOSeg();
Int_t tmpListTracks[96];
Int_t nTimesTot=0;
for(Int_t layer=0; layer<12; layer++) {
Int_t nCells=getNCells(layer);
if(nCells==0) continue;
loc[1]=seg*2+layer/6;
loc[2]=layer%6;
for(Int_t n=0; n<nCells; n++) {
UChar_t nCTimes=getSignId(layer,n);
loc[3]=getCell(layer,n);
HMdcCal1Sim *fCal1Sim=(HMdcCal1Sim*)fCalCat->getObject(loc);
if(fCal1Sim)
{
if(nCTimes&1) tmpListTracks[nTimesTot++]=fCal1Sim->getNTrack1();
if(nCTimes&2) tmpListTracks[nTimesTot++]=fCal1Sim->getNTrack2();
} else Error("calcNTracks","Zero pointer received!");
}
}
Short_t counter[96];
listTracks[4]=-99;
nTimes[4]=0;
for(Int_t n=0; n<nTimesTot; n++) {
if(tmpListTracks[n]<0 &&
tmpListTracks[n]!=gHades->getEmbeddingRealTrackId()) {
nTimes[4]++;
continue;
} else if(tmpListTracks[n]>0 ||
tmpListTracks[n]==gHades->getEmbeddingRealTrackId()) {
tmpListTracks[nTracks]=tmpListTracks[n];
counter[nTracks]=1;
for(Int_t m=n+1; m<nTimesTot; m++) {
if(tmpListTracks[m] != tmpListTracks[nTracks]) continue;
counter[nTracks]++;
tmpListTracks[m]=0;
}
nTracks++;
}
}
if(nTracks>0)
{
Int_t index[nTracks];
if(nTracks>1) HTool::sort(nTracks,counter,index,kTRUE,kTRUE);
else index[0]=0;
if(nTracks>4) nTracks=(nTimes[4]==0) ? 5:4;
for(Int_t n=0; n<nTracks; n++) {
listTracks[n]=tmpListTracks[index[n]];
nTimes[n]=counter[n];
}
}
return nTracks;
}
Int_t HMdcSegSim::getNumNoiseWires(void) const {
for(Int_t n=0; n<5; n++) if(listTracks[n]==-99) return nTimes[n];
return 0;
}
void HMdcSegSim::sortTrListByContr(void) {
nNotFakeTracks = 0;
for(Int_t t=0;t<nTracks;t++) if( !isFakeContribution(t) ) {
nNotFakeTracks++;
}
if(nTracks==1) return;
Int_t nTimesSort[5];
for(Int_t t=0;t<nTracks;t++) {
nTimesSort[t] = nTimes[t];
if(isFakeContribution(t)) continue;
nTimesSort[t] <<= 16;
}
for(Int_t t1=0;t1<nTracks-1;t1++) {
Int_t maxInd = t1;
for(Int_t t2=t1+1;t2<nTracks;t2++) if(nTimesSort[t2] > nTimesSort[maxInd]) maxInd = t2;
if(maxInd == t1) continue;
nTimesSort[maxInd] = nTimesSort[t1];
exchangeTrPos(t1,maxInd);
}
}
void HMdcSegSim::exchangeTrPos(Int_t t1,Int_t t2) {
Int_t v1 = listTracks[t1];
Short_t v2 = nTimes[t1];
UChar_t v3 = nDigiTimes[t1];
UChar_t v4 = trackStatus[t1];
listTracks[t1] = listTracks[t2];
nTimes[t1] = nTimes[t2];
nDigiTimes[t1] = nDigiTimes[t2];
trackStatus[t1] = trackStatus[t2];
listTracks[t2] = v1;
nTimes[t2] = v2;
nDigiTimes[t2] = v3;
trackStatus[t2] = v4;
}
void HMdcSegSim::print(void) {
HMdcSeg::print();
printf(" GEANT: %i tracks in segment",nTracks);
if(nNotFakeTracks==0) printf(". FAKE SEGMENT!\n");
else {
if(nNotFakeTracks>=0 && nNotFakeTracks != nTracks)
printf(", %i of them - fakes contribution.\n",nTracks-nNotFakeTracks);
}
for(Int_t n=0; n<5; n++) if(nTimes[n]>0) {
printf("%6i(%2iw.",listTracks[n],nTimes[n]);
if(listTracks[n] > 0) {
printf(" from %2iw.)",nDigiTimes[n]);
if((trackStatus[n]&254) == 254) printf(" Ok.");
else {
if((trackStatus[n]&2) == 0) printf(" FakeContribution");
else {
if((trackStatus[n]&2) == 0) printf(" FakeSegment");
if((trackStatus[n]&4) == 0) printf(" ClFnLevelTooHigh");
if((trackStatus[n]&16) == 0) printf(" SegNotRec");
else if((trackStatus[n]&8) == 0) printf(" 1or2HitsNotRec");
if((trackStatus[n]&32) == 0) printf(" TrackNotRec");
if((trackStatus[n]&64) == 0) printf(" NoMeta");
if((trackStatus[n]&128) == 0) printf(" GEANT_Bug");
}
}
}
else if(listTracks[n] == -500) printf(") Embeded real track");
else if(listTracks[n] == -99) printf(") Noised wires");
else if(listTracks[n] == -9) printf(") GEANT bug wires");
else printf(") Not known track number!");
printf("\n");
}
}
void HMdcSegSim::setTrackInf(const Int_t *lst,const Short_t *nTms,
const UChar_t *nDTms,const UChar_t *tSt) {
for(Int_t i=0;i<5;i++) {
listTracks[i] = lst[i];
nTimes[i] = nTms[i];
nDigiTimes[i] = nDTms[i];
trackStatus[i] = tSt[i];
}
}
UChar_t HMdcSegSim::getTrackStatus(Int_t n) const {
return indOk(n) ? trackStatus[n] : 0;
}
Int_t HMdcSegSim::getGoodTrack(Int_t i1,HMdcSegSim* outerSeg,Int_t nWiresCut) const {
if(getIOSeg() != 0) {
Error("getGoodTrack","call this function for inner segment only!");
return 0;
}
if(outerSeg == 0 || outerSeg->getIOSeg() != 1) {
Error("getGoodTrack","Parameter outerSeg must be outer segment!");
return 0;
}
if(i1<0 || i1>=nNotFakeTracks) return 0;
if(outerSeg->nNotFakeTracks<1) return 0;
if(nTimes[i1]<nWiresCut) return 0;
for(Int_t i2=0;i2<outerSeg->nNotFakeTracks;i2++) {
if(listTracks[i1] != outerSeg->listTracks[i2]) continue;
if(outerSeg->nTimes[i2]<nWiresCut) continue;
return listTracks[i1];
}
return 0;
}
Int_t HMdcSegSim::getNextGoodTrack(Int_t& i1,HMdcSegSim* outerSeg,Int_t nWiresCut) const {
if(getIOSeg() != 0) {
Error("getGoodTrack","call this function for inner segment only!");
return 0;
}
if(outerSeg == 0 || outerSeg->getIOSeg() != 1) {
Error("getGoodTrack","Parameter outerSeg must be outer segment!");
return 0;
}
if(outerSeg->nNotFakeTracks<1) return 0;
if(i1<0) i1=0;
if(i1>=nNotFakeTracks) return 0;
for(;i1<nNotFakeTracks;i1++) {
if(nTimes[i1]<nWiresCut) continue;
Int_t track = listTracks[i1];
for(Int_t i2=0;i2<outerSeg->nNotFakeTracks;i2++) {
if(track != outerSeg->listTracks[i2]) continue;
if(outerSeg->nTimes[i2]<nWiresCut) continue;
i1++;
return track;
}
}
return 0;
}
Int_t HMdcSegSim::findTrack(Int_t geantNum,Int_t nDgTimes) const {
for(Int_t n=0;n<nTracks;n++) if(geantNum == listTracks[n]) {
if(nDgTimes==0 || nDgTimes == nDigiTimes[n]) return n;
}
return -1;
}
Int_t HMdcSegSim::getTrackIndex(Int_t tr) const {
for(Int_t i=0;i<nTracks;i++) if(listTracks[i] == tr) return i;
return -1;
}
Bool_t HMdcSegSim::resetFakeContributionFlag(void) {
if( !isFakeContribution(0) || nTimes[0] < 5 || nTimes[0]*2 <= getSumWires() ) return kFALSE;
trackStatus[0] |= 2;
nNotFakeTracks++;
return kTRUE;
}
Bool_t HMdcSegSim::setFakeContributionFlag(void) {
if( isFakeContribution(0) ) return kFALSE;
trackStatus[0] &= 253;
nNotFakeTracks--;
return kTRUE;
}