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