BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//_____________________________________________________________________
//
//  Cluster Finder for Drift Chambers
//
//_____________________________________________________________________
//
//  $Id: BrDCClusterFinder.cxx,v 1.22 2002/06/10 16:41:08 ufstasze Exp $
//  $Author: ufstasze $
//  $Date: 2002/06/10 16:41:08 $
//

#include "BrDCClusterFinder.h"

#include "BrGeometryDbManager.h"
#include "BrParameterDbManager.h"

//#include "BrHitDig.h"
#include "BrDcDig.h"
#include "BrDetectorHit.h"
#include "BrDCHit.h"
#include "BrClonesArray.h"

#include "BrTrackDefines.h"
#include "BrDCHitPosition.h"
#include "BrDriverDC.h"

#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TDirectory
#include "TDirectory.h"
#endif

#define USEGETLAST
#define USESHRINK

ClassImp(BrDCClusterFinder);

//////////////////////////////////////////////////////////////////////////////////
//
// The BrDCClusterFinder class finds clusters
//
//////////////////////////////////////////////////////////////////////////////////
 BrDCClusterFinder::BrDCClusterFinder()
{
  // DO NOT USE

  SetState(kSetup);

  fDCDriver        = 0;
  fHitPositionList = 0;
}

//_____________________________________________________________
 BrDCClusterFinder::BrDCClusterFinder(Char_t *Name,Char_t *Title, 
				     Int_t combineMode, Float_t clusDx,
				     Float_t clusDy, Float_t trioWin,
				     Bool_t EventByEvent, Int_t imode,
				     Int_t ClustMode, Int_t XYClustOpt, 
				     Float_t posRes, Int_t lowLimit, 
				     Int_t upLimit) 
  : BrModule(Name,Title)
{
  
  SetState(kSetup);

  fPlaneCombineMode = combineMode;
  fClusDx           = clusDx;
  fClusDy           = clusDy;
  fTrioChisqWin     = trioWin;
  fEventByEvent     = EventByEvent;
  fPosRes           = posRes;
  fLowLimit         = lowLimit;
  fUpLimit          = upLimit;
  

  fDCDriver = new  BrDriverDC(GetName(),GetName());   // KH after Pawel  
  fHitPositionList = new TObjArray();
  
  SetMode(imode); // Table Mode (no default, should be specified)
  SetClustMode(ClustMode); // default is 0
  SetXYClusterOption(XYClustOpt); // default is 0 
  fNumVol = 0;  
}

//_____________________________________________________________
 BrDCClusterFinder::~BrDCClusterFinder(){
}

//_____________________________________________________________
 void BrDCClusterFinder::Init() {
  // The init member function/method is used to define histograms
  // The histograms is added to the list of hist objects in this
  // module.

   SetState(kInit);

  Int_t i;
  Char_t volbuf[64];
  BrGeometryDbManager *gGeomDb;
  BrParameterDbManager *gParamDb;
  BrDetectorVolume    *vol;
  
  //First Set Volumes
  //Create instance of data base manager
  gGeomDb = BrGeometryDbManager::Instance();
  
  gParamDb = BrParameterDbManager::Instance();
  
  fParams = 
    (BrDetectorParamsDC*)gParamDb->GetDetectorParameters("BrDetectorParamsDC",GetName());
  
  fParams->SetPosres(fPosRes); // it goes from Traking module
  //Get Master volume for DC's
  strcpy(volbuf,GetName());
  vol = (BrDetectorVolume*)gGeomDb->GetDetectorVolume("BrDetectorVolume",volbuf); 
  //vol->ListParameters();
  if(vol) {
     SetDetectorVolume(vol);
     // Get DC Sub Modules
     for(i=0;i<3;i++) {
        sprintf(volbuf,"%sA%d",GetName(),i+1);
        vol = (BrDetectorVolume*)gGeomDb->GetDetectorVolume("BrDetectorVolume",volbuf);
        //vol->ListParameters();
	     SetDetectorVolume(vol);
        }
     }
  // define pointer to BrDriverDC
  if(!fDCDriver) {
    fDCDriver = new  BrDriverDC(GetName(),GetName());   //Pawel
  }
  if(GetMode()==RawData || GetMode()==RedData){
    fDCDriver->SetRunNumber(fRunNo);   
    if(!fUseMySql)fDCDriver->ReadOffsets(fOffsetFile,fGlobalTdcOffset); //fTdcOffset is 0 for pp runs
    fGlobalTdcOffsetSave=fGlobalTdcOffset;
    if(!fUseMySql)fDCDriver->ReadCalibData(fCalibFile,fDriftTime);
    fDriftTimeSave=fDriftTime;
    //fDCDriver->SetRunNumber(fRunNo); 
    //fDCDriver->ReadCuts(); // reading cleaning cuts for a given run
    fDCDriver->SetMinWidth(fMinWidth);
    fDCDriver->SetMinTdc(fMinTdc);
    fDCDriver->SetMaxTdc(fMaxTdc);
  }else{
    fDCDriver->SetSetupStatus(kFALSE);
  }

  // create tables of selected hits
  fSelectedDCHits1 = new BrDataTable("hits1", "hits1");
  fSelectedDCHits2 = new BrDataTable("hits2", "hits2");
  fSelectedDCHits3 = new BrDataTable("hits3", "hits3");

  // define offsets for DCPair and DCTrio
  DefineOffsets();
}

//_____________________________________________________________
 void BrDCClusterFinder::Begin() {

  if (GetState() != kInit) {
    Stop("Begin", "Must be called after Init"); 
    return;  
  }

  // this two parameter can be re-defined in BrDCTrackingModule::Begin() 
  fDCDriver->SetMinTdc(fMinTdc);
  fDCDriver->SetMaxTdc(fMaxTdc);
  if(fGlobalTdcOffsetSave!=fGlobalTdcOffset){
    cout<<"Global Tdc Offset has changed:"<<endl;
    cout<<"current value (from db): "<<fGlobalTdcOffset<<endl;
    cout<<"previous value: "<<fGlobalTdcOffsetSave<<endl;
    cout<<"MinTdc       = "<<fMinTdc<<endl;
    cout<<"MaxTdc      = "<<fMaxTdc<<endl;
    if(strcmp("T3",GetName()))cout<<"PromptDelay = "<<fPromptDelay<<endl;
    fDCDriver->ReadOffsets(fOffsetFile,fGlobalTdcOffset);
    fGlobalTdcOffsetSave=fGlobalTdcOffset;
  }
  if(fDriftTimeSave!=fDriftTime){
    cout<<"Drift Time has changed:"<<endl;
    cout<<"current value (from db): "<<fDriftTime<<endl;
    cout<<"previous value: "<<fDriftTimeSave<<endl;
    fDCDriver->ReadCalibData(fCalibFile,fDriftTime);
    fDriftTimeSave=fDriftTime;
  }
}

//_____________________________________________________________
 void BrDCClusterFinder::DefineHistograms() {

  if (GetState() != kInit) {
    Stop("DefineHistograms", "Must be called after Init"); 
    return;  
  }
  
  TDirectory* saveDir = gDirectory;
  TDirectory* histDir = gDirectory->mkdir(Form("%sCluster", GetName()));
  histDir->cd();

  // Here define some histograms
  Char_t HistName[32];
  sprintf(HistName,"TrioChisq%s",GetName());
  fChisq = new TH1F(HistName,"chisq used as clustering criterion",150,0,15);
 
  for(Int_t i=0;i<3;i++){
    fDCDriver->AtSubModule(i);
    sprintf(HistName,"PairUDu%s_%d",GetName(),i+1);
    fPairUDu[i] = new TH1F(HistName,"u1-u2 distribution for U view",2000,-10,10);
    sprintf(HistName,"PairVDu%s_%d",GetName(),i+1);
    fPairVDu[i] = new TH1F(HistName,"u1-u2 distribution for V view",2000,-10,10);
    sprintf(HistName,"PairXDu%s_%d",GetName(),i+1);
    fPairXDu[i] = new TH1F(HistName,"u1-u2 distribution for X view",2000,-10,10);
    sprintf(HistName,"PairYDu%s_%d",GetName(),i+1);
    fPairYDu[i] = new TH1F(HistName,"u1-u2 distribution for Y view",2000,-10,10);
    
    sprintf(HistName,"Trio12XDu%s_%d",GetName(),i+1);
    fTrio12XDu[i] = new TH1F(HistName,"u1-u2 distribution for X",2000,-10,10);
    sprintf(HistName,"Trio13XDu%s_%d",GetName(),i+1);
    fTrio13XDu[i] = new TH1F(HistName,"u1-u3 distribution for X",2000,-10,10);
    sprintf(HistName,"Trio23XDu%s_%d",GetName(),i+1);
    fTrio23XDu[i] = new TH1F(HistName,"u2-u3 distribution for X",2000,-10,10);
    
    sprintf(HistName,"Trio12YDu%s_%d",GetName(),i+1);
    fTrio12YDu[i] = new TH1F(HistName,"u1-u2 distribution for Y",2000,-10,10);
    sprintf(HistName,"Trio13YDu%s_%d",GetName(),i+1);
    fTrio13YDu[i] = new TH1F(HistName,"u1-u3 distribution for Y",2000,-10,10);
    sprintf(HistName,"Trio23YDu%s_%d",GetName(),i+1);
    fTrio23YDu[i] = new TH1F(HistName,"u2-u3 distribution for Y",2000,-10,10);
    for(Int_t ip=0;ip<fDCDriver->GetMaxPlaneNum();ip++){
      sprintf(HistName,"%sDriftDist%d_%d",GetName(),i+1,ip+1);
      fDriftDist[i][ip] = new TH1F(HistName,HistName,800,-1,3);
      sprintf(HistName,"%sDriftTime%d_%d",GetName(),i+1,ip+1);
      fhDriftTime[i][ip] = new TH1F(HistName,HistName,2000,1500,5500);
      sprintf(HistName,"%sRawHitPos%d_%d",GetName(),i+1,ip+1);
      fRawHitPos[i][ip] = new TH1F(HistName,HistName,6000,-30,30);
    }
    
  }

  sprintf(HistName,"TrioDevAll%s",GetName());
  fDeviaAll = new TH1F(HistName,"Deviation from X and Y for all treefold hits",2000,-1,1);
  sprintf(HistName,"TrioDevAcce%s",GetName());
  fDeviaAcce = new TH1F(HistName,"Deviation from X and Y for accepted treefold hits",2000,-1,1);  
  sprintf(HistName,"TotComb%s",GetName());
  fhTotComb = new TH1F(HistName,"Total Number of Combination",1000,0,20000);

  gDirectory = saveDir;
}

//_____________________________________________________________
 void BrDCClusterFinder::DefineOffsets() 
{
  // this offsets have been introduced because tracks (on average) are
  // not paraller to the detector axis in the horizontal plane
  // It cause that the custer combining procedures (DCPair) and (DCTrio) are more effective.
  // Used values are the result of averaging over low and middle field settings.  
  if(!strcmp("T3",GetName())){
    fOffset[0]=0.036; //for X viw
    fOffset[1]=0.0;   //for Y view
    fOffset[2]=0.037; //for U view
    fOffset[3]=0.033; //for V view
  }
  if(!strcmp("T4",GetName())){
    fOffset[0]=0.031; //for X view
    fOffset[1]=0.0;   //for Y view
    fOffset[2]=0.028; //for U view
    fOffset[3]=0.036; //for V view
  }
  if(!strcmp("T5",GetName())){
    fOffset[0]=0.015; //for X view
    fOffset[1]=0.0;   //for Y view
    fOffset[2]=0.015; //for U view
    fOffset[3]=0.022; //for V view
  }
}
			      
//_____________________________________________________________
 void BrDCClusterFinder::SetDetectorVolume(BrDetectorVolume *vol) 
{
  Int_t i;
  for(i=0;i<fNumVol;i++) {
    if(!strcmp(fVolumeParams_p[i]->GetName(),vol->GetName())) {
      fVolumeParams_p[i] = vol;
      return;
    }
  }
  if(fNumVol<4) {
    fVolumeParams_p[fNumVol] = vol;
    fNumVol++;
  }
  else 
    cout<<"Too many volume parameters, this one not added"<<endl;
}

//_____________________________________________________________
 BrDetectorVolume *BrDCClusterFinder::GetDetectorVolume(const Char_t *name) {
Int_t i;
 for(i=0;i<fNumVol;i++) {
   if(!strcmp(fVolumeParams_p[i]->GetName(),name)) {
     return fVolumeParams_p[i];
   }
 }
 cout<<"Detector Volume "<<name<<" does not exist"<<endl;
 return NULL;
}

//_____________________________________________________________
 void BrDCClusterFinder::FindClusters(BrDataTable *digitizedHits, 
     BrClonesArray *detectorHits, Int_t &nDetectorHits, Int_t tof1TimeRef) {
  //The cluster finding routine.  This routine takes the digitized hits list and
  //fills the detector hit list.
  fTof1TimeRef=tof1TimeRef;
  fDetectorHits = detectorHits;
  
  fEventStatus=kFALSE;
  
  if(GetMode()==RawData || GetMode()==RedData){
    DecodeDat(digitizedHits);
  }else if(GetMode()==Digitized){
    DecodeDig(digitizedHits);
  }else{
    cout<<"Wrong status specification: can not continue"<<endl;
    return;
  }
  
  
  DCCluster();
  nDetectorHits = fDetectorHits->GetLast() + 1;
}

//________________________________________________________________
 void BrDCClusterFinder::DecodeDat(BrDataTable* digitizedHits)
{
  //Generate DC Hit Positions using the time and wire fired to build
  // the left-right ambiguity.
  static const Float_t csgn[2] = {(float)-1.0,(float)1.0};
  
  BrDCPlane* dcpl;
  BrDetectorVolume *vol;
  BrDCHitPosition *hitpos_p;
  
  vol = GetDetectorVolume(GetName());
  
  fHitPositionList->Delete();  // Added  when debugging on 1.11.2000 (PS)
  
  //////// Read Data ////////////
  Int_t EveTab[2000][5];
  Int_t ReList[2000];
  Int_t numRawHits = digitizedHits->GetEntries();
 
  if(numRawHits>1999){
    Warning("Decode","- %s Skip because %d more than 2000",GetName(),numRawHits);
    return;
  }
  
  Int_t ii=0;
  for(Int_t i = 0; i < numRawHits; i++) {
    BrDcDig* digdc_p = (BrDcDig*)digitizedHits->At(i);
    Int_t im  =  digdc_p->GetSubModule() - 1;
    Int_t ip  =  digdc_p->GetPlane() - 1;
    Int_t iw  =  digdc_p->GetWire() - 1;
    Int_t it  =  digdc_p->GetTime();
    Int_t il  =  digdc_p->GetWidth(); 
    //cout<<im<<" "<<ip<<" "<<iw<<" "<<it<<" "<<il<<endl;
    // some cleaning:
    // T3 section
    if(!strcmp("T3",GetName())){
      if(fDCDriver->HitIsOK(it,il)){
	EveTab[ii][0]=im;
	EveTab[ii][1]=ip;
	EveTab[ii][2]=iw;
	EveTab[ii][3]=it;
	EveTab[ii][4]=il;
	ReList[ii]=i;
	ii++;
      }
    }
    // T4/T5 section
    if(!strcmp("T4",GetName()) || !strcmp("T5",GetName())){
      Int_t PromptDelay=fPromptDelay;
      if(fDCDriver->HitIsOK(it,il)){
	if(PromptDelay){
	  if(iw<100){
	    if(it+fTof1TimeRef>PromptDelay){
	      EveTab[ii][0]=im;
	      EveTab[ii][1]=ip;
	      EveTab[ii][2]=iw;
	      EveTab[ii][3]=it;
	      EveTab[ii][4]=il;
              ReList[ii]=i;
	      ii++;
	    }
	  }else{
	    if(it+fTof1TimeRef<=PromptDelay){
	      iw=iw%100;
	      EveTab[ii][0]=im;
	      EveTab[ii][1]=ip;
	      EveTab[ii][2]=iw;
	      EveTab[ii][3]=it;
	      EveTab[ii][4]=il;
	      ReList[ii]=i;
	      ii++;
	    }
	  }
	  //cout<<im<<" "<<ip<<" "<<iw<<" "<<it<<" "<<il<<endl;
	}else{
	  cout<<"Error: PromptDelay variable has to be defined"<<endl;
	  return;
	}
      }
    }
  }
  Int_t NumCleanHits=ii;
  
  if(NumCleanHits<fLowLimit || NumCleanHits>fUpLimit) return;
  
  fEventStatus=kTRUE;
  
  
  //////// fill array with BrDCHitPosition
  
  //cout<<"NumCleanHits: "<<NumCleanHits<<endl;
  for(Int_t idet=0;idet<3;idet++) {
    fDCDriver->AtSubModule(idet);
    for(Int_t ihit=0;ihit<NumCleanHits;ihit++) {
      if( EveTab[ihit][0] == idet ) {
	BrDcDig* digdc_p = (BrDcDig*)digitizedHits->At(ReList[ihit]);
	Int_t iplane =  EveTab[ihit][1];
	Int_t iwire  =  EveTab[ihit][2];
	Int_t itdc   =  EveTab[ihit][3] + fTof1TimeRef;
	Int_t iwidth =  EveTab[ihit][4];
	
	fDCDriver->AtPlane(iplane);
	Float_t xwire  = fDCDriver->GetWirePosition(iwire);
	Float_t xdrift = fDCDriver->GetDriftDist(idet,iplane,iwire,itdc);	
	
	if(HistOn()){
	  fDriftDist[idet][iplane]->Fill(xdrift);
	  fhDriftTime[idet][iplane]->Fill(itdc);
	  fRawHitPos[idet][iplane]->Fill(xwire+xdrift);
	  fRawHitPos[idet][iplane]->Fill(xwire-xdrift);
	}

	if(xdrift>=0){
	  if(fDCDriver->HitIsOK(itdc,iwidth)){
	    for(Int_t i=0;i<2;i++ ) {
	      //Create hit position and add to list.
	      hitpos_p = new BrDCHitPosition();
	      fHitPositionList->Add(hitpos_p);
	      
	      hitpos_p->SetNwire(iwire);
	      hitpos_p->SetXwire(xwire);
	      hitpos_p->SetXdrift(xdrift);
	      hitpos_p->SetSign(csgn[i]);
	      hitpos_p->SetUhit(xwire + csgn[i]*xdrift);
              hitpos_p->SetTdc(itdc);
	      hitpos_p->SetDigDC(digdc_p);      //needed for using BrDcDig
	      //dighit_p->AddHitPos(hitpos_p);
	      if(xdrift<0.0010)break; // creating only one hit in this case
	    } 
	  }
	}
      }//if(imod==idet)
    }//ihit
  }//idet
}

//________________________________________________________________
 void BrDCClusterFinder::DecodeDig(BrDataTable* digitizedHits)
{
  //Generate DC Hit Positions using the time and wire fired to build
  // the left-right ambiguity.
  static const Float_t csgn[2] = {(float)-1.0,(float)1.0};
  
  BrDCPlane* dcpl;
  BrDetectorVolume *vol;
  BrDCHitPosition *hitpos_p;
  
  vol = GetDetectorVolume(GetName());
  
  fHitPositionList->Delete();  // Added  when debugging on 1.11.2000 (PS)
  
  //////// Read Data ////////////
  Int_t EveTab[2000][5];
  Int_t ReList[2000];
  Int_t numRawHits = digitizedHits->GetEntries();
  //cout<<numRawHits<<endl;
  if(numRawHits>1999){
    Warning("Decode","- %s Skip because %d more than 1000",GetName(),numRawHits);
    return;
  }
  
  Int_t ii=0;
  for(Int_t i = 0; i < numRawHits; i++) {
    BrDcDig* digdc_p = (BrDcDig*)digitizedHits->At(i);
    Int_t im  =  digdc_p->GetSubModule() - 1;
    Int_t ip  =  digdc_p->GetPlane() - 1;
    Int_t iw  =  digdc_p->GetWire() - 1;
    Int_t it  =  digdc_p->GetTime();
    Int_t il  =  digdc_p->GetWidth(); 
    EveTab[ii][0]=im;
    EveTab[ii][1]=ip;
    EveTab[ii][2]=iw;
    EveTab[ii][3]=it;
    EveTab[ii][4]=il;
    ReList[ii]=i;
    ii++;
  }
  Int_t NumCleanHits=ii;
  
  if(NumCleanHits<fLowLimit || NumCleanHits>fUpLimit) return;
  
  fEventStatus=kTRUE;
  
  
  for(Int_t idet=0;idet<3;idet++) {
    fDCDriver->AtSubModule(idet);
    for(Int_t ihit=0;ihit<NumCleanHits;ihit++) {
      if( EveTab[ihit][0] == idet ) {
	BrDcDig* digdc_p = (BrDcDig*)digitizedHits->At(ReList[ihit]);
	Int_t iplane =  EveTab[ihit][1];
	Int_t iwire  =  EveTab[ihit][2];
	Int_t itdc   =  EveTab[ihit][3];
	Int_t iwidth =  EveTab[ihit][4];

	fDCDriver->AtPlane(iplane);
	Float_t xwire = fDCDriver->GetWirePosition(iwire);
        Float_t xdrift = 0;

	dcpl   = fParams->GetPlaneAt(iplane);
	Float_t time = dcpl->GetRealTime(itdc,iwire); 
	xdrift = fParams->GetDriftv() * time;

	//cout<<iplane<<" "<<iwire<<" "<<xdrift<<endl;
	
	if(HistOn()){
	  fDriftDist[idet][iplane]->Fill(xdrift);
	  fhDriftTime[idet][iplane]->Fill(itdc);
	  fRawHitPos[idet][iplane]->Fill(xwire+xdrift);
	  fRawHitPos[idet][iplane]->Fill(xwire-xdrift);
	}
	
	if(xdrift>=0){
	  for(Int_t i=0;i<2;i++ ) {
	    //Create hit position and add to list.
	    hitpos_p = new BrDCHitPosition();
	    fHitPositionList->Add(hitpos_p);
	    
	    hitpos_p->SetNwire(iwire);
	    hitpos_p->SetXwire(xwire);
	    hitpos_p->SetXdrift(xdrift);
	    hitpos_p->SetSign(csgn[i]);
	    hitpos_p->SetUhit(xwire + csgn[i]*xdrift);
	    hitpos_p->SetTdc(itdc);
	    hitpos_p->SetDigDC(digdc_p);      //needed for using BrDcDig
	    //dighit_p->AddHitPos(hitpos_p);
	    if(xdrift<0.0010)break; // creating only one hit in this case	    
	  }
	}
      }//if(imod==idet)
    }//ihit
  }//idet
}
//_____________________________________________________________
 void BrDCClusterFinder::DCCluster()
{
  Int_t i;
  
  Int_t numplanes;
  
#define MaxNumDCPLs 10
  Float_t wirang[MaxNumDCPLs];
  
  Int_t npair,ntrio,nsingle,iview,ipl,inview;
  Int_t idet;
  
#define maxpl 30
#define maxpair 10
  
  Int_t slist[maxpl];
  Int_t plist[maxpair];
  Int_t tlist[maxpair];
  
  Int_t isview[maxpl];
  Int_t ipview[maxpair];
  Int_t itview[maxpair];
  
  BrDetectorVolume *vol[4];
  
  for(i=0;i<3;i++) {
     Char_t volname[32];
     sprintf(volname,"%sA%d",GetName(),i+1);
     vol[i] = GetDetectorVolume(volname);      //sub-modules
     }
  vol[3] = GetDetectorVolume(GetName());       //main module

  for(idet=0;idet<3;idet++) {
    
     numplanes = fParams->GetNplane();
    
     if(numplanes == 0) {
        cout<<"numplanes = 0!!!, there is some problem with " 
                    "parameters; check it out!!!"<<endl;
        return;
        }
    
     for(i=0;i<numplanes;i++) wirang[i] = fParams->GetPlaneAt(i)->GetWirang();
    
     npair = 0;
     ntrio = 0;
     nsingle = 0;
     iview = 1;
     ipl = 0;
     if(fPlaneCombineMode == kPairsWhenTogether) {
        while(ipl < numplanes ) {
           inview = 1;
           while((wirang[ipl+inview] == wirang[ipl]) && (ipl+inview<numplanes)) {
              inview++;
              }
           if(inview == 1) {
              slist[nsingle] = ipl;
              isview[nsingle] = iview;
              nsingle++;
              }
           else if(inview == 2) {
              plist[npair] = ipl;
              ipview[npair] = iview;
              npair++;
              }
           else if(inview == 3) {
              tlist[ntrio] = ipl;
              itview[ntrio] = iview;
              ntrio++;
              }
           else {
              cout<<"DC_clust> *****************************"<<endl;
              cout<<"DC_clust> ERROR ERROR ERROR ERROR ERROR"<<endl;
              cout<<"DC_clust> I do not know how to handle  "<<endl;
              cout<<"DC_clust> this plane configuration !!! "<<endl;
              }
           ipl += inview;
           iview++;
           }
        }
     else if(fPlaneCombineMode == kAllSinglePlanes) {
        while(ipl < numplanes ) {
           slist[nsingle] = ipl;
           isview[nsingle] = ipl + 1;
           nsingle++;
           ipl++;
           }
        }

     fTotalComb=1;

     for(i=0;i<npair;i++)   DCPair(idet,plist[i],ipview[i]);
     for(i=0;i<nsingle;i++) DCSingle(idet,slist[i],isview[i]);
     for(i=0;i<ntrio;i++)   DCTrio(idet,tlist[i],itview[i]);
  } //loop over idet
  
  //cout<<"tu3"<<endl;  
  if(HistOn()){
    if(fhTotComb)fhTotComb->Fill(fTotalComb);
  }
  //cout<<"tu4"<<endl;   
  
}

//____________________________________________________________________
 void BrDCClusterFinder::DCSingle(Int_t idet, Int_t ipl, Int_t iview)
{
  Int_t i;
  BrDCPlane *dcpl;
  
  Float_t detZ,z1;
  // Int_t ih1,ip1;
  Float_t hit_pos[3];
  Float_t hit_dpos[2];
  
  BrDcDigInfo *diginfo_p;
  BrDcDig *dighit_p;
  
  BrDCHitPosition *hitpos_p;
  BrDCHit *hit_p;
  
  BrDetectorVolume *vol[4];
  BrDataTable* selectedDCHits = fSelectedDCHits1;

  for(i=0;i<3;i++) {
    Char_t volname[32];
    sprintf(volname,"%sA%d",GetName(),i+1);
    vol[i] = GetDetectorVolume(volname);      //sub-modules
  }
  vol[3] = GetDetectorVolume(GetName());       //main module
  
  dcpl = fParams->GetPlaneAt(ipl);
  detZ = vol[idet]->GetPosition()[2];               //Z of center of detector
  
  //z1 = detZ + dcpl->GetPlaneZ((Float_t)0.0,(Float_t)0.0);
  z1 = fDCDriver->GetPlanePosition(idet,ipl);

  selectedDCHits->Clear();
  SelectDCHits(idet,ipl, selectedDCHits);

  Int_t numSelectedHits = selectedDCHits->GetEntries();
  for(Int_t ihit=0;ihit<numSelectedHits;ihit++) {
     hitpos_p = (BrDCHitPosition*)selectedDCHits->At(ihit);
     diginfo_p = hitpos_p->GetDigDCInfo();     if(diginfo_p->GetUsed() == 0) {
        dighit_p = diginfo_p->GetDigDC();

        BrClonesArray &hit = *fDetectorHits;
        Int_t nhit = fDetectorHits->GetLast()+1;
        hit_p = new(hit[nhit]) BrDCHit();
	
        hit_pos[0]  = hitpos_p->GetUhit();
        hit_pos[1]  = (Float_t)0.0;
        hit_pos[2]  = z1;
        
        hit_p->SetPos(hit_pos);
        hit_dpos[0] = fParams->GetPosres();
        hit_dpos[1] = (Float_t)0.0;
        hit_p->SetDpos(hit_dpos);
        hit_p->SetImod((idet + 1)*100 + iview);
        hit_p->SetStat(1);
	
        diginfo_p->IncUsed();
        }
     }
  selectedDCHits->Clear();

}

//_____________________________________________________________
 void BrDCClusterFinder::DCPair(Int_t idet, Int_t ipl, Int_t iview) //,Float_t ddx,Float_t ddy)
{
  Int_t i;
  BrDCPlane *dcpl;
  BrDCPlane *dcpl2;
  
  BrDetectorVolume   *vol[4];
  
  static const Double_t rad = .01745329;
  
  Float_t detZ,z1,z2,zc,ddu;
  Float_t hit_pos[3];
  Float_t hit_dpos[2];
  

  BrDcDigInfo *diginfo_p1;
  BrDcDigInfo *diginfo_p2;

  BrDCHitPosition *hitpos_p1;
  BrDCHitPosition *hitpos_p2;
  
  BrDCHit *hit_p;
  //BrDCHit *hit_p;

  BrDcDig *dighit_p1;
  BrDcDig *dighit_p2;
    
  for(i=0;i<3;i++) {
    Char_t volname[32];
    sprintf(volname,"%sA%d",GetName(),i+1);
    vol[i] = GetDetectorVolume(volname);      //sub-modules
  }
  vol[3] = GetDetectorVolume(GetName());       //main module
  
  detZ = vol[idet]->GetPosition()[2];              //center of detector
  
  dcpl  = fParams->GetPlaneAt(ipl);
  dcpl2 = fParams->GetPlaneAt(ipl+1);
  
  if(!(dcpl->GetWirang()==dcpl2->GetWirang()))cout<<"logical error in DCPair"<<endl;
  Char_t ViewName;
  if(dcpl->GetWirang()==-18)ViewName='U';
  else if(dcpl->GetWirang()==18)ViewName='V';
  else if(dcpl->GetWirang()==0)ViewName='X';
  else if(dcpl->GetWirang()==-90)ViewName='Y';
  else cout<<"Wrong wire angle: "<<dcpl->GetWirang()<<endl;
    
  // ddu = fClusDx*(Float_t)TMath::Cos(dcpl->GetWirang()*rad) 
  //  - fClusDy*(Float_t)TMath::Sin(dcpl->GetWirang()*rad);
 
  if(iview==2)ddu = fClusDy; // for Y view we can apply narrower cuts 
  else ddu = fClusDx; 
  
  //z1 = detZ + dcpl->GetPlaneZ(0,0);  // This this way of getting z should be changed (PS)
  //z2 = detZ + dcpl2->GetPlaneZ(0,0);
  z1 = fDCDriver->GetPlanePosition(idet,ipl);
  z2 = fDCDriver->GetPlanePosition(idet,ipl+1);
  zc = (Float_t)0.5 * (z1 + z2);
  //cout<<"z1,z2 "<<dcpl->GetPlaneZ(0,0)<<" "<<dcpl2->GetPlaneZ(0,0)<<endl;  
  //cout<<"detZ : "<<detZ<<endl;
  
  if(z2-z1<0.0)cout<<"View name is "<<ViewName<<endl;
  fSelectedDCHits1->Clear();
  fSelectedDCHits2->Clear();
  SelectDCHits(idet,ipl,fSelectedDCHits1);
  SelectDCHits(idet,ipl+1,fSelectedDCHits2);

  Int_t numSelectedHits1 = fSelectedDCHits1->GetEntries();
  Int_t numSelectedHits2 = fSelectedDCHits2->GetEntries();
  //if(numSelectedHits1)fTotalComb=fTotalComb*numSelectedHits1;
  //if(numSelectedHits2)fTotalComb=fTotalComb*numSelectedHits2;
  //if(!strcmp("T4",GetName())&& idet==1 && iview==2)
  //cout<<"~~~~Pair: Nhits: "<<numSelectedHits1<<" "<<numSelectedHits2<<endl;
  for(Int_t ihit1=0;ihit1<numSelectedHits1;ihit1++) {
     hitpos_p1 = (BrDCHitPosition*)fSelectedDCHits1->At(ihit1);
     diginfo_p1 = hitpos_p1->GetDigDCInfo();
     if(diginfo_p1->GetUsed())cout<<"hit1 alredy used?"<<endl;
     if(diginfo_p1->GetUsed() == 0) {
        dighit_p1 = diginfo_p1->GetDigDC();

        for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
           hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
           diginfo_p2 = hitpos_p2->GetDigDCInfo();
 
	   if(diginfo_p2->GetUsed() == 0 || GetClustMode()) {
              dighit_p2 = diginfo_p2->GetDigDC();

              Float_t u1 = hitpos_p1->GetUhit();
              Float_t u2 = hitpos_p2->GetUhit();
	      //if(!strcmp("T5",GetName())&& idet==1 && iview==2)
	      //  cout<<"~~~~u1,u2: "<<u1<<" "<<u2<<" "
	      //      <<TMath::Abs(u1-u2)<<" "<<0.5*(u1+u2)<<endl;
	      if(HistOn()){
		if(ViewName=='U')fPairUDu[idet]->Fill(u1-u2);
		if(ViewName=='V')fPairVDu[idet]->Fill(u1-u2);
		if(ViewName=='X')fPairXDu[idet]->Fill(u1-u2);
		if(ViewName=='Y')fPairYDu[idet]->Fill(u1-u2);
	      }
              Float_t ddu_check = u1 - u2 - fOffset[iview-1];
              if(TMath::Abs(ddu_check)<=ddu) {

                 BrClonesArray &hit = *fDetectorHits;
                 Int_t nhit = fDetectorHits->GetLast()+1;

                 hit_p = new(hit[nhit]) BrDCHit();
                 //hit_p = new(hit[nhit]) BrDCHit();   

                 hit_pos[0] = (Float_t)0.5*(u1 + u2);
                 hit_pos[1] = (Float_t)0.0;
                 hit_pos[2] = zc;

                 hit_p->SetPos(hit_pos);
                 hit_dpos[0] = fParams->GetPosres() / (Float_t)1.41;
                 hit_dpos[1] = (Float_t)0.0;
                 hit_p->SetDpos(hit_dpos);
                 hit_p->SetImod((idet + 1)*100 + iview);
                 hit_p->SetStat(1);

		 // save primary hits
		 hit_p->SetNumCombined(2);
                 hit_p -> SetU(u1,u2,0);
		 hit_p -> SetZ(z1,z2,0);
		 hit_p -> SetPlane(ipl,ipl+1,0);
		 hit_p -> SetWire(hitpos_p1->GetNwire(),hitpos_p2->GetNwire(),0);
		 hit_p -> SetTdc(hitpos_p1->GetTdc(),hitpos_p2->GetTdc(),0);

                 diginfo_p1->IncUsed();
                 diginfo_p2->IncUsed();
	      }
	   }
	}
     }
  }
  fSelectedDCHits1->Clear();
  fSelectedDCHits2->Clear();
  
}

//_____________________________________________________________
 void BrDCClusterFinder::DCTrio(Int_t idet, Int_t  ipl, Int_t iview) //,Float_t ddx,Float_t ddy)
{
  Int_t i;
  BrDCPlane *dcpl1;
  BrDCPlane *dcpl2;
  BrDCPlane *dcpl3;
  
  BrDetectorVolume   *vol[4];
  
  static const Double_t rad = .01745329;
  
  Float_t detZ,z1,z2,z3,zc,ddu;
  Float_t hit_pos[3];
  Float_t hit_dpos[2];
  
  
  /*
    Int_t NumDigHitMod1;
    BrDataTable DigHitMod1;
    
    Int_t NumDigHitMod2;
    BrDataTable DigHitMod2;
    
    Int_t NumDigHitMod3;
    BrDataTable DigHitMod3;
  */  
  
  
  BrDcDigInfo *diginfo_p1;
  BrDcDigInfo *diginfo_p2;
  BrDcDigInfo *diginfo_p3;
  
  BrDCHitPosition *hitpos_p1;
  BrDCHitPosition *hitpos_p2;
  BrDCHitPosition *hitpos_p3;
  
  BrDCHit *hit_p;
  BrDcDig *dighit_p1;
  BrDcDig *dighit_p2;
  BrDcDig *dighit_p3;
  
  dcpl1 = fParams->GetPlaneAt(ipl);
  dcpl2 = fParams->GetPlaneAt(ipl+1);
  dcpl3 = fParams->GetPlaneAt(ipl+2);
  if(!(dcpl1->GetWirang()==dcpl2->GetWirang()))cout<<"logical error in DCTrio (1-2)"<<endl;
  if(!(dcpl1->GetWirang()==dcpl3->GetWirang()))cout<<"logical error in DCTrio (1-3)"<<endl;
  if(!(dcpl2->GetWirang()==dcpl3->GetWirang()))cout<<"logical error in DCTrio (2-3)"<<endl;
  
  for(i=0;i<3;i++) {
    Char_t volname[32];
    sprintf(volname,"%sA%d",GetName(),i+1);
    vol[i] = GetDetectorVolume(volname);      //sub-modules
  }
  vol[3] = GetDetectorVolume(GetName());       //main module
  
  detZ = vol[idet]->GetPosition()[2];              //center of detector

  if(iview==2)ddu = fClusDy; // for Y view we can apply narrower cuts 
  else ddu = fClusDx;

  z1 = fDCDriver->GetPlanePosition(idet,ipl);
  z2 = fDCDriver->GetPlanePosition(idet,ipl+1);
  z3 = fDCDriver->GetPlanePosition(idet,ipl+2);
  zc = (z1 + z2 + z3) / (Float_t)3.0;

  
  //cout<<"Trio: iview "<<iview<<endl;
  
  fSelectedDCHits1->Clear();
  fSelectedDCHits2->Clear();
  fSelectedDCHits3->Clear();
  SelectDCHits(idet,ipl,fSelectedDCHits1);
  SelectDCHits(idet,ipl+1,fSelectedDCHits2);
  SelectDCHits(idet,ipl+2,fSelectedDCHits3);
  
  Int_t numSelectedHits1 = fSelectedDCHits1->GetEntries();
  Int_t numSelectedHits2 = fSelectedDCHits2->GetEntries();
  Int_t numSelectedHits3 = fSelectedDCHits3->GetEntries();
  //if(numSelectedHits1)fTotalComb=fTotalComb*numSelectedHits1; //this 3 lines are for debuging purpose
  //if(numSelectedHits2)fTotalComb=fTotalComb*numSelectedHits2;
  //if(numSelectedHits3)fTotalComb=fTotalComb*numSelectedHits3;
  //cout<<"Trio: Num of Hits "<<numSelectedHits1<<" "<<numSelectedHits2<<" "<<numSelectedHits3<<endl;
  

  //////// What follows is just to fill histograms with u1-u2, u1-u3 and u2-u3

  for(Int_t ihit1=0;ihit1<numSelectedHits1;ihit1++) {
    hitpos_p1 = (BrDCHitPosition*)fSelectedDCHits1->At(ihit1);
    diginfo_p1 = hitpos_p1->GetDigDCInfo();
    dighit_p1 = diginfo_p1->GetDigDC();
	
    for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
      hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
      diginfo_p2 = hitpos_p2->GetDigDCInfo();
      dighit_p2 = diginfo_p2->GetDigDC();
	    
      Int_t   iw1= hitpos_p1->GetNwire();
      Int_t   iw2= hitpos_p2->GetNwire(); 
      Float_t u1 = hitpos_p1->GetUhit();
      Float_t u2 = hitpos_p2->GetUhit();
      if(HistOn()){ 
	if(iview==1)fTrio12XDu[idet]->Fill(u1-u2);
	if(iview==2)fTrio12YDu[idet]->Fill(u1-u2);
      }
    }
  }

  for(Int_t ihit1=0;ihit1<numSelectedHits1;ihit1++) {
    hitpos_p1 = (BrDCHitPosition*)fSelectedDCHits1->At(ihit1);
    diginfo_p1 = hitpos_p1->GetDigDCInfo();
    dighit_p1 = diginfo_p1->GetDigDC();
	
    for(Int_t ihit3=0;ihit3<numSelectedHits3;ihit3++) {
      hitpos_p3 = (BrDCHitPosition*)fSelectedDCHits3->At(ihit3);
      diginfo_p3 = hitpos_p3->GetDigDCInfo();
      dighit_p3 = diginfo_p3->GetDigDC();
	    
      Int_t   iw1= hitpos_p1->GetNwire();
      Int_t   iw3= hitpos_p3->GetNwire(); 
      Float_t u1 = hitpos_p1->GetUhit();
      Float_t u3 = hitpos_p3->GetUhit();
      if(HistOn()){ 
	if(iview==1)fTrio13XDu[idet]->Fill(u1-u3);
	if(iview==2)fTrio13YDu[idet]->Fill(u1-u3);
      }
    }
  }

  for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
    hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
    diginfo_p2 = hitpos_p2->GetDigDCInfo();
    dighit_p2 = diginfo_p2->GetDigDC();
	
    for(Int_t ihit3=0;ihit3<numSelectedHits3;ihit3++) {
      hitpos_p3 = (BrDCHitPosition*)fSelectedDCHits3->At(ihit3);
      diginfo_p3 = hitpos_p3->GetDigDCInfo();
      dighit_p3 = diginfo_p3->GetDigDC();
	    
      Int_t   iw2= hitpos_p2->GetNwire();
      Int_t   iw3= hitpos_p3->GetNwire(); 
      Float_t u2 = hitpos_p2->GetUhit();
      Float_t u3 = hitpos_p3->GetUhit();
      if(HistOn()){ 
	if(iview==1)fTrio23XDu[idet]->Fill(u2-u3);
	if(iview==2)fTrio23YDu[idet]->Fill(u2-u3);
      }
    }
  }


  // First combine treefold hits:
  
  for(Int_t ihit1=0;ihit1<numSelectedHits1;ihit1++) {
    hitpos_p1 = (BrDCHitPosition*)fSelectedDCHits1->At(ihit1);
    diginfo_p1 = hitpos_p1->GetDigDCInfo();
    
    if(diginfo_p1->GetUsed())cout<<"Trio: hit1 already used?"<<endl;
    if(diginfo_p1->GetUsed() == 0) {
      dighit_p1 = diginfo_p1->GetDigDC();
      
      for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
	hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
	diginfo_p2 = hitpos_p2->GetDigDCInfo();
	
	if(diginfo_p2->GetUsed() == 0 || GetClustMode()) {
	  dighit_p2 = diginfo_p2->GetDigDC();
	  
	  Int_t   iw1= hitpos_p1->GetNwire();
	  Int_t   iw2= hitpos_p2->GetNwire(); 
	  Float_t u1 = hitpos_p1->GetUhit();
	  Float_t u2 = hitpos_p2->GetUhit();
	  Float_t ddu_check = u1 - u2 - fOffset[iview-1];
	  //cout<<"view="<<iview<<endl;
	  //cout<<"duu: "<<ddu<<" "<<ddu_check1<<" "<<u1<<" "<<u2<<endl;
	  if(TMath::Abs(ddu_check)<=ddu) {
	    //We have a match between first two planes.
	    //Now see if this match also matches third plane.
	    for(Int_t ihit3=0;ihit3<numSelectedHits3;ihit3++) {
	      hitpos_p3 = (BrDCHitPosition*)fSelectedDCHits3->At(ihit3);
	      diginfo_p3 = hitpos_p3->GetDigDCInfo();
	      
	      if(diginfo_p3->GetUsed() == 0 || GetClustMode()) {
		dighit_p3 = diginfo_p3->GetDigDC();
		
		Int_t   iw3= hitpos_p3->GetNwire();
		Float_t u3 = hitpos_p3->GetUhit();
		// fit track to u1,u2,u3 and calculate chisq
		Float_t sumy = u1 + u2 + u3;
		Float_t sumx = z1 + z2 + z3;
		Float_t sumxy = u1*z1 + u2*z2 + u3*z3;
		Float_t sumxsq = z1*z1 + z2*z2 + z3*z3;
		Float_t sum = (Float_t)3.0;
		Float_t d = sum * sumxsq - sumx*sumx;
		Float_t slope = (sumxy*sum - sumx*sumy) / d;
		Float_t rint =  (sumxsq*sumy - sumx*sumxy) / d;
		Float_t dchi = (u1 - (slope*z1+rint)) * (u1 - (slope*z1+rint));
		dchi +=        (u2 - (slope*z2+rint)) * (u2 - (slope*z2+rint));
		dchi +=        (u3 - (slope*z3+rint)) * (u3 - (slope*z3+rint));

		Float_t err = fParams->GetPosres();
		Float_t chisq = dchi / (err*err);
		Float_t deviation = 0.5*(u1+u3) - u2;
		if(HistOn()){
		  fChisq->Fill(chisq);
		  fDeviaAll->Fill(deviation);
		}


		
		if(chisq < fTrioChisqWin) {
		  if(HistOn())
		    fDeviaAcce->Fill(deviation);
		  BrClonesArray &hit = *fDetectorHits;
		  Int_t nhit = fDetectorHits->GetLast()+1;
		  hit_p = new(hit[nhit]) BrDCHit();
		  
		  
		  Float_t upos = (u1+u2+u3)/3.0;   //perhaps use slope and int
		  hit_pos[0] = upos;
		  hit_pos[1] = (Float_t)0.0;
		  hit_pos[2] = zc;
		  //cout<<hit_pos[0]<<" "<<hit_pos[2]<<" "<<iview<<" "<<3<<endl;

		  hit_p->SetPos(hit_pos);
		  hit_dpos[0] = fParams->GetPosres() / (Float_t)1.732; //sqrt(3)???
		  //hit_dpos[0] = fParams->GetPosres();
		  hit_dpos[1] = (Float_t)0.0;
		  hit_p->SetDpos(hit_dpos);
		  hit_p->SetImod((idet + 1)*100 + iview);
		  hit_p->SetStat(1);

		  // save primary hits
		  hit_p->SetNumCombined(3);
		  hit_p -> SetU(u1,u2,u3);
		  hit_p -> SetZ(z1,z2,z3);
		  hit_p -> SetPlane(ipl,ipl+1,ipl+2);
		  hit_p -> SetWire(iw1,iw2,iw3);
		  hit_p -> SetTdc(hitpos_p1->GetTdc(),hitpos_p2->GetTdc(),hitpos_p3->GetTdc());

		  diginfo_p1->IncUsed();
		  diginfo_p2->IncUsed();
		  diginfo_p3->IncUsed();			
		}
	      }
	    }
	  }
	}
      }
    }
  }
  
  if(GetXYClusterOption()){
    // All treefold hits combined, so lets find possible double hits.
    // First for planes X1 and X2 (Y1 and Y2):
    
    for(Int_t ihit1=0;ihit1<numSelectedHits1;ihit1++) {
      hitpos_p1 = (BrDCHitPosition*)fSelectedDCHits1->At(ihit1);
      diginfo_p1 = hitpos_p1->GetDigDCInfo();
      
      if(diginfo_p1->GetUsed() == 0) { //lets exclude hits used to combine treefold clusters
	dighit_p1 = diginfo_p1->GetDigDC();
	
	for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
	  hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
	  diginfo_p2 = hitpos_p2->GetDigDCInfo();
	  
	  if(diginfo_p2->GetUsed() == 0) { //lets exclude hits used to combine treefold clusters
	    dighit_p2 = diginfo_p2->GetDigDC();
	    
	    Int_t   iw1= hitpos_p1->GetNwire();
	    Int_t   iw2= hitpos_p2->GetNwire(); 
	    Float_t u1 = hitpos_p1->GetUhit();
	    Float_t u2 = hitpos_p2->GetUhit();
	    Float_t ddu_check = u1 - u2 - fOffset[iview-1];
	    //cout<<"view="<<iview<<endl;
	    //cout<<"duu: "<<ddu<<" "<<ddu_check1<<" "<<u1<<" "<<u2<<endl;
	    if(TMath::Abs(ddu_check)<=ddu) {
	      // We are here means that we should create a new combine hit                    
	      
	      BrClonesArray &hit = *fDetectorHits;
	      Int_t nhit = fDetectorHits->GetLast()+1;
	      hit_p = new(hit[nhit]) BrDCHit();
	      
	      Float_t upos = (u1+u2)/2.0;   //perhaps use slope and int
	      hit_pos[0]   =  upos;
	      hit_pos[1]   = (Float_t)0.0;
	      hit_pos[2]   = (z1+z2)/2.0;

	      hit_p->SetPos(hit_pos);
	      hit_dpos[0] = fParams->GetPosres() / (Float_t)1.41; //sqrt(2)???
	      hit_dpos[1] = (Float_t)0.0;
	      hit_p->SetDpos(hit_dpos);
	      hit_p->SetImod((idet + 1)*100 + iview);
	      hit_p->SetStat(1);

	      // save primary hits
	      hit_p->SetNumCombined(2);
	      hit_p -> SetU(u1,u2,0);
	      hit_p -> SetZ(z1,z2,0);
	      hit_p -> SetPlane(ipl,ipl+1,0);
	      hit_p -> SetWire(iw1,iw2,0);
	      hit_p -> SetTdc(hitpos_p1->GetTdc(),hitpos_p2->GetTdc(),0);

	      diginfo_p1->IncUsed();
	      diginfo_p2->IncUsed();
	    }
	  }
	}
      }
    }
    
    // And then for planes X2 and X3 (Y2 and Y3):
    // We exclude combination X1 and X3 as it suffers from left-right ambiguity.
    
    for(Int_t ihit2=0;ihit2<numSelectedHits2;ihit2++) {
      hitpos_p2 = (BrDCHitPosition*)fSelectedDCHits2->At(ihit2);
      diginfo_p2 = hitpos_p2->GetDigDCInfo();
      
      if(diginfo_p2->GetUsed() == 0) { //lets exclude hits used to combine treefold clusters
	dighit_p2 = diginfo_p2->GetDigDC();
	
	for(Int_t ihit3=0;ihit3<numSelectedHits3;ihit3++) {
	  hitpos_p3 = (BrDCHitPosition*)fSelectedDCHits3->At(ihit3);
	  diginfo_p3 = hitpos_p3->GetDigDCInfo();
	  
	  if(diginfo_p3->GetUsed() == 0 ) {//lets exclude hits used to combine treefold clusters
	    dighit_p3 = diginfo_p3->GetDigDC();
	    
	    Int_t   iw2= hitpos_p2->GetNwire();
	    Int_t   iw3= hitpos_p3->GetNwire(); 
	    Float_t u2 = hitpos_p2->GetUhit();
	    Float_t u3 = hitpos_p3->GetUhit();
	    Float_t ddu_check = u2 - u3 - fOffset[iview-1];
	    //cout<<"view="<<iview<<endl;
	    //cout<<"duu: "<<ddu<<" "<<ddu_check1<<" "<<u1<<" "<<u2<<endl;
	    if(TMath::Abs(ddu_check)<=ddu) {
	      // We are here means that we should create a new combine hit                    
	      
	      BrClonesArray &hit = *fDetectorHits;
	      Int_t nhit = fDetectorHits->GetLast()+1;
	      hit_p = new(hit[nhit]) BrDCHit();
	      
	      Float_t upos = (u2+u3)/2.0;   //perhaps use slope and int
	      hit_pos[0]   =  upos;
	      hit_pos[1]   = (Float_t)0.0;
	      hit_pos[2]   = (z2+z3)/2.0;

	      hit_p->SetPos(hit_pos);
	      hit_dpos[0] = fParams->GetPosres() / (Float_t)1.41; //sqrt(2)???
	      hit_dpos[1] = (Float_t)0.0;
	      hit_p->SetDpos(hit_dpos);
	      hit_p->SetImod((idet + 1)*100 + iview);
	      hit_p->SetStat(1);	

	      // save primary hits
	      hit_p->SetNumCombined(2);
	      hit_p -> SetU(u2,u3,0);
	      hit_p -> SetZ(z2,z3,0);
	      hit_p -> SetPlane(ipl+1,ipl+2,0);
	      hit_p -> SetWire(iw2,iw3,0);
	      hit_p -> SetTdc(hitpos_p2->GetTdc(),hitpos_p3->GetTdc(),0);
    
	      diginfo_p2->IncUsed();
	      diginfo_p3->IncUsed();	      
	    }
	  }
	}
      }
    }
    
  }
  
  
  fSelectedDCHits1->Clear();
  fSelectedDCHits2->Clear();
  fSelectedDCHits3->Clear();
}

//_____________________________________________________________
 void BrDCClusterFinder::SelectDCHits(const Int_t idet,const Int_t iplane,
				  BrDataTable *selectedHits)
{
  //Select collection of BrDCHitPositions in which the associated digitized hits 
  //match idet and iplane
  Int_t i;
  BrDcDig* dighit_p;
  BrDCHitPosition *hitpos_p;
    
  Int_t numDCHits = fHitPositionList->GetLast()+1; 
  for(i=0;i<numDCHits;i++) {
    hitpos_p = (BrDCHitPosition*)fHitPositionList->At(i);
    dighit_p = hitpos_p->GetDigDC();
    if(( dighit_p->GetSubModule()-1 == idet   || idet   == IANY ) &&
       ( dighit_p->GetPlane()-1     == iplane || iplane == IANY )) {
      selectedHits->Add(hitpos_p);
      }
  }
}



//  $Log: BrDCClusterFinder.cxx,v $
//  Revision 1.22  2002/06/10 16:41:08  ufstasze
//  Splitted decoding to DecodeDat for data and DecodeDig for digitize geant simul.
//
//  Revision 1.21  2002/05/11 13:56:47  ufstasze
//  Added fDCDriver->SetRunNumber(fRunNo); in Init()
//
//  Revision 1.20  2002/05/10 12:28:25  ufstasze
//  Calibration data are read in Init() only when fUseMySql is false.
//
//  Revision 1.19  2002/05/08 11:28:47  ufstasze
//  minor changes
//
//  Revision 1.18  2002/05/07 17:32:20  ouerdane
//  added driftTime db parameter
//
//  Revision 1.17  2002/05/02 15:04:52  ufstasze
//  Minor changes
//
//  Revision 1.16  2002/04/29 14:07:23  ufstasze
//  Added new debugging histograms and corrected one bug in Begin method
//
//  Revision 1.15  2002/03/08 16:27:33  ufstasze
//  Changes that have to do with introducing the readout of global Tdc offset form the data base
//
//  Revision 1.14  2002/03/01 18:11:07  videbaek
//  Add HistOn() condition for all histogramming.
//  As is the code brode the codingerules.
//  Added a warning for many hits.
//
//  Revision 1.13  2002/02/20 13:45:19  ufstasze
//  Set accepted number of raw hits from 1000 to 2000 (see. EveTab and ReList).
//  Replaced if(xdrift<0.0025) by if(xdrift<0.0010).
//  Commented tree unnecessary lines:
//   if(numRawHits<220)fDCDriver->SetMinWidth(fMinWidth);
//   else if(numRawHits<300)fDCDriver->SetMinWidth(30);
//   else fDCDriver->SetMinWidth(40);
//  Added one more diagnostic histogram.
//
//  Revision 1.12  2002/02/15 15:41:44  ufstasze
//  Few changes related to study of pp data.
//  1. Added globalTdcOffset
//  2. Added offsets used in DCPair and DCTrio
//  3. Removed bug is Decode (xdrift>0)=>(xdrift>=0).
//
//  Revision 1.11  2001/08/31 12:51:15  staszel
//  minor modifications.
//
//  Revision 1.10  2001/08/30 13:43:15  ufstasze
//  minor changes.
//
//  Revision 1.9  2001/08/30 13:29:20  staszel
//  Time reference base on Tof1 raw hits.
//
//  Revision 1.8  2001/08/23 10:51:24  staszel
//  T3: fMinWidth now depends on numRawHits + minor changes.
//
//  Revision 1.7  2001/08/10 16:26:14  staszel
//  minor changes
//
//  Revision 1.6  2001/08/07 13:48:30  ouerdane
//  Cleaned up a lot the DC tracking modules and utilities:
//   Made all utilities deriving from BrModule
//   Set the class version number to 0 (NOT 1 like before)
//   Removed + in the LinkDef file for all modules
//   Added ClassDef in the View Combiner class (didn't exist)
//   Structurized the histogramming section in TDirectories
//
//  Revision 1.5  2001/08/03 13:27:15  staszel
//  low and up limits on number of hits added.
//
//  Revision 1.4  2001/07/30 11:52:06  staszel
//  Changes that have to do with introduction of tracking from
//  exp. data: 1) new constructor formal variable list,
//  modified Decode method and some new diagnostics histograms.
//
//  Revision 1.3  2001/07/20 17:27:45  krakow
//  Changes related to BrDriverDC
//
//  Revision 1.2  2001/06/22 17:43:32  cholm
//  Changes to do with data class renaming
//
//  Revision 1.1.1.1  2001/06/21 14:55:11  hagel
//  Initial revision of brat2
//
//  Revision 1.12  2001/06/20 11:59:23  staszel
//  BrDetectorHit replaced by BrDCHit.
//  New BrDCHit class objects are filled with additional
//  info. that refers to primary detector hits.
//
//  Revision 1.11  2001/06/15 15:39:50  staszel
//  Changes having to do with development of dc tracking package
//
//  Revision 1.10  2001/06/13 13:12:32  staszel
//  father development of dc tracking
//
//  Revision 1.9  2001/01/19 17:53:50  staszel
//  Changes having to do with development of BrDCTrackingModule
//
//  Revision 1.8  2000/11/23 01:32:52  brahmlib
//  Cleaned up code in general. BrDriverDC now usess ClassImp/ClassDef.
//
//  Revision 1.7  2000/10/25 17:58:05  hagel
//  Further development of BrDCTrackingModule
//
//  Revision 1.6  2000/10/25 15:12:45  staszel
//  Now we declare only one pointer to DrDriverDC in the Init method.
//
//  Revision 1.5  2000/10/11 14:43:46  staszel
//  Changes in Decode method to use BrDriverDC when one refers to DCs' geometry.
//
//  Revision 1.4  2000/10/05 02:21:31  hagel
//  Further development of BrDCTrackingModule
//
//  Revision 1.3  2000/09/29 02:15:59  hagel
//  Changes having to do with development of BrDCTrackingModule
//
//  Revision 1.2  2000/09/19 23:04:18  hagel
//  Changed BrDetectorVolume::GetPos to GetPosition
//
//  Revision 1.1  2000/09/19 21:10:55  hagel
//  Initial placeholder revision
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS