//*-- Author : Laura Fabbietti
//*-- Modified : 08/05/2000 L.Fabbietti
//*-- Modified : Oct. 2000 W. Koenig (reduced content of HRichPadSignal)
//*-- Modified : Tue Feb 12 16:54:10 CET 2002 teberl@ph.tum.de
//*--            introduced ctr flag to skip events
//_HADES_CLASS_DESCRIPTION 
///////////////////////////////////////////////////////
//______________________________________________________
//  HRichAnalysisSim
//  This class besides the Rich Analysis contains
//  the necessary functions to retrieve the parent track 
//  number corresponding to each pad that belongs to
//  a Ring structure.
//  The Ring Finding algorithm is executed by the class
//  HRichRingFindSim. This class contains 2 different
//  algorithms to find a ring, once a ring is found
//  the track numbers of the particles that have hit
//  the pads belonging to the ring structure are memorized
//  in an array. (Int_t *iRingTrack). 
//  Once all track numbers are collected, 
//  3 tracks number are saved ( HRichHitSim:track1....)
//  for each Hit with the corresponding weights (cfr. updateHits).
//  (The weight
//  is the number of pads a photon or a Ip has fired.)
//  A flag for each of the three track numbers is saved too,
//  to be able to distinguish between a Chrenkov photon
//  and a direct hit.  
//
//  use kSkip in the constructor to skip writing of 
//  event if no ring was found

//////////////////////////////////////////////////////

using namespace std;
#include "hrichanalysissim.h"
#include <iostream> 
#include <iomanip>
#include "hlocation.h"
#include "hades.h"
#include "hrichhitsim.h"
#include "hspectrometer.h"
#include "richdef.h"
#include "hevent.h"
#include "hiterator.h"
#include "hmatrixcategory.h"
#include "hlinearcategory.h"
#include "hrichringfindsim.h"
#include "hrichpadclean.h"
#include "hrichpadlabel.h"
#include "hrichcalsim.h"
#include "hrichtrack.h"
#include "hruntimedb.h"

ClassImp(HRichAnalysisSim)

 HRichAnalysisSim::HRichAnalysisSim(void){
 pRingFindSim = new HRichRingFindSim;
 
 cont = 0;
 secCount = 0;
 // pRings = NULL; // set by ringfinder
 pRichCalSim =  NULL;
}
 HRichAnalysisSim::HRichAnalysisSim(Text_t *name,Text_t *title, Bool_t kSkip)
                                  : HRichAnalysis(name, title, kSkip) {
 pRingFindSim = new HRichRingFindSim;
 kSkipEvtIfNoRing = kSkip;
 secCount = 0;
 pRichCalSim =  NULL;
}
 HRichAnalysisSim::~HRichAnalysisSim(void){

 if (pRingFindSim) delete pRingFindSim;
 pRingFindSim = NULL;

}
 Bool_t HRichAnalysisSim::init() {  

//allocate input/output categories

  
    HRichDetector *pRichDet = (HRichDetector*)gHades->getSetup()
	->getDetector("Rich");
    
    m_pCalCat=gHades->getCurrentEvent()->getCategory(catRichCal);
    if (!m_pCalCat) {
	m_pCalCat=pRichDet->buildMatrixCat("HRichCalSim",1);
	
	if (!m_pCalCat) return kFALSE;
	else gHades->getCurrentEvent()
                        ->addCategory(catRichCal, m_pCalCat, "Rich");
    }
    
    fIter = (HIterator*)m_pCalCat->MakeIterator();
    
     m_pHitCat=gHades->getCurrentEvent()->getCategory(catRichHit);
    if (!m_pHitCat) {
	
	// ????????????????????????????????????????????????????????????????????
	m_pHitCat=pRichDet->buildMatrixCat("HRichHitSim",1); //et why Matrix ?!
	// ????????????????????????????????????????????????????????????????????
	// why does it crash (in updateHits: getNewSlot)
	// when a Linear Cat is used ?
	// The structure is the same as for HRichHit and there a lin cat 
	// is used
	
	//cout<<"address of cat rich hit sim"<<m_pHitCat<<endl;
	
      if (!m_pHitCat) return kFALSE;
      else gHades->getCurrentEvent()
	       ->addCategory(catRichHit, m_pHitCat, "Rich");
    }
    
    m_pHitHdrCat=gHades->getCurrentEvent()->getCategory(catRichHitHdr);
    if (!m_pHitHdrCat) {
      m_pHitHdrCat=pRichDet->buildCategory(catRichHitHdr);

      if (!m_pHitHdrCat) return kFALSE;
      else gHades->getCurrentEvent()
                        ->addCategory(catRichHitHdr, m_pHitHdrCat, "Rich");
    }

    fIterHitHeader = (HIterator*)m_pHitHdrCat->MakeIterator("native");
    //cout << "Made IterHitHeader: " << fIterHitHeader << endl;

    m_pTrackCat = gHades->getCurrentEvent()->getCategory(catRichTrack);

     if (!m_pTrackCat) {
	 m_pTrackCat = pRichDet->buildCategory(catRichTrack);
	 if (!m_pTrackCat) return kFALSE;
	 else gHades->getCurrentEvent()->addCategory(catRichTrack,m_pTrackCat , "Rich");
     }
     
     HRuntimeDb* rtdb=gHades->getRuntimeDb();
     HRichAnalysisPar *pAnalysisPar = (HRichAnalysisPar*)rtdb->
	 getContainer("RichAnalysisParameters");
     if (pAnalysisPar == NULL) {
	 pAnalysisPar = new HRichAnalysisPar;
      rtdb->addContainer(pAnalysisPar);
     }
     setAnalysisPar(pAnalysisPar);
     if (pAnalysisPar == NULL) return kFALSE;
     
     HRichGeometryPar *pGeomPar = (HRichGeometryPar*)rtdb->
	 getContainer("RichGeometryParameters");
     
     if (pGeomPar == NULL) {
	 pGeomPar = new HRichGeometryPar;
	 rtdb->addContainer(pGeomPar);
     }
     setGeomPar(pGeomPar);
     if (pGeomPar == NULL) return kFALSE;
     if (initParameters() == kFALSE) return kFALSE;
     pPadClean->init();

     return kTRUE;
     
}
 Bool_t HRichAnalysisSim::initParameters() {

//allocate non event by event classes
       HRichGeometryPar *pGeomPar = getGeometryPar();                                  
    
    iRingNrTot=0;
    allPairNrTot=0;
    sectorPairNrTot=0;
    maxFiredTotalPads = 3000; // upper limit of number of fired pads
    maxFiredSectorPads =1000; // hardwired, needs to be set by an access function
    
    maxCols = pGeomPar->getColumns();
    maxRows = pGeomPar->getRows();
    //  maxPads = ((HRichGeometryPar*)fpGeomPar)->getPadsNr();
    if(pLeftBorder) delete [] pLeftBorder;
    pLeftBorder = new short[maxRows];
    if(pRightBorder) delete [] pRightBorder;
    pRightBorder = new short[maxRows];
    
    for (int row=0;row<maxRows;++row) {
    Int_t col=0;
    Int_t padOffset = row*maxCols;
    while(!pGeomPar->fPads.getPad(col+padOffset)->getPadActive() && col<maxCols) ++col;
    if(col==maxCols) {
      maxRows=row;
      break;
    }
    pLeftBorder[row]=col;
    while(pGeomPar->fPads.getPad(col+padOffset)->getPadActive() && col<maxCols) ++col;
    pRightBorder[row]=col-1;
    }
    maxPads=maxRows*maxCols;
    
    
    // now creating pads array
    
    Int_t i;
    Int_t j;
    if (pPads) {
     for (j = 0; j < 6; j++) delete[] pPads[j];
    } else {
     pPads = new HRichPadSignal * [6];
    }
    for (j = 0; j < 6; j++) {
     pSectorPads = pPads[j] = new HRichPadSignal[maxPads];
     for (i = 0; i < maxPads; pSectorPads[i++].clear());
    }
    pSectorPads=pPads[iActiveSector];
    
    return kTRUE;
}
 Bool_t HRichAnalysisSim::reinit() {
       initParameters();

    pRingFindSim->init(this);


    iPadActive.Set(maxCols*maxRows);
    for (int i=0 ; i<maxCols*maxRows; i++)
     if (((HRichGeometryPar*)fpGeomPar)->getPadsPar()->getPad(i)->getPadActive() >0)
        iPadActive[i] = 1; else iPadActive[i] = 0;

  Int_t i,j,k,m,n;

    Int_t iMatrixSurface=0, iPartSurface=0;
    Int_t iMaskSize = ((HRichAnalysisPar*)fpAnalysisPar)->iRingMaskSize;
    Int_t iMaskSizeSquared = iMaskSize*iMaskSize;
    for (k = 0; k < iMaskSizeSquared; k++)
     if (((HRichAnalysisPar*)fpAnalysisPar)->iRingMask[k] == 1) iMatrixSurface++;


      for (j = 0; j < maxRows; j++)
       for (i = 0; i < maxCols; i++)   {
        iPartSurface = 0;
        for (k = 0; k < iMaskSizeSquared; k++) {
         m = (k % iMaskSize) - iMaskSize/2;
         n = (k / iMaskSize) - iMaskSize/2;
         if (!IsOut(i,j,m,n))
          if (((HRichAnalysisPar*)fpAnalysisPar)->iRingMask[k] == 1) iPartSurface++;
        }
        ((HRichGeometryPar*)fpGeomPar)->getPadsPar()->
          getPad(i,j)->setAmplitFraction((Float_t)iPartSurface/(Float_t)iMatrixSurface);
      }


 return kTRUE;
}
 Int_t  HRichAnalysisSim::getPadsNTrack1(Int_t padx, Int_t pady,Int_t sec){
    //     This function returns for each pad the corresponding
    //     NTrack1 value (cfr. HRichCalSim, HRichDigitizer::execute).
    //     All track numbers are stored during digitization  in the
    //     catRichTrack Linear Category.
    //     NTrack1 is the index in the Track array corresponding to the
    //     first track for each pad.  

    //     This function is called from HRichRingFindSim::CalcRingParamters.

 HLocation loc1;
 loc1.set(3, sec, pady, padx);


 pRichCalSim = (HRichCalSim*)((HMatrixCategory*)getCalCat())->getObject(loc1);
 if (pRichCalSim) return pRichCalSim->getNTrack1();   
 return 0;
}
//----------------------------------------------------------------------------
 Int_t  HRichAnalysisSim::getPadsNTrack2(){

    //   This functions returns NTrack2, which is the index in 
    //   the Track Array corresponding to the last track for each pad.
    //   Pad must be identified by calling getPadsNTrack1(...) first. 

 if (pRichCalSim) return pRichCalSim->getNTrack2();
 return 0;
}
//----------------------------------------------------------------------------
 Int_t HRichAnalysisSim::getFlag(Int_t index) {
    //  it is called from HRichRingFindSim::LookForTrack().
     //  This function returns the flag contained in the
   //  catRichTrack container at the position index.
  // This flag is 0 for Chrenkov photons and 1 for IP.

    HRichTrack *t = (HRichTrack*)((HLinearCategory*)m_pTrackCat)->getObject(index);
    Int_t i = -1;
    if (t) i=t->getFlag();
    return  i;
}
 
//----------------------------------------------------------------------------
 Int_t HRichAnalysisSim::getTrack(Int_t index) {
    //  This function returns the track number contained in the
    //  catRichTrack container at the position index.

    HRichTrack *trk = ((HRichTrack*)((HLinearCategory*)m_pTrackCat)
		       ->getObject(index));
    Int_t track=-1;
    if(trk)  track=trk->getTrack();
    return track;

}
 
//----------------------------------------------------------------------------
 Int_t HRichAnalysisSim::execute() {
 
       // count total nb of rings in event
  Int_t iRingNrTotEvt;
  iRingNrTotEvt = 0;

 HRichCal *pCal;
  Int_t i, j, ampl;
  Int_t sec, padnr;
  
  Reset();
//cout << "In execute after reset" << endl;
  for (i = 0; i < 6; i++) {
   if (fPadFired[i] > 0) {
    fPadFired[i] = 0;
    HRichPadSignal * pSecPads=pPads[i];
    for (j = 0; j < maxPads; pSecPads[j++].clear());
   }
  }

  fIter->Reset();
  //cout << "In execute after iter->reset" << endl;
  while((pCal = (HRichCal *)fIter->Next())) {
      
    if ( (ampl = (Int_t)pCal->getCharge()) > 0){
	  sec = pCal->getSector();
	  fPadFired[sec]++;
	  padnr = pCal->getCol() + pCal->getRow()*maxCols;
	  pPads[sec][padnr].setAmplitude(ampl);  
     
   }
  }
  //cout << "In execute after setamplitude" << endl;
  iEventNr++;
  // if ( iEventNr%1000==0)   cout << "Next rich event goes... " << iEventNr << endl;

  Int_t fPadFiredTot=0;
  for(i=6;i--;fPadFiredTot+=fPadFired[i]);
  if(fPadFiredTot >  maxFiredTotalPads) return 0;
  for (i=0; i<6; i++)
      if (fPadFired[i] >= maxFiredSectorPads) {
	  Warning("execute","To many fired pads in sector %i. %i/%i",i,fPadFired[i],maxFiredSectorPads);
	  return 0;
      }
  // **************************************************************
  // ------- loop over sectors --- begin ---
  //cout << "In execute before sector loop" << endl;
  for(secCount = 0; secCount < 6; secCount++) 
      if (((HRichGeometryPar*)fpGeomPar)->getSector(secCount) > 0) {
	  
	  Reset();
	  SetActiveSector(secCount);
	  iPadFiredNr = fPadFired[secCount];
	 
	  
	  //cout << "calling padclean" << endl;
	  iPadCleanedNr=pPadClean->Execute(this);
	  iLabelNr=pPadLabel->Execute(this);
	  //cout << "In execute after padlabel->execute" << endl;
	  if (((HRichAnalysisPar*)fpAnalysisPar)->isActiveLabelPads == 0) {
	    iLabelNr = 1;
	    pLabelArea = new HRichLabel[1];
	    pLabelArea[0].iLeftX = 0;
	    pLabelArea[0].iRightX = maxCols;
	    pLabelArea[0].iLowerY = 0;
	    pLabelArea[0].iUpperY = maxRows;
	    pLabelArea[0].iLabeledPadsNr = maxPads;
	    pLabelArea[0].iFiredPadsNr = iPadFiredNr;
	    pLabelArea[0].iSignature = 0;
	  }
	  
	  iRingNr=pRingFindSim->Execute(this);
	  //cout << "In execute after ringfinder" << endl;
	  iRingNrTot+=iRingNr;
	  // increment total nb of rings in evt
	  iRingNrTotEvt+=iRingNr;
	  //cout << "In execute before header update" << endl;
	  updateHeaders(secCount, iEventNr);
	  updateHits(secCount);
	  //cout << "In execute after hit update" << endl;
      }
  // ------- loop over sectors --- end ---
  // modification to skip event which does not contain any ring
  if (kSkipEvtIfNoRing && iRingNrTotEvt==0) return kSkipEvent;
  
  return 0;
  
}

 void HRichAnalysisSim::updateHits(Int_t nSec) {
    // Each Hit is stored, in addition to real data for simulated one
    // the tracks number corresponding to each ring are stored too.
    // Maximal 3 tracks are stored for each ring.
   HRichHitSim *hit=NULL;
  for (int i = 0; i < iRingNr; i++) {

      loc.set(1, nSec);


  

      hit=(HRichHitSim *)m_pHitCat->getNewSlot(loc,NULL);
      if (hit!=NULL) {
        hit=new(hit) HRichHitSim;

	HRichHitSim & ring = pRings[i];
 
        *hit = ring;
        hit->setSector(nSec);

        HRichPad * pad = ((HRichGeometryPar*)fpGeomPar)->getPadsPar()->
                         getPad(ring.iRingX,ring.iRingY);
	if(pad){
	  hit->setTheta(pad-> getTheta() );
	  hit->setPhi(pad->getPhi(nSec));
	}
	else {
	  hit->fPhi = -10;
	  hit->fTheta = -10;
	}
        Int_t k = 0;
        while(ring.iRingTrack[k]){
	  
	  if (hit->track1==0) {
	    hit->track1 = ring.iRingTrack[k];
	    hit->flag1 =  ring.iRingFlag[k];
	    (hit->weigTrack1)++;
	  } else{
	    if(ring.iRingTrack[k]== hit->track1){
	      (hit->weigTrack1)++;

	    } else {
	      if(hit->track2==0) {
		hit->track2 = ring.iRingTrack[k];
		hit->flag2 =  ring.iRingFlag[k];
		(hit->weigTrack2)++;
	      } else{
		if(ring.iRingTrack[k]== hit->track2){
		  (hit->weigTrack2)++;

		} else {
		  if (hit->track3==0) {
		    hit->track3 = ring.iRingTrack[k];
		    hit->flag3 =  ring.iRingFlag[k];
		    (hit->weigTrack3)++;
		  }
		  else (hit->weigTrack3)++;
		}
	      }
	    }  
	  }
	  k++;
	
        }//end loop on track array
	
	//if(hit->track1==0) Error("updateHits(Int_t nSec)","rich hit contains no GEANT track nb information");
      }
      
  }//end loop on rings
            
}
      

















ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.