00001
00008 #include "Alignment/LaserAlignment/interface/BeamProfileFitter.h"
00009
00010
00011 #include "FWCore/Framework/interface/ESHandle.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013
00014
00015 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00016 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00017 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00018 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
00019 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00020 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00021 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00022
00023
00024
00025 #include "TF1.h"
00026 #include "TH1.h"
00027 #include "TMath.h"
00028
00029
00030 double BeamProfileFitter::angle(double theAngle)
00031 {
00032 if ( theAngle >= 0.0 )
00033 { return theAngle; }
00034 else if ( theAngle < 0.0 )
00035 { return theAngle + 2.0 * M_PI; }
00036 else
00037 {
00038 edm::LogError("BeamProfileFitter") << "BeamProfileFitter::Angle(..): Warning! Something wrong with this Angle = "
00039 << theAngle << "! Please check!!!";
00040 return -666;
00041 }
00042 }
00043
00044
00045 BeamProfileFitter::BeamProfileFitter(edm::ParameterSet const& theConf, const edm::EventSetup* aSetup ) :
00046 theClearHistoAfterFit(theConf.getUntrackedParameter<bool>("ClearHistogramAfterFit",true)),
00047 theScaleHisto(theConf.getUntrackedParameter<bool>("ScaleHistogramBeforeFit",true)),
00048 theMinSignalHeight(theConf.getUntrackedParameter<double>("MinimalSignalHeight",0.0)),
00049 theCorrectBSkink(theConf.getUntrackedParameter<bool>("CorrectBeamSplitterKink",true)),
00050 theBSAnglesSystematic(theConf.getUntrackedParameter<double>("BSAnglesSystematic",0.0007)) {
00051
00052 theSetup = aSetup;
00053
00054 }
00055
00056
00057
00058 BeamProfileFitter::~BeamProfileFitter() {}
00059
00060
00061
00062
00063 std::vector<LASBeamProfileFit> BeamProfileFitter::doFit(
00064 DetId theDetUnitId,
00065 TH1D * theHistogram,
00066 bool theSaveHistograms,
00067 int ScalingFactor,
00068 int theBeam,
00069 int theDisc,
00070 int theRing,
00071 int theSide,
00072 bool isTEC2TEC,
00073 bool & isGoodResult) {
00074
00075
00076 double theScalingFactor = (double)ScalingFactor;
00077
00078
00079 edm::ESHandle<TrackerGeometry> theTrackerGeometry;
00080 theSetup->get<TrackerDigiGeometryRecord>().get(theTrackerGeometry);
00081 const TrackerGeometry& theTracker(*theTrackerGeometry);
00082
00083
00084 std::vector<LASBeamProfileFit> theResult;
00085
00086 if ( theHistogram )
00087 {
00088 if ( theHistogram->GetEntries() > 0 )
00089 {
00090
00091 const char * theHistoName = theHistogram->GetName();
00092
00093 if (theSaveHistograms)
00094 {
00095
00096
00097 std::string theSavedHistoName = theHistoName;
00098
00099 theSavedHistoName += "Saved";
00100
00101 TH1D *theSavedHist = (TH1D*)theHistogram->Clone(theSavedHistoName.c_str());
00102
00103 theSavedHist->SetDirectory(theHistogram->GetDirectory());
00104 }
00105
00106
00107 TH1D *theCloneHist = (TH1D*)theHistogram->Clone("CloneHist");
00108 if (theScaleHisto) theCloneHist->Scale(theScalingFactor);
00109
00110
00111 std::vector<double> thePeakPosition = findPeakGaus(theCloneHist,theDisc, theRing);
00112
00113
00114
00115 if ( thePeakPosition.at(0) > 0.0 && thePeakPosition.at(1) > 0.0 &&
00116 thePeakPosition.at(2) > 0.0 && thePeakPosition.at(3) > 0.0)
00117 {
00118
00119 double theMean = thePeakPosition.at(0);
00120 double theSigma = thePeakPosition.at(1);
00121 double theMeanError = thePeakPosition.at(2);
00122 double theSigmaError = thePeakPosition.at(3);
00123
00124
00125
00126
00127 std::vector<double> bsKinkPosTEC;
00128 bsKinkPosTEC.push_back(-0.001399 + theBSAnglesSystematic);
00129 bsKinkPosTEC.push_back(-0.000796 + theBSAnglesSystematic);
00130 bsKinkPosTEC.push_back(0.000397 + theBSAnglesSystematic);
00131 bsKinkPosTEC.push_back(-0.001260 + theBSAnglesSystematic);
00132 bsKinkPosTEC.push_back(0.000160 + theBSAnglesSystematic);
00133 bsKinkPosTEC.push_back(0.000068 + theBSAnglesSystematic);
00134 bsKinkPosTEC.push_back(-0.000632 + theBSAnglesSystematic);
00135 bsKinkPosTEC.push_back(0.000562 + theBSAnglesSystematic);
00136 bsKinkPosTEC.push_back(-0.002532 + theBSAnglesSystematic);
00137 bsKinkPosTEC.push_back(-0.000274 + theBSAnglesSystematic);
00138 bsKinkPosTEC.push_back(-0.002072 + theBSAnglesSystematic);
00139 bsKinkPosTEC.push_back(-0.001195 + theBSAnglesSystematic);
00140 bsKinkPosTEC.push_back(-0.001983 + theBSAnglesSystematic);
00141 bsKinkPosTEC.push_back(0.000816 + theBSAnglesSystematic);
00142 bsKinkPosTEC.push_back(0.000693 + theBSAnglesSystematic);
00143 bsKinkPosTEC.push_back(0.000009 + theBSAnglesSystematic);
00144
00145
00146 std::vector<double> bsKinkNegTEC;
00147 bsKinkNegTEC.push_back(0.001010 + theBSAnglesSystematic);
00148 bsKinkNegTEC.push_back(0.000346 + theBSAnglesSystematic);
00149 bsKinkNegTEC.push_back(-0.002120 + theBSAnglesSystematic);
00150 bsKinkNegTEC.push_back(0.000151 + theBSAnglesSystematic);
00151 bsKinkNegTEC.push_back(0.001206 + theBSAnglesSystematic);
00152 bsKinkNegTEC.push_back(-0.002780 + theBSAnglesSystematic);
00153 bsKinkNegTEC.push_back(0.000313 + theBSAnglesSystematic);
00154 bsKinkNegTEC.push_back(-0.001397 + theBSAnglesSystematic);
00155 bsKinkNegTEC.push_back(-0.000386 + theBSAnglesSystematic);
00156 bsKinkNegTEC.push_back(0.000356 + theBSAnglesSystematic);
00157 bsKinkNegTEC.push_back(-0.002350 + theBSAnglesSystematic);
00158 bsKinkNegTEC.push_back(-0.000432 + theBSAnglesSystematic);
00159 bsKinkNegTEC.push_back(0.000251 + theBSAnglesSystematic);
00160 bsKinkNegTEC.push_back(-0.001587 + theBSAnglesSystematic);
00161 bsKinkNegTEC.push_back(-0.002577 + theBSAnglesSystematic);
00162 bsKinkNegTEC.push_back(-0.000478 + theBSAnglesSystematic);
00163
00164
00165
00166 const double theBSPosition = 70.5;
00167
00168
00169 if ( theMean > 0.0 && theMean < 512.0 )
00170 {
00171
00172 const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetUnitId));
00173
00174
00175 double theUncorrectedMean = theMean;
00176
00177 if (theCorrectBSkink)
00178 {
00179 if ( (theDisc == 5) || (theDisc == 6) || (theDisc == 7) || (theDisc == 8) )
00180 {
00181 if (theSide == 1)
00182 {
00183
00184
00185 theMean -= (TMath::Abs(theStripDet->position().z()) - theBSPosition) * tan(bsKinkNegTEC.at(theBeam));
00186 }
00187 else if (theSide == 2)
00188 {
00189
00190
00191 theMean -= (TMath::Abs(theStripDet->position().z()) - theBSPosition) * tan(bsKinkPosTEC.at(theBeam));
00192 }
00193 }
00194 }
00195
00196
00197 TVector3 GlobalPos(theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(theMean)).x(),
00198 theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(theMean)).y(),
00199 theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(theMean)).z());
00200
00201
00202 ErrorFrameTransformer theErrorTransformer;
00203 GlobalError theGlobalPositionError = theErrorTransformer.transform(theStripDet->specificTopology().localError(theMean,pow(theMeanError,2)),
00204 theStripDet->surface());
00205
00206 Float_t gerrors[9] = { theGlobalPositionError.matrix()(1,1), theGlobalPositionError.matrix()(1,2), theGlobalPositionError.matrix()(1,3),
00207 theGlobalPositionError.matrix()(2,1), theGlobalPositionError.matrix()(2,2), theGlobalPositionError.matrix()(2,3),
00208 theGlobalPositionError.matrix()(3,1), theGlobalPositionError.matrix()(3,2), theGlobalPositionError.matrix()(3,3) };
00209 TMatrix GlobalError(3,3,gerrors,"");
00210
00211
00212
00213 TVector3 GlobalPosError(TMath::Sqrt(GlobalError(0,0)),TMath::Sqrt(GlobalError(1,1)),TMath::Sqrt(GlobalError(2,2)));
00214
00215
00216 Double_t GlobalPhi = angle(GlobalPos.Phi());
00217 Double_t GlobalPhiError = phiError(GlobalPos, GlobalError);
00218
00219
00220 theResult.push_back(LASBeamProfileFit(theHistoName, theMean, theMeanError, theUncorrectedMean,
00221 theSigma, theSigmaError, theStripDet->specificTopology().localPitch(theStripDet->specificTopology().localPosition(theMean)), GlobalPhi, GlobalPhiError));
00222
00223 isGoodResult = true;
00224
00225
00226 LogDebug("BeamProfileFitter:doFit") << " **** Results of the Beam Profile Fit for " << theHistoName << " **** "
00227 << "\n Mean = " << theMean << " +/- " << theMeanError
00228 << "\n Sigma = " << theSigma << " +/- " << theSigmaError
00229 << "\n Pitch = " << theStripDet->specificTopology().localPitch(theStripDet->specificTopology().localPosition(theMean))
00230 << "\n Fitted Global Position = (" << GlobalPos.X() << "," << GlobalPos.Y() << "," << GlobalPos.Z() << ")"
00231 << "\n Global Position Error = (" << GlobalPosError.X() << "," << GlobalPosError.Y() << "," << GlobalPosError.Z() << ")"
00232 << "\n Fitted Global Phi = " << GlobalPhi << " +/- " << GlobalPhiError
00233 << "\n ******************************************************************************* ";
00234 }
00235 else
00236 {
00237 edm::LogWarning("BeamProfileFitter::Fit ERROR") << " Error! Result of the fit for detId: " << theDetUnitId.rawId()
00238 << " is not ok! Mean: " << theMean << " is not a value between 0 and 512 ... ";
00239
00240
00241 theResult.push_back(LASBeamProfileFit(theHistoName, 0.0, 0.0, 0.0, 0.0));
00242
00243 isGoodResult = false;
00244 }
00245
00246 }
00247 else
00248 {
00249 edm::LogWarning("BeamProfileFitter:Fit ERROR") << " Error! Result of the fit for detId: " << theDetUnitId.rawId()
00250 << " is not ok! No position information available ... ";
00251
00252
00253 theResult.push_back(LASBeamProfileFit(theHistoName, 0.0, 0.0, 0.0, 0.0));
00254
00255 isGoodResult = false;
00256 }
00257 }
00258 else
00259 {
00260 edm::LogWarning("BeamProfileFitter:Fit ERROR") << "<BeamProfileFitter::DoFit(...)>: Histogram for detId: " << theDetUnitId.rawId()
00261 << " is empty!!! Skipping the fit :-( ... ";
00262
00263
00264 theResult.push_back(LASBeamProfileFit(theHistogram->GetName(), 0.0, 0.0, 0.0, 0.0));
00265
00266 isGoodResult = false;
00267 }
00268 }
00269 else
00270 {
00271 edm::LogWarning("BeamProfileFitter:Fit ERROR") << "<BeamProfileFitter::DoFit(...)>: Histogram for detId: " << theDetUnitId.rawId()
00272 << " does not exist!???? Nothing to fit :-( ... ";
00273
00274
00275 theResult.push_back(LASBeamProfileFit("no histogram found", 0.0, 0.0, 0.0, 0.0));
00276
00277 isGoodResult = false;
00278 }
00279
00280
00281 if (theClearHistoAfterFit)
00282 {
00283 theHistogram->Reset("");
00284 }
00285
00286
00287 return theResult;
00288 }
00289
00290
00291
00292
00293 std::vector<double> BeamProfileFitter::findPeakGaus(TH1D * hist, int theDisc, int theRing)
00294 {
00295 double position = -1.0;
00296 double positionError = -1.0;
00297 double sigmaError = -1.0;
00298
00299 TF1 *fitSignal = new TF1("fitSignal", "gaus" ,0.0,50000.0);
00300 TF1 *fitFun;
00301
00302 hist->SetLineColor(kBlue);
00303 int iMax = hist->GetMaximumBin();
00304 double mu = hist->GetBinCenter(iMax);
00305 double sigma = 200.0;
00306 double sMax = hist->GetBinContent(iMax);
00307 hist->SetMaximum(1.3*sMax);
00308 hist->SetMinimum(0.0);
00309
00310 if (sMax < theMinSignalHeight)
00311 {
00312 LogDebug("BeamProfileFitter:findPeakGaus") << "R" << theRing
00313 << ": Laser signal below threshold for Disc "
00314 << theDisc+1;
00315 std::vector<double> result;
00316 for (int i = 0; i < 4; i++)
00317 { result.push_back(-2.0); }
00318
00319 return result;
00320 }
00321
00322
00323 fitSignal->SetParameters(sMax,mu,sigma);
00324 hist->Fit("fitSignal","EQ","",mu-4*sigma,mu+4*sigma);
00325 fitFun = hist->GetFunction("fitSignal");
00326 sMax = fitFun->GetParameter(0);
00327 mu = fitFun->GetParameter(1);
00328 sigma = fabs(fitFun->GetParameter(2));
00329 fitSignal->SetParameters(sMax,mu,sigma);
00330 hist->Fit("fitSignal","EQ","",mu-2*sigma,mu+2*sigma);
00331 fitFun = hist->GetFunction("fitSignal");
00332 position = fitFun->GetParameter(1);
00333
00334
00335
00336 if ( (theDisc == 0 || theDisc == 1) && (theRing == 6) )
00337 {
00338 fitSignal->SetParameters(sMax,mu,sigma);
00339 hist->Fit("fitSignal","EQ","",mu-1*sigma,mu+1*sigma);
00340 fitFun = hist->GetFunction("fitSignal");
00341 position = fitFun->GetParameter(1);
00342
00343 }
00344
00345 int iBin0 = hist->FindBin(position-6*sigma);
00346 int iBin1 = hist->FindBin(position+6*sigma);
00347 bool refit = false;
00348 for (int i=iBin0; i<=iBin1; i++)
00349 {
00350 if (hist->GetBinContent(i)<=0)
00351 {
00352 hist->SetBinError(i,100000.0);
00353 refit = true;
00354 }
00355 }
00356 if (refit)
00357 {
00358 if (theDisc != 0 && theDisc != 1)
00359 {
00360 fitSignal->SetParameters(hist->GetBinContent(iMax),hist->GetBinCenter(iMax),200.0);
00361 hist->Fit("fitSignal","EQ","",mu-4*sigma,mu+4*sigma);
00362 fitFun = hist->GetFunction("fitSignal");
00363 position = fitFun->GetParameter(1);
00364 }
00365 else
00366 {
00367 sigma = 100.0;
00368 fitSignal->SetParameters(hist->GetBinContent(iMax),hist->GetBinCenter(iMax),200.0);
00369 hist->Fit("fitSignal","EQ","",mu-4*sigma,mu+4*sigma);
00370 fitFun = hist->GetFunction("fitSignal");
00371 sMax = fitFun->GetParameter(0);
00372 mu = fitFun->GetParameter(1);
00373 sigma = fabs(fitFun->GetParameter(2));
00374 fitSignal->SetParameters(sMax,mu,sigma);
00375 hist->Fit("fitSignal","EQ","",mu-2*sigma,mu+2*sigma);
00376 fitFun = hist->GetFunction("fitSignal");
00377 position = fitFun->GetParameter(1);
00378 sigma = fitFun->GetParameter(2);
00379 }
00380 }
00381
00382 position = fitFun->GetParameter(1);
00383 positionError = fitFun->GetParError(1);
00384 sigma = fitFun->GetParameter(2);
00385 sigmaError = fitFun->GetParError(2);
00386
00387
00388 std::vector<double> result;
00389 result.push_back(position);
00390 result.push_back(sigma);
00391 result.push_back(positionError);
00392 result.push_back(sigmaError);
00393
00394 return result;
00395 }
00396
00397 Double_t BeamProfileFitter::phiError(TVector3 thePosition, TMatrix theCovarianceMatrix)
00398 {
00399
00400 Double_t aX = thePosition.X();
00401 Double_t aY = thePosition.Y();
00402 Double_t aVarX = theCovarianceMatrix(0,0);
00403 Double_t aVarY = theCovarianceMatrix(1,1);
00404 Double_t aCovXY = theCovarianceMatrix(0,1);
00405
00406 Double_t thePhiError = 0.0;
00407
00408 thePhiError = TMath::Sqrt( TMath::Abs( pow(aY, 2)/( pow(aX, 4) + 2 * pow(aX,2) * pow(aY,2) + pow(aY, 4) ) * aVarX
00409 + pow(aX, 2)/( pow(aX, 4) + 2 * pow(aX,2) * pow(aY,2) + pow(aY, 4) ) * aVarY
00410 - 2.0 * aX*aY/( pow(aX, 4) + 2 * pow(aX,2) * pow(aY,2) + pow(aY, 4) ) *aCovXY
00411 ));
00412
00413 return thePhiError;
00414 }
00415