- Timestamp:
- Jan 11, 2019, 4:39:56 PM (6 years ago)
- Branches:
- ImprovedOutputFile, Timing, dual_readout, master
- Children:
- e39abb4
- Parents:
- ef8a06d
- Location:
- modules
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
modules/DualReadoutCalorimeter.cc
ref8a06d ra1b19ea 20 20 /** \class DualReadoutCalorimeter 21 21 * 22 * Fills DualReadoutCalorimeter towers, performs DualReadoutCalorimeter resolution smearing, 23 * and creates energy flow objects (tracks, photons, and neutral hadrons). 22 23 // ============ TODO ========================================================= 24 // This implementation of dual calorimetry relies on several approximations: 25 // - If hadronic energy is found in the tower the energy resolution then the full tower enrgy is smeared according to hadronic resolution (pessimistic for (e,n) or (pi+,gamma)) 26 // - While e+ vs pi+ (or gamma vs n) separation is in principle possible for single particles (using C/S, PMT timing, lateral shower profile) it is not obvious it can be done overlapping particles. 27 // Now we assume that regarless of the number of particle hits per tower we can always distinguish e+ vs pi+, which is probably not true in the case (e+,n) vs (pi+,gamma) without longitudinal segmentation. 28 24 29 * 25 * \author P. Demin - UCL, Louvain-la-Neuve30 * \author M. Selvaggi - CERN 26 31 * 27 32 */ … … 67 72 fHCalTowerTrackArray = new TObjArray; 68 73 fItHCalTowerTrackArray = fHCalTowerTrackArray->MakeIterator(); 74 75 fTowerTrackArray = new TObjArray; 76 fItTowerTrackArray = fTowerTrackArray->MakeIterator(); 69 77 70 78 } … … 83 91 if(fHCalTowerTrackArray) delete fHCalTowerTrackArray; 84 92 if(fItHCalTowerTrackArray) delete fItHCalTowerTrackArray; 93 94 if(fTowerTrackArray) delete fTowerTrackArray; 95 if(fItTowerTrackArray) delete fItTowerTrackArray; 85 96 86 97 } … … 212 223 Double_t ecalFraction, hcalFraction; 213 224 Double_t ecalEnergy, hcalEnergy; 214 Double_t ecalSigma, hcalSigma ;215 Double_t energyGuess ;225 Double_t ecalSigma, hcalSigma, sigma; 226 Double_t energyGuess, energy; 216 227 Int_t pdgCode; 217 228 … … 365 376 fECalTrackEnergy = 0.0; 366 377 fHCalTrackEnergy = 0.0; 378 fTrackEnergy = 0.0; 367 379 368 380 fECalTrackSigma = 0.0; 369 381 fHCalTrackSigma = 0.0; 382 fTrackSigma = 0.0; 370 383 371 384 fTowerTrackHits = 0; … … 374 387 fECalTowerTrackArray->Clear(); 375 388 fHCalTowerTrackArray->Clear(); 389 fTowerTrackArray->Clear(); 376 390 377 391 } … … 388 402 ecalEnergy = momentum.E() * fECalTrackFractions[number]; 389 403 hcalEnergy = momentum.E() * fHCalTrackFractions[number]; 404 energy = ecalEnergy + hcalEnergy; 390 405 391 406 if(ecalEnergy > fTimingEnergyMin && fTower) … … 397 412 } 398 413 414 415 /* 399 416 if(fECalTrackFractions[number] > 1.0E-9 && fHCalTrackFractions[number] < 1.0E-9) 400 417 { … … 419 436 } 420 437 438 // muons 421 439 else if(fECalTrackFractions[number] < 1.0E-9 && fHCalTrackFractions[number] < 1.0E-9) 422 440 { 423 441 fEFlowTrackOutputArray->Add(track); 424 442 } 443 */ 444 445 // in Dual Readout we do not care if tracks are ECAL of HCAL 446 if(fECalTrackFractions[number] > 1.0E-9 || fHCalTrackFractions[number] > 1.0E-9) 447 { 448 fTrackEnergy += energy; 449 // this sigma will be used to determine whether neutral excess is significant. We choose the resolution according to bthe higest deposited fraction (in practice had for charged hadrons and em for electrons) 450 sigma = 0.0; 451 if(fHCalTrackFractions[number] > 0) 452 sigma = fHCalResolutionFormula->Eval(0.0, fTowerEta, 0.0, momentum.E()); 453 else 454 sigma = fECalResolutionFormula->Eval(0.0, fTowerEta, 0.0, momentum.E()); 455 456 if(sigma/momentum.E() < track->TrackResolution) 457 energyGuess = ecalEnergy + hcalEnergy; 458 else 459 energyGuess = momentum.E(); 460 461 fTrackSigma += (track->TrackResolution)*energyGuess*(track->TrackResolution)*energyGuess; 462 fTowerTrackArray->Add(track); 463 464 } 465 else 466 { 467 fEFlowTrackOutputArray->Add(track); 468 } 425 469 426 470 continue; … … 461 505 { 462 506 463 464 465 466 507 Candidate *track, *tower, *mother; 467 508 Double_t energy, pt, eta, phi; 468 509 Double_t ecalEnergy, hcalEnergy; 469 Double_t ecalNeutralEnergy, hcalNeutralEnergy ;510 Double_t ecalNeutralEnergy, hcalNeutralEnergy, neutralEnergy; 470 511 471 512 Double_t ecalSigma, hcalSigma, sigma; 472 Double_t ecalNeutralSigma, hcalNeutralSigma ;513 Double_t ecalNeutralSigma, hcalNeutralSigma, neutralSigma; 473 514 474 515 Double_t weightTrack, weightCalo, bestEnergyEstimate, rescaleFactor; … … 491 532 // if no hadronic fraction at all, then use ECAL resolution 492 533 493 //cout<<"fECalTowerEnergy: "<<fECalTowerEnergy<<", fHCalTowerEnergy: "<<fHCalTowerEnergy<<endl; 494 534 //cout<<"fECalTowerEnergy: "<<fECalTowerEnergy<<", fHCalTowerEnergy: "<<fHCalTowerEnergy<<", Eta: "<<fTowerEta<<endl; 535 536 // if no hadronic energy, use ECAL resolution 495 537 if (fHCalTowerEnergy <= fHCalEnergyMin) 496 538 { 497 539 energy = fECalTowerEnergy; 498 540 sigma = fECalResolutionFormula->Eval(0.0, fTowerEta, 0.0, energy); 499 //cout<<"em : "<<energy<<","<<sigma<<endl;541 //cout<<"em energy"<<energy<<", sigma: "<<sigma<<endl; 500 542 } 501 543 … … 505 547 energy = fECalTowerEnergy + fHCalTowerEnergy; 506 548 sigma = fHCalResolutionFormula->Eval(0.0, fTowerEta, 0.0, energy); 507 //cout<<"had : "<<energy<<","<<sigma<<endl;549 //cout<<"had energy: "<<energy<<", sigma: "<<sigma<<endl; 508 550 } 509 551 … … 525 567 if(ecalEnergy < fECalEnergyMin || ecalEnergy < fECalEnergySignificanceMin*ecalSigma) ecalEnergy = 0.0; 526 568 if(hcalEnergy < fHCalEnergyMin || hcalEnergy < fHCalEnergySignificanceMin*hcalSigma) hcalEnergy = 0.0; 527 //cout<<energy<<","<<ecalEnergy<<","<<hcalEnergy<<endl; 528 569 570 //cout<<"Measured energy: "<<energy<<endl; 529 571 530 572 if(fSmearTowerCenter) … … 563 605 } 564 606 565 566 607 fTower->Momentum.SetPtEtaPhiE(pt, eta, phi, energy); 567 608 fTower->Eem = ecalEnergy; … … 579 620 fPhotonOutputArray->Add(fTower); 580 621 } 581 582 622 fTowerOutputArray->Add(fTower); 583 623 } 584 624 625 // fill energy flow candidates 626 627 fTrackSigma = TMath::Sqrt(fTrackSigma); 628 neutralEnergy = max( (energy - fTrackEnergy) , 0.0); 629 neutralSigma = neutralEnergy / TMath::Sqrt(fTrackSigma*fTrackSigma + sigma*sigma); 630 631 //cout<<"trackEnergy: "<<fTrackEnergy<<", trackSigma: "<<fTrackSigma<<", Ntracks: "<<fTowerTrackArray->GetEntries()<<endl; 632 633 //cout<<"neutralEnergy: "<<neutralEnergy<<", neutralSigma: "<<neutralSigma<<endl; 634 635 // For now, if neutral excess is significant, simply create neutral EflowPhoton tower and clone each track into eflowtrack !!! -> Creating only photons !! EFlowNeutralHadron collection will be empy!!! TO BE FIXED 636 if(neutralEnergy > fEnergyMin && neutralSigma > fEnergySignificanceMin) 637 { 638 639 //cout<<"significant neutral excess found:"<<endl; 640 // create new photon tower 641 tower = static_cast<Candidate*>(fTower->Clone()); 642 pt = neutralEnergy / TMath::CosH(eta); 643 //cout<<"Creating tower with Pt, Eta, Phi, Energy: "<<pt<<","<<eta<<","<<phi<<","<<neutralEnergy<<endl; 644 tower->Momentum.SetPtEtaPhiE(pt, eta, phi, neutralEnergy); 645 tower->Eem = neutralEnergy; 646 tower->Ehad = 0.0; 647 tower->PID = 22; 648 649 fEFlowPhotonOutputArray->Add(tower); 650 651 652 //clone tracks 653 fItTowerTrackArray->Reset(); 654 while((track = static_cast<Candidate*>(fItTowerTrackArray->Next()))) 655 { 656 //cout<<"looping over tracks"<<endl; 657 mother = track; 658 track = static_cast<Candidate*>(track->Clone()); 659 track->AddCandidate(mother); 660 fEFlowTrackOutputArray->Add(track); 661 } 662 } 663 664 665 // if neutral excess is not significant, rescale eflow tracks, such that the total charged equals the best measurement given by the DualReadoutCalorimeter and tracking 666 else if(fTrackEnergy > 0.0) 667 { 668 //cout<<"no significant neutral excess found:"<<endl; 669 weightTrack = (fTrackSigma > 0.0) ? 1 / (fTrackSigma*fTrackSigma) : 0.0; 670 weightCalo = (sigma > 0.0) ? 1 / (sigma*sigma) : 0.0; 671 672 bestEnergyEstimate = (weightTrack*fTrackEnergy + weightCalo*energy) / (weightTrack + weightCalo); 673 rescaleFactor = bestEnergyEstimate/fTrackEnergy; 674 675 //rescale tracks 676 fItTowerTrackArray->Reset(); 677 while((track = static_cast<Candidate*>(fItTowerTrackArray->Next()))) 678 { 679 mother = track; 680 track = static_cast<Candidate*>(track->Clone()); 681 track->AddCandidate(mother); 682 683 track->Momentum *= rescaleFactor; 684 685 fEFlowTrackOutputArray->Add(track); 686 } 687 } 688 689 690 /* 585 691 // fill energy flow candidates 586 692 fECalTrackSigma = TMath::Sqrt(fECalTrackSigma); … … 693 799 } 694 800 } 695 696 801 802 */ 697 803 } 698 804 -
modules/DualReadoutCalorimeter.h
ref8a06d ra1b19ea 25 25 * and creates energy flow objects (tracks, photons, and neutral hadrons). 26 26 * 27 * \author P. Demin - UCL, Louvain-la-Neuve27 * \author M. Selvaggi - CERN 28 28 * 29 29 */ … … 59 59 Double_t fECalTowerEnergy, fHCalTowerEnergy; 60 60 Double_t fECalTrackEnergy, fHCalTrackEnergy; 61 Double_t fTrackEnergy; 61 62 62 63 Double_t fTimingEnergyMin; … … 75 76 Double_t fECalTrackSigma; 76 77 Double_t fHCalTrackSigma; 78 Double_t fTrackSigma; 77 79 78 80 Bool_t fSmearTowerCenter; … … 114 116 TIterator *fItHCalTowerTrackArray; //! 115 117 118 TObjArray *fTowerTrackArray; //! 119 TIterator *fItTowerTrackArray; //! 120 116 121 void FinalizeTower(); 117 122 Double_t LogNormal(Double_t mean, Double_t sigma);
Note:
See TracChangeset
for help on using the changeset viewer.