4 using namespace marlin ;
13 _description =
"a photon finder processor based on the KIT and KITutil 'classes and fuctions'" ;
15 registerProcessorParameter(
"colNameECAL" ,
16 "ECAL Collection Name" ,
18 std::string(
"ECAL") );
20 registerProcessorParameter(
"collectionNameOfEMShowerCandidates",
21 "Name of the collection of EM shower candidates",
23 std::string(
"EMShowerCandidates"));
25 registerProcessorParameter(
"Cleaning",
26 "To do the cleaning on hits or not ",
29 registerProcessorParameter(
"TopologicalCut",
30 "At which number of neighbors to put the threshold, condition is < so you need to put N+1 ",
34 registerProcessorParameter(
"NumberOfLevels",
35 "Number of levels for central loop ",
38 vector<float> miipstep;
39 miipstep.push_back(0.1);
40 miipstep.push_back(1.5);
41 miipstep.push_back(2.5);
42 miipstep.push_back(4.0);
43 miipstep.push_back(6.0);
44 miipstep.push_back(9.0);
45 miipstep.push_back(16.0);
46 miipstep.push_back(26.0);
47 miipstep.push_back(41.0);
48 miipstep.push_back(65.0);
50 registerProcessorParameter(
"Levels",
51 "Levels for central loop in MIP ",
55 registerProcessorParameter(
"MinHit0",
56 "Minimal Number of hits for ground level cluster ",
60 registerProcessorParameter(
"MinHitSplit",
61 "Minimal Number of hits for i-th level cluster ",
65 registerProcessorParameter(
"Rcut",
66 "Fluctuation suprresion cut",
69 registerProcessorParameter(
"Distcut",
70 "Square of distance cut for merging ",
73 registerProcessorParameter(
"Coscut",
74 "Cosine of the angle for merging ",
78 registerProcessorParameter(
"energyDeviationCut",
79 "cut on energy deviation of em shower candidates from estimated energy ( abs( (Ecluster - Eestimated)/Eestimated ) < cut )",
83 registerProcessorParameter(
"probabilityDensityCut",
84 "cut on the probability density to assign hits to shower cores",
88 registerProcessorParameter(
"DebugLevel",
89 "limits the amount of information written to std out (0 - none, 9 - maximal information)",
93 registerProcessorParameter(
"DrawOnCED",
94 "draw objects on CED",
108 CellIDDecoder<CalorimeterHit>::setDefaultEncoding(
"M:3,S-1:3,I:9,J:9,K-1:6");
134 MarlinCED::newEvent(
this,0);
135 MarlinCED::drawMCParticleTree(evt,
"MCParticle",0.05,4.0,15.5,50.0,1626.0,2500.0);
142 LCCollection* colt = evt->getCollection(
_colNameECAL.c_str()) ;
143 CellIDDecoder<CalorimeterHit> CDECAL(colt);
149 unsigned int nelem=colt->getNumberOfElements();
151 vector<Superhit2*> calo[10];
160 vector <PROTSEED2> prs2;
167 const unsigned int N=
_N;
168 vector< vector<Tmpcl2*> > bbb(N);
181 std::vector<ECALHitWithAttributes> ECALHitsWithAttributes;
183 std::vector<CoreCalib2> coreCalibrationLDC00;
187 for(
unsigned int i=0;i<prs2.size();i++)
189 if(prs2[i].active==
true)
192 double centerPosition[3];
193 centerPosition[0]=(double)prs2[i].cl->getCenter()[0];
194 centerPosition[1]=(double)prs2[i].cl->getCenter()[1];
195 centerPosition[2]=(double)prs2[i].cl->getCenter()[2];
197 double directionOfCluster[3];
198 prs2[i].cl->findInertia();
199 directionOfCluster[0] = prs2[i].cl->direction[0];
200 directionOfCluster[1] = prs2[i].cl->direction[1];
201 directionOfCluster[2] = prs2[i].cl->direction[2];
204 double coreEnergy = 0.0;
205 double startPosition[3];
206 double startPositionMinProjection[3];
207 double startPositionMaxProjection[3];
208 double minProjectionAlongMainPrincipalAxis = DBL_MAX;
209 double maxProjectionAlongMainPrincipalAxis = 0.0;
212 for(
unsigned int j=0;j<prs2[i].cl->hits.size();j++) {
215 coreEnergy += prs2[i].cl->hits[j]->chit->getEnergy();
218 if (
_drawOnCED) ced_hit( prs2[i].cl->hits[j]->chit->getPosition()[0], prs2[i].cl->hits[j]->chit->getPosition()[1],
219 prs2[i].cl->hits[j]->chit->getPosition()[2], 0 | 4 << CED_LAYER_SHIFT, 2, 0xff47e6);
223 double vCenterToHit[3];
224 for(
unsigned int k=0;
k<3;
k++) vCenterToHit[
k] = centerPosition[
k] - prs2[i].cl->hits[j]->chit->getPosition()[
k];
226 double projectionAlongMainPrincipalAxis = 0.0;
227 for(
unsigned int k=0;
k<3;
k++) projectionAlongMainPrincipalAxis += directionOfCluster[
k]*vCenterToHit[
k];
229 if ( projectionAlongMainPrincipalAxis < minProjectionAlongMainPrincipalAxis ) {
231 minProjectionAlongMainPrincipalAxis = projectionAlongMainPrincipalAxis;
232 for(
unsigned int k=0;
k<3;
k++) startPositionMinProjection[
k] = centerPosition[
k] - 2.0*minProjectionAlongMainPrincipalAxis*directionOfCluster[
k];
237 if ( projectionAlongMainPrincipalAxis > maxProjectionAlongMainPrincipalAxis ) {
239 maxProjectionAlongMainPrincipalAxis = projectionAlongMainPrincipalAxis;
240 for(
unsigned int k=0;
k<3;
k++) startPositionMaxProjection[
k] = centerPosition[
k] - 2.0*maxProjectionAlongMainPrincipalAxis*directionOfCluster[
k];
246 double rStartPositionMinProjection = sqrt( pow(startPositionMinProjection[0],2) + pow(startPositionMinProjection[1],2) + pow(startPositionMinProjection[2],2));
247 double rStartPositionMaxProjection = sqrt( pow(startPositionMaxProjection[0],2) + pow(startPositionMaxProjection[1],2) + pow(startPositionMaxProjection[2],2));
249 if ( rStartPositionMinProjection < rStartPositionMaxProjection ) {
251 startPosition[0] = startPositionMinProjection[0];
252 startPosition[1] = startPositionMinProjection[1];
253 startPosition[2] = startPositionMinProjection[2];
258 startPosition[0] = startPositionMaxProjection[0];
259 startPosition[1] = startPositionMaxProjection[1];
260 startPosition[2] = startPositionMaxProjection[2];
269 double photonE =
giveMeEEstimate2(prs2[i].level,prs2[i].cl->getEnergy(),coreCalibrationLDC00);
277 std::cout <<
"EM Shower Core found by the KIT package: " << std::endl
278 <<
"CoreEnergy: " << coreEnergy <<
" " <<
" estimated 'em' particle energy: " << photonE << std::endl
279 <<
"centerPos: " <<
"(" << centerPosition[0] <<
", " << centerPosition[1] <<
", " << centerPosition[2] <<
")"
280 <<
" " <<
"startPos: " <<
"(" << startPosition[0] <<
", " << startPosition[1] <<
", " << startPosition[2] <<
")"
281 << std::endl << std::endl;
286 ced_hit(centerPosition[0],centerPosition[1],centerPosition[2], 2 | 4 << CED_LAYER_SHIFT, 6, 0xffffff);
287 ced_hit(startPosition[0],startPosition[1],startPosition[2], 2 | 4 << CED_LAYER_SHIFT, 6, 0xff0004);
294 if ( photonE > 0.0 ) {
297 Photon2* photonFinder =
new Photon2(photonE,centerPosition,startPosition);
300 for(
unsigned int j = 0; j < nelem; ++j) {
302 double probabilityAndDistance[2];
303 CalorimeterHit* ECALHit =
dynamic_cast<CalorimeterHit*
>(colt->getElementAt(j));
307 bool isECALHitAlreadyAssigned =
false;
308 int indexOfECALHitAlreadyAssigned = 0;
309 for(
unsigned int k = 0;
k < ECALHitsWithAttributes.size(); ++
k) {
311 if ( ECALHitsWithAttributes.at(
k).ECALHit == ECALHit) {
313 isECALHitAlreadyAssigned =
true;
314 indexOfECALHitAlreadyAssigned =
k;
323 if ( !isECALHitAlreadyAssigned ) {
325 if ( probabilityAndDistance[0] > 0.0 ) {
329 hitWithAttributes.
ECALHit = ECALHit;
335 ECALHitsWithAttributes.push_back(hitWithAttributes);
342 if ( probabilityAndDistance[0] > 0.0 ) {
344 ECALHitsWithAttributes.at(indexOfECALHitAlreadyAssigned).relatedCores.push_back(&(prs2[i]));
345 ECALHitsWithAttributes.at(indexOfECALHitAlreadyAssigned).probabilitiesForThisECALHit.push_back(probabilityAndDistance[0]);
346 ECALHitsWithAttributes.at(indexOfECALHitAlreadyAssigned).distancesToCoresForThisECALHit.push_back(probabilityAndDistance[1]);
347 ECALHitsWithAttributes.at(indexOfECALHitAlreadyAssigned).estimatedEnergyPerCore.push_back(photonE);
368 std::cout <<
"CalorimeterHits in ECAL and their probability to belong to EM showers: " << std::endl;
369 for(
unsigned int i = 0; i < ECALHitsWithAttributes.size(); ++i) {
370 std::cout <<
"ECAL Hit: " << ECALHitsWithAttributes.at(i).ECALHit <<
" (" << ECALHitsWithAttributes.at(i).ECALHit->getPosition()[0] <<
", "
371 << ECALHitsWithAttributes.at(i).ECALHit->getPosition()[1] <<
", " << ECALHitsWithAttributes.at(i).ECALHit->getPosition()[2] <<
")" <<
" "
372 <<
"E = " << ECALHitsWithAttributes.at(i).ECALHit->getEnergy() <<
" " << std::endl;
373 std::cout <<
"Cores: " <<
"(";
374 for(
unsigned int j = 0; j < ECALHitsWithAttributes.at(i).relatedCores.size(); ++j) {
375 std::cout << ECALHitsWithAttributes.at(i).relatedCores.at(j);
376 if (j < ECALHitsWithAttributes.at(i).relatedCores.size() - 1) std::cout <<
",";
378 std::cout <<
")" <<
" " << std::endl;
379 std::cout <<
"Probs: " <<
"(";
380 for(
unsigned int j = 0; j < ECALHitsWithAttributes.at(i).probabilitiesForThisECALHit.size(); ++j) {
381 std::cout << ECALHitsWithAttributes.at(i).probabilitiesForThisECALHit.at(j);
382 if (j < ECALHitsWithAttributes.at(i).probabilitiesForThisECALHit.size() - 1) std::cout <<
",";
384 std::cout <<
")" <<
" " << std::endl;
385 std::cout <<
"Dists: " <<
"(";
386 for(
unsigned int j = 0; j < ECALHitsWithAttributes.at(i).distancesToCoresForThisECALHit.size(); ++j) {
387 std::cout << ECALHitsWithAttributes.at(i).distancesToCoresForThisECALHit.at(j);
388 if (j < ECALHitsWithAttributes.at(i).distancesToCoresForThisECALHit.size() - 1) std::cout <<
",";
390 std::cout <<
")" <<
" " << std::endl;
391 std::cout <<
"Estimated EM Energy: " <<
"(";
392 for(
unsigned int j = 0; j < ECALHitsWithAttributes.at(i).estimatedEnergyPerCore.size(); ++j) {
393 std::cout << ECALHitsWithAttributes.at(i).estimatedEnergyPerCore.at(j);
394 if (j < ECALHitsWithAttributes.at(i).estimatedEnergyPerCore.size() - 1) std::cout <<
",";
396 std::cout <<
")" << std::endl << std::endl;
404 std::map<PROTSEED2*,ClusterImpl*> mapCoreToCluster;
405 std::map<PROTSEED2*,double> mapCoreToEstimatedEnergy;
407 for(
unsigned int i = 0; i < ECALHitsWithAttributes.size(); ++i) {
410 double estimatedEnergyOfCoreToAddHitTo = 0.0;
412 if (ECALHitsWithAttributes.at(i).relatedCores.size() == 1) {
414 coreToAddHitTo = ECALHitsWithAttributes.at(i).relatedCores.at(0);
415 estimatedEnergyOfCoreToAddHitTo = ECALHitsWithAttributes.at(i).estimatedEnergyPerCore.at(0);
420 unsigned int indexOfMaxProbability = 0;
421 double maxProbability = 0.0;
423 for(
unsigned int j = 0; j < ECALHitsWithAttributes.at(i).relatedCores.size(); ++j){
425 if ( ECALHitsWithAttributes.at(i).probabilitiesForThisECALHit.at(j) > maxProbability ) {
427 indexOfMaxProbability = j;
428 maxProbability = ECALHitsWithAttributes.at(i).probabilitiesForThisECALHit.at(j);
434 coreToAddHitTo = ECALHitsWithAttributes.at(i).relatedCores.at(indexOfMaxProbability);
435 estimatedEnergyOfCoreToAddHitTo = ECALHitsWithAttributes.at(i).estimatedEnergyPerCore.at(indexOfMaxProbability);
440 std::map<PROTSEED2*,ClusterImpl*>::iterator position = mapCoreToCluster.find(coreToAddHitTo);
442 if ( position == mapCoreToCluster.end() ) {
444 mapCoreToCluster[coreToAddHitTo] =
new ClusterImpl();
445 mapCoreToEstimatedEnergy[coreToAddHitTo] = estimatedEnergyOfCoreToAddHitTo;
446 position = mapCoreToCluster.find(coreToAddHitTo);
450 (*position).second->addHit(ECALHitsWithAttributes.at(i).ECALHit,(float)1.0);
457 for(std::map<PROTSEED2*,ClusterImpl*>::iterator i = mapCoreToCluster.begin(); i != mapCoreToCluster.end(); ++i) {
459 ClusterImpl* cluster = (*i).second;
461 double estimatedEnergyOfCluster = mapCoreToEstimatedEnergy[(*i).first];
464 unsigned int n = cluster->getCalorimeterHits().size();
466 float* x =
new float[n];
467 float* y =
new float[n];
468 float* z =
new float[n];
469 float* a =
new float[n];
472 for (
unsigned int j = 0; j < n; ++j) {
474 x[j] = cluster->getCalorimeterHits().at(j)->getPosition()[0];
475 y[j] = cluster->getCalorimeterHits().at(j)->getPosition()[1];
476 z[j] = cluster->getCalorimeterHits().at(j)->getPosition()[2];
477 a[j] = cluster->getCalorimeterHits().at(j)->getEnergy();
479 energy += cluster->getCalorimeterHits().at(j)->getEnergy();
485 double energyDeviation = fabs( (energy-estimatedEnergyOfCluster)/estimatedEnergyOfCluster );
490 const unsigned int cutOnLayer = 10;
491 const unsigned int contOnNumberOfHitsInLayerCut = 4;
493 unsigned int nHitsInLayerCut = 0;
494 bool hitWithinCutRangeFound =
false;
496 for (
unsigned int j = 0; j < cluster->getCalorimeterHits().size(); ++j) {
498 unsigned int layer = CDECAL(cluster->getCalorimeterHits().at(j))[
"K-1"];
500 if ( layer <= cutOnLayer ) ++nHitsInLayerCut;
502 if ( nHitsInLayerCut >= contOnNumberOfHitsInLayerCut ) {
503 hitWithinCutRangeFound =
true;
515 std::cout << std::endl <<
"Cluster Size:" << cluster->getCalorimeterHits().size() << std::endl
516 <<
"energy of cluster: " << energy <<
" " <<
"estimated energy: " << estimatedEnergyOfCluster <<
" " <<
"deviation: " << energyDeviation << std::endl
517 <<
"Calorimeter Hist in this Cluster:" << std::endl;
518 for (
unsigned int j = 0; j < cluster->getCalorimeterHits().size(); ++j) {
520 std::cout <<
"Position: " <<
"(" << cluster->getCalorimeterHits().at(j)->getPosition()[0] <<
"," << cluster->getCalorimeterHits().at(j)->getPosition()[1] <<
","
521 << cluster->getCalorimeterHits().at(j)->getPosition()[2] <<
")" <<
" " <<
"E = " << cluster->getCalorimeterHits().at(j)->getEnergy() <<
" "
522 <<
"layer: " << CDECAL(cluster->getCalorimeterHits().at(j))[
"K-1"] << std::endl;
534 for (
unsigned int j = 0; j < cluster->getCalorimeterHits().size(); ++j) cluster->getCalorimeterHits().at(j)->ext<
isPartOfEMShowerCandidate>() = 1;
536 ClusterShapes* clusterShape =
new ClusterShapes(n,a,x,y,z);
539 position[0]=clusterShape->getCentreOfGravity()[0];
540 position[1]=clusterShape->getCentreOfGravity()[1];
541 position[2]=clusterShape->getCentreOfGravity()[2];
544 cluster->setPosition(position);
545 cluster->setEnergy(energy);
546 clscol->addElement(cluster);
551 std::cout <<
"EM Shower Candidate FOUND : " <<
"cluster " << cluster <<
" with energy E = " << cluster->getEnergy() <<
" " <<
"n of hits = "
552 << cluster->getCalorimeterHits().size() << std::endl;
558 int color = 0x8f57ff * ( iCluster + 32);
559 MarlinCED::drawClusterImpl(cluster,2,2,color,5);
586 mapCoreToCluster.clear();
587 ECALHitsWithAttributes.clear();
593 for(
unsigned int i=0;i<N;i++)
595 if( bbb[i].size()!=0)
596 for(
unsigned int im=0;im<bbb[i].size();im++)
602 for(
unsigned int im=0;im<2;im++)
604 if(calo[im].size()!=0)
605 for(
unsigned int iij=0;iij<calo[im].size();iij++)
606 delete (calo[im])[iij];
613 }
catch(DataNotAvailableException &
e) {std::cout <<
"no valid ECAL collection in event " <<
_nEvt << std::endl; }
std::vector< double > distancesToCoresForThisECALHit
void Prob(CalorimeterHit *ch, double cut, double *out)
virtual void processEvent(LCEvent *evt)
std::vector< PROTSEED2 * > relatedCores
container for keeping the parameters of the core fineder together
unsigned int MinHitSplit
minimal number of hits in i-th level cluster to be accepted for splitting of the core ...
std::string _collectionNameOfEMShowerCandidates
unsigned int MinHit0
minimal number of hits needed for 0-th level cluster to be accepted as a core candidate ...
virtual void processRunHeader(LCRunHeader *run)
vector< float > _miipstep
void FindCores2(Shitvec2 *secal1, vector< Tmpclvec2 > &bbb, vector< PROTSEED2 > *prs2, unsigned int N, vector< float > miipstep, CoreCut2 Ccut)
Global EM core finding function , iput is vector of superhits, array of Tmpcl vectors bbb for interna...
double Distcut
distance cut for core merging
std::vector< double > probabilitiesForThisECALHit
virtual void check(LCEvent *evt)
void TotalPrecalc2(vector< Superhit2 * > *calo, CellIDDecoder< CalorimeterHit > &id, unsigned int nelem, int Ncut)
Global precalculation function , iput is vector of superhits, ECAL decoder, number of hits...
EMShowerFinder aEMShowerFinder
double Coscut
angular cut for core merging (value of the cosine is stored not the angle!)
container for storing the EM shower core candidates
std::vector< double > estimatedEnergyPerCore
double _energyDeviationCut
std::vector< LCCollection * > LCCollectionVec
double _probabilityDensityCut
double Rcut
fluctuation suppresion cut
double giveMeEEstimate2(int nivo, double Ecore, vector< CoreCalib2 > cc)
returns energy estimate for a given core , input int level, double core energy in GeV...
void CreateCalibrationLDC00(vector< CoreCalib2 > *cc)
Example function for creation of the energy estimaiton table.
void CreateAllShits2(LCCollection *colt, CellIDDecoder< CalorimeterHit > &id, vector< Superhit2 * > *calo)
Creation of superhits, input is ECAL collection ,it's decoded and pointer to resulting container for ...