00001
00002
00003
00004
00005
00006
00007 #include "Alignment/AlignRotB.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 "TrkRBase/TrkChamGeo.h"
00015 #include "TrkRBase/TrkCand.h"
00016 #include "TrkRBase/WireClust.h"
00017 #include "TrkRBase/TrkRUtil.h"
00018
00019 #include <TMinuit.h>
00020 #include <TTree.h>
00021
00022 #include <cmath>
00023 #include <cassert>
00024 #include <iostream>
00025
00026 MODULE_DECL(AlignRotB);
00027
00028 using namespace std;
00029 using namespace TrkRUtil;
00030
00031 static AlignRotB* gModule = 0;
00032
00033
00034
00035 AlignRotB::AlignRotB(const char* version) :
00036 JobCModule("AlignRotB")
00037 {
00038
00039 SetCfgVersion(version);
00040
00041 CheckInit();
00042 }
00043
00044
00045
00046 AlignRotB::~AlignRotB()
00047 {
00048 }
00049
00050
00051
00052 JobCResult AlignRotB::Ana(const EDMEventHandle& evt)
00053 {
00054 vector<const TrkCand*> vec(0);
00055
00056 try { evt.Reco().Get(fFolder.c_str(), vec); }
00057 catch (...) { return kFailed; }
00058
00059 TrkInfo_t ti;
00060
00061 for (unsigned int i = 0; i < vec.size(); ++i) {
00062 const TrkCand* trk = vec[i];
00063 if (!trk->SegBC()) continue;
00064
00065 memset(&ti, 0, sizeof(TrkInfo_t));
00066
00067 int nClu = 0;
00068 for (int j = 0; j < trk->NClust(); ++j) {
00069 const WireClust* wc = trk->Clust(j);
00070 int cham = wc->Chamber();
00071 int p = wc->Plane() - 1;
00072 if (wc->NWire() > 1) continue;
00073
00074 nClu++;
00075 ti.fWire[cham][p] = wc->AvgWire();
00076 ti.fWeight[cham][p] = 1.0 / (wc->USig() * wc->USig());
00077 }
00078 if (nClu < fMinNClust) continue;
00079 fTrackList.push_back(ti);
00080 }
00081
00082 return kPassed;
00083 }
00084
00085
00086
00087 void AlignRotB::NewRun(int run, int subrun)
00088 {
00089 GMIPPGeo::Instance(run);
00090 config_bfield(run, subrun);
00091 TrkChamGeo::Instance().Init(run);
00092 fZ0 = GMIPPGeo::Instance().Cham(kBC3).ZGas();
00093 }
00094
00095
00096
00097 double AlignRotB::ComputeF()
00098 {
00099 CalcLambda(fZ0, fLambdaX, fLambdaY);
00100
00101 double u[kNCham * kNPlane];
00102 double w[kNCham * kNPlane];
00103 double z[kNCham * kNPlane];
00104 double cosA[kNCham * kNPlane];
00105 double sinA[kNCham * kNPlane];
00106 double lambdaX[kNCham * kNPlane];
00107 double lambdaY[kNCham * kNPlane];
00108 int chamber[kNCham * kNPlane];
00109
00110 double f = 0;
00111 for (unsigned int i = 0; i < fTrackList.size(); ++i) {
00112 TrkInfo_t& ti = fTrackList[i];
00113
00114 int nClust = 0;
00115 for (int cham = 0; cham < kNCham; ++cham) {
00116 GChamGeo& geo = GMIPPGeo::Instance().Cham(cham);
00117 for (int p = 0; p < kNPlane; ++p) {
00118 if (ti.fWeight[cham][p] < 1e-3) continue;
00119 geo.WireToU(p + 1, ti.fWire[cham][p], u[nClust]);
00120 w[nClust] = ti.fWeight[cham][p];
00121 z[nClust] = geo.Z(p + 1);
00122 cosA[nClust] = geo.GAngleCos(p + 1);
00123 sinA[nClust] = geo.GAngleSin(p + 1);
00124 lambdaX[nClust] = fLambdaX[cham][p];
00125 lambdaY[nClust] = fLambdaY[cham][p];
00126 chamber[nClust] = cham * kNPlane + p;
00127 nClust++;
00128 }
00129 }
00130
00131 double par[5];
00132 FitCurvedTrack(nClust, u, w, z, cosA, sinA, fZ0, lambdaX, lambdaY,
00133 par, 0);
00134
00135
00136 double lx[kNCham][kNPlane], ly[kNCham][kNPlane];
00137 CalcLambda(fZ0, lx, ly, par);
00138 for (int i = 0; i < nClust; ++i) {
00139 int cham =chamber[i] / kNPlane;
00140 int pl = chamber[i] % kNPlane;
00141 lambdaX[i] = lx[cham][pl];
00142 lambdaY[i] = ly[cham][pl];
00143 }
00144 f += FitCurvedTrack(nClust, u, w, z, cosA, sinA, fZ0, lambdaX, lambdaY,
00145 par, 0);
00146 }
00147 return f;
00148 }
00149
00150
00151
00152 double AlignRotB::Fit(const TrkInfo_t& ti, double resid[kNCham][kNPlane],
00153 double dxdz[kNCham])
00154 {
00155 int nClust = 0;
00156 double u[kNCham * kNPlane];
00157 double w[kNCham * kNPlane];
00158 double z[kNCham * kNPlane];
00159 double cosA[kNCham * kNPlane];
00160 double sinA[kNCham * kNPlane];
00161 double lambdaX[kNCham * kNPlane];
00162 double lambdaY[kNCham * kNPlane];
00163 short chamber[kNCham * kNPlane];
00164
00165 for (int cham = 0; cham < kNCham; ++cham) {
00166 GChamGeo& geo = GMIPPGeo::Instance().Cham(cham);
00167 for (int p = 0; p < kNPlane; ++p) {
00168 resid[cham][p] = 0;
00169 if (ti.fWeight[cham][p] < 1e-3) continue;
00170 geo.WireToU(p + 1, ti.fWire[cham][p], u[nClust]);
00171 w[nClust] = ti.fWeight[cham][p];
00172 z[nClust] = geo.Z(p + 1);
00173 cosA[nClust] = geo.GAngleCos(p + 1);
00174 sinA[nClust] = geo.GAngleSin(p + 1);
00175 lambdaX[nClust] = fLambdaX[cham][p];
00176 lambdaY[nClust] = fLambdaY[cham][p];
00177 chamber[nClust] = cham * kNPlane + p;
00178 nClust++;
00179 }
00180 }
00181
00182 double par[5];
00183 FitCurvedTrack(nClust, u, w, z, cosA, sinA, fZ0, lambdaX, lambdaY,
00184 par, 0);
00185
00186
00187 double lx[kNCham][kNPlane], ly[kNCham][kNPlane];
00188 CalcLambda(fZ0, lx, ly, par, kDC1, kPWC6);
00189 for (int i = 0; i < nClust; ++i) {
00190 int cham =chamber[i] / kNPlane;
00191 int pl = chamber[i] % kNPlane;
00192 lambdaX[i] = lx[cham][pl];
00193 lambdaY[i] = ly[cham][pl];
00194 }
00195 FitCurvedTrack(nClust, u, w, z, cosA, sinA, fZ0, lambdaX, lambdaY,
00196 par, 0);
00197 double mom = par[4];
00198 SwimMIPP swim;
00199 swim.Swim(fZ0, par);
00200 for (int c = kDC1; c < kNCham; ++c) {
00201 double p[3];
00202 swim.GetPatZ(GMIPPGeo::Instance().Cham(c).ZGas(), p);
00203 dxdz[c] = p[0] / p[2];
00204 }
00205
00206
00207
00208 for (int i = 0; i < nClust; ++i) {
00209 double saveW = w[i];
00210 w[i] = 0;
00211 FitCurvedTrack(nClust, u, w, z, cosA, sinA, fZ0, lambdaX, lambdaY,
00212 par, 0);
00213 w[i] = saveW;
00214
00215 int c = chamber[i] / kNPlane;
00216 int p = chamber[i] % kNPlane;
00217 GChamGeo& geo = GMIPPGeo::Instance().Cham(c);
00218
00219 double dz = geo.Z(p + 1) - fZ0;
00220 double x = par[0] + dz * par[2] + par[4] * lambdaX[i];
00221 double y = par[1] + dz * par[3] + par[4] * lambdaY[i];
00222 double ufit;
00223 geo.XYToU(p + 1, x, y, ufit);
00224 resid[c][p] = ufit - u[i];
00225 }
00226
00227 return mom;
00228 }
00229
00230
00231
00232 static void gsFCN(int& , double* , double& f,
00233 double* par, int )
00234 {
00235
00236 Swimmer::SetFieldRotZ(par[0], par[1]);
00237
00238
00239 f = gModule->ComputeF();
00240 }
00241
00242
00243
00244 void AlignRotB::EndRun(int , int )
00245 {
00246 if (fTrackList.size() < 200) {
00247 cout << "Can't do minimization with less than 200 tracks!" << endl;
00248 return;
00249 }
00250
00251 cout << "Doing minimization with " << fTrackList.size() << " tracks"
00252 << endl;
00253
00254 gModule = this;
00255
00256 TMinuit minu(2);
00257 minu.SetFCN(gsFCN);
00258
00259 minu.DefineParameter(0, "JGG field z-rotation", 0, 1e-3, -0.02, 0.02);
00260 minu.DefineParameter(1, "Rosie field z-rotation", 0, 1e-3, -0.02, 0.02);
00261
00262 for (unsigned int i = 0; i < fFixParam.size(); ++i)
00263 minu.FixParameter(fFixParam[i]);
00264
00265 minu.Migrad();
00266
00267
00268
00269 for (int i = 0; i < 2; ++i) {
00270 double par, perr;
00271 minu.GetParameter(i, par, perr);
00272 cout << ((i == 0) ? "JGG " : "Rosie ")
00273 << " field rotation: " << par*1e3 << " mrad, err: " << perr*1e3 << endl;
00274 }
00275 }
00276
00277
00278
00279 void AlignRotB::MakeTree()
00280 {
00281 double mom;
00282 double resid[kNCham][kNPlane];
00283 double u[kNCham][kNPlane];
00284 double dxdz[kNCham];
00285
00286 TTree* tree = new TTree("altree", "Post-alignment residuals");
00287 tree->Branch("mom", &mom, "mom/D");
00288 tree->Branch("resid", &resid, "resid[9][4]/D");
00289 tree->Branch("u", &u, "u[9][4]/D");
00290 tree->Branch("dxdz", &dxdz, "dxdz[9]/D");
00291
00292 for (unsigned int i = 0; i < fTrackList.size(); ++i) {
00293 TrkInfo_t& ti = fTrackList[i];
00294
00295 mom = Fit(ti, resid, dxdz);
00296 for (int c = 0; c < kNCham; ++c) {
00297 GChamGeo& geo = GMIPPGeo::Instance().Cham(c);
00298 for (int p = 0; p < kNPlane; ++p) {
00299 if (ti.fWeight[c][p] < 1e-3) u[c][p] = 1e6;
00300 else geo.WireToU(p + 1, ti.fWire[c][p], u[c][p]);
00301 }
00302 }
00303 tree->Fill();
00304 }
00305
00306 tree->Write();
00307 delete tree;
00308 }
00309
00310
00311
00312 void AlignRotB::Update(const CfgConfig& c)
00313 {
00314 c("Debug").Get(fDebug);
00315 c("Folder").Get(fFolder);
00316 c("MinNClust").Get(fMinNClust);
00317 fFixParam.clear();
00318 try { c("FixParam").Get(fFixParam); }
00319 catch (...) {
00320 int i;
00321 c("FixParam").Get(i);
00322 fFixParam.push_back(i);
00323 }
00324
00325
00326 fIsInit = true;
00327 }
00328
00329