00001
00002
00003
00004
00005
00006
00007 #include "Alignment/AlignTPCDrift.h"
00008
00009 #include "Bfield/bfield.h"
00010 #include "Bfield/BFMagnet.h"
00011 #include "Config/CfgConfig.h"
00012 #include "Config/CfgParam.h"
00013 #include "EventDataModel/EDMEventHandle.h"
00014 #include "Geometry/GTPCGeo.h"
00015 #include "RecoBase/RBKTrack.h"
00016 #include "RecoBase/RBKVertex.h"
00017 #include "RecoBase/RBViewHit.h"
00018 #include "Swimmer/SwimDrift.h"
00019 #include "Swimmer/SwimMIPP.h"
00020 #include "TPCRecoJP/TPCRHit.h"
00021 #include "TrkRBase/TrkRUtil.h"
00022
00023 #include <TMinuit.h>
00024 #include <cmath>
00025
00026 MODULE_DECL(AlignTPCDrift);
00027
00028 using namespace std;
00029
00030 AlignTPCDrift* AlignTPCDrift::gModule = 0;
00031
00032
00033
00034 AlignTPCDrift::AlignTPCDrift(const char* version) :
00035 JobCModule("AlignTPCDrift")
00036 {
00037
00038 SetCfgVersion(version);
00039
00040 CheckInit();
00041 }
00042
00043
00044
00045 AlignTPCDrift::~AlignTPCDrift()
00046 {
00047 }
00048
00049
00050
00051 JobCResult AlignTPCDrift::Ana(const EDMEventHandle& evt)
00052 {
00053 vector<const RBKVertex*> vtx(0);
00054
00055 try { evt.Reco().Get(fFolder.c_str(), vtx); }
00056 catch (...) { return kFailed; }
00057 if (vtx.empty()) { return kFailed;}
00058
00059 TrkInfo_t ti;
00060 GTPCGeo& tpcgeo = GMIPPGeo::Instance().TPC();
00061
00062 int nGood = 0;
00063 for (unsigned int i = 0; i < vtx.size(); ++i) {
00064 const RBKVertex* v = vtx[i];
00065 if (fRequireBeamTrk && !v->InTrack()) continue;
00066 int nTrk = v->NTracks() + (v->InTrack() ? 1 : 0);
00067 if (nTrk < fMinTrkVtx) continue;
00068
00069 for (int j = 0; j < v->NTracks(); ++j) {
00070 const RBKTrack* t = v->OutTrack(j);
00071
00072 if (t->NSpacePoints() < fMinTPCHits ||
00073 t->NSpacePoints() > fMaxTPCHits ||
00074 t->NViewHits() < fMinChamHits ||
00075 fabs(t->QoP()) > fMinP ||
00076 t->Time() < fMinTrkTime ||
00077 t->Time() > fMaxTrkTime ||
00078 t->GoF() < fMinGoF) {
00079 if (fDebug) {
00080 cout << "Skipping track: nSpacePts=" << t->NSpacePoints()
00081 << " nViewHits=" << t->NViewHits()
00082 << " QoP=" << t->QoP()
00083 << " T=" << t->Time()
00084 << " GoF=" << t->GoF()
00085 << endl;
00086 }
00087 continue;
00088 }
00089
00090 ti.fNTPCHit = t->NSpacePoints();
00091 if (ti.fNTPCHit > 128) ti.fNTPCHit = 128;
00092 for (int j = 0; j < ti.fNTPCHit; ++j) {
00093 const TPCRHit* hit =
00094 & dynamic_cast<const TPCRHit&>(t->SpacePoint(j));
00095 assert (hit);
00096 ti.fPadX[j] = tpcgeo.PadColToX(hit->PadCol());
00097 ti.fPadZ[j] = tpcgeo.PadRowToZ(hit->PadRow());
00098 ti.fDriftT[j] = hit->TDC() * GTPCGeo::kUsecPerBucket +
00099 tpcgeo.TOffset();
00100 }
00101
00102 ti.fNChamHit = t->NViewHits();
00103 if (ti.fNChamHit > 36) ti.fNChamHit = 36;
00104 for (int j = 0; j < ti.fNChamHit; ++j) {
00105 const RBViewHit& hit = t->ViewHit(j);
00106 ti.fChamZ[j] = hit.Z();
00107 ti.fU[j] = hit.U();
00108 ti.fW[j] = 1 / (hit.USig() * hit.USig());
00109 ti.fCosA[j] = hit.CosTheta();
00110 ti.fSinA[j] = hit.SinTheta();
00111 }
00112 ti.fZ0 = t->VtxZ();
00113 ti.fPar[0] = t->VtxX();
00114 ti.fPar[1] = t->VtxY();
00115 ti.fPar[2] = t->VtxDXDZ();
00116 ti.fPar[3] = t->VtxDYDZ();
00117 ti.fPar[4] = t->QoP();
00118 if (fabs(ti.fPar[4]) < 1e-3) ti.fPar[4] = 1e-3;
00119
00120 ti.fSwim = new SwimMIPP;
00121 ti.fSwim->Swim(ti.fZ0, ti.fPar);
00122
00123 fTrkInfo.push_back(ti);
00124 ++nGood;
00125 }
00126 }
00127
00128 if (fDebug) cout << " picked " << nGood << " tracks" << endl;
00129
00130 return (nGood > 0);
00131 }
00132
00133
00134
00135 void AlignTPCDrift::NewRun(int run, int subrun)
00136 {
00137 GMIPPGeo::Instance(run);
00138 config_bfield(run, subrun);
00139
00140 fTrigOffset = 0.1;
00141 fXOffset = 0;
00142 fYOffset = GMIPPGeo::Instance().TPC().YOffset();
00143 fZOffset = 0;
00144
00145 }
00146
00147
00148
00149 void AlignTPCDrift::EndRun(int , int )
00150 {
00151 if (fTrkInfo.size() < 5) {
00152 cout << "Can't do minimization with " << fTrkInfo.size() << " tracks"
00153 << endl;
00154 return;
00155 }
00156 cout << "AlignTPCDrift: doing minimization with " << fTrkInfo.size()
00157 << " tracks" << endl;
00158 gModule = this;
00159
00160 TMinuit* minu = new TMinuit(15);
00161 minu->SetMaxIterations(1000000);
00162 minu->SetFCN(AlignTPCDrift::MinFCN);
00163 char name[32];
00164 int nPar = 0;
00165 for (int i = 0; i < 6; ++i) {
00166 sprintf(name, "X par %d", i);
00167 minu->DefineParameter(nPar, name, fInitParam[nPar],
00168 0.3 * fabs(fInitParam[nPar]) + 0.001, -5, 5);
00169 ++nPar;
00170 }
00171 for (int i = 0; i < 4; ++i) {
00172 sprintf(name, "Y par %d", i);
00173 minu->DefineParameter(nPar, name, fInitParam[nPar],
00174 0.3 * fabs(fInitParam[nPar]) + 0.001, -5, 5);
00175 ++nPar;
00176 }
00177 for (int i = 0; i < 5; ++i) {
00178 sprintf(name, "Z par %d", i);
00179 minu->DefineParameter(nPar, name, fInitParam[nPar],
00180 0.3 * fabs(fInitParam[nPar]) + 0.001, -5, 5);
00181 ++nPar;
00182 }
00183
00184 for (unsigned int i = 0; i < fFixParam.size(); ++i)
00185 minu->FixParameter(fFixParam[i]);
00186
00187 SwimDrift::Instance().SetUseDriftMap(2);
00188 minu->Migrad();
00189
00190 delete minu;
00191 }
00192
00193
00194
00195 void AlignTPCDrift::MinFCN(int& , double* , double& f,
00196 double* par, int )
00197 {
00198 SwimDrift::Instance().SetFitDrift(&par[0], &par[6], &par[6+4]);
00199
00200 f = 0;
00201 for (unsigned int i = 0; i < gModule->fTrkInfo.size(); ++i)
00202 f += gModule->ComputeTrkChi2(gModule->fTrkInfo[i]);
00203
00204 }
00205
00206
00207
00208 void AlignTPCDrift::Update(const CfgConfig& c)
00209 {
00210 c("Debug").Get(fDebug);
00211 c("Folder").Get(fFolder);
00212 c("InitParam").Get(fInitParam);
00213 fFixParam.clear();
00214 try { c("FixParam").Get(fFixParam); }
00215 catch (...) {
00216 int val;
00217 c("FixParam").Get(val);
00218 fFixParam.push_back(val);
00219 }
00220 c("MinTrkVtx").Get(fMinTrkVtx);
00221 c("RequireBeamTrk").Get(fRequireBeamTrk);
00222 c("MinTPCHits").Get(fMinTPCHits);
00223 c("MaxTPCHits").Get(fMaxTPCHits);
00224 c("MinChamHits").Get(fMinChamHits);
00225 c("MinP").Get(fMinP);
00226 fMinP = (fMinP > 0) ? 1 / fMinP : 1e6;
00227 c("MinGoF").Get(fMinGoF);
00228 c("TPCSigmaX").Get(fTPCSigmaX);
00229 fTPCSigmaX = 1 / (fTPCSigmaX * fTPCSigmaX);
00230 c("TPCSigmaY").Get(fTPCSigmaY);
00231 fTPCSigmaX = 1 / (fTPCSigmaY * fTPCSigmaY);
00232
00233 c("MinTrkTime").Get(fMinTrkTime);
00234 c("MaxTrkTime").Get(fMaxTrkTime);
00235
00236
00237 fIsInit = true;
00238 }
00239
00240
00241
00242 double AlignTPCDrift::ComputeTrkChi2(TrkInfo_t& ti)
00243 {
00244
00245 GTPCGeo& geo = GMIPPGeo::Instance().TPC();
00246 SwimDrift& drift = SwimDrift::Instance();
00247 double xPad[3], xGlob[3], xCorr[3];
00248
00249 double chi2 = 0;
00250 for (int i = 0; i < ti.fNTPCHit; ++i) {
00251 xPad[0] = ti.fPadX[i];
00252 xPad[1] = 0;
00253 xPad[2] = ti.fPadZ[i];
00254
00255 geo.PPLNToCAVE(xPad, xGlob);
00256
00257 drift.CorrectDistortion(xGlob, xCorr, ti.fDriftT[i]);
00258
00259 chi2 += ti.fSwim->DsqrPointToTrack(xCorr[0], xCorr[1], xCorr[2]);
00260 }
00261
00262 return chi2;
00263 }
00264
00265