Skip to content
Snippets Groups Projects
MegatileLayerGridXY.cpp 14.1 KiB
Newer Older
/*
 * MegatileLayerGridXY.cpp
 *
 *  Created on: April 19, 2016
 *      Author: S. Lu, DESY
 *              D Jeans UTokyo
 */

#define VERBOSEcoterra 1


#include "DDSegmentation/MegatileLayerGridXY.h"

#include <cassert>

namespace DD4hep {
  namespace DDSegmentation {

    /// default constructor using an encoding string
    MegatileLayerGridXY::MegatileLayerGridXY(const std::string& cellEncoding) :
      CartesianGrid(cellEncoding) {
      // define type and description
      _type = "MegatileLayerGridXY";
      // _description = "Cartesian segmentation in the local XY-plane for both Normal wafer and Magic wafer(depending on the layer dimensions)";
      _description = "Cartesian segmentation in the local XY-plane: megatiles with dead areas; integer number of megatiles and cells";



//////// setup in the compact-steering file (i.e., ILD_o3_v05.xml)//// 
// for example,
// <segmentation type="MegatileLayerGridXY" yer_nCells="36" layer_nStripsX="2" layer_nStripsY="36" deadWidth="0" layer_configuration="TL"/>

      registerParameter("nMegaY", "number of megatiles along Z", _nMegaY , 1 , SegmentationParameter::NoUnit, true);
//      _nMegaY is given by Ecal_n_wafers_per_tower from "model_parameters_ILD_o3_v05.xml"

      registerParameter("layer_nCells", "division of megatile into square tiles", _nCells, 36 , SegmentationParameter::NoUnit, true);
      registerParameter("layer_nStripsX", "division of megatile into strips (1)", _nStripsX, 4 , SegmentationParameter::NoUnit, true);
      registerParameter("layer_nStripsY", "division of megatile into strips (2)", _nStripsY, 36 , SegmentationParameter::NoUnit, true);

      registerParameter("deadWidth", "width of dead region at edge of megatile", _deadWidth, 0., SegmentationParameter::LengthUnit, true);

      registerIdentifier("identifier_x", "Cell ID identifier for X", _xId, "cellX");
      registerIdentifier("identifier_y", "Cell ID identifier for Y", _yId, "cellY");

      registerParameter("identifier_wafer", "Cell encoding identifier for wafer", _identifierWafer, std::string("wafer"),
                        SegmentationParameter::NoUnit, true);

//      registerParameter("identifier_wafer_y", "Cell encoding identifier for wafer in y", _identifierWaferY, std::string("waferY"),
//                        SegmentationParameter::NoUnit, true);

      registerParameter("identifier_layer", "Cell encoding identifier for layer", _identifierLayer, std::string("layer"),
                        SegmentationParameter::NoUnit, true);

      //      registerParameter("identifier_deadArea", "Cell encoding identifier for dead area", _identifierGR, std::string("deadArea"),
      //			SegmentationParameter::NoUnit, true);

      //registerParameter("layer_configuration", "layer configuration (S, T, L)", _layerConfig, std::string("TLS"), SegmentationParameter::NoUnit, true);
      registerParameter("layer_configuration", "layer configuration (S, T, L)", _layerConfig, std::string("TLS"), SegmentationParameter::NoUnit, true);

      _calculated=false;

    }

    /// destructor
    MegatileLayerGridXY::~MegatileLayerGridXY() {

    }


    void MegatileLayerGridXY::calculateDerivedQuantities() const {

			if (_calculated) return; // already up to date

///// g514 coterra      _megaSize  =   _totalSizeX / _nMegaX ; // size of square megatile in this layer
///// Here we determine standard strip dimension. Therefore, we use the standard EBU dimension.
//		Therefore we use global values _megaSize determined with _totalSizeY and _nMegaY.
      _megaSize  =   _totalSizeY / _nMegaY ; // size of square megatile in this layer
      _gridSizeL =  (_megaSize - 2.*_deadWidth) / _nStripsX ; // size of cell within megatile (x)
      _gridSizeT =  (_megaSize - 2.*_deadWidth) / _nStripsY ;
      _gridSizeS = (_megaSize - 2.*_deadWidth) / _nCells;

      std::cout << "calculateDerivedQuantities: total X width: " << _totalSizeX << " / nMega: " << _nMegaY << " = " << _megaSize << " ; dead width = " << _deadWidth << 
	" ; nstripsX,Y, nCells : " << _nStripsX << " " << _nStripsY << " " << _nCells << 
	" ; stripX,Y/cell size: " << _gridSizeL << " " << _gridSizeT << " " << _gridSizeS << std::endl;

      _calculated=true;

      return;
    }

    /// determine the position based on the cell ID
    Vector3D MegatileLayerGridXY::position(const CellID& cID) const {

      calculateDerivedQuantities();

      _decoder->setValue(cID);
      unsigned int LayerIndex;
      unsigned int WaferIndex;
      unsigned int CellIndexX;
      unsigned int CellIndexY;
      Vector3D cellPosition;

      LayerIndex = (*_decoder)[_identifierLayer];
      WaferIndex = (*_decoder)[_identifierWafer];
//      WaferIndexY = (*_decoder)[_identifierWaferY];

      CellIndexX = (*_decoder)[_xId];
      CellIndexY = (*_decoder)[_yId];

#if 0
      // offset of area
      cellPosition.X = - _totalSizeX[ LayerIndex ] / 2.;
      cellPosition.Y = - _totalSizeY / 2.;
#if VERBOSEcoterra 
			std::cout << "with offset: cellPosition.X = " << cellPosition.X << ", cellPosition.Y = " << cellPosition.Y << std::endl;
#endif
      // WaferIndex is stard with 1.
      int WaferIndexX = ( WaferIndex - 1 ) / _nMegaY + 1;
      int WaferIndexY = WaferIndex%_nMegaY + 1;
#if VERBOSEcoterra
			std::cout << "WaferIndexY = WaferIndex%_nMegaY + 1;  " << WaferIndexY << " = " <<  WaferIndex << " % " << _nMegaY << " + " << 1 << std::endl;
#endif

      cellPosition.X += (WaferIndexX - 1) * _megaSize;
      cellPosition.Y += (WaferIndexY - 1) * _megaSize;
#if VERBOSEcoterra 
			std::cout << "WaferIndexX = " << WaferIndexX << ", WaferIndexY = " <<  WaferIndexY << std::endl;
			std::cout << "+ WaferIndexX*_megaSize: cellPosition.X = " << cellPosition.X << ", cellPosition.Y = " << cellPosition.Y << std::endl;
#endif
#endif

			double regulatingEBUSizeX = _waferOffsetX[LayerIndex][WaferIndex] * 2;
			double regulatingEBUSizeY = _waferOffsetY[LayerIndex][WaferIndex] * 2;

      std::vector<double> celldims = layercellDimensions( LayerIndex );
			cellPosition.X = -regulatingEBUSizeX / 2.;
			cellPosition.Y = -regulatingEBUSizeY / 2.;   // _megaSize includes two _deadWidth.
      cellPosition.Y += (CellIndexY + 0.5) * celldims[1];
			double XfromEdge = 0;
			//double d_regulation = _megaSize - regulatingEBUSizeX;
			//if  ( d_regulation >  0.1 && celldims[0] > celldims[1]*1.5 ) {

#if VERBOSEcoterra
	if ( _isRegulatingEBU[LayerIndex][WaferIndex] ) {
		std::cout << "regulatingEBUSizeX, regulatingEBUSizeY(layer) = " << regulatingEBUSizeX << ", " << regulatingEBUSizeY 
		<< "(" << LayerIndex << ")" << std::endl;
		 std::cout << "CellIndexX, Y = " << CellIndexX << ", " << CellIndexY << ", celldims[0], [1] = " << celldims[0] 
				<< ", " << celldims[1] << std::endl;
		std::cout << "cellPosition.X, Y = " << cellPosition.X << ", " << cellPosition.Y << std::endl;
	}
#endif


			int n_cellX = regulatingEBUSizeX / celldims[0];
			if  (  _isRegulatingEBU[LayerIndex][WaferIndex] && celldims[0] > celldims[1]*1.5 
						&&CellIndexX == (unsigned int)(n_cellX - 1) ) {
					XfromEdge = ( n_cellX -1) * celldims[0] + ( regulatingEBUSizeX-( n_cellX -1) * celldims[0] )/2;
#if VERBOSEcoterra
						std::cout << "This hit is out of regulation EBU=> merged into neighbour strip; XfromEdge = " << XfromEdge << std::endl;
#endif
			} else {
				 XfromEdge = (CellIndexX + 0.5) * celldims[0];
			}
	
      ////////////////cellPosition.X += _deadWidth + XfromEdge;
      cellPosition.X += XfromEdge;
		
#if VERBOSEcoterra 
			std::cout << "+ _deadWidth + ( CellIndexX + 0.5 )*celldims[0]: cellPosition.X = " << cellPosition.X << ", cellPosition.Y = " << cellPosition.Y << std::endl;
			std::cout << "CellIndexX * celldims[0] = " << CellIndexX << " x " << celldims[0] 
							<< ", CellIndexY * celldims[1] = " << CellIndexY << " x " << celldims[1] 
							<< ", _isRegulatingEBU[" << LayerIndex << "][" << WaferIndex << "] = " << _isRegulatingEBU[LayerIndex][WaferIndex]
							<< std::endl;
			std::cout << "in MegatileLayerGridXY: regulatingEBUSizeX = " << regulatingEBUSizeX << std::endl;
#endif

      return cellPosition;
    }

    /// determine the cell ID based on the position
    CellID MegatileLayerGridXY::cellID(const Vector3D& localPosition, const Vector3D& /* globalPosition */, const VolumeID& vID) const {
      calculateDerivedQuantities();
      _decoder->setValue(vID);
      unsigned int layerIndex = (*_decoder)[_identifierLayer];
			unsigned int waferIndex = (*_decoder)[_identifierWafer];

      double _x = localPosition.X; 
      double _y = localPosition.Y;

      int _cellIndexX(-1);
      int _cellIndexY(-1);

	//  std::cout << "hello3 " << _x << " " << _y << std::endl;
			std::vector<double> celldims = layercellDimensions( layerIndex );

#if VERBOSEcoterra
			std::cout << "in cellID before area check" << std::endl;
			std::cout << "_x = localPosition.X: " << _x << " = " << localPosition.X << ", _waferOffsetX[" 
								<< layerIndex << "][" << waferIndex << "] = " << _waferOffsetX[layerIndex][waferIndex] << std::endl;
			std::cout << "_y = localPosition.Y: " << _y << " = " << localPosition.Y << ", _waferOffsetY["
								<< layerIndex << "][" << waferIndex << "] = " << _waferOffsetY[layerIndex][waferIndex] << std::endl;
//			std::cout << "_waferIndexX = " << _waferIndexX[][] << std::endl;
//			std::cout << "_waferIndexY = " << _waferIndexY << std::endl;
			std::cout << "_megaSize = " << _megaSize << std::endl;
#endif
			double WaferOffsetX = _waferOffsetX[layerIndex][waferIndex];
			double WaferOffsetY = _waferOffsetY[layerIndex][waferIndex];
#if VERBOSEcoterra
			std::cout << "WaferOffsetX = " << _waferOffsetX[layerIndex][waferIndex] 
			<< " layer, wafer = " << layerIndex << ", " << waferIndex
			<< std::endl;
#endif
      // _waferOffsetX has negative sign. <<<---??? not true!!
			if ( _x < -WaferOffsetX || _x > WaferOffsetX ||
	  	  	 _y < -WaferOffsetY || _y > WaferOffsetY ) {
#if VERBOSEcoterra
			std::cout << "This hit falls down in to dead width." << std::endl;
#endif
	  		// dead area at edge of wafer
				} else {

			// localPosition.X is in a coordination which center is at the center of wafer.
      // _waferOffsetX is 1/2 of wafer_dim_x, 
      // and wafer_dim_x is already subtracted with the guard ring (deadWidth);
      // _x should be interpret in a coodination who's origin is on the edge of wafre... negative--> positive sign.

      	 _x += WaferOffsetX;
      	 _y += WaferOffsetY;

#if VERBOSEcoterra
  if ( _isRegulatingEBU[layerIndex][waferIndex] ) {
			std::cout << "in cellID on hit " << std::endl;
			std::cout << "_x = localPosition.X + _waferOffsetX; => " << _x << " = " << localPosition.X << " + " << WaferOffsetX << std::endl;
			std::cout << "_y = localPosition.Y + _waferOffsetY; => " << _y << " = " << localPosition.Y << " + " << WaferOffsetY << std::endl;
//			std::cout << "_waferIndexX = " << _waferIndexX << std::endl;
//			std::cout << "_waferIndexY = " << _waferIndexY << std::endl;
			std::cout << "_megaSize = " << _megaSize << std::endl;
	}
#endif

	  // edge of active area of megatile
	  			_cellIndexX = int ( _x / celldims[0] );
	  			_cellIndexY = int ( _y / celldims[1] );
#if VERBOSEcoterra
      std::cout << "in cellID after subtract other  wafers" << std::endl;
			std::cout << "_x = " << _x << " and _y = " << _y << " _deadWidth = " << _deadWidth << "; in cellID" << std::endl;
				if ( _isRegulatingEBU[layerIndex][waferIndex] && celldims[0] < celldims[1]*1.5 ) {
					int temp_n_cellX = WaferOffsetX * 2 / celldims[0];
			//		if ( _cellIndexX > temp_n_cellX - 1 ) {
						std::cout << "EXESS hit in transeverse layer WaferOffsetX = " << WaferOffsetX 
						<< ", celldims[0] = " << celldims[0]
						<< ", _cellIndexX = " << _cellIndexX
						<< ", _x = " << _x
						<< ", _megaSize = " << _megaSize
						<< ", temp_n_cellX = " << temp_n_cellX
						<< std::endl;
			//		}
				}
#endif 
					if ( _isRegulatingEBU[layerIndex][waferIndex] && celldims[0] > celldims[1]*1.5 ) {
						int n_cellX = WaferOffsetX * 2 / celldims[0]; // How many strip-row can stay on this EBU.
						if ( _cellIndexX > n_cellX - 1 ) { // hit position is out of this EBU.
							_cellIndexX -= 1;
#if VERBOSEcoterra
						std::cout << "This hit is out of regulation EBU=> merged into neighbour strip; _cellIndexX = " << _cellIndexX << std::endl;
#endif
						}
					}
				}
			//      std::cout << " wafer, cell indx " << _waferIndexX << " " << _waferIndexY << " , " << _cellIndexX << " " << _cellIndexY << std::endl;
/////xxxxxxxxxxxxxxxxxxx
	if ( _isRegulatingEBU[layerIndex][waferIndex] ) {
//      	 _cellIndexX = 0;
	}


      	(*_decoder)[_xId] = _cellIndexX;
      	(*_decoder)[_yId] = _cellIndexY;
		//_waferIndexX(Y) were calculated in SEcal04Hybrid_Barrel using setWaferIndexX(Y)
  //    	(*_decoder)[_identifierWaferX] = _waferIndexX;
    //  	(*_decoder)[_identifierWaferY] = _waferIndexY;
      
      	return _decoder->getValue();
    }

    std::vector<double> MegatileLayerGridXY::cellDimensions(const CellID& cID) const {

      _decoder->setValue( cID );
      unsigned int _layerIndex = (*_decoder)[_identifierLayer];

      return layercellDimensions(_layerIndex);

    }

    std::vector<double> MegatileLayerGridXY::layercellDimensions(const int layerIndex) const {

      calculateDerivedQuantities();

      unsigned int mm = layerIndex % _layerConfig.length();
      
      const char laytype = _layerConfig.at(mm);

      double xsize(0);
      double ysize(0);

      if ( laytype=='S' ) { // square cell
				xsize = ysize = _gridSizeS;
      } else if ( laytype=='T' ) { // transverse
				xsize = _gridSizeT;
				ysize = _gridSizeL;
      } else if ( laytype=='L' ) { // transverse
				xsize = _gridSizeL;
				ysize = _gridSizeT;
      } else {
				assert(0);
      }
      
      //      std::cout << laytype << " " << xsize << " " << ysize << std::endl;

#if __cplusplus >= 201103L
      //      return {_gridSizeX[_layerIndex], _gridSizeY[_layerIndex]};
      //      return {_gridSizeX, _gridSizeY};
      return {xsize, ysize};
#else
      std::vector<double> cellDims(2,0.0);
      //cellDims[0] = _gridSizeX[_layerIndex];
      //cellDims[1] = _gridSizeY[_layerIndex];
      //cellDims[0] = _gridSizeX;
      //cellDims[1] = _gridSizeY;
      cellDims[0] = xsize;
      cellDims[1] = ysize;
      return cellDims;
#endif
    }

    REGISTER_SEGMENTATION(MegatileLayerGridXY)

  } /* namespace DDSegmentation */
} /* namespace DD4hep */