AlignRotB.cxx

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////
00002 // $Id: AlignRotB.cxx,v 1.1 2007/01/09 21:45:45 lebedev Exp $
00003 //
00004 // lebedev@physics.harvard.edu
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   // Register module to be updated with a given config version
00039   SetCfgVersion(version);
00040   // Make sure that configuration has been loaded
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; // We must have tracks with BC info
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     // Reinitialize lambda's based on the first-try fit
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   // Reinitialize lambda's based on the first-try fit
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   // Loop through every cluster, exclude it from the fit and compute
00207   // residual
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& /*npar*/, double* /*gin*/, double& f,
00233                   double* par, int /*iflag*/)
00234 {
00235   // Setup field rotation
00236   Swimmer::SetFieldRotZ(par[0], par[1]);
00237   
00238   // Compute the function we want to minimize
00239   f = gModule->ComputeF();
00240 }
00241 
00242 //......................................................................
00243 
00244 void AlignRotB::EndRun(int /*run*/, int /* subrun */)
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   //MakeTree();
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   // Change the flag to signify that our configuration has been read
00326   fIsInit = true;
00327 }
00328 
00329 ////////////////////////////////////////////////////////////////////////

Generated on Mon Nov 23 08:01:43 2009 for MIPP(E907) by  doxygen 1.4.7