3 #include <IMPL/CalorimeterHitImpl.h>
5 #include <EVENT/LCCollection.h>
6 #include <EVENT/CalorimeterHit.h>
7 #include <UTIL/CellIDDecoder.h>
8 #include <CalorimeterHitType.h>
10 #include "DD4hep/DetType.h"
20 #include "DD4hep/DetectorSelector.h"
21 #include "DD4hep/DetType.h"
22 #include "DD4hep/Detector.h"
28 _description =
"makes a collection of ECAL gap hits" ;
31 std::string inputCollection;
32 registerInputCollection( LCIO::CALORIMETERHIT,
33 "inputHitCollection" ,
34 "input simcalhit Collection Name" ,
38 std::string outputCollection;
39 registerOutputCollection(LCIO::CALORIMETERHIT,
40 "outputHitCollection",
41 "output calorimeterhit Collection Name" ,
45 registerProcessorParameter(
"CellIDLayerString" ,
46 "name of the part of the cellID that holds the layer" ,
51 registerProcessorParameter(
"CellIDModuleString" ,
52 "name of the part of the cellID that holds the module" ,
57 registerProcessorParameter(
"CellIDStaveString" ,
58 "name of the part of the cellID that holds the stave" ,
63 registerProcessorParameter(
"expectedInterModuleDistance",
64 "size of gap across module boundaries (from edge to edge of cells, in mm ; accuracy < cell size)",
69 registerProcessorParameter(
"interModuleNonlinearFactor",
70 "nonlin factor f: E_corr = interModuleCorrectionFactor*(1/f)*log(1 + f*E_calc)",
74 registerProcessorParameter(
"intraModuleNonlinearFactor",
75 "nonlin factor f: E_corr = intraModuleCorrectionFactor*(1/f)*log(1 + f*E_calc)",
79 registerProcessorParameter(
"interModuleCorrectionFactor",
80 "factor applied to calculated energy of inter-module gap hits",
84 registerProcessorParameter(
"intraModuleCorrectionFactor",
85 "factor applied to calculated energy of intra-module gap hits",
89 registerProcessorParameter(
"applyInterModuleCorrection",
90 "apply correction for gaps between modules?",
101 _flag.setBit(LCIO::CHBIT_LONG);
102 _flag.setBit(LCIO::RCHBIT_TIME);
116 int numElements = col->getNumberOfElements();
117 streamlog_out ( DEBUG1 ) <<
_inputHitCollection <<
" number of elements = " << numElements << endl;
119 if ( numElements>0 ) {
121 CellIDDecoder<CalorimeterHit> idDecoder( col );
129 for (
int j(0); j < numElements; ++j) {
130 CalorimeterHit * hit =
dynamic_cast<CalorimeterHit*
>( col->getElementAt( j ) ) ;
137 assert( layer>=0 && layer<MAXLAYER );
138 assert( stave>=0 && stave<MAXSTAVE );
139 assert( module>=0 && module<MAXMODULE);
146 std::string encodingString = col->getParameters().getStringVal(LCIO::CellIDEncoding);
148 newcol->parameters().setValue(LCIO::CellIDEncoding,encodingString);
149 newcol->setFlag(
_flag.getFlag());
158 }
catch(DataNotAvailableException &
e){
159 streamlog_out(DEBUG1) <<
"could not find input collection " <<
_inputHitCollection << std::endl;
169 CHT calHitType( ihitType );
170 if ( ! calHitType.is(CHT::ecal) ) {
171 streamlog_out (ERROR) <<
"this is not an ECAL hit!" << endl;
176 if ( calHitType.is( CHT::barrel ) ) iLayout=
ECALBARREL;
177 else if ( calHitType.is( CHT::endcap ) ) iLayout=
ECALENDCAP;
179 streamlog_out (ERROR) <<
"this hit is in neither barrel not endcap" << endl;
186 unsigned int includeFlag(0);
187 unsigned int excludeFlag(0);
189 if ( calHitType.is( CHT::barrel ) ) {
190 includeFlag = ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL);
191 excludeFlag = ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD );
192 }
else if ( calHitType.is( CHT::endcap ) ) {
193 includeFlag = ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP);
194 excludeFlag = ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD );
197 dd4hep::Detector & lcdd = dd4hep::Detector::getInstance();
198 const std::vector< dd4hep::DetElement>& theDetectors = dd4hep::DetectorSelector(lcdd).detectors( includeFlag, excludeFlag ) ;
199 streamlog_out( DEBUG2 ) <<
" getExtension : includeFlag: " << dd4hep::DetType( includeFlag ) <<
" excludeFlag: " << dd4hep::DetType( excludeFlag )
200 <<
" found : " << theDetectors.size() <<
" - first det: " << theDetectors.at(0).name() << std::endl ;
202 if( theDetectors.size() != 1 ){
203 std::stringstream es ;
204 streamlog_out (ERROR) <<
" getExtension: selection is not unique (or empty) includeFlag: " << dd4hep::DetType( includeFlag ) <<
" excludeFlag: " << dd4hep::DetType( excludeFlag )
205 <<
" --- found detectors : " ;
206 for(
unsigned i=0, N= theDetectors.size(); i<N ; ++i ){
207 streamlog_out (ERROR) << theDetectors.at(i).name() <<
", " ;
211 _caloGeomData = theDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>();
214 streamlog_out ( WARNING ) <<
"could not get calorimeter geometry information!" << endl;
226 streamlog_out ( DEBUG1 ) <<
" starting addIntraModuleGapHits" << endl;
229 const float verySmallDist = 0.01;
230 const float slop = 0.01;
235 float cellsizeA, cellsizeB;
246 streamlog_out ( DEBUG1 )<<
"cell sizes in layer " << il <<
" = " << cellsizeA <<
" " << cellsizeB << endl;
251 if ( theseHits.size()>1 ) {
254 for (
size_t ih=0; ih<theseHits.size()-1; ih++) {
255 for (
size_t jh=ih+1; jh<theseHits.size(); jh++) {
257 for (
int i=0; i<3; i++)
258 dist1d[i] = fabs( theseHits[ih]->getPosition()[i] - theseHits[jh]->getPosition()[i] );
259 float distXY = sqrt( pow( dist1d[0], 2 ) + pow( dist1d[1], 2 ) );
263 if ( dist1d[2]<verySmallDist &&
264 distXY>(1.+slop)*cellsizeA &&
265 distXY<(2.-slop)*cellsizeA ) {
267 enFrac = (distXY-cellsizeA)/cellsizeA;
268 }
else if (distXY<verySmallDist &&
269 dist1d[2]>(1.+slop)*cellsizeB &&
270 dist1d[2]<(2.-
slop)*cellsizeB ) {
272 enFrac = (dist1d[2]-cellsizeB)/cellsizeB;
276 if ( dist1d[1]<verySmallDist &&
277 dist1d[0]>(1.+slop)*cellsizeA &&
278 dist1d[0]<(2.-
slop)*cellsizeA ) {
280 enFrac = (dist1d[0]-cellsizeA)/cellsizeA;
281 }
else if ( dist1d[0]<verySmallDist &&
282 dist1d[1]>(1.+slop)*cellsizeB &&
283 dist1d[1]<(2.-
slop)*cellsizeB ) {
285 enFrac = (dist1d[1]-cellsizeB)/cellsizeB;
290 streamlog_out ( DEBUG1 ) <<
" GOT A GAP " << endl;
292 float position[3]={0.};
293 for (
int k=0;
k<3;
k++)
294 position[
k] = 0.5*(theseHits[ih]->getPosition()[
k] + theseHits[jh]->getPosition()[
k]);
295 float extraEnergy = enFrac*(theseHits[ih]->getEnergy() + theseHits[jh]->getEnergy())/2.;
296 float mintime = std::min( theseHits[ih]->getTime(), theseHits[jh]->getTime() );
297 CHT::CaloType cht_type = CHT::em;
298 CHT::CaloID cht_id = CHT::ecal;
300 CalorimeterHitImpl* newGapHit =
new CalorimeterHitImpl();
302 newGapHit->setPosition( position );
303 newGapHit->setTime( mintime );
304 newGapHit->setType( CHT( cht_type , cht_id , cht_lay , il) );
305 newcol->addElement( newGapHit );
314 streamlog_out ( DEBUG1 ) <<
" done addIntraModuleGapHits " << newcol->getNumberOfElements() << endl;
323 streamlog_out ( DEBUG1 ) <<
" starting addInterModuleGapHits" << endl;
326 const float verySmallDist = 0.01;
332 float cellsizeA, cellsizeB;
348 if ( theseHits.size()==0 )
continue;
351 if ( im+1>=0 && im+1<MAXMODULE ) {
353 if ( nextHits.size()==0 )
continue;
358 for (
size_t ih=0; ih<theseHits.size(); ih++) {
360 for (
size_t jh=0; jh<nextHits.size(); jh++) {
363 for (
int i=0; i<3; i++)
364 dist1d[i] = fabs( theseHits[ih]->getPosition()[i] - nextHits[jh]->getPosition()[i] );
365 float distXY = sqrt( pow( dist1d[0], 2 ) + pow( dist1d[1], 2 ) );
369 if ( distXY<verySmallDist &&
372 enFrac = dist1d[2] / cellsizeB;
376 if ( dist1d[1]<verySmallDist &&
379 enFrac = dist1d[0]/cellsizeA;
380 }
else if ( dist1d[0]<verySmallDist &&
383 enFrac = dist1d[1]/cellsizeB;
388 streamlog_out ( DEBUG1 ) <<
" addInterModuleGapHits: found gap " << dist1d[0] <<
" " << dist1d[1] <<
" " << dist1d[2]<< endl;
390 float position[3]={0.};
391 for (
int k=0;
k<3;
k++)
392 position[
k] = 0.5*(theseHits[ih]->getPosition()[
k] + nextHits[jh]->getPosition()[
k]);
393 float extraEnergy = enFrac*(theseHits[ih]->getEnergy() + nextHits[jh]->getEnergy())/2.;
394 float mintime = std::min( theseHits[ih]->getTime(), nextHits[jh]->getTime() );
395 CHT::CaloType cht_type = CHT::em;
396 CHT::CaloID cht_id = CHT::ecal;
398 CalorimeterHitImpl* newGapHit =
new CalorimeterHitImpl();
400 newGapHit->setPosition( position );
401 newGapHit->setTime( mintime );
402 newGapHit->setType( CHT( cht_type , cht_id , cht_lay , il) );
403 newcol->addElement( newGapHit );
412 streamlog_out ( DEBUG1 ) <<
" done addInterModuleGapHits " << newcol->getNumberOfElements() << endl;
void addInterModuleGapHits(LCCollectionVec *newcol)
void addIntraModuleGapHits(LCCollectionVec *newcol)
dd4hep::rec::LayeredCalorimeterData * _caloGeomData
float _interModuleNonlinearFactor
std::string _outputHitCollection
std::string _inputHitCollection
float _intraModuleNonlinearFactor
void getGeometryData(const int ihitType)
std::string _cellIDStaveString
std::vector< LCCollection * > LCCollectionVec
std::string _cellIDLayerString
BruteForceEcalGapFiller()
bool _applyInterModuleCor
BruteForceEcalGapFiller aBruteForceEcalGapFiller
std::vector< CalorimeterHit * > hitsByLayerModuleStave[MAXLAYER][MAXSTAVE][MAXMODULE]
std::string _cellIDModuleString
virtual void processEvent(LCEvent *evt)