AlignChamZNoBF.cxx

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////
00002 // $Id: AlignChamZNoBF.cxx,v 1.2 2007/07/05 21:55:40 jpaley Exp $
00003 //
00004 // lebedev@physics.harvard.edu
00005 ////////////////////////////////////////////////////////////////////////
00006 
00007 #include "Alignment/AlignChamZNoBF.h"
00008 
00009 #include "Config/CfgConfig.h"
00010 #include "Config/CfgParam.h"
00011 #include "EventDataModel/EDMEventHandle.h"
00012 #include "TrkRBase/TrackSeg.h"
00013 #include "TrkRBase/TrkRUtil.h"
00014 
00015 #include <TMinuit.h>
00016 #include <TTree.h>
00017 
00018 #include <iostream>
00019 #include <cmath>
00020 
00021 MODULE_DECL(AlignChamZNoBF);
00022 using namespace std;
00023 
00024 static AlignChamZNoBF* gModule = 0;
00025 
00026 //......................................................................
00027 
00028 AlignChamZNoBF::AlignChamZNoBF(const char* version) :
00029   JobCModule("AlignChamZNoBF")
00030 {
00031   // Register module to be updated with a given config version
00032   SetCfgVersion(version);
00033   // Make sure that configuration has been loaded
00034   CheckInit();
00035 }
00036 
00037 //......................................................................
00038 
00039 AlignChamZNoBF::~AlignChamZNoBF()
00040 {
00041 }
00042 
00043 //......................................................................
00044 
00045 JobCResult AlignChamZNoBF::Ana(const EDMEventHandle& evt)
00046 {
00047   evt.Raw();
00048   evt.Cal();
00049   std::vector<const TrackSeg*> seg(0);
00050   try {
00051     evt.Reco().Get(fSegFolder.c_str(), seg); 
00052     if (seg.empty()) return kFailed;
00053     if (fDebug) cout << "Got " << seg.size() << " tracks" << endl;
00054   }
00055   catch (...) { return kFailed; }
00056 
00057   TrkInfo_t ti;
00058   double resid[6][4];
00059 
00060   for (unsigned int i = 0; i < seg.size(); ++i) {
00061     const TrackSeg* trk = seg[i];
00062 
00063     if (trk->NClust() < fMinNClust) continue;
00064 
00065     int nGoodClu = 0;
00066 
00067     memset(&ti, 0, sizeof(ti));
00068 
00069     for (int c = kDC1; c < kNCham; ++c) {
00070       for (int p = 0; p < kNPlane; ++p) {
00071     const WireClust* wc = trk->Clust(c, p);
00072     if (!wc || wc->NWire() > 1) continue;
00073     nGoodClu++;
00074     ti.fWire[c - kDC1][p] = wc->AvgWire();
00075     ti.fWeight[c - kDC1][p] = 1.0 / (wc->USig() * wc->USig());
00076       }
00077     }
00078 
00079     if (nGoodClu < fMinNClust) continue;
00080 
00081     // Make sure that track residuals are reasonable
00082     Fit(ti, resid);
00083     for (int c = 0; c < 6 && nGoodClu > 0; ++c) {
00084       for (int p = 0; p < kNPlane; ++p) {
00085     if (ti.fWeight[c][p] > 1 && 
00086         fabs(resid[c][p]) > 1.5 * GChamGeo::Pitch(c + kDC1)) {
00087       nGoodClu = 0;
00088       break;
00089     }
00090       }
00091     }
00092 
00093     if (nGoodClu < fMinNClust) continue;
00094 
00095     fTrackList.push_back(ti);
00096   }
00097 
00098   return kPassed;
00099 }
00100 
00101 //......................................................................
00102   
00103 void AlignChamZNoBF::NewRun(int run, int /*subrun*/)
00104 {
00105   GMIPPGeo::Instance(run);
00106 }
00107 
00108 //......................................................................
00109 
00110 double AlignChamZNoBF::ComputeF()
00111 {
00112   if (fUseCorr) return ComputeCorrF();
00113   else return ComputeChi2F();
00114 }
00115 
00116 //......................................................................
00117 
00118 double AlignChamZNoBF::ComputeChi2F()
00119 {
00120   double f = 0;
00121 
00122   double u[24];
00123   double w[24];
00124   double z[24];
00125   double cosA[24];
00126   double sinA[24];
00127   double z1 = GMIPPGeo::Instance().Cham(kDC1).ZGas() - 50;
00128   double z2 = GMIPPGeo::Instance().Cham(kPWC6).ZGas() + 50;
00129   double par[4];
00130   double parErr[4];
00131 
00132   for (unsigned int i = 0; i < fTrackList.size(); ++i) {
00133     TrkInfo_t& ti = fTrackList[i];
00134 
00135     int nClu = 0;
00136     
00137     for (int c = 0; c < 6; ++c) {
00138       GChamGeo& geo = GMIPPGeo::Instance().Cham(c + kDC1);
00139       for (int p = 0; p < kNPlane; ++p) {
00140     if (ti.fWeight[c][p] < 1e-3) continue;
00141     
00142     geo.WireToU(p + 1, ti.fWire[c][p], u[nClu]);
00143     w[nClu] = ti.fWeight[c][p];
00144     z[nClu] = geo.Z(p + 1);
00145     cosA[nClu] = geo.GAngleCos(p + 1);
00146     sinA[nClu] = geo.GAngleSin(p + 1);
00147     
00148     nClu++;
00149       }
00150     }
00151     
00152     f += TrkRUtil::FitLineFromWires(nClu, u, w, z, cosA, sinA, z1, z2, 
00153                     par, parErr);
00154   }
00155   return f;
00156 }
00157 
00158 //......................................................................
00159 
00160 double AlignChamZNoBF::ComputeCorrF() {
00161   double resid[6][kNPlane];
00162   int n[6][kNPlane];
00163   double x[6][kNPlane];
00164   double y[6][kNPlane];
00165   double xx[6][kNPlane];
00166   double yy[6][kNPlane];
00167   double xy[6][kNPlane];
00168   memset(x, 0, sizeof(x));
00169   memset(n, 0, sizeof(n));
00170   memset(y, 0, sizeof(y));
00171   memset(xx, 0, sizeof(xx));
00172   memset(yy, 0, sizeof(yy));
00173   memset(xy, 0, sizeof(xy));
00174 
00175   for (unsigned int i = 0; i < fTrackList.size(); ++i) {
00176     TrkInfo_t& ti = fTrackList[i];
00177     double dxdz = Fit(ti, resid);
00178 
00179     for (int c = 0; c < 6; ++c) {
00180       for (int p = 0; p < kNPlane; ++p) {
00181     if (ti.fWeight[c][p] < 1) continue;
00182         n[c][p]++;
00183         x[c][p] += dxdz;
00184         xx[c][p] += dxdz * dxdz;
00185         y[c][p] += resid[c][p];
00186         yy[c][p] += resid[c][p] * resid[c][p];
00187         xy[c][p] += dxdz * resid[c][p];
00188       }
00189     }
00190   }
00191   double f = 0;
00192   for (int c = 0; c < 6; ++c) {
00193     for (int p = 0; p < kNPlane; ++p) {
00194       if (n[c][p] < 10) continue;
00195 
00196       // Add square of correlation coefficient for this plane
00197       double corr = (n[c][p] * xy[c][p] - x[c][p] * y[c][p]);
00198       corr *= corr;
00199       corr /= (n[c][p] * xx[c][p] - x[c][p] * x[c][p]) *
00200         (n[c][p] * yy[c][p] - y[c][p] * y[c][p]);
00201       assert(fabs(corr) < 1);
00202 
00203       f += corr;
00204     }
00205   }
00206   return f;
00207 }
00208 
00209 //......................................................................
00210 
00211 double AlignChamZNoBF::Fit(TrkInfo_t& ti, double resid[6][4], float* dydz,
00212              float xc[6][4], float yc[6][4])
00213 {
00214   double u[24];
00215   double w[24];
00216   double z[24];
00217   double cosA[24];
00218   double sinA[24];
00219   double z1 = GMIPPGeo::Instance().Cham(kDC1).ZGas() - 50;
00220   double z2 = GMIPPGeo::Instance().Cham(kPWC6).ZGas() + 50;
00221   double par[4];
00222   double parErr[4];
00223   int plane[24];
00224 
00225   int nClu = 0;
00226 
00227   for (int c = 0; c < 6; ++c) {
00228     GChamGeo& geo = GMIPPGeo::Instance().Cham(c + kDC1);
00229     for (int p = 0; p < kNPlane; ++p) {
00230       if (ti.fWeight[c][p] < 1e-3) {
00231     resid[c][p] = 1e6;
00232     continue;
00233       }
00234 
00235       geo.WireToU(p + 1, ti.fWire[c][p], u[nClu]);
00236       w[nClu] = ti.fWeight[c][p];
00237       z[nClu] = geo.Z(p + 1);
00238       cosA[nClu] = geo.GAngleCos(p + 1);
00239       sinA[nClu] = geo.GAngleSin(p + 1);
00240       plane[nClu] = c * 4 + p;
00241 
00242       nClu++;
00243     }
00244   }
00245 
00246   TrkRUtil::FitLineFromWires(nClu, u, w, z, cosA, sinA, z1, z2, 
00247                  par, parErr);
00248 
00249   double x1[3] = {par[0], par[1], z1};
00250   double x2[3] = {par[2], par[3], z2};
00251   double x[3];
00252 
00253   double dxdz = (par[2] - par[0]) / (z2 - z1);
00254   if (dydz) *dydz = (par[3] - par[1]) / (z2 - z1);
00255   if (xc && yc) {
00256     for (int c = 0; c < 6; ++c) {
00257       GChamGeo& geo = GMIPPGeo::Instance().Cham(c + kDC1);
00258       for (int p = 0; p < 4; ++p) {
00259     x[2] = geo.Z(p + 1);
00260     TrkRUtil::PredictXY(x1, 0, x2, 0, x, 0);
00261     xc[c][p] = x[0];
00262     yc[c][p] = x[1];
00263       }
00264     }
00265   }
00266 
00267   for (int i = 0; i < nClu; ++i) {
00268     double saveW = w[i];
00269     w[i] = 0;
00270     TrkRUtil::FitLineFromWires(nClu, u, w, z, cosA, sinA, z1, z2, 
00271                    par, parErr);
00272     w[i] = saveW;
00273 
00274     x1[0] = par[0];
00275     x1[1] = par[1];
00276     x2[0] = par[2];
00277     x2[1] = par[3];
00278     x[2] = z[i];
00279     TrkRUtil::PredictXY(x1, 0, x2, 0, x, 0);
00280     
00281     int c = plane[i] / 4;
00282     int p = plane[i] % 4;
00283     GMIPPGeo::Instance().Cham(c + kDC1).XYToU(p + 1, x[0], x[1], 
00284                           resid[c][p]);
00285     resid[c][p] -= u[i];
00286   }
00287 
00288   return dxdz;
00289 }
00290 
00291 //......................................................................
00292 
00293 static void gsFCN(int& /*npar*/, double* /*gin*/, double& f,
00294                   double* par, int /*iflag*/)
00295 {
00296   // Setup geometry based on the new constants
00297   for (int i = 0; i < 6; ++i) {
00298     GMIPPGeo::Instance().Cham(i + kDC1).SetZGas(par[i]);
00299     GMIPPGeo::Instance().Cham(i + kDC1).SetGAngle(par[i + 6] * 1e-3);
00300   }
00301 
00302   f = gModule->ComputeF();
00303 }
00304 
00305 //......................................................................
00306   
00307 void AlignChamZNoBF::EndRun(int /*run*/, int /*subrun*/)
00308 {
00309   if (fTrackList.size() < 100) {
00310     cout << "Can't do alignment with " << fTrackList.size() << " tracks"
00311      << endl;
00312     return;
00313   }
00314 
00315   cout << "Doing no B-field alignment with " << fTrackList.size()
00316        << " tracks" << endl;
00317 
00318   MakeTree("pre");
00319 
00320   gModule = this;
00321   TMinuit minu(12);
00322   minu.SetFCN(gsFCN);
00323   
00324   char name[256];
00325   int ierr;
00326   double savePos[6], saveAng[6];
00327   for (int i = 0; i < 6; ++i) {
00328     GChamGeo& geo = GMIPPGeo::Instance().Cham(i + kDC1);
00329     sprintf(name, "%s_z", geo.Name());
00330     minu.mnparm(i, name, geo.ZGas(), 0.1, 
00331         geo.ZGas() - 10, geo.ZGas() + 10, ierr);
00332     savePos[i] = geo.ZGas();
00333 
00334     sprintf(name, "%s_angle", geo.Name());
00335     saveAng[i] = geo.GAngle(1) - geo.LAngle(1);
00336     minu.mnparm(i + 6, name, saveAng[i] * 1e3, 1, -5e2, 5e2, ierr);
00337   }
00338 
00339   for (unsigned int i = 0; i < fFixCham.size(); ++i) 
00340     minu.FixParameter(fFixCham[i]);
00341 
00342   minu.Migrad();
00343 
00344   MakeTree("post");
00345 
00346   double par, pe;
00347   for (int i = 0; i < 6; ++i) {
00348     minu.GetParameter(i, par, pe);
00349     cout << GChamGeo::Name(i + kDC1) << " z shift: " << par - savePos[i]
00350      << " cm, err: " << pe << endl;
00351 
00352     minu.GetParameter(i + 6, par, pe);
00353     cout << GChamGeo::Name(i + kDC1) << " angle shift: " 
00354      << par * 1e-3 - saveAng[i] << " deg, err: " << pe << endl;
00355   }
00356 }
00357 
00358 //......................................................................
00359 
00360 void AlignChamZNoBF::MakeTree(const char* name)
00361 {
00362   char str[256];
00363   sprintf(str, "%s-alignment Tree", name);
00364   TTree* tree = new TTree(name, str);
00365 
00366   double u[6][4];
00367   float x[6][4];
00368   float y[6][4];
00369   double uperp[6][4];
00370   double resid[6][4];
00371   float dxdz;
00372   float dydz;
00373   tree->Branch("u", &u, "u[6][4]/D");
00374   tree->Branch("x", &x, "x[6][4]/D");
00375   tree->Branch("y", &y, "y[6][4]/D");
00376   tree->Branch("uperp", &uperp, "uperp[6][4]/D");
00377   tree->Branch("resid", &resid, "resid[6][4]/D");
00378   tree->Branch("dxdz", &dxdz, "dxdz/F");
00379   tree->Branch("dydz", &dydz, "dydz/F");
00380   
00381   for (unsigned int i = 0; i < fTrackList.size(); ++i) {
00382     TrkInfo_t& ti = fTrackList[i];
00383 
00384     dxdz = Fit(ti, resid, &dydz, x, y);
00385 
00386     for (int c = 0; c < 6; ++c) {
00387       GChamGeo& geo = GMIPPGeo::Instance().Cham(c + kDC1);
00388       for (int p = 0; p < 4; ++p) {
00389     if (ti.fWeight[c][p] < 1e-3) u[c][p] = 1e6;
00390     else geo.WireToU(p + 1, ti.fWire[c][p], u[c][p]);
00391     geo.XYToUperp(p + 1, x[c][p], y[c][p], uperp[c][p]);
00392       }
00393     }
00394     tree->Fill();
00395   }
00396 
00397   tree->Write();
00398   delete tree;
00399 }
00400 
00401 //......................................................................
00402 
00403 void AlignChamZNoBF::Update(const CfgConfig& c)
00404 {
00405   fFixCham.clear();
00406   c("Debug").Get(fDebug);
00407   c("SegFolder").Get(fSegFolder);
00408   c("MinNClust").Get(fMinNClust);
00409   try { c("FixCham").Get(fFixCham); }
00410   catch (...) {
00411     int i;
00412     c("FixCham").Get(i);
00413     fFixCham.push_back(i);
00414   }
00415   c("UseCorr").Get(fUseCorr);
00416 
00417   // Change the flag to signify that our configuration has been read
00418   fIsInit = true;
00419 }
00420 
00421 ////////////////////////////////////////////////////////////////////////

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