#include "hgeantmdc.h"
#include "hgeantkine.h"
#include "hmdcdigitizer.h"
#include "hmdcdef.h"
#include "hdebug.h"
#include "hades.h"
#include "hmdcgeantcell.h"
#include "hmdccal1sim.h"
#include "hiterator.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hmdcdetector.h"
#include "hevent.h"
#include "hcategory.h"
#include "hlocation.h"
#include "hmdclayergeompar.h"
#include "hmdcdigitpar.h"
#include "hmdccal2parsim.h"
#include "hmdccelleff.h"
#include "hmdcwirestat.h"
#include "hmessagemgr.h"
#include "hmdcsizescells.h"
#include "hmdcdedx2.h"
#include "hmdctimecut.h"
#include "hmdcgeomstruct.h"
#include "TMath.h"
#include "TFile.h"
#include "TGraph.h"
#include <iostream>
#include <iomanip>
#include <iomanip>
#include <map>
using namespace std;
Float_t HMdcDigitizer::dTime [NMAXHITS]              = {0.};
Float_t HMdcDigitizer::dTime2[NMAXHITS]              = {0.};
Float_t HMdcDigitizer::dTimeErr [NMAXHITS]           = {0.};
Float_t HMdcDigitizer::dTime2Err[NMAXHITS]           = {0.};
Float_t HMdcDigitizer::minimumdist[NMAXHITS]         = {0.};
Int_t   HMdcDigitizer::track[NMAXHITS]               = {-99};
Float_t HMdcDigitizer::timeOfFlight[NMAXHITS]        = {0.};
Float_t HMdcDigitizer::angle[NMAXHITS]               = {0.};
Int_t   HMdcDigitizer::statusflag[NMAXHITS]          = {0};
Float_t HMdcDigitizer::fractionOfmaxCharge[NMAXHITS] = {0};
Bool_t  HMdcDigitizer::cutEdge[NMAXHITS]             = {kFALSE};
Float_t HMdcDigitizer::wireOffset[NMAXHITS]          = {0.};
Float_t HMdcDigitizer::efficiency[NMAXHITS]          = {0.};
Float_t HMdcDigitizer::theta[NMAXHITS]               = {0.};
HMdcDigitizer::HMdcDigitizer(void)
{
    initVariables();
}
HMdcDigitizer::HMdcDigitizer(const Text_t *name,const Text_t *title):
HReconstructor(name,title)
{
    initVariables();
}
HMdcDigitizer::HMdcDigitizer(const Text_t *name,const Text_t *title,Int_t TDCMODE,Bool_t NTUPLE) :
HReconstructor(name,title)
{
    
    
    
    
    
    
    initVariables();
    setTdcMode(TDCMODE);
    setNTuple(NTUPLE);
}
HMdcDigitizer::~HMdcDigitizer(void) {
  
  if(iterin)   delete iterin;
  if(itercell) delete itercell;
  if(itercal1) delete itercal1;
}
void HMdcDigitizer::setOffsets(Float_t off0,Float_t off1,Float_t off2,Float_t off3,Int_t on_off)
{
    
    
    
    if(on_off == 1)
    {
	useOffsets = kTRUE;
    }
    else
    {
	useOffsets = kFALSE;
    }
    offsets[0] = off0;
    offsets[1] = off1;
    offsets[2] = off2;
    offsets[3] = off3;
}
void HMdcDigitizer::setEffLevel(Float_t eff0,Float_t eff1,Float_t eff2,Float_t eff3,Int_t on_off)
{
    
    
    if(on_off == 1)
    {
	useCellEff = kTRUE;
    }
    else
    {
	useCellEff = kFALSE;
    }
    effLevel[0] = eff0;
    effLevel[1] = eff1;
    effLevel[2] = eff2;
    effLevel[3] = eff3;
}
void HMdcDigitizer::setNoiseLevel(Float_t noise0,Float_t noise1,Float_t noise2,Float_t noise3,Int_t on_off)
{
    
    
    if(on_off == 1)
    {
	useNoise = kTRUE;
    }
    else
    {
	useNoise = kFALSE;
    }
    noiseLevel[0] = noise0 * 0.01;
    noiseLevel[1] = noise1 * 0.01;
    noiseLevel[2] = noise2 * 0.01;
    noiseLevel[3] = noise3 * 0.01;
}
void HMdcDigitizer::setNoiseRange(Int_t rangeLo0,Int_t rangeLo1,Int_t rangeLo2,Int_t rangeLo3,
				  Int_t rangeHi0,Int_t rangeHi1,Int_t rangeHi2,Int_t rangeHi3)
{
    
    noiseRangeLo[0] = rangeLo0;
    noiseRangeLo[1] = rangeLo1;
    noiseRangeLo[2] = rangeLo2;
    noiseRangeLo[3] = rangeLo3;
    noiseRangeHi[0] = rangeHi0;
    noiseRangeHi[1] = rangeHi1;
    noiseRangeHi[2] = rangeHi2;
    noiseRangeHi[3] = rangeHi3;
}
void HMdcDigitizer::setScalerTime1Err(Float_t m0,Float_t m1,Float_t m2,Float_t m3)
{
    
    scaleError[0] = m0;
    scaleError[1] = m1;
    scaleError[2] = m2;
    scaleError[3] = m3;
}
void HMdcDigitizer::initVariables()
{
    
    fbetadEdx     = HMdcDeDx2::energyLossGraph(14,0.6,"beta");
    fBetaLow      = 0.7;
    useDeDxScaling= kTRUE;
    useDeDxTimeScaling = kTRUE;
    fGeantCellCat = 0;
    fCalCat       = 0;
    fDigitGeomPar = 0;
    fDigitPar     = 0;
    fCal2ParSim   = 0;
    fCellEff      = 0;
    fWireStat     = 0;
    fTimeCut      = 0;
    fsizescells   = 0;
    fdEdX         = 0;
    fCal          = 0;
    fCalnoise     = 0;
    fCell         = 0;
    iterin        = 0;
    itercell      = 0;
    itercal1      = 0;
    fEventId      = 0;
    pi = acos(-1.)/180;
    time1         = 0;
    time1Error    = 0;
    time2         = 0;
    time2Error    = 0;
    setTdcMode(2);
    setEffLevel  (90 ,90 ,90 ,90);
    setNoiseLevel(5. ,5. ,5. ,5.);
    setOffsets   (1.5,2.5,4.5,5.5);
    setOffsetsUse   (kFALSE);
    setCellEffUse   (kTRUE);
    setWireStatUse  (kFALSE);
    setWireStatEffUse(kTRUE);
    setLayerThicknessEffUse(kTRUE);
    setWireStatOffsetUse(kTRUE);
    setNoiseUse     (kFALSE);
    setTofUse       (kTRUE);
    setErrorUse     (kTRUE);
    setWireOffsetUse(kTRUE);
    setDeDxUse      (kTRUE);
    setTimeCutUse   (kFALSE);
    setNTuple       (kFALSE);
    hasPrinted = kFALSE;
    setTime1Noise(0.);
    setTime2Noise(0.);
    resetListVariables();
    setNoiseMode(1);
    for(Int_t i = 0; i < 5; i ++)
    {
	arrayNoise[i] = 0;
    }
    setNoiseRange(-500,-500,-500,-500,
		  1500,1500,1500,1500);
    setNoiseBandWidth(20.);
    setNoiseWhiteWidth(500.);
    setNoiseWhiteRatio(0.1);
    setEmbeddingMode(1);
    setSignalSpeed(0.004);
    for(Int_t i = 0; i < 4; i ++)
    {
	scaleError[i] = 1.;
	scaleErrorMIPS[i] = 1.;
    }
    for(Int_t s = 0; s < 6; s ++){
        for(Int_t m = 0; m < 4; m ++){
            for(Int_t l = 0; l < 6; l ++){
                for(Int_t c = 0; c < 220; c ++){
                    rndmoffsets[s][m][l][c] = 0.0;
                }
            }
        }
    }
    setCreateOffsets(kFALSE);
    offsetsCreated  = kFALSE;
    setSigmaOffsets(2.0);
    setScaleTime(1.0);
    vLayEff.reserve(500);
    setDeltaElectronUse(kTRUE,kFALSE,109,-950.,400.,20.,2.);
    setDeltaElectronMinMomCut(2.,2.,4.5,2.,2.,4.5);
}
void HMdcDigitizer::setParContainers() {
    
    
    fDigitGeomPar = (HMdcLayerGeomPar*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcLayerGeomPar"));
    if(!fDigitGeomPar)
    {
	Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCLAYERGEOMPAR RECIEVED!");
	exit(1);
    }
    fDigitPar = (HMdcDigitPar*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcDigitPar"));
    if(!fDigitPar)
    {
	Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCDIGITPAR RECIEVED!");
	exit(1);
    }
    fCal2ParSim  = (HMdcCal2ParSim*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcCal2ParSim"));
    if(!fCal2ParSim)
    {
	Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCCAL2PARSIM RECIEVED!");
	exit(1);
    }
    geomstruct = (HMdcGeomStruct*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcGeomStruct"));
    if(!geomstruct)
    {
	Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCGEOMSTRUCT RECIEVED!");
	exit(1);
    }
    if(getCellEffUse())
    {
	fCellEff = (HMdcCellEff*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcCellEff"));
	if(!fCellEff)
	{
	    Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCCELLEFF RECIEVED!");
	    exit(1);
	}
    }
    if(getWireStatUse())
    {
	fWireStat = (HMdcWireStat*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcWireStat"));
	if(!fWireStat)
	{
	    Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCWIRESTAT RECIEVED!");
	    exit(1);
	}
    }
    fsizescells = (HMdcSizesCells*)HMdcSizesCells::getObject();
    if(!fsizescells)
    {
	Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCSIZESCELLS RECIEVED!");
	exit(1);
    }
    if(getDeDxUse())
    {
	fdEdX = (HMdcDeDx2*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcDeDx2"));
	if(!fdEdX)
	{
	    Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCDEDX2 RECIEVED!");
	    exit(1);
	}
    }
    if(getTimeCutUse() )
    {
        fTimeCut = (HMdcTimeCut*) gHades->getRuntimeDb()->getContainer("MdcTimeCut");
    }
}
void HMdcDigitizer::setNTuples(void) {
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    myoutput->cd();
    distance_time = new TNtuple("cal2sim", "cal2sim", "sec:mod:lay:cell:dist:angle:time1:time1Err:time2:time2Err:tof:cutEdge:status:track:eff");
}
Bool_t HMdcDigitizer::init(void) {
    
    
    
    
    setParContainers();
    getMdcSetup();
    fGeantMdcCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcGeantRaw));
    if(!fGeantMdcCat) {
	Error("HMdcDigitizer::init()","HGeant MDC input missing");
	return kFALSE;
    }
    iterin = (HIterator*)((HCategory*)fGeantMdcCat)->MakeIterator("native");
    fGeantKineCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catGeantKine));
    if(!fGeantKineCat) {
	Error("HMdcDigitizer::init()","HGeant Kine input missing");
	return kFALSE;
    }
    fGeantCellCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcGeantCell));
    if (!fGeantCellCat) {
	fGeantCellCat = (HCategory*)((HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"))->buildCategory(catMdcGeantCell));
	if (!fGeantCellCat) return kFALSE;
	else ((HEvent*)(gHades->getCurrentEvent()))->addCategory(catMdcGeantCell,fGeantCellCat,"Mdc");
    }
    fGeantCellCat->setPersistency(kFALSE);   
    itercell = (HIterator*)((HCategory*)fGeantCellCat)->MakeIterator("native");
    fCalCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcCal1));
    if (!fCalCat) {
	HMdcDetector* mdc = (HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"));
	fCalCat = (HCategory*)(((HMdcDetector*)mdc)->buildMatrixCategory("HMdcCal1Sim",0.5F));
	if (!fCalCat) return kFALSE;
	else ((HEvent*)(gHades->getCurrentEvent()))->addCategory(catMdcCal1,fCalCat,"Mdc");
        itercal1 = (HIterator*)fCalCat->MakeIterator("native");
    } else {
	itercal1 = (HIterator*)fCalCat->MakeIterator("native");
	if (fCalCat->getClass() != HMdcCal1Sim::Class()) {
	    Error("HMdcDigitizer::init()","Misconfigured output category");
	    return kFALSE;
	}
    }
    if(getNTuple())
    {
	
	myoutput = new TFile("digitizer.root","RECREATE");
	myoutput->cd();
	setNTuples();
    }
    return kTRUE;
}
Bool_t HMdcDigitizer::reinit(void)
{
    
    
    if(fWireStat && useWireStatOffset && !offsetsCreated) {
	memset(&rndmoffsets[0][0][0][0],0, sizeof(Float_t) * 6 * 4 * 6 * 220);
	for(Int_t s = 0;s < 6; s ++){
	    for(Int_t m = 0; m < 4; m ++){
		for(Int_t l = 0; l < 6; l ++){
		    for(Int_t c = 0; c < 220; c ++){
			rndmoffsets[s][m][l][c] = fWireStat->getOffset(s,m,l,c);
		    }
		}
	    }
	}
    } else {
	if(!offsetsCreated) memset(&rndmoffsets[0][0][0][0],0, sizeof(Float_t) * 6 * 4 * 6 * 220);
    }
    fBetaLow = fDigitPar->getCellScale();
    for(Int_t m = 0; m < 4; m ++){
        scaleError[m]     = fDigitPar->getTime1ErrScale(m);
        scaleErrorMIPS[m] = fDigitPar->getTime1ErrScaleMIPS(m);
    }
    Bool_t result = kFALSE;
    setSignalSpeed(fDigitPar->getSignalSpeed());
    result = fsizescells->initContainer();
    if(result){
        
	for(Int_t s = 0;s < 6; s ++){
	    for(Int_t m = 0; m < 4; m ++){
		for(Int_t l = 0; l < 6; l ++){
		    layEff.cmin[s][m][l] =-1;
		    layEff.cmax[s][m][l] =-1;
		    layEff.Lmax[s][m][l] =-1;
		    layEff.Lmin[s][m][l] =-1;
		}
	    }
	}
	const HGeomVector& p4 = fsizescells->getTargetMiddlePoint();  
	for(Int_t s = 0;s < 6; s ++){
	    for(Int_t m = 0; m < 4; m ++){
               if(!fsizescells->modStatus(s,m)) continue;
		for(Int_t l = 0; l < 6; l ++){
		    layEff.cmax[s][m][l] = (*fsizescells)  [s][m][l].getNCells()-1;
		    layEff.cmin[s][m][l] = (*fDigitGeomPar)[s][m][l].getCentralWireNr();  
                     
		    Int_t c = layEff.cmax[s][m][l];
		    {
			const HGeomVector& p1 = *(*fsizescells)[s][m][l][c].getWirePoint(0);
			const HGeomVector& p2 = *(*fsizescells)[s][m][l][c].getWirePoint(1);
			HGeomVector tmp =  p2+p1;
			tmp*=0.5;
			HGeomVector p3  =  tmp;    
			HMdcSizesCellsLayer &sizesCellsLayer = (*fsizescells)[s][m][l];
			Int_t firstCell,lastCell;
			Float_t firstCellPath,midCellPath,lastCellPath;
			Int_t ncells=0;
			if(sizesCellsLayer.calcCrossedCells(p4.getX(),p4.getY(),p4.getZ(),
							    p3.getX(),p3.getY(),p3.getZ(),
							    firstCell,lastCell,
							    firstCellPath,midCellPath,lastCellPath))
			{
			    ncells = 1;
			    ncells += lastCell-firstCell;
			    Float_t totalePathInLayer = 0.;
			    for(Int_t cell=firstCell;cell<=lastCell;++cell) {
				Float_t cellPath;
				if      (cell == firstCell) { cellPath = firstCellPath;}
				else if (cell == lastCell)  { cellPath = lastCellPath; }
				else                        { cellPath = midCellPath;  }
				totalePathInLayer += cellPath;
			    }
			    layEff.Lmax[s][m][l]  = totalePathInLayer ;
			}
		    }
		    c = layEff.cmin[s][m][l];
		    {
			const HGeomVector& p1 = *(*fsizescells)[s][m][l][c].getWirePoint(0);
			const HGeomVector& p2 = *(*fsizescells)[s][m][l][c].getWirePoint(1);
			HGeomVector tmp =  p2+p1;
			tmp*=0.5;
			HGeomVector p3  =  tmp;    
			HMdcSizesCellsLayer &sizesCellsLayer = (*fsizescells)[s][m][l];
			Int_t firstCell,lastCell;
			Float_t firstCellPath,midCellPath,lastCellPath;
			Int_t ncells=0;
			if(sizesCellsLayer.calcCrossedCells(p4.getX(),p4.getY(),p4.getZ(),
							    p3.getX(),p3.getY(),p3.getZ(),
							    firstCell,lastCell,
							    firstCellPath,midCellPath,lastCellPath))
			{
			    ncells = 1;
			    ncells += lastCell-firstCell;
			    Float_t totalePathInLayer = 0.;
			    for(Int_t cell=firstCell;cell<=lastCell;++cell) {
				Float_t cellPath;
				if      (cell == firstCell) { cellPath = firstCellPath;}
				else if (cell == lastCell)  { cellPath = lastCellPath; }
				else                        { cellPath = midCellPath;  }
				totalePathInLayer += cellPath;
			    }
			    layEff.Lmin[s][m][l]  = totalePathInLayer ;
			}
		    }
		} 
	    } 
	} 
    }
    printStatus();
    return result;
}
void HMdcDigitizer::printStatus()
{
    
    
  SEPERATOR_msg("*",60);
  INFO_msg(10,HMessageMgr::DET_MDC,"DEFAULT SETTINGS");
  SEPERATOR_msg("-",60);
  INFO_msg(10,HMessageMgr::DET_MDC,"Options input 1 (default)      two leading edges");
  INFO_msg(10,HMessageMgr::DET_MDC,"              2                leading and trailing edge");
  INFO_msg(10,HMessageMgr::DET_MDC,"NTuple        kFALSE (default) no NTuple filled");
  INFO_msg(10,HMessageMgr::DET_MDC,"              kTRUE            NTuple in digitizer.root filled");
  INFO_msg(10,HMessageMgr::DET_MDC,"Use Offsets   kFALSE (default)");
  INFO_msg(10,HMessageMgr::DET_MDC,"Use Tof       kTRUE  (default) cal1sim = drift time + tof");
  INFO_msg(10,HMessageMgr::DET_MDC,"Use Cell Eff  kFALSE (default)");
  INFO_msg(10,HMessageMgr::DET_MDC,"Use Noise     kFALSE (default)");
  INFO_msg(10,HMessageMgr::DET_MDC,"Noise mode    1 (default) GEANT hits will be replaced by noise");
  SEPERATOR_msg("-",60);
  INFO_msg(10,HMessageMgr::DET_MDC,"ACTUAL CONFIGURATION");
  SEPERATOR_msg("*",60);
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName(),"HMdcDigiSetup:");
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"tdcModeDigi       =  %i :  1 = two leading edges, 2 = leading and trailing edge",getTdcMode());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"NtupleDigi        =  %i :  0 = noNtuple, 1 = digitizer.root",(Int_t)getNTuple());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useTofDigi        =  %i :  0 = NoTof in cal1, 1 = Tof in cal1 \n",(Int_t)getTofUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useErrorDigi      =  %i :  0 = NoErr in cal1, 1 = Err in cal1 \n",(Int_t)getErrorUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useWireOffsetDigi =  %i :  1 = add wireOffset to drift time, 0 = don't add wireOffsets"
			 , getWireOffsetUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useWireStatDigi   =  %i :  1 = use wirestat container, 0 = don't use wirestat container"
			 , getWireStatUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useWireStatEff    =  %i :  1 = use eff from wirestat container"
			 , getWireStatEffUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useWireStatOffset =  %i :  1 = use offsets from wirestat container"
			 , getWireStatOffsetUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"useTimeCut        =  %i :  1 = use time cut container, 0 = don't use time cut container"
			 , (Int_t)getTimeCutUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"offsetsOnDigi     =  %i :  0 = global offsets off, 1 = global offsets on",(Int_t)getOffsetsUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"offsetsDigi       = %4.1f  %4.1f   %4.1f  %4.1f ns offset per plane (substracted from (drift time + tof))\n"
			 ,getOffset(0),getOffset(1),getOffset(2),getOffset(3));
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseModeDigi     =  %i :  1 = override geant by noise, 2 = keep geant cells",getNoiseMode());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseOnDigi       =  %i :  0 = noise off, 1 = noise on",(Int_t)getNoiseUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseLevelDigi    = %4.1f%% %4.1f%%  %4.1f%% %4.1f%% noise level per plane"
			 ,100*getNoiseLevel(0),100*getNoiseLevel(1),100*getNoiseLevel(2),100*getNoiseLevel(3));
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseRangeDigi    =%5i %5i %5i %5i %5i %5i %5i %5i ns lower/upper limit of noise"
			 ,getNoiseRangeLo(0),getNoiseRangeLo(1),getNoiseRangeLo(2),getNoiseRangeLo(3)
			 ,getNoiseRangeHi(0),getNoiseRangeHi(1),getNoiseRangeHi(2),getNoiseRangeHi(3));
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseBandWidth    =  %5.1f ns : width of the t2-t1 noise band",getNoiseBandWidth());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseWhiteWidth   =  %5.1f ns : width of the t2-t1 white noise region",getNoiseWhiteWidth());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"noiseWhiteRatio   =  %5.1f    : ratio between t2-t1 band/white noise\n",getNoiseWhiteRatio());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"cellEffOnDigi     =  %i :  0 = cellEff off, 1 = cellEff",(Int_t)getCellEffUse());
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"cellEffDigi       =  %4.1f%% %4.1f%%  %4.1f%% %4.1f%% level of cellEff per plane"
			 ,getCellEffLevel(0),getCellEffLevel(1),getCellEffLevel(2),getCellEffLevel(3));
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"fBetaLow          =  %f :  onset scaling point for LayerEff,CellEff,time1Err with dEdx"
			 , fBetaLow);
 gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"scaleTime1Err     =  %5.4f %5.4f %5.4f %5.4f input scaling for t1 err"
			 ,scaleError[0],scaleError[1],scaleError[2],scaleError[3]);
  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
			 ,"scaleTime1ErrMIPS =  %5.4f %5.4f %5.4f %5.4f scaling for t1 err for MIPS"
			 ,scaleErrorMIPS[0],scaleErrorMIPS[1],scaleErrorMIPS[2],scaleErrorMIPS[3]);
  hasPrinted=kTRUE;
}
Bool_t HMdcDigitizer::finalize(void)
{
    
    if(getNTuple())
    {
        
	myoutput->cd();
	distance_time->Write();
	myoutput->Save();
	myoutput->Close();
    }
    return kTRUE;
}
Int_t HMdcDigitizer::execute(void) {
    
    
    
    
    
    
    
  Float_t xcoord, ycoord, tof, theta, phi, ptot;
  Int_t trkNum;
  myalpha = 0;
  HGeantMdc* fGeant;
  loc.set(4,0,0,0,0);   
  vLayEff.clear();
  
  
  
  if(getEmbeddingMode() > 0)
  {
      if(gHades->getEmbeddingDebug() == 1)   fCalCat->Clear();
      itercal1->Reset();
      while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
      {
	  fCal->setNTrack1(gHades->getEmbeddingRealTrackId());
	  fCal->setNTrack2(gHades->getEmbeddingRealTrackId());
          fCal->setStatus1(3);
          fCal->setStatus2(3);
	  fCal->resetTrackList(-99); 
          fCal->setTrackList(0,gHades->getEmbeddingRealTrackId());  
	  fCal->resetStatusList(0);  
          fCal->setStatusList(0,3);  
      }
  }
  
  
  
  if(useDeltaElectrons)
  {
      mDeltaTrackT0.clear();
      if(fGeantKineCat){
	  Int_t nKine = fGeantKineCat->getEntries();
	  for(Int_t i=0;i<nKine;i++){
	      HGeantKine* kine =  (HGeantKine*)fGeantKineCat-> getObject(i);
	      Float_t mom = kine->getTotalMomentum() ;
              Int_t generator = kine->getGeneratorInfo();
	      if(kine->getParentTrack() == 0 &&
		 (kine->getID() == ionID ||                                                    
		  ( useDeltaMomSelection && kine->getID() == 3 && mom < momMaxDeltaElecCut) || 
		  (!useDeltaMomSelection && kine->getID() == 3 && generator ==-3 )             
		 )
		)
	      {
		  Float_t t0offset = gRandom->Rndm()* (t1maxDeltaElec-t1minDeltaElec) + t1minDeltaElec;
		  mDeltaTrackT0[kine] = t0offset;
	      }
	  }
      }
  }
  
  iterin->Reset();
  while((fGeant = (HGeantMdc*)iterin->Next()) != NULL) {
      loc[0] = (Int_t)(fGeant->getSector());
      loc[1] = (Int_t)(fGeant->getModule());
      if(!testMdcSetup(loc[0],loc[1]) ) continue; 
      loc[2] = (Int_t)(fGeant->getLayer());
      
      fGeant->getHit(xcoord, ycoord, tof, ptot);
      fGeant->getIncidence(theta, phi);
      trkNum = fGeant->getTrack();
      
      
      Bool_t isDelta      = kFALSE;
      Float_t mom         = 0;
      Int_t   generator   = 0;
      HGeantKine* primary = HGeantKine::getPrimary(trkNum,(HLinearCategory*)fGeantKineCat);
      if(primary) { 
	  mom       = primary->getTotalMomentum() ;
	  generator = primary->getGeneratorInfo();
	  if( primary->getID() == ionID ||                                                    
	     ( useDeltaMomSelection && primary->getID() == 3 && mom <momMaxDeltaElecCut)  ||  
	     (!useDeltaMomSelection && primary->getID() == 3 && generator ==-3 )              
	    ) isDelta = kTRUE;
      } else {
         Error("execute()","No primary for trk = %i found!",trkNum);
      }
      
      
      
      if(useDeltaElectrons)
      {
	  if(isDelta)
	  {
	      Float_t t0offset = 0;
	      itDelta = mDeltaTrackT0.find(primary);
	      if(itDelta != mDeltaTrackT0.end()) t0offset = itDelta->second;
	      else {
		  Error("execute()","No primary in delta map for trk = %i found! Should not happen!",trkNum);
		  primary->print();
	      }
	      if(mom < momMinDeltaCut[loc[0]]) continue;
	      if(fProbDeltaAccepted<1){
		  if(gRandom->Rndm() < fProbDeltaAccepted) continue; 
	      }
	      tof+=t0offset;
	      fGeant->setHit(xcoord, ycoord, tof, ptot);  
	  }
      } else { 
	  if(isDelta) continue;
      }
      
      if(loc[2]<6)
      {
          Int_t ind = findTrack(trkNum);
	  if(ind == -1) {  
	      HMdcDigiLayEff layeff(trkNum);
	      layeff.ct[loc[0]][loc[1]][loc[2]]++;
	      vLayEff.push_back(layeff);
	  } else {
	      vLayEff[ind].ct[(Int_t)loc[0]][(Int_t)loc[1]][(Int_t)loc[2]]++;
	  }
      }
      if(loc[2] < 6) transform(xcoord,ycoord,theta,phi,tof,trkNum);
  }
  fCell = 0;
  fCal  = 0;
  initArrays();
  itercell->Reset();
  setLoopVariables(0,0,0,0);
  while ((fCell=(HMdcGeantCell *)itercell->Next()) != NULL)
  {
     initArrays();
     loc[0] = fCell->getSector();
     loc[1] = fCell->getModule();
     loc[2] = fCell->getLayer();
     loc[3] = fCell->getCell();
    
    fCal = 0;
    fCal = (HMdcCal1Sim*)fCalCat->getObject(loc);
    resetCal1Real(); 
    if (fCal)
    {  
	getCal1Real();  
	
	if((getNHitsReal() == 2 && getTdcMode() == 1) ||
	   (getNHitsReal() <  0 && getTdcMode() == 2) )
	{
	    Warning("HMdcDigitizer:execute()","HMdcCalibater1 and HMdcDigitizer running in different tdc modes!");
	}
    }
    
    
    
    Int_t nHits = fCell->getNumHits();
    for(Int_t ihit = 0; ihit < nHits; ihit ++)
    {
	fillArrays        (ihit,loc[0],loc[1],fCell);  
	setEfficiencyFlags(ihit,loc[0],loc[1],loc[2]); 
        
    }
    
    if(getEmbeddingMode() == 1 && getTime1Real() != -999)
    {   
	fillArraysReal(nHits);                 
	if(getTdcMode() == 2)     nHits = nHits + 1; 
	else if(getTdcMode() == 1)nHits = nHits + 2; 
    }
    
    if (nHits > 1) select(nHits);  
    resetListVariables();
    if(getNTuple())
    {
	
	for(Int_t hit = 0; hit < NMAXHITS; hit ++)
	{
	    if(getStatus(hit) == 0)continue;
	    fillNTuple(loc[0],loc[1],loc[2],loc[3],hit,
		       fCell,distance_time);
	}
    }
    
    findFirstValidHit();
    if(!fCal)
    {   
	fCal = (HMdcCal1Sim*)fCalCat->getSlot(loc);
	if (fCal)
	{
	    fCal = new(fCal) HMdcCal1Sim;
	    fCal->setAddress(loc[0],loc[1],loc[2],loc[3]);
	}
	else
	{
	    Warning("HMdcDigitizer:execute()","CAL1SIM:getSlot(loc) failed!");
	}
    }
    
    if(fCal)
    {
	if(getTdcMode() == 1 || getTdcMode() == 2)
	{ 
	    if(getFirstHit() != -999)
	    {
		
		
		
		
		
		
		
		
		
		
                
                
		
		fCal->setTime1(
			       getDTime1(getFirstHit())
			       + ( ((Int_t)getTofUse()  - 1)       * getTof(getFirstHit()) )
			       + ( ((Int_t)getErrorUse() - 1)      * getDTime1Err(getFirstHit()) )
			       - ( ((Int_t)getOffsetsUse())        * getOffset(loc[1]) )
			       + ( ((Int_t)getWireOffsetUse() - 1) * getWireOffset(getFirstHit()) ) );
		fCal->setNTrack1(getTrackN(getFirstHit()));
		fCal->setStatus1(getStatus(getFirstHit()));
		fCal->setAngle1(getAngle(getFirstHit()));
		fCal->setMinDist1(getMinimumDist(getFirstHit()));
		fCal->setError1(getDTime1Err(getFirstHit()));
		fCal->setTof1(getTof(getFirstHit()));
                fCal->setWireOffset1(getWireOffset(getFirstHit()));
	    }
	    else
	    {
		fCal->setStatus1(findNonValidHit()); 
	    }
	}
	
	if(getTdcMode() == 2)
	{ 
	    if(getFirstHit() != -999)
	    { 
		fCal->setTime2(
			       getDTime2(getFirstHit())
			       + ( ((Int_t)getTofUse() - 1)       * getTof(getFirstHit()) )
                               + ( ((Int_t)getErrorUse() - 1)     * getDTime2Err(getFirstHit()) )
			       - ( ((Int_t)getOffsetsUse())       * getOffset(loc[1]) )
			       + ( ((Int_t)getWireOffsetUse() - 1)* getWireOffset(getFirstHit()) ) );
		fCal->setNTrack2(getTrackN(getFirstHit()));         
		fCal->setNHits(2);                                  
		fCal->setStatus2(getStatus(getFirstHit())); 
		fCal->setAngle2(getAngle(getFirstHit()));
                fCal->setMinDist2(getMinimumDist(getFirstHit()));
		fCal->setError2(getDTime2Err(getFirstHit()));
                fCal->setTof2(getTof(getFirstHit()));
                fCal->setWireOffset2(getWireOffset(getFirstHit()));
	    }
	    else
	    {
		fCal->setStatus2(findNonValidHit()); 
	    }
	}
	
     
	if (nHits == 1 && getTdcMode() == 1) fCal->setNHits(-1);  
	else
	{
	    if(nHits > 1 && getTdcMode() == 1 && getFirstHit() != -999)
	    { 
		findSecondValidHit();
		if (getSecondHit() == -999 )
		{
		    fCal->setNHits(-1); 
		}
		else
		{
		    fCal->setTime2(
				   getDTime1(getSecondHit())
				   + ( ((Int_t)getTofUse() - 1)       * getTof(getSecondHit()) )
                                   + ( ((Int_t)getErrorUse() - 1)     * getDTime1Err(getSecondHit()) )
				   - ( ((Int_t)getOffsetsUse())       * getOffset(loc[1]) )
				   + ( ((Int_t)getWireOffsetUse() -1) * getWireOffset(getSecondHit()) ) );
   
		    fCal->setNTrack2(getTrackN(getSecondHit()));          
		    fCal->setNHits(-2);                                   
		    fCal->setStatus2(getStatus(getSecondHit())); 
		    fCal->setAngle2(getAngle(getSecondHit()));
		    fCal->setMinDist2(getMinimumDist(getSecondHit()));
		    fCal->setError2(getDTime1Err(getSecondHit()));
		    fCal->setTof2(getTof(getSecondHit()));
                    fCal->setWireOffset2(getWireOffset(getSecondHit()));
		}
	    }
	    else if(nHits > 1 && getTdcMode() == 1)
	    {
		fCal->setStatus2(findNonValidHit()); 
	    }
	}
	
	fillTrackList(fCal); 
                             
    }
  }
  
  if(getNoiseUse())
  {
      
      
      
      
      
      
      
      setLoopVariables(0,0,0,0);
      itercal1->Reset();
      Int_t sec,mod,lay,cell;
      while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
      {
	  fCal->getAddress(sec,mod,lay,cell);                               
	  if(getNoiseMode() == 1 && ( gRandom->Rndm()<getNoiseLevel(mod)) )
	  {
	      
	      
	      
	      fillNoiseToGeantCells(mod,fCal);                              
	  }
	  fillNoise(firstsec,firstmod,firstlay,firstcell,sec,mod,lay,cell); 
	  setLoopVariables(sec,mod,lay,cell + 1,kTRUE);                     
      }
      fillNoise(firstsec,firstmod,firstlay,firstcell,5,3,5,999);            
  }
  
  
  if(getTimeCutUse())
  {
      itercal1->Reset();
      while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
      {
	  setTimeCutFlags(fCal);
      }
  }
  
  return 0;
}
void HMdcDigitizer::fillArrays(Int_t ihit,Int_t sec,Int_t mod,HMdcGeantCell* fCell)
{
    
    
    Int_t l = fCell->getLayer();
    Int_t c = fCell->getCell();
    setMinimumDist(ihit,fCell->getMinDist    (ihit));
    setAngle      (ihit,fCell->getImpactAngle(ihit));
    setTrackN     (ihit,fCell->getNTrack     (ihit));
    setTof        (ihit,fCell->getTimeFlight (ihit));
    setWireOffset (ihit,fCell->getWireOffset (ihit));
    setEfficiency (ihit,fCell->getEfficiency (ihit));
    setTheta      (ihit,fCell->getTheta (ihit));
    setCutEdge    (ihit,fCell->getFlagCutEdge(ihit));
    fCal2ParSim->calcTimeDigitizer(sec,mod,getAngle(ihit),(getMinimumDist(ihit)),&time1,&time1Error);
    setDTime1   (ihit,(Float_t)time1 * getScaleTime() + time1Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
    setDTime1Err(ihit,time1Error);
    if(getDeDxUse())
    {
	
	
	
	
        fCal2ParSim->calcTime2Digitizer(sec,mod,getAngle(ihit),(getMinimumDist(ihit)),&time2,&time2Error);
	
        
	HGeantKine* kine = (HGeantKine*)fGeantKineCat->getObject(getTrackN(ihit) - 1);
	if(kine){
	    
	    
	    
 	    kine->resetMdcIter(); 
	    HGeantMdc* gMdc = 0;
            Bool_t    found = kFALSE;
	    while((gMdc = (HGeantMdc*)kine->nextMdcHit()) != 0)
	    {
		if(gMdc->getModule() == mod &&
		   gMdc->getLayer()  == l) {
		    
		    
                    
                    found = kTRUE;
		    break;
		}
	    }
            if(!found) gMdc = 0;
	    
           
	    
            
	    Float_t p = 0;
	    if(gMdc){
		Float_t x,y,tof;
		gMdc->getHit(x, y, tof, p);
	    }else{
		
                
		p = kine->getTotalMomentum();
                Warning("fillArrays()","HGeantMdc object not found, take kine momentum instead!");
	    }
	    
	    
            
	    Float_t initFrac  = 100.- getCellEffLevel(mod); 
            Double_t beta     = HMdcDeDx2::beta(kine->getID(),p);
	    if(useDeDxScaling && beta > fBetaLow){
		
                
		Double_t dedx_low = fbetadEdx->Eval(fBetaLow);
		Double_t dedx     = fbetadEdx->Eval(beta);
		if(dedx > dedx_low) dedx = dedx_low;
		initFrac          *= dedx_low/dedx;
	    }
            setFractionOfmaxCharge(ihit,initFrac); 
 	    
	    
	    
	    if(useDeDxTimeScaling ) {
		Float_t scale = initFrac/(100.- getCellEffLevel(mod));
                scale+=  (scale-1.) * scaleErrorMIPS[mod];
		time1Error = time1Error * scaleError[mod] * scale;
		setDTime1   (ihit,(Float_t)time1 * getScaleTime() + time1Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
		setDTime1Err(ihit,time1Error);
	    }
	    
	    
	    
            
	    Float_t t2;
	    t2 = fdEdX->scaledTimeAboveThreshold(kine,p,time1,time2,&time2Error,
						 sec,mod,l,c,getAngle(ihit),getMinimumDist(ihit));
	    if(TMath::Finite(t2) && t2 > 0){
                
		time2 = t2;
	    }
	    
	}else {
            
	    Error("fillArrays()","ZERO POINTER for kine object retrieved!");
	}
    }else{
        
	fCal2ParSim->calcTime2Digitizer(sec,mod,getAngle(ihit),(getMinimumDist(ihit)),&time2,&time2Error);
    }
    Float_t mytime2 = time2*getScaleTime() + time2Error + getTof(ihit) + rndmoffsets[sec][mod][l][c];
    if(mytime2 < getDTime1(ihit))
    {   
	setDTime2(ihit,time1 * getScaleTime() + time1Error + 20 + (10 * gRandom->Gaus(0,1)) + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
    }
    else
    {
	setDTime2(ihit,time2 * getScaleTime() + time2Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
    }
    setDTime2Err(ihit,time2Error);
}
void HMdcDigitizer::fillArraysReal(Int_t i)
{
    
    
    Float_t def_val = -99;
    if(getTdcMode() == 2 && i < NMAXHITS-1)
    {   
	setMinimumDist(i,def_val);
	setAngle      (i,def_val);
	setTrackN     (i,gHades->getEmbeddingRealTrackId());
	setTof        (i,-999);
	setDTime1     (i,getTime1Real());
	setDTime1Err  (i,def_val);
	if(getTime2Real() > -998)
	{   
	    setDTime2(i,getTime2Real());
	}
	else
	{   
            setDTime2(i,getTime1Real() + 80);
	}
	setDTime2Err(i,def_val);
	setCutEdge(i,kFALSE);
        setWireOffset(i,0.);
        setEfficiency(i,1.);
        setTheta(i,0.);
	setStatus(i,3);
	setFractionOfmaxCharge(i,0);
    }
    else if(getTdcMode() == 1 && i < NMAXHITS-2)
    {   
        
	setMinimumDist(i,def_val);
	setAngle      (i,def_val);
	setTrackN     (i,gHades->getEmbeddingRealTrackId());
	setTof        (i,-999);
	setDTime1     (i,getTime1Real());
	setDTime1Err  (i,def_val);
	setDTime2     (i,-999);
	setDTime2Err  (i,def_val);
	setCutEdge    (i,kFALSE);
	setWireOffset (i,0.);
        setEfficiency (i,1.);
        setTheta(i,0.);
	setStatus     (i,3);
	setFractionOfmaxCharge(i,0);
        
	setMinimumDist(i + 1,def_val);
	setAngle      (i + 1,def_val);
	setTrackN     (i + 1,gHades->getEmbeddingRealTrackId());
	setTof        (i + 1,def_val);
	if(getTime2Real() > -998)
	{   
	    setDTime1(i + 1,getTime2Real());
	}
	else
	{   
            setDTime1(i + 1,1000);
	}
	setDTime1Err (i + 1,def_val);
	setDTime2    (i + 1,-999);
	setDTime2Err (i + 1,def_val);
	setCutEdge   (i + 1,kFALSE);
	setWireOffset(i + 1,0.);
	setStatus    (i + 1,3);
	setFractionOfmaxCharge(i + 1,0);
    }
    else
    {
	Warning("HMdcDigitizer:fillArraysReal()","real hit could not be stored to array,\n because the maximum has been exceeded!");
    }
}
void HMdcDigitizer::setEfficiencyFlags(Int_t ihit,Int_t sec,Int_t mod,Int_t lay)
{
    
    
    
    if(getTrackN(ihit) != gHades->getEmbeddingRealTrackId())
    {
	Float_t layEffPenalty = getEfficiency(ihit); 
	Float_t efflevel = getFractionOfmaxCharge(ihit);
        
	if(evalWireStat(sec,mod,lay,loc[3]))
	{ 
	    if(getCellEffUse())
	    {
		
		
		setStatus             (ihit,fCellEff->calcEfficiency(mod,getMinimumDist(ihit),getAngle(ihit),efflevel));
		setFractionOfmaxCharge(ihit,fCellEff->calcEffval(mod,getMinimumDist(ihit)    ,getAngle(ihit),efflevel));
	    }
	    else
	    {
		setStatus(ihit,1);
		setFractionOfmaxCharge(ihit,100);
	    }
	    
	    Float_t eff  = fDigitPar->getLayerEfficiency     (sec,mod,lay);
	    if(useLayerThickness) eff*= layEffPenalty;  
	    if(fWireStat && useWireStatEff){ eff *= fWireStat->getEfficiency(sec,mod,lay,loc[3]);}
	    Float_t valRand = 1;
	    Int_t ind = findTrack(getTrackN(ihit));
	    if(ind == -1) {
		Error("setEfficiencyFlags()","tracknumber %i not Found",getTrackN(ihit));
	    } else if (vLayEff[ind].ct[sec][mod][lay] == 1){ 
		valRand = vLayEff[ind].eff[sec][mod][lay];
	    } else {  
		valRand = gRandom->Rndm();
	    }
	    
	    
	    if(getCellEffUse()&&useDeDxScaling){
		
		Double_t initFrac  = 100.- getCellEffLevel(mod);                      
                Double_t scale     = efflevel/initFrac;                               
		Double_t effScale  = fDigitPar->getLayerEfficiencyScale(sec,mod,lay); 
		Double_t dedx_low = fbetadEdx->Eval(fBetaLow);
		Double_t dedx_mip = fbetadEdx->Eval(0.95);
                Double_t scaleMip = dedx_low/dedx_mip;
		eff -=  (( scale - 1. )/(scaleMip -1.))*(1.-effScale);
                if(eff < 0) eff = 0;
	    }
	    
	    if(valRand > eff)
	    {
		switch (getStatus(ihit))
		{
		case   1: setStatus(ihit,-2); 
		break;
		case  -1: setStatus(ihit,-1); 
		break;
		default : setStatus(ihit,-7); 
		break;
		}
	    }
	}
	else
	{ 
	    setStatus(ihit,-3);
	    setFractionOfmaxCharge(ihit,0);
	}
    }
    else
    {
        
	setStatus(ihit,3);
	setFractionOfmaxCharge(ihit,0);
    }
}
void HMdcDigitizer::setTimeCutFlags(Int_t ihit,Int_t sec,Int_t mod,Int_t lay)
{
    
    
    if(getTimeCutUse())
    {
	if(getTrackN(ihit) != gHades->getEmbeddingRealTrackId())
	{
	    
	    if( getStatus(ihit) > 0                             &&
	        (
		 !fTimeCut->cutTime1   (sec,mod,getDTime1(ihit)) ||
		 !fTimeCut->cutTime2   (sec,mod,getDTime2(ihit)) ||
		 !fTimeCut->cutTimesDif(sec,mod,getDTime1(ihit),getDTime2(ihit))
		)
	      )
	    {
		
		setStatus(ihit,-5);
	    }
	}
    }
}
void HMdcDigitizer::setTimeCutFlags(HMdcCal1Sim* cal1)
{
    
    
    if(getTimeCutUse())
    {
	if( cal1->getStatus1() > 0 &&
	   (
	    !fTimeCut->cutTime1   (cal1) ||
	    !fTimeCut->cutTime2   (cal1) ||
	    !fTimeCut->cutTimesDif(cal1)
	   )
	  )
	{
	    
	    cal1->setStatus1(-5);
	    cal1->setStatus2(-5);
	}
    }
}
Bool_t HMdcDigitizer::evalWireStat(Int_t sec,Int_t mod,Int_t lay,Int_t cell)
{
    
    
    Bool_t result = kTRUE;
    Int_t stat    = -99;
    if(getWireStatUse()) {
        stat = fWireStat->getStatus(sec,mod,lay,cell);
        (stat > 0)? result = kTRUE : result = kFALSE;
    }
    return result;
}
void HMdcDigitizer::initArrays()
{
    
    for(Int_t i = 0; i < NMAXHITS; i ++)   
    {
	dTime              [i] = 0.;
	dTime2             [i] = 0.;
	dTimeErr           [i] = 0.;
	dTime2Err          [i] = 0.;
	minimumdist        [i] = 0.;
	track              [i] = -99;
	timeOfFlight       [i] = 0.;
	angle              [i] = 0.;
	statusflag         [i] = 0;
	fractionOfmaxCharge[i] = 0.;
	cutEdge            [i] = kFALSE;
	wireOffset         [i] = 0.;
	efficiency         [i] = 1.;
	theta              [i] = 0.;
    }
}
void HMdcDigitizer::resetListVariables()
{
    
    
    setFirstHit  (-999); 
    setSecondHit (-999); 
    setFirstTime2(-999); 
    setEndList1  (-999); 
};
void HMdcDigitizer::resetCal1Real()
{
    
    
    setTime1Real(-999);
    setTime2Real(-999);
    setNHitsReal(0);
};
void HMdcDigitizer::getCal1Real()
{
    
    
    setTime1Real(fCal->getTime1());
    setTime2Real(fCal->getTime2());
    setNHitsReal(fCal->getNHits());
}
void HMdcDigitizer::fillNTuple(Int_t sec,Int_t mod,Int_t lay,Int_t cell,Int_t ihit,
			       HMdcGeantCell* fCell, TNtuple* distance_time)
{
    
    distance_time->Fill(sec,mod,lay,cell,
			getMinimumDist(ihit),
			getAngle(ihit),
			getDTime1(ihit),
			getDTime1Err(ihit),
			getDTime2(ihit),
			getDTime2Err(ihit),
			getTof(ihit),
			getCutEdge(ihit),
			getStatus(ihit),
			getTrackN(ihit),
			getFractionOfmaxCharge(ihit)
		       );
}
void HMdcDigitizer::fillNTuple(Int_t sec,Int_t mod,Int_t lay,Int_t cell,
			       Float_t time, Float_t time2,
			       Int_t status)
{
    
    
    distance_time->Fill(sec,mod,lay,cell,
			-1,
			-1,
			time ,0,
			time2,0,
			0,
			0,
			status,
			-99,
		        100);
}
Float_t HMdcDigitizer::fillTime1Noise(Int_t mod)
{
    
    
    Float_t time1Noise = -999;
    time1Noise = (gRandom->Rndm() * (getNoiseRangeHi(mod)-getNoiseRangeLo(mod))) + getNoiseRangeLo(mod);
    return  time1Noise;
}
Float_t HMdcDigitizer::fillTime2Noise(Int_t mod)
{
    
    
    Float_t time2Noise = -999;
    if(gRandom->Rndm() < getNoiseWhiteRatio())
    {
	time2Noise = getTime1Noise() + gRandom->Rndm() * getNoiseWhiteWidth();
    }
    else {
	time2Noise = getTime1Noise() + gRandom->Rndm() * getNoiseBandWidth();
    }
    return  time2Noise;
}
void HMdcDigitizer::fillNoiseLists(HMdcCal1Sim* cal1,Int_t statval,Int_t geant)
{
    
    
    
    
    if(geant == 0)
    {   
	Int_t dummystat [5] = {  0,  0,  0,  0,  0};
	Int_t dummytrack[5] = {-99,-99,-99,-99,-99};
	dummystat[0] =statval;
	cal1->setStatusList(dummystat);       
	cal1->setTrackList(dummytrack);       
    }
    else
    {   
	Int_t* mylist = cal1->getStatusList();
	mylist[0] = statval;
    }
}
void HMdcDigitizer::fillNoiseToGeantCells(Int_t mod,HMdcCal1Sim* cal1)
{
    
    
    
    setTime1Noise(fillTime1Noise(mod));
    setTime2Noise(fillTime2Noise(mod));
    if(getTime1Noise() < cal1->getTime1())
    {
	    cal1->setStatus1(2);              
	    cal1->setTime1(getTime1Noise());  
	    cal1->setTime2(getTime2Noise());  
            cal1->setError1(-99);             
	    cal1->setError2(-99);             
	    cal1->setTof1(-999);               
            cal1->setTof2(-999);               
	    cal1->setWireOffset1(-99);        
	    cal1->setWireOffset2(-99);        
            cal1->setStatus1(2);              
            cal1->setStatus2(2);              
            cal1->setAngle1(-99);             
            cal1->setAngle2(-99);             
            cal1->setMinDist1(-99);           
            cal1->setMinDist2(-99);           
            cal1->setNTrack1(-99);            
            cal1->setNTrack2(-99);            
            fillNoiseLists(cal1,-4,1);        
    }
}
void HMdcDigitizer::setLoopVariables(Int_t s,Int_t m,Int_t l,Int_t c,Bool_t check)
{
    if(check)handleOverFlow(s,m,l,c);
    else {
	firstsec  = s;
	firstmod  = m;
	firstlay  = l;
        firstcell = c;
    }
}
void HMdcDigitizer::handleOverFlow(Int_t firsts, Int_t firstm, Int_t firstl, Int_t firstc)
{
    
    
    if(firstc>(*geomstruct)[firsts][firstm][firstl])
    {
	
	if(firstl < 5)
	{ 
	    setLoopVariables(firsts,firstm,firstl + 1,0);
	}
	else
	{ 
	    Int_t found = 0;
	    for(Int_t i = firsts; i < 6; i ++)
	    {
		for(Int_t j = firstm; j < 4; j ++)
		{
		    if(testMdcSetup(i,j))
		    {   
			found ++;
			if(found == 1) setLoopVariables(i,j,0,0);
		    }
		}
	    }
	    
	    if(found == 0) setLoopVariables(firsts,firstm,firstl,500);
	}
    } else setLoopVariables(firsts,firstm,firstl,firstc);
}
void HMdcDigitizer::fillNoise(Int_t firsts, Int_t firstm, Int_t firstl, Int_t firstc,
			      Int_t lastsec, Int_t lastmod, Int_t lastlay, Int_t lastcell)
{
    
    
    
    fCalnoise = 0;
    locnoise.set(4,0,0,0,0);
    if(lastcell != 999) handleOverFlow(firsts,firstm,firstl,firstc);
    for (Int_t sec = firstsec; sec <= lastsec; sec ++)
    {
        if(sec > 5) continue;
	for (Int_t mod = firstmod; mod <= lastmod; mod ++)
	{
            if(mod > 3) continue;
	    
	    if(!testMdcSetup(sec,mod) )continue;
	    for (Int_t lay = firstlay; lay <= lastlay; lay ++)
	    {
                if(lay > 5) continue;
		if(lastcell != 999)
		{
		    for (Int_t cell = firstcell; cell < lastcell; cell ++)
		    {
                        if(cell > (*geomstruct)[sec][mod][lay]) continue;
			if(evalWireStat(sec,mod,lay,cell))
                        { 
                            if(gRandom->Rndm()<getNoiseLevel(mod))
                            {
                                locnoise[0] = sec;
                                locnoise[1] = mod;
                                locnoise[2] = lay;
                                locnoise[3] = cell;
				fCalnoise = (HMdcCal1Sim*)fCalCat->getSlot(locnoise);
                                if (fCalnoise)
                                {
				    fCalnoise = new(fCalnoise) HMdcCal1Sim;
                                    fCalnoise->setAddress(sec,mod,lay,cell);
                                    if (getTdcMode() == 1)
                                    {
                                        fCalnoise->setNHits(-1);
                                        fCalnoise->setStatus1(2);
                                        fCalnoise->setStatus2(-3);
					setTime1Noise(fillTime1Noise(locnoise[1]));
                                        setTime2Noise(-999);
                                        fCalnoise->setTime1(getTime1Noise());
					if(getNTuple())
                                        {
                                            fillNTuple(locnoise[0],locnoise[1],locnoise[2],locnoise[3],
                                                       getTime1Noise(),getTime2Noise(),2);
                                        }
                                    }
                                    else if(getTdcMode() == 2)
                                    {
					fCalnoise->setNHits(2);
                                        fCalnoise->setStatus1(2);
                                        fCalnoise->setStatus2(2);
                                        setTime1Noise(fillTime1Noise(locnoise[1]));
                                        setTime2Noise(fillTime2Noise(locnoise[1]));
                                        fCalnoise->setTime1(getTime1Noise());
                                        fCalnoise->setTime2(getTime2Noise());
					if(getNTuple())
                                        {
                                            fillNTuple(locnoise[0],locnoise[1],locnoise[2],locnoise[3],
                                                       getTime1Noise(),getTime2Noise(),2);
                                        }
                                    }
                                    fillNoiseLists(fCalnoise,2,0);
				}
                            }
                        }
                    }
                }
                if(lastcell == 999)
                {   
                    HMdcLayerGeomParLay& layernoise = (*fDigitGeomPar)[sec][mod][lay];
                    Int_t   nWires = layernoise.getNumWires(); 
                    for (Int_t cell = firstc; cell < nWires; cell ++)
                    {
                       if(evalWireStat(sec,mod,lay,cell))
                        { 
                            if(gRandom->Rndm() < getNoiseLevel(mod))
                            {
                                locnoise[0] = sec;
                                locnoise[1] = mod;
                                locnoise[2] = lay;
                                locnoise[3] = cell;
                                fCalnoise = (HMdcCal1Sim*)fCalCat->getSlot(locnoise);
                                if(fCalnoise)
                                {
                                    fCalnoise = new(fCalnoise) HMdcCal1Sim;
                                    fCalnoise->setAddress(sec,mod,lay,cell);
                                    if(getTdcMode() == 1)
                                    {
                                        fCalnoise->setNHits(-1);
                                        fCalnoise->setStatus1(2);
                                        fCalnoise->setStatus2(-3);
                                        setTime1Noise(fillTime1Noise(locnoise[1]));
                                        setTime2Noise(-999);
                                        fCalnoise->setTime1(getTime1Noise());
					if(getNTuple())
                                        {
                                            fillNTuple(locnoise[0],locnoise[1],locnoise[2],locnoise[3],
                                                       getTime1Noise(),getTime2Noise(),2);
                                        }
                                    }
                                    else if(getTdcMode() == 2)
                                    {
					fCalnoise->setNHits(2);
                                        fCalnoise->setStatus1(2);
                                        fCalnoise->setStatus2(2);
                                        setTime1Noise(fillTime1Noise(locnoise[1]));
                                        setTime2Noise(fillTime2Noise(locnoise[1]));
                                        fCalnoise->setTime1(getTime1Noise());
                                        fCalnoise->setTime2(getTime2Noise());
					if(getNTuple())
                                        {
                                            fillNTuple(locnoise[0],locnoise[1],locnoise[2],locnoise[3],
                                                       getTime1Noise(),getTime2Noise(),2);
                                        }
                                    }
				    fillNoiseLists(fCalnoise,2,0);
				}
                            }
                        }
                    }
                }
            }
        }
    }
}
void HMdcDigitizer::fillTrackList( HMdcCal1Sim* fCal)
{
    
    Int_t array [5];
    Int_t array1[5];
    for(Int_t i = 0; i < 5; i ++)
    {
	array [i] = getTrackN(i);
	array1[i] = getStatus(i);
    }
    fCal->setTrackList (array);  
    fCal->setStatusList(array1); 
}
void HMdcDigitizer::findFirstValidHit()
{
    
    
    
    Int_t hit     = 0;
    Int_t lasthit = 0;
    while(getStatus(hit) <= 0) 
    {
	lasthit ++;
	hit ++;
	if(hit == NMAXHITS)
	{
	    
	    
            resetListVariables();
	    break;
	}
    }
    if(hit < NMAXHITS)
    {
	while(lasthit < NMAXHITS && getDTime1(lasthit) <= getDTime2(hit))
	{
	    lasthit ++; 
	}
	
	setFirstHit(hit);
	setFirstTime2(getDTime2(hit));
	if(lasthit < NMAXHITS)
	{
	    setEndList1(lasthit);
	}
	else
	{
	    setEndList1(-999);
	}
    }
}
void HMdcDigitizer::findSecondValidHit()
{
    
    
    
    Int_t hit = getEndList1() + 1;
    if(hit < NMAXHITS && getEndList1() != -999) 
    {
	while(getStatus(hit) <= 0)
	{
	    
	    hit ++;
	    if(hit == NMAXHITS)
	    {
		
		
		setSecondHit(-999);
		break;
	    }
	}
	if(hit < NMAXHITS)
	{
            
	    setSecondHit(hit);
	}
    }
    else
    {
	
        
	setSecondHit(-999);
    }
}
Int_t HMdcDigitizer::findNonValidHit()
{
    
    
    
    Int_t hit          = 0;
    Int_t foundTimeCut = 0;
    while(getStatus(hit) <= 0) 
    {
	if(getStatus(hit) == -5 ) foundTimeCut ++;
	hit ++;
	if(hit == NMAXHITS)
	{
	    break;
	}
    }
    if(hit == NMAXHITS)
    {   
	return  foundTimeCut > 0 ? -5 : -3;
    } else { return -7; }
}
void HMdcDigitizer::select(Int_t nHits)
{
    
    
    
    register Int_t a,b,c;
    Int_t exchange;
    Float_t t;
    Float_t t2;
    Float_t tErr;
    Float_t t2Err;
    Float_t flight;
    Float_t angleLocal;
    Int_t statlocal;
    Int_t tracklocal;
    Float_t mindistlocal;
    Bool_t cutEdgelocal;
    Float_t fractionlocal;
    Float_t wireOffsetlocal;
    if(nHits <= NMAXHITS)
    {
	for(a = 0; a < nHits - 1; ++ a)
	{
	    exchange = 0;
	    c = a;
	    t               = dTime[a];
	    tErr            = dTimeErr[a];
	    t2              = dTime2[a];
	    t2Err           = dTime2Err[a];
	    tracklocal      = track[a];
	    flight          = timeOfFlight[a];
	    angleLocal      = angle[a];
	    statlocal       = statusflag[a];
	    mindistlocal    = minimumdist[a];
	    cutEdgelocal    = cutEdge[a];
	    fractionlocal   = fractionOfmaxCharge[a];
            wireOffsetlocal = wireOffset[a];
	    for(b=a+1;b<nHits;++b)
	    {
		if(dTime[b]<t)
		{
		    c = b;
		    t               = dTime[b];
		    tErr            = dTimeErr[b];
		    t2              = dTime2[b];
		    t2Err           = dTime2Err[b];
		    tracklocal      = track[b];
		    flight          = timeOfFlight[b];
		    angleLocal      = angle[b];
		    statlocal       = statusflag[b];
		    mindistlocal    = minimumdist[b];
		    cutEdgelocal    = cutEdge[b];
		    fractionlocal   = fractionOfmaxCharge[b];
		    wireOffsetlocal = wireOffset[b];
		    exchange = 1;
		}
	    }
	    if(exchange)
	    {
		dTime[c]               = dTime[a];
		dTime[a]               = t;
		dTimeErr[c]            = dTimeErr[a];
		dTimeErr[a]            = tErr;
		dTime2[c]              = dTime2[a];
		dTime2[a]              = t2;
		dTime2Err[c]           = dTime2Err[a];
		dTime2Err[a]           = t2Err;
		track[c]               = track[a];
		track[a]               = tracklocal;
		timeOfFlight[c]        = timeOfFlight[a];
		timeOfFlight[a]        = flight;
		angle[c]               = angle[a];
		angle[a]               = angleLocal;
		statusflag[c]          = statusflag[a];
		statusflag[a]          = statlocal;
		minimumdist[c]         = minimumdist[a];
		minimumdist[a]         = mindistlocal;
		cutEdge[c]             = cutEdge[a];
		cutEdge[a]             = cutEdgelocal;
		fractionOfmaxCharge[c] = fractionOfmaxCharge[a];
		fractionOfmaxCharge[a] = fractionlocal;
		wireOffset[c]          = wireOffset[a];
		wireOffset[a]          = wireOffsetlocal;
	    }
	}
    }
    else
    {
	Warning("HMdcDigitizer:select(nHits)","nHits > 15! Entries >15 skipped! ");
    }
}
void HMdcDigitizer::getMdcSetup()
{
    
    HMdcDetector* mdcDet=(HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"));
    if (!mdcDet)
    {
	Error("HMdcDigitizer::getMdcSetup()","Mdc-Detector setup (gHades->getSetup()->getDetector(\"Mdc\")) missing.");
    }
    for(Int_t s = 0; s < 6; s ++) {
	for(Int_t m = 0; m < 4; m ++) {
	    if (!mdcDet->getModule(s, m)) setup[s][m] = 0;
	    if ( mdcDet->getModule(s, m)) setup[s][m] = 1;
	}
    }
}
Bool_t HMdcDigitizer::testMdcSetup(Int_t s, Int_t m)
{
    
    
    Bool_t result=kFALSE;
    if(setup[s][m] == 0) result = kFALSE;
    if(setup[s][m] == 1) result = kTRUE;
    return result;
}
Bool_t HMdcDigitizer::transform(Float_t xcoor,Float_t ycoor,Float_t theta,
                                Float_t phi  ,Float_t tof  ,Int_t trkNum) {
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    HMdcSizesCellsLayer &sclayer = (*fsizescells)[loc[0]][loc[1]][loc[2]];
    Int_t nCmin,nCmax;
    if( !sclayer.calcCrCellsGeantMdc(xcoor,ycoor,theta,phi,nCmin,nCmax) ) return kFALSE;
    Float_t effPenalty = effLayerThickness(xcoor,ycoor,theta, phi,loc[0],loc[1],loc[2]);
    
    Float_t halfPitch   = sclayer.getHalfPitch();
    Float_t halfCatDist = sclayer.getHalfCatDist();
    
    for (loc[3] = nCmin; loc[3] <= nCmax; loc[3] ++) {
    
        Float_t yDist     = sclayer.getYinRotLay(loc[3],xcoor,ycoor) - sclayer.calcWireY(loc[3]);
        Float_t wOrient   = sclayer.getWireOrient(loc[3]) * pi;
        Float_t ctanalpha = tan(theta * pi) * sin(phi * pi - wOrient);
        
        
        myalpha = 90. - fabs(atan(ctanalpha) * TMath::RadToDeg());
     
	Float_t sinAlpha = sqrt(1. / (1. + ctanalpha * ctanalpha));
	Float_t cosAlpha = sqrt(1. - sinAlpha * sinAlpha);
	Float_t per = fabs(yDist * sinAlpha);
	Bool_t flagCutEdge = kFALSE;
	if(per * sinAlpha > halfPitch) {  
	    flagCutEdge = kTRUE;
	} else if(per * cosAlpha > halfCatDist) { 
	    flagCutEdge = kTRUE;
	}
	Float_t wireOffset = 0;
	if(getWireOffsetUse()) {
          
          HMdcSizesCellsCell& mycell = sclayer[loc[3]];
          if(&mycell != NULL && mycell.getReadoutSide() != '0') {
            Float_t x_wire = sclayer.getXinRotLay(loc[3],xcoor,ycoor);
            wireOffset = getSignalSpeed() * mycell.getSignPath(x_wire);
          }
        }
	storeCell(per,tof,myalpha,trkNum,flagCutEdge,wireOffset,effPenalty,theta);
    }
    return kTRUE;
}
void HMdcDigitizer::storeCell(Float_t per,Float_t tof,Float_t myangle,Int_t trkNum
			      ,Bool_t flagCutEdge,Float_t wireOffset,Float_t eff,Float_t theta)
{
    
    
    hit = (HMdcGeantCell*)fGeantCellCat->getObject(loc);
    if (!hit) {
	hit = (HMdcGeantCell*)fGeantCellCat->getSlot(loc);
	hit = new(hit) HMdcGeantCell;
    }
    Int_t nHit;
    nHit = hit->getNumHits();
    if (nHit < NMAXHITS ) {  
	hit->setSector(loc[0]);
	hit->setModule(loc[1]);
	hit->setLayer(loc[2]);
	hit->setCell(loc[3]);
	hit->setNumHits(nHit +  1);
	hit->setMinDist(per,nHit);
	hit->setTimeFlight(tof,nHit);
	hit->setImpactAngle(myangle,nHit);
	hit->setNTrack(trkNum,nHit);
	hit->setFlagCutEdge(flagCutEdge,nHit);
        hit->setWireOffset(wireOffset,nHit);
	hit->setEfficiency(eff,nHit);
        hit->setTheta(theta,nHit);
    }
    else
    {
	Warning("HMdcDigitizer:storeCell()","hit could not be stored in HMdcGeantCell ,\n because number of hits exceeded the maximum!");
    }
}
void HMdcDigitizer::initOffsets(TString filename)
{
    
    
    
    
    
    
    
    if(createoffsets)
    {   
        for(Int_t s = 0;s < 6; s ++){
            for(Int_t m = 0; m < 4; m ++){
                for(Int_t l = 0; l < 6; l ++){
                    for(Int_t c = 0; c < 220; c ++){
                        rndmoffsets[s][m][l][c] = gRandom->Gaus(0.,getSigmaOffsets());
                    }
                }
            }
        }
        if(filename.CompareTo("") == 0)
        {
            Warning("HMdcDigitizer:initOffsets()","No file name specified, offsets will not be written to file!");
        }
        else
        {
            FILE* ascii=fopen(filename,"w");
            for(Int_t s = 0; s < 6; s ++){
                for(Int_t m = 0; m < 4; m ++){
                    for(Int_t l = 0; l < 6; l ++){
                        for(Int_t c = 0; c <220; c ++){
                            fprintf(ascii,"%i %i %i %3i %7.3f \n",s,m,l,c,rndmoffsets[s][m][l][c]);
                        }
                    }
                }
            }
            fclose(ascii);
        }
    }
    else
    {
        FILE* ascii = fopen(filename,"r");
        if(!ascii)
        {
            Warning("HMdcDigitizer:initOffsets()","Specified file %s does not exist, offsets will be 0.0.!",filename.Data());
        }
        else
        {
            cout<<"HMdcDigitizer:initOffsets() Reading offset table from file "<<filename.Data()<<endl;
	    Char_t line[400];
            while(1)
            {
                Int_t s,m,l,c;
                Float_t off;
                if(feof(ascii)) break;
                Bool_t res=fgets(line, sizeof(line), ascii);
		if(!res)cout<<"initOffsets: cannot read next line!"<<endl;
                sscanf(line,"%i %i %i %i %f",&s,&m,&l,&c,&off);
                rndmoffsets[s][m][l][c] = off;
            }
            fclose(ascii);
        }
    }
    offsetsCreated = kTRUE;
}
Int_t HMdcDigitizer::findTrack(Int_t trk)
{
    
    
    for(UInt_t i = 0; i < vLayEff.size(); i ++){
       if(vLayEff[i].trackNum == trk) return i;
    }
    return -1;
}
Float_t HMdcDigitizer::effLayerThickness(Float_t xcoor,Float_t ycoor,Float_t th,Float_t ph,Int_t s,Int_t m,Int_t l)
{
    Float_t effmin = fDigitPar ->getLayerEfficiencyThickness(s,m,l);
    if(effmin==0) return 1;
    const Float_t effmax = 1.00;
    HMdcSizesCellsMod&   sizescellsMod = (*fsizescells)[s][m];
    HMdcSizesCellsLayer& sizescellsLay = (*fsizescells)[s][m][l];
    Float_t Lmin = layEff.Lmin[s][m][l];
    Float_t Lmax = layEff.Lmax[s][m][l];
    if(Lmin < 0 || Lmax < 0) {
	Error("effLayerThickness()","Lmin or Lmax not set Lmin =  %f , Lmax =  %f ! ",Lmin,Lmax);
        return 1;
    }
    
    
    
    Double_t x1,y1,z1,x2,y2,z2;
    Double_t theta = th*TMath::DegToRad();
    Double_t phi   = ph*TMath::DegToRad();
    Double_t sinTh = sin(theta);
    Double_t xDir  = sinTh*cos(phi);
    Double_t yDir  = sinTh*sin(phi);
    Double_t zDir  = sqrt(1.-sinTh*sinTh);
    x2=x1=xcoor;
    y2=y1=ycoor;
    z2=z1=0.;
    x2 += xDir*1000.;
    y2 += yDir*1000.;
    z2 += zDir*1000.;
    sizescellsMod.transFromZ0(x1,y1,z1);
    sizescellsMod.transFrom  (x2,y2,z2);
    
    
    
    Int_t firstCell,lastCell;
    Float_t firstCellPath,midCellPath,lastCellPath;
    Int_t ncells=0;
    if(sizescellsLay.calcCrossedCells(x1,y1,z1, x2,y2,z2,
				      firstCell,lastCell,
				      firstCellPath,midCellPath,lastCellPath))
    {
	ncells = 1;
	ncells += lastCell-firstCell;
	Float_t totalePathInLayer = 0.;
	for(Int_t cell=firstCell;cell<=lastCell;++cell) {
	    Float_t cellPath;
	    if      (cell == firstCell) { cellPath = firstCellPath;}
	    else if (cell == lastCell)  { cellPath = lastCellPath; }
	    else                        { cellPath = midCellPath;  }
	    totalePathInLayer += cellPath;
	}
        if(totalePathInLayer>Lmax) totalePathInLayer = Lmax;
        if(totalePathInLayer<Lmin) totalePathInLayer = Lmin;
        Float_t eff  = effmin +  ( (effmax - effmin)  *  (totalePathInLayer-Lmin) / (Lmax-Lmin) );
        
        return eff;
    } else return 1;
    
}
ClassImp(HMdcDigitizer)