00001 #include "RecoParticleFlow/PFClusterTools/interface/SpaceManager.h"
00002 #include <cassert>
00003 #include <algorithm>
00004 #include <cmath>
00005 #include <TROOT.h>
00006 #include <string>
00007 #include <TH3F.h>
00008 #include <TVirtualFitter.h>
00009 using namespace pftools;
00010
00011 SpaceManager::SpaceManager(std::string name) :
00012 name_(name), barrelLimit_(1.4), transitionLimit_(1.4), endcapLimit_(5.0) {
00013 regionsToSVs_[BARREL_POS] = barrelPosRegion_;
00014 regionsToSVs_[ENDCAP_POS] = endcapPosRegion_;
00015 }
00016
00017 SpaceManager::~SpaceManager() {
00018
00019 }
00020
00021 void SpaceManager::clear() {
00022 for (std::map<SpaceVoxelPtr, CalibratorPtr>::iterator it =
00023 myAddressBook.begin(); it!= myAddressBook.end(); ++it) {
00024 SpaceVoxelPtr s = (*it).first;
00025 CalibratorPtr c = (*it).second;
00026 }
00027 }
00028
00029 void SpaceManager::createCalibrators(const Calibrator& toClone,
00030 const double etaSeg, const double phiSeg, const double energySeg) {
00031 std::cout << __PRETTY_FUNCTION__
00032 << ": this method has not yet been implemented!\n";
00033 PFToolsException me("Unimplemented method! Sorry!");
00034 throw me;
00035
00036 }
00037
00038 void SpaceManager::createCalibrators(const Calibrator& toClone) {
00039 clear();
00040 std::cout << __PRETTY_FUNCTION__
00041 << ": creating default calibration schema.\n";
00042
00043 SpaceVoxelPtr sv(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 0, 3.0));
00044 barrelPosRegion_.push_back(sv);
00045 SpaceVoxelPtr sv1(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 3, 9.0));
00046 barrelPosRegion_.push_back(sv1);
00047 SpaceVoxelPtr sv2(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 9.0, 16.0));
00048 barrelPosRegion_.push_back(sv2);
00049 SpaceVoxelPtr sv3(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 16.0, 25.0));
00050 barrelPosRegion_.push_back(sv3);
00051 SpaceVoxelPtr sv4(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 25.0, 100.0));
00052 barrelPosRegion_.push_back(sv4);
00053 SpaceVoxelPtr sv5(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 100.0, 200.0));
00054 barrelPosRegion_.push_back(sv5);
00055 SpaceVoxelPtr sv6(new SpaceVoxel(-1.0*barrelLimit_, barrelLimit_, -3.2, 3.2, 200.0, 400.0));
00056 barrelPosRegion_.push_back(sv6);
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 SpaceVoxelPtr sve(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 0, 3.0));
00094 endcapPosRegion_.push_back(sve);
00095 SpaceVoxelPtr sve0(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 3.0, 9.0));
00096 endcapPosRegion_.push_back(sve0);
00097 SpaceVoxelPtr sve1(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 9.0, 16.0));
00098 endcapPosRegion_.push_back(sve1);
00099 SpaceVoxelPtr sve2(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 16.0, 25.0));
00100 endcapPosRegion_.push_back(sve2);
00101 SpaceVoxelPtr sve3(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 25.0, 100.0));
00102 endcapPosRegion_.push_back(sve3);
00103 SpaceVoxelPtr sve4(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 100.0, 200.0));
00104 endcapPosRegion_.push_back(sve4);
00105 SpaceVoxelPtr sve5(new SpaceVoxel(barrelLimit_, endcapLimit_, -3.2, 3.2, 200.0, 400.0));
00106 endcapPosRegion_.push_back(sve5);
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 for (std::vector<SpaceVoxelPtr>::iterator it = barrelPosRegion_.begin(); it
00146 != barrelPosRegion_.end(); ++it) {
00147 myKnownSpaceVoxels.push_back(*it);
00148 }
00149
00150 for (std::vector<SpaceVoxelPtr>::iterator it = endcapPosRegion_.begin(); it
00151 != endcapPosRegion_.end(); ++it) {
00152 myKnownSpaceVoxels.push_back(*it);
00153 }
00154
00155 for (std::vector<SpaceVoxelPtr>::iterator it = myKnownSpaceVoxels.begin(); it
00156 != myKnownSpaceVoxels.end(); ++it) {
00157 CalibratorPtr c(toClone.clone());
00158 myAddressBook[*it] = c;
00159 }
00160 std::cout << "Address book size: \t\t"<< myAddressBook.size() << "\n";
00161 std::cout << "Known space voxels size: \t"<< myKnownSpaceVoxels.size()
00162 << "\n";
00163 assert(myAddressBook.size() == myKnownSpaceVoxels.size());
00164
00165 }
00166
00167 void SpaceManager::createCalibrators(const Calibrator& toClone,
00168 const unsigned nEta, const double etaMin, const double etaMax,
00169 const unsigned nPhi, const double phiMin, const double phiMax,
00170 const unsigned nEnergy, const double energyMin, const double energyMax)
00171 throw(PFToolsException&) {
00172 clear();
00173
00174 if (nEta == 0|| nPhi ==0|| nEnergy == 0) {
00175 PFToolsException
00176 me("Can't create calibrators with zero values for nEta, nPhi or nEnergy!");
00177 throw me;
00178 }
00179
00180 double etaSeg = (etaMax - etaMin) / nEta;
00181 double phiSeg = (phiMax - phiMin) / nPhi;
00182 double energySeg = (energyMax - energyMin) / nEnergy;
00183
00184 double eta1, eta2, phi1, phi2, energy1, energy2;
00185 for (unsigned k(0); k < nEta; ++k) {
00186 for (unsigned l(0); l < nPhi; ++l) {
00187 for (unsigned m(0); m < nEnergy; ++m) {
00188 eta1 = etaMin + k * etaSeg;
00189 eta2 = eta1 + etaSeg;
00190
00191 phi1 = phiMin + l * phiSeg;
00192 phi2 = phi1 + phiSeg;
00193
00194 energy1 = energyMin + m * energySeg;
00195 energy2 = energy1 + energySeg;
00196 SpaceVoxelPtr sv(new SpaceVoxel(eta1, eta2, phi1, phi2, energy1, energy2));
00197 myKnownSpaceVoxels.push_back(sv);
00198 CalibratorPtr c(toClone.clone());
00199 myAddressBook[sv] = c;
00200 }
00201 }
00202 }
00203 unsigned nCalibrators = nEta * nPhi * nEnergy;
00204 std::cout << "Created "<< nCalibrators << " calibrators.\n";
00205 std::cout << "Address book size: \t\t"<< myAddressBook.size() << "\n";
00206 std::cout << "Known space voxels size: \t"<< myKnownSpaceVoxels.size()
00207 << "\n";
00208 assert(myAddressBook.size() == myKnownSpaceVoxels.size());
00209 makeInverseAddressBook();
00210
00211 }
00212 CalibratorPtr SpaceManager::createCalibrator(const Calibrator& toClone,
00213 SpaceVoxelPtr s) {
00214 CalibratorPtr c;
00215 int known = count(myKnownSpaceVoxels.begin(), myKnownSpaceVoxels.end(), s);
00216 if (known == 0) {
00217 myKnownSpaceVoxels.push_back(s);
00218 c.reset(toClone.clone());
00219 myAddressBook[s] = c;
00220 } else {
00221 c = myAddressBook[s];
00222 }
00223 assert(c != 0);
00224 return c;
00225
00226 }
00227
00228 CalibratorPtr SpaceManager::findCalibrator(const double eta, const double phi,
00229 const double energy) const {
00230 CalibratorPtr answer;
00231 for (std::vector<SpaceVoxelPtr>::const_iterator cit =
00232 myKnownSpaceVoxels.begin(); cit != myKnownSpaceVoxels.end(); ++cit) {
00233 SpaceVoxelPtr s = *cit;
00234 if (s->contains(eta, phi, energy)) {
00235 assert(count(myKnownSpaceVoxels.begin(), myKnownSpaceVoxels.end(), s) != 0);
00236 answer = (*myAddressBook.find(s)).second;
00237 break;
00238 } else {
00239
00240 }
00241 }
00242 return answer;
00243 }
00244
00245 void SpaceManager::assignCalibration(CalibratorPtr c,
00246 std::map<DetectorElementPtr, double> result) {
00247 calibrationCoeffs_[c] = result;
00248 makeInverseAddressBook();
00249 }
00250
00251 std::map<DetectorElementPtr, double> SpaceManager::getCalibration(CalibratorPtr c) {
00252 return calibrationCoeffs_[c];
00253 }
00254
00255 TH1* SpaceManager::extractEvolution(DetectorElementPtr det, Region r, TF1& f1,
00256 bool useTruth) {
00257
00258 std::vector<SpaceVoxelPtr> region;
00259 if (r == BARREL_POS)
00260 region = barrelPosRegion_;
00261 if (r == ENDCAP_POS)
00262 region = endcapPosRegion_;
00263
00264
00265 std::sort(region.begin(), region.end(), SpaceVoxel());
00266
00267 std::string detElName = DetElNames[det->getType()];
00268 std::string name("hDist_");
00269 name.append(RegionNames[r]);
00270 name.append("_");
00271 name.append(DetElNames[det->getType()]);
00272
00273 double minE(1000);
00274 double maxE(0);
00275
00276 TH2F hDist(name.c_str(), name.c_str(), 100, 0, 300, 50, 0.0, 2.5);
00277
00278
00279 for (std::vector<SpaceVoxelPtr>::iterator i = region.begin(); i
00280 != region.end(); ++i) {
00281 SpaceVoxelPtr s = *i;
00282
00283 if (s->maxEnergy() > maxE)
00284 maxE = s->maxEnergy();
00285 if (s->minEnergy() < minE)
00286 minE = s->minEnergy();
00287 CalibratorPtr c = myAddressBook[s];
00288 double coeff = calibrationCoeffs_[c][det];
00289 if (coeff != 0.0) {
00290 std::vector<ParticleDepositPtr> particles = c->getParticles();
00291 for (std::vector<ParticleDepositPtr>::iterator it =
00292 particles.begin(); it != particles.end(); ++it) {
00293 if (useTruth)
00294 hDist.Fill((*it)->getTruthEnergy(), coeff);
00295 else
00296 hDist.Fill((*it)->getRecEnergy(), coeff);
00297 }
00298 }
00299 }
00300
00301 hDist.FitSlicesY();
00302 hDist.ProfileX();
00303 hDist.Write();
00304 std::string nameProfile(name);
00305 nameProfile.append("_pfx");
00306 name.append("_1");
00307
00308 TH1D* slices = (TH1D*) gDirectory->Get(name.c_str());
00309
00310 TProfile* profile = (TProfile*) gDirectory->Get(nameProfile.c_str());
00311 profile->Fit(&f1);
00312 slices->Fit(&f1);
00313 profile->Write();
00314
00315 return slices;
00316
00317 }
00318
00319 double SpaceManager::evolveCoefficient(DetectorElementPtr det, double energy,
00320 double eta, double phi) {
00321 if (eta < barrelLimit_) {
00322 TF1& func = barrelPosEvolutions_[det];
00323 return func.Eval(energy);
00324 }
00325 TF1& func = endcapPosEvolutions_[det];
00326 return func.Eval(energy);
00327 }
00328
00329 double SpaceManager::interpolateCoefficient(DetectorElementPtr det,
00330 double energy, double eta, double phi) {
00331 CalibratorPtr c = findCalibrator(eta, phi, energy);
00332
00333 SpaceVoxelPtr s = inverseAddressBook_[c];
00334
00335 double midEnergy = (s->minEnergy() + s->maxEnergy())/2.0;
00336
00337 double diffEnergy = energy - midEnergy;
00338 double thisCoeff = calibrationCoeffs_[c][det];
00339
00340 double interpolatedCoeff = thisCoeff;
00341 double adjacentCoeff = 0.0;
00342 double adjacentEnergy = 0.0;
00343 if (diffEnergy > 0) {
00344
00345 CalibratorPtr adjC = findCalibrator(eta, phi, s->maxEnergy() + 0.1);
00346 if (adjC != 0) {
00347 SpaceVoxelPtr adjS = inverseAddressBook_[adjC];
00348 adjacentCoeff = calibrationCoeffs_[adjC][det];
00349 adjacentEnergy = (adjS->minEnergy() + adjS->maxEnergy()) / 2.0;
00350 }
00351 } else {
00352
00353 CalibratorPtr adjC = findCalibrator(eta, phi, s->minEnergy() - 0.1);
00354 if (adjC != 0) {
00355 SpaceVoxelPtr adjS = inverseAddressBook_[adjC];
00356 adjacentCoeff = calibrationCoeffs_[adjC][det];
00357 adjacentEnergy = (adjS->minEnergy() + adjS->maxEnergy()) / 2.0;
00358 }
00359 }
00360 if (adjacentCoeff != 0) {
00361 interpolatedCoeff = thisCoeff + diffEnergy* (adjacentCoeff - thisCoeff)
00362 / (adjacentEnergy - midEnergy);
00363 }
00364 return interpolatedCoeff;
00365 }
00366
00367 std::ostream& SpaceManager::printCalibrations(std::ostream& stream) {
00368 stream << "Calibration results: \n";
00369
00370
00371 stream << "WARNING! Haven't sorted space voxels properly!\n";
00372 for (std::vector<SpaceVoxelPtr>::iterator it = myKnownSpaceVoxels.begin(); it
00373 != myKnownSpaceVoxels.end(); ++it) {
00374 SpaceVoxelPtr s = *it;
00375 CalibratorPtr c = myAddressBook[s];
00376 stream << *s << "\n";
00377 stream << "\t[";
00378 std::map<DetectorElementPtr, double> result = calibrationCoeffs_[c];
00379 for (std::map<DetectorElementPtr, double>::iterator b = result.begin(); b
00380 != result.end(); ++b) {
00381 DetectorElementPtr d = (*b).first;
00382 stream << *d << ": ";
00383 double ans = (*b).second;
00384 stream << ans << ", ";
00385 }
00386 stream << "]\n";
00387 }
00388
00389 return stream;
00390 }
00391
00392 void SpaceManager::makeInverseAddressBook() {
00393 inverseAddressBook_.clear();
00394 for (std::map<SpaceVoxelPtr, CalibratorPtr>::iterator it =
00395 myAddressBook.begin(); it != myAddressBook.end(); ++it) {
00396 SpaceVoxelPtr s = (*it).first;
00397 CalibratorPtr c = (*it).second;
00398 inverseAddressBook_[c] = s;
00399 }
00400 }