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