Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DetectorAlignment.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // DetectorAlignment
00004 //
00005 // Package: DetectorAlignment
00006 //
00007 // An alignment engine 
00008 //
00009 // Contact: rustem@fnal.gov
00010 //
00011 // Created on: Fri Sep 24 15:26:05 2004
00012 //
00014 
00015 
00016 //DetectorAlignment classes
00017 #include "DetectorAlignment.h"
00018 #include "NtpAlignmentRecord.h"
00019 #include "NtpAlignTrackStrip.h"
00020 #include "NtpAlignCandStrip.h"
00021 
00022 //MINOSSOFT
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 //ROOT
00031 #include "TClonesArray.h"
00032 
00033 //C++
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    //clear vectors that store AlignmentStrips and track's time inteval
00065    fTrackTimes.clear();
00066 
00067    //Save strip data from CandTrackSR to vector<AlignmentStrip>, one for each view
00068    GetTrackStrips(tkh);
00069 
00070    //Save data from candidate strips to vector<AlignmentStrip>, one for each view
00071    //Ignore strips that belong to a track
00072    GetCandStrips(cslh);
00073 
00074    //Get directional cosines for 3d track
00075    ntpalignrec -> hcosu = tkh -> GetHoughDirCosU();
00076    ntpalignrec -> hcosv = tkh -> GetHoughDirCosV();
00077    ntpalignrec -> hcosz = tkh -> GetHoughDirCosZ();
00078 
00079    //Fit V view track with a straight line and save fit information
00080    vector<AlignmentStrip>::iterator begitr = fTrackVStrip.begin();
00081    vector<AlignmentStrip>::iterator enditr = fTrackVStrip.end();
00082 
00083    //V view: calculate residuals, track charge and residual rms
00084    MakeAlignmentTrack(begitr, enditr);
00085 
00086    FitTrackLessOne(begitr, enditr, enditr);
00087 
00088    //Fill ntuples record for V view track
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    //Fit U view track with a straight line and save fit information
00102    begitr = fTrackUStrip.begin(); 
00103    enditr = fTrackUStrip.end();
00104    
00105    //U view: calculate residuals, track charge and residual rms
00106    MakeAlignmentTrack(begitr, enditr);
00107 
00108    FitTrackLessOne(begitr, enditr, enditr);
00109 
00110    //Fill ntuples record for U view track
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    //Fill TClonesArrays with candidate strips and track strips
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 //Get charges of hit strips in CandTrack and fill corresponding histograms
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    //store ony candidate handles that are not part of CandTrackSRHandle
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    //Filing vectors with data from 2d track
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       //store residual in AlignStrip
00269       itr -> residual = residual;
00270 
00271       //calculating "rms" of a current track
00272       f2dTrackResidualRMS += residual*residual;
00273       
00274       begtime.push_back(itr -> begtime);
00275       endtime.push_back(itr -> endtime);
00276       
00277       //add charge as we iterate along 2d track:
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    //sorting begtime and endtime to get time time interval of 2d track
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 // Fit 2d track with a straight line using least squares method
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    // Linear regression parameters least squares method. See for eg. Num Rec Ch 15
00316    // Fit y = ax + b, as in W. R. Leo, Techniques for ..., Section 4.7.2
00317    // x is strip's Z position, y is strip's transverse position (U or V).
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; //determinant of error matrix
00336    if(det < 0.000001)
00337    {
00338       MSG("Align", Msg::kError) << "Linear fit failed!" << endl;
00339       return -100.0;
00340    }
00341    
00342    // The linear fitparameters in y = ax + b
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    //square root of least squares sum
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    //if there is a track strip such that: PlexStripEndIds are the same
00384    //                                     beggining times are within 10ns of each other
00385    //then return true
00386    //
00387    //otherwise return false
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    //if there is a track strip such that: PlexStripEndIds are the same
00412    //                                     beggining times are within 1ns of each other
00413    //then return true
00414    //
00415    //otherwise return false
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 

Generated on Thu Nov 1 11:50:23 2007 for loon by  doxygen 1.3.9.1