00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014
00015
00016
00017 #include "DetectorAlignment.h"
00018 #include "NtpAlignmentRecord.h"
00019 #include "NtpAlignTrackStrip.h"
00020 #include "NtpAlignCandStrip.h"
00021
00022
00023 #include "MessageService/MsgService.h"
00024 #include "MessageService/MsgFormat.h"
00025 #include "RecoBase/CandStripHandle.h"
00026 #include "RecoBase/CandStripListHandle.h"
00027 #include "CandTrackSR/CandTrackSRHandle.h"
00028 #include "CandTrackSR/CandTrackSRListHandle.h"
00029
00030
00031 #include "TClonesArray.h"
00032
00033
00034 #include <algorithm>
00035 #include <iostream>
00036 #include <cmath>
00037
00038 CVSID("$Id: DetectorAlignment.cxx,v 1.5 2009/02/28 21:46:10 gmieg Exp $");
00039
00040 using std::endl;
00041
00042 DetectorAlignment::DetectorAlignment()
00043 :f2dTrackCharge(0.0),
00044 fCandVCharge(0.0),
00045 fCandUCharge(0.0),
00046 f2dTrackResidualRMS(0.0),
00047 fUncertaintyInTPosofStrips(0.0),
00048 fFita(0.0),
00049 fFitb(0.0),
00050 fSigmaOfa(0.0),
00051 fSigmaOfb(0.0),
00052 fCovab(0.0),
00053 fDeltaT(0.0)
00054 {
00055 MSG("Align", Msg::kDebug) << "Constructor DetectorAlignment()" << endl;
00056 }
00057
00058 bool DetectorAlignment::RunAlignment(const CandTrackSRHandle* tkh,
00059 const CandStripListHandle* cslh,
00060 NtpAlignmentRecord* ntpalignrec)
00061 {
00062
00063 if(!tkh || !cslh || !ntpalignrec) return false;
00064
00065
00066 fTrackTimes.clear();
00067
00068
00069 GetTrackStrips(tkh);
00070
00071
00072
00073 GetCandStrips(cslh);
00074
00075
00076 ntpalignrec -> hcosu = tkh -> GetHoughDirCosU();
00077 ntpalignrec -> hcosv = tkh -> GetHoughDirCosV();
00078 ntpalignrec -> hcosz = tkh -> GetHoughDirCosZ();
00079
00080
00081 vector<AlignmentStrip>::iterator begitr = fTrackVStrip.begin();
00082 vector<AlignmentStrip>::iterator enditr = fTrackVStrip.end();
00083
00084
00085 MakeAlignmentTrack(begitr, enditr);
00086
00087 FitTrackLessOne(begitr, enditr, enditr);
00088
00089
00090 ntpalignrec -> vcharge = f2dTrackCharge;
00091 ntpalignrec -> vcandcharge = fCandVCharge;
00092 ntpalignrec -> vtrackrms = f2dTrackResidualRMS;
00093 ntpalignrec -> vfita = fFita;
00094 ntpalignrec -> vfitb = fFitb;
00095 ntpalignrec -> vsigmaofa = fSigmaOfa;
00096 ntpalignrec -> vsigmaofb = fSigmaOfb;
00097 ntpalignrec -> vsigmaoftpos = fUncertaintyInTPosofStrips;
00098 ntpalignrec -> vcovab = fCovab;
00099 ntpalignrec -> vdt = fDeltaT;
00100
00101
00102
00103 begitr = fTrackUStrip.begin();
00104 enditr = fTrackUStrip.end();
00105
00106
00107 MakeAlignmentTrack(begitr, enditr);
00108
00109 FitTrackLessOne(begitr, enditr, enditr);
00110
00111
00112 ntpalignrec -> ucharge = f2dTrackCharge;
00113 ntpalignrec -> ucandcharge = fCandUCharge;
00114 ntpalignrec -> utrackrms = f2dTrackResidualRMS;
00115 ntpalignrec -> ufita = fFita;
00116 ntpalignrec -> ufitb = fFitb;
00117 ntpalignrec -> usigmaofa = fSigmaOfa;
00118 ntpalignrec -> usigmaofb = fSigmaOfb;
00119 ntpalignrec -> usigmaoftpos = fUncertaintyInTPosofStrips;
00120 ntpalignrec -> ucovab = fCovab;
00121 ntpalignrec -> udt = fDeltaT;
00122
00123
00124 TClonesArray& trackvstrips = *(ntpalignrec -> trackvstrip);
00125 for(unsigned int i = 0; i < fTrackVStrip.size(); ++i){
00126 NtpAlignTrackStrip* ntpalign = new(trackvstrips[i])NtpAlignTrackStrip(fTrackVStrip[i]);
00127 if(!ntpalign)
00128 MSG("Align", Msg::kError) <<"Failed to fill TClonesArray!" << endl;
00129 }
00130
00131 TClonesArray& trackustrips = *(ntpalignrec -> trackustrip);
00132 for(unsigned int i = 0; i < fTrackUStrip.size(); ++i){
00133 NtpAlignTrackStrip* ntpalign = new(trackustrips[i])NtpAlignTrackStrip(fTrackUStrip[i]);
00134 if(!ntpalign)
00135 MSG("Align", Msg::kError) <<"Failed to fill TClonesArray!" << endl;
00136 }
00137
00138 TClonesArray& candvstrips = *(ntpalignrec -> candvstrip);
00139 for(unsigned int i = 0; i < fCandVStrip.size(); ++i){
00140 NtpAlignCandStrip* ntpalign = new(candvstrips[i])NtpAlignCandStrip(fCandVStrip[i]);
00141 if(!ntpalign)
00142 MSG("Align", Msg::kError) <<"Failed to fill TClonesArray!" << endl;
00143 }
00144
00145 TClonesArray& candustrips = *(ntpalignrec -> candustrip);
00146 for(unsigned int i = 0; i < fCandUStrip.size(); ++i){
00147 NtpAlignCandStrip* ntpalign = new(candustrips[i])NtpAlignCandStrip(fCandUStrip[i]);
00148 if(!ntpalign)
00149 MSG("Align", Msg::kError) <<"Failed to fill TClonesArray!" << endl;
00150 }
00151
00152 ntpalignrec -> nstrip = cslh -> GetNDaughters();
00153 ntpalignrec -> ntrackvstrip = fTrackVStrip.size();
00154 ntpalignrec -> ntrackustrip = fTrackUStrip.size();
00155 ntpalignrec -> ncandvstrip = fCandVStrip.size();
00156 ntpalignrec -> ncandustrip = fCandUStrip.size();
00157
00158 sort(fTrackTimes.begin(), fTrackTimes.end());
00159
00160 if(fTrackTimes.size() > 0)
00161 ntpalignrec -> dt = fTrackTimes[fTrackTimes.size()-1]-fTrackTimes[0];
00162 else
00163 ntpalignrec -> dt = 0.0;
00164
00165 const int sum = fTrackVStrip.size() + fTrackUStrip.size() + fCandVStrip.size() + fCandUStrip.size();
00166 const int diff = cslh->GetNDaughters() - sum;
00167 if(diff != 0){
00168 MSG("Align", Msg::kDebug)<< "# of cand and track strips do not add up! "
00169 << "diff = " << diff << endl;
00170 return false;
00171 }
00172 return true;
00173 }
00174
00175
00176
00177 void DetectorAlignment::GetTrackStrips(const CandTrackSRHandle* tkh)
00178 {
00179 MSG("Align", Msg::kVerbose) << "Getting CandStripHandles from CandTrack: "
00180 << "tkh->GetNDaughters() = "
00181 << tkh->GetNDaughters()
00182 << ", tkh->GetTitle() = " << tkh->GetTitle()<<endl;
00183
00184 fTrackVStrip.clear();
00185 fTrackUStrip.clear();
00186
00187 int nstrip = 0;
00188 TIter sitr(tkh->GetDaughterIterator());
00189 while( CandStripHandle* csh = dynamic_cast<CandStripHandle*>(sitr()) ){
00190 AlignmentStrip astrip(csh);
00191 nstrip++;
00192 MSG("Align", Msg::kVerbose) << "Adding " <<PlexStripEndId(astrip.plexseid)
00193 <<" to track record" <<endl;
00194 if( csh -> GetPlaneView() == PlaneView::kV)
00195 fTrackVStrip.push_back(astrip);
00196 else
00197 fTrackUStrip.push_back(astrip);
00198 }
00199
00200 MSG("Align", Msg::kVerbose) <<"Added "<<nstrip<<" track strips." << endl;
00201 return;
00202 }
00203
00204
00205 void DetectorAlignment::GetCandStrips(const CandStripListHandle* cslh)
00206 {
00207 MSG("Align", Msg::kVerbose) << "Separating CandStripHandles from track strips" <<endl
00208 << "cslh->GetNDaughters() = "<< cslh -> GetNDaughters()
00209 << ", cslh->GetTitle() = " << cslh -> GetTitle() <<endl;
00210 fCandVStrip.clear();
00211 fCandUStrip.clear();
00212
00213 fCandVCharge = 0.0;
00214 fCandUCharge = 0.0;
00215
00216 MsgFormat ffmt("%10.9f");
00217
00218 TIter sitr(cslh->GetDaughterIterator());
00219 while( CandStripHandle* csh = dynamic_cast<CandStripHandle*>(sitr()) ){
00220 MSG("Align", Msg::kVerbose) << "CandStrip: " << csh->GetStripEndId()
00221 << " time: " << ffmt(csh->GetBegTime())
00222 << " charge = " << csh->GetCharge(CalDigitType::kNone) <<endl;
00223 AlignmentStrip astrip(csh);
00224 if(csh->GetPlaneView() == PlaneView::kV){
00225 bool result = StripBelongsToVTrack(astrip);
00226 if(!result){
00227 fCandVStrip.push_back(astrip);
00228 fCandVCharge += astrip.charge;
00229 MSG("Align", Msg::kVerbose) <<"Adding candstrip " <<PlexStripEndId(astrip.plexseid)<<endl;
00230 }
00231 continue;
00232 }
00233
00234 if(csh->GetPlaneView() == PlaneView::kU){
00235 bool result = StripBelongsToUTrack(astrip);
00236 if(!result){
00237 fCandUStrip.push_back(astrip);
00238 fCandUCharge += astrip.charge;
00239 MSG("Align", Msg::kVerbose) <<"Adding candstrip " <<PlexStripEndId(astrip.plexseid)<<endl;
00240 }
00241 continue;
00242 }
00243 MSG("Align", Msg::kError) << "Strip is not in V or U view!!!"<<endl;
00244 }
00245 }
00246
00247
00248 void DetectorAlignment::MakeAlignmentTrack(vector<AlignmentStrip>::iterator begin,
00249 vector<AlignmentStrip>::iterator end)
00250 {
00251 MSG("Align", Msg::kVerbose) << "MakeAlignmentTrack()..."<<endl;
00252
00253 f2dTrackCharge = 0.0;
00254 f2dTrackResidualRMS = 0.0;
00255 fDeltaT = 0.0;
00256
00257 vector<AlignmentStrip>::iterator itr;
00258 double size = 0.0;
00259
00260 vector<Double_t> begtime;
00261 vector<Double_t> endtime;
00262
00263
00264 for (itr = begin; itr != end; ++itr) {
00265 size += 1.0;
00266 const double residual = FitTrackLessOne(begin, end, itr);
00267 const double &charge = itr -> charge;
00268
00269
00270 itr -> residual = residual;
00271
00272
00273 f2dTrackResidualRMS += residual*residual;
00274
00275 begtime.push_back(itr -> begtime);
00276 endtime.push_back(itr -> endtime);
00277
00278
00279 if(charge > 0.0)
00280 f2dTrackCharge += itr->charge;
00281 else
00282 MSG("Align", Msg::kVerbose) <<PlexStripEndId(itr->plexseid)<<" charge = "<<charge<<endl;
00283
00284 MSG("Align", Msg::kVerbose) <<PlexStripEndId(itr->plexseid)<<" residual = "<<residual<<endl;
00285 }
00286
00287
00288 if(begtime.size() > 0 && endtime.size() > 0){
00289 sort(begtime.begin(), begtime.end());
00290 sort(endtime.begin(), endtime.end());
00291 fDeltaT = endtime[endtime.size()-1] - begtime[0];
00292 fTrackTimes.push_back(endtime[endtime.size()-1]);
00293 fTrackTimes.push_back(begtime[0]);
00294 }
00295
00296 if(size > 0.0) f2dTrackResidualRMS = pow(f2dTrackResidualRMS/size, 0.5);
00297
00298 MSG("Align", Msg::kVerbose) << "MakeAlignmentTrack() DONE!" << endl;
00299 }
00300
00301
00302
00303 double DetectorAlignment::FitTrackLessOne(vector<AlignmentStrip>::const_iterator begin,
00304 vector<AlignmentStrip>::const_iterator end,
00305 vector<AlignmentStrip>::const_iterator skip)
00306 {
00307 MSG("Align", Msg::kVerbose) << "FitTrack..." << endl;
00308
00309 fFita = 0.0;
00310 fFitb = 0.0;
00311 fSigmaOfa = 0.0;
00312 fSigmaOfb = 0.0;
00313 fCovab = 0.0;
00314 fUncertaintyInTPosofStrips = 0.0;
00315
00316
00317
00318
00319 double A = 0.0, B=0.0, C=0.0, D=0.0, E=0.0, F=0.0, S=0.0;
00320
00321 for(vector<AlignmentStrip>::const_iterator run = begin; run != end; ++run)
00322 {
00323 if(run != skip)
00324 {
00325 const double &x = run -> zpos;
00326 const double &y = run -> tpos;
00327 A += x;
00328 B += 1.0;
00329 C += y;
00330 D += x*x;
00331 E += x*y;
00332 F += y*y;
00333 }
00334 }
00335
00336 const double det = B*D - A*A;
00337 if(det < 0.000001)
00338 {
00339 MSG("Align", Msg::kError) << "Linear fit failed!" << endl;
00340 return -100.0;
00341 }
00342
00343
00344 const double a = (E*B-C*A)/det;
00345 const double b = (D*C-E*A)/det;
00346
00347 if(skip != end)
00348 {
00349 const double skipped_x = skip -> zpos;
00350 const double skipped_y = skip -> tpos;
00351 const double predict = a*skipped_x + b;
00352 return (predict - skipped_y);
00353 }
00354
00355 fFita = a;
00356 fFitb = b;
00357 fSigmaOfa = pow(B/det, 0.5);
00358 fSigmaOfb = pow(D/det, 0.5);
00359 fCovab = -A/det;
00360
00361 double npoints = 0.0;
00362 for(vector<AlignmentStrip>::const_iterator run = begin; run != end; ++run)
00363 {
00364 const double &x = run -> zpos;
00365 const double &y = run -> tpos;
00366 S += (y-a*x-b)*(y-a*x-b);
00367 npoints += 1.0;
00368 }
00369
00370 if(npoints - 2.0 < 0.9){
00371 MSG("Align", Msg::kError) << "Linear fit failed!" << endl;
00372 return -100.0;
00373 }
00374
00375
00376 fUncertaintyInTPosofStrips = pow(S/(npoints-2.0), 0.5);
00377
00378 return fUncertaintyInTPosofStrips;
00379 }
00380
00381
00382 bool DetectorAlignment::StripBelongsToVTrack(const AlignmentStrip& astrip)
00383 {
00384
00385
00386
00387
00388
00389
00390 for(unsigned int i = 0; i < fTrackVStrip.size(); ++i){
00391 if(fTrackVStrip[i].plexseid == astrip.plexseid){
00392 double diff = fabs(fTrackVStrip[i].begtime - astrip.begtime);
00393 if(diff < 0.000000002){
00394 MsgFormat ffmt("%10.9f");
00395 MsgFormat fi("%3d");
00396 MSG("Align", Msg::kVerbose) << "Removing "
00397 << PlexStripEndId(astrip.plexseid) << " V track strip #"<<fi(i) <<endl
00398 << " Charge = " << astrip.charge
00399 << " lhs t = " << ffmt(fTrackVStrip[i].begtime)
00400 << " rhs t = " << ffmt(astrip.begtime)
00401 << " diff = "<< ffmt(diff) <<endl;
00402
00403 return true;
00404 }
00405 }
00406 }
00407 return false;
00408 }
00409
00410 bool DetectorAlignment::StripBelongsToUTrack(const AlignmentStrip& astrip)
00411 {
00412
00413
00414
00415
00416
00417
00418 for(unsigned int i = 0; i < fTrackUStrip.size(); ++i){
00419 if(fTrackUStrip[i].plexseid == astrip.plexseid){
00420 double diff = fabs(fTrackUStrip[i].begtime - astrip.begtime);
00421 if(diff < 0.000000002){
00422 MsgFormat ffmt("%10.9f");
00423 MsgFormat fi("%3d");
00424 MSG("Align", Msg::kVerbose) << "Removing "
00425 << PlexStripEndId(astrip.plexseid) << " U track strip #"<<fi(i)<<endl
00426 << " Charge = " << astrip.charge
00427 << " lhs t = " << ffmt(fTrackUStrip[i].begtime)
00428 << " rhs t = " << ffmt(astrip.begtime)
00429 << " diff = "<< ffmt(diff) <<endl;
00430 return true;
00431 }
00432 }
00433 }
00434 return false;
00435 }
00436
00437