CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Alignment/KalmanAlignmentAlgorithm/src/KalmanAlignmentMetricsCalculator.cc

Go to the documentation of this file.
00001 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentMetricsCalculator.h"
00002 #include <limits.h>
00003 
00004 KalmanAlignmentMetricsCalculator::KalmanAlignmentMetricsCalculator( void ) : theMaxDistance( SHRT_MAX ) {}
00005 
00006 
00007 KalmanAlignmentMetricsCalculator::~KalmanAlignmentMetricsCalculator( void ) { clear(); }
00008 
00009 
00010 void KalmanAlignmentMetricsCalculator::updateDistances( const std::vector< Alignable* >& alignables )
00011 {
00012   // List of the distances of the current alignables.
00013   FullDistancesList currentDistances;
00014 
00015   // Updated list of the distances of the current alignables.
00016   FullDistancesList updatedDistances;
00017 
00018   // List of distances between the current and all other alignables that changed due to the update of the list
00019   // of the current alignables. This information has to be propagated to the lists of all other alignables.
00020   FullDistancesList propagatedDistances;
00021 
00022   // Iterate over current alignables and set the distances between them to 1 - save pointers to
00023   // their distances-lists for further manipulation.
00024   std::vector< Alignable* >::const_iterator itA;
00025   for ( itA = alignables.begin(); itA != alignables.end(); ++itA )
00026   {
00027     FullDistancesList::iterator itD = theDistances.find( *itA );
00028 
00029     if ( itD != theDistances.end() )
00030     {
00031       currentDistances[*itA] = itD->second;
00032 
00033       std::vector< Alignable* >::const_iterator itA2;
00034       for ( itA2 = alignables.begin(); itA2 != alignables.end(); ++itA2 ) (*itD->second)[*itA2] = ( *itA == *itA2 ) ? 0 : 1;
00035     }
00036     else
00037     {
00038       SingleDistancesList* newEntry = new SingleDistancesList;
00039       theDistances[*itA] = newEntry;
00040       currentDistances[*itA] = newEntry;
00041 
00042       std::vector< Alignable* >::const_iterator itA2;
00043       for ( itA2 = alignables.begin(); itA2 != alignables.end(); ++itA2 ) (*newEntry)[*itA2] = ( *itA == *itA2 ) ? 0 :  1;
00044     }
00045   }
00046 
00047   // Iterate over the current alignables' distances-lists and compute updates.
00048   FullDistancesList::iterator itC1;
00049   FullDistancesList::iterator itC2;
00050   for ( itC1 = currentDistances.begin(); itC1 != currentDistances.end(); ++itC1 )
00051   {
00052     SingleDistancesList* updatedList = new SingleDistancesList( *itC1->second );
00053 
00054     for ( itC2 = currentDistances.begin(); itC2 != currentDistances.end(); ++itC2 )
00055     {
00056       if ( itC1->first != itC2->first ) updateList( updatedList, itC2->second );
00057     }
00058 
00059     extractPropagatedDistances( propagatedDistances, itC1->first, itC1->second, updatedList );
00060     updatedDistances[itC1->first] = updatedList;
00061   }
00062 
00063   // Insert the updated distances-lists.
00064   insertUpdatedDistances( updatedDistances );
00065 
00066   // Insert the propagated distances-lists.
00067   insertPropagatedDistances( propagatedDistances );
00068 
00069   // Used only temporary - clear it to deallocate its memory.
00070   clearDistances( propagatedDistances );
00071 }
00072 
00073 
00074 const KalmanAlignmentMetricsCalculator::SingleDistancesList&
00075 KalmanAlignmentMetricsCalculator::getDistances( Alignable* i ) const
00076 {
00077   FullDistancesList::const_iterator itD = theDistances.find( i );
00078   if ( itD == theDistances.end() ) return theDefaultReturnList;
00079   return *itD->second;
00080 }
00081 
00082 
00083 short int KalmanAlignmentMetricsCalculator::operator()( Alignable* i, Alignable* j ) const
00084 {
00085   if ( i == j ) return 0;
00086 
00087   FullDistancesList::const_iterator itD = theDistances.find( i );
00088   if ( itD == theDistances.end() ) return -1;
00089 
00090   SingleDistancesList::const_iterator itL = itD->second->find( j );
00091   if ( itL == itD->second->end() ) return -1;
00092 
00093   return itL->second;
00094 }
00095 
00096 
00097 unsigned int KalmanAlignmentMetricsCalculator::nDistances( void ) const
00098 {
00099   unsigned int nod = 0;
00100 
00101   FullDistancesList::const_iterator itD;
00102   for ( itD = theDistances.begin(); itD != theDistances.end(); ++itD ) nod += itD->second->size();
00103 
00104   return nod;
00105 }
00106 
00107 
00108 void KalmanAlignmentMetricsCalculator::clear( void )
00109 {
00110   clearDistances( theDistances );
00111 }
00112 
00113 
00114 const std::vector< Alignable* > KalmanAlignmentMetricsCalculator::alignables( void ) const
00115 {
00116   std::vector< Alignable* > alignables;
00117   alignables.reserve( theDistances.size() );
00118 
00119   for ( FullDistancesList::const_iterator itL = theDistances.begin(); itL != theDistances.end(); ++itL )
00120     alignables.push_back( itL->first );
00121 
00122   return alignables;
00123 }
00124 
00125 
00126 void KalmanAlignmentMetricsCalculator::clearDistances( FullDistancesList& dist )
00127 {
00128   FullDistancesList::iterator itD;
00129   for ( itD = dist.begin(); itD != dist.end(); ++itD ) delete itD->second;
00130   dist.clear();
00131 }
00132 
00133 
00134 void KalmanAlignmentMetricsCalculator::updateList( SingleDistancesList* thisList,
00135                                     SingleDistancesList* otherList )
00136 {
00137   SingleDistancesList::iterator itThis;
00138   SingleDistancesList::iterator itOther;
00139 
00140   // Iterate through the ordered entries (via "<") of thisList and otherList.
00141   for ( itThis = thisList->begin(), itOther = otherList->begin(); itOther != otherList->end(); ++itOther )
00142   {
00143     // Irrelevant information.
00144     if ( itOther->second >= theMaxDistance ) continue;
00145 
00146     // Skip these elements of thisList - no new information available for them in otherList.
00147     while ( itThis != thisList->end() && itThis->first < itOther->first ) ++itThis;
00148 
00149     // Insert new element ...
00150     if ( itThis == thisList->end() || itThis->first > itOther->first ) {
00151       (*thisList)[itOther->first] = itOther->second + 1;
00152     // ... or write smaller distance for existing element.
00153     } else if ( itThis->second > itOther->second ) {
00154       itThis->second = itOther->second + 1;
00155     }
00156 
00157   }
00158 }
00159 
00160 
00161 void KalmanAlignmentMetricsCalculator::insertUpdatedDistances( FullDistancesList& updated )
00162 {
00163   FullDistancesList::iterator itOld;
00164   FullDistancesList::iterator itNew;
00165 
00166   for ( itNew = updated.begin(); itNew != updated.end(); ++itNew )
00167   {
00168     itOld = theDistances.find( itNew->first );
00169     delete itOld->second;
00170     itOld->second = itNew->second;
00171   }
00172 }
00173 
00174 
00175 void KalmanAlignmentMetricsCalculator::insertPropagatedDistances( FullDistancesList& propagated )
00176 {
00177   FullDistancesList::iterator itOld;
00178   FullDistancesList::iterator itNew;
00179 
00180   for ( itNew = propagated.begin(); itNew != propagated.end(); ++itNew )
00181   {
00182     itOld = theDistances.find( itNew->first );
00183     SingleDistancesList::iterator itL;
00184     for ( itL = itNew->second->begin(); itL != itNew->second->end(); ++itL )
00185       insertDistance( itOld->second, itL->first, itL->second );
00186   }
00187 }
00188 
00189 
00190 void KalmanAlignmentMetricsCalculator::extractPropagatedDistances( FullDistancesList& changes,
00191                                                     Alignable* alignable,
00192                                                     SingleDistancesList* oldList,
00193                                                     SingleDistancesList* newList )
00194 {
00195   SingleDistancesList::iterator itOld;
00196   SingleDistancesList::iterator itNew;
00197 
00198   SingleDistancesList newConnections;
00199 
00200   // Distances-list newList has at least entries for the same indices as distances-list
00201   // oldList. For this reason 'newList->begin()->first <= oldList->begin()->first' and
00202   // hence 'itNew->first <= itOld->first' is always true in the loop below.
00203   for ( itOld = oldList->begin(), itNew = newList->begin(); itNew != newList->end(); ++itNew )
00204   {
00205     // No entry associated to index itNew->first present in oldList. --> This is indeed a change.
00206     if ( itOld == oldList->end() || itNew->first < itOld->first )
00207     {
00208       insertDistance( changes, itNew->first, alignable, itNew->second );
00209       newConnections[itNew->first] = itNew->second;
00210     // Entry associated to index itNew->first present in oldList. --> Check if it has changed.
00211     } else if ( itNew->first == itOld->first ) {
00212       if ( itNew->second != itOld->second ) insertDistance( changes, itNew->first, alignable, itNew->second );
00213       ++itOld;
00214     }
00215   }
00216 
00217   SingleDistancesList::iterator it;
00218   for ( it = newConnections.begin(); it != newConnections.end(); ++it )
00219     connect( changes, newList, it->first, it->second );
00220 }
00221 
00222 
00223 void KalmanAlignmentMetricsCalculator::connect( FullDistancesList& changes, SingleDistancesList* connection,
00224                                                 Alignable* alignable, short int value )
00225 {
00226   SingleDistancesList::iterator itL;
00227   for ( itL = connection->begin(); itL != connection->end(); ++itL )
00228   {
00229     if ( itL->first != alignable ) insertDistance( changes, alignable, itL->first, value + itL->second );
00230   }
00231 
00232 }
00233 
00234 
00235 void KalmanAlignmentMetricsCalculator::insertDistance( FullDistancesList& dist, Alignable* i, Alignable* j, short int value )
00236 {
00237   FullDistancesList::iterator itD = dist.find( i );
00238   if ( itD != dist.end() ) // Found distances-list for index i.
00239   {
00240     insertDistance( itD->second, j, value );
00241   }
00242   else // No distances-list found for value i.
00243   {
00244     SingleDistancesList* newList = new SingleDistancesList;
00245     (*newList)[j] = value;
00246     dist[i] = newList;
00247   }
00248 }
00249 
00250 
00251 void KalmanAlignmentMetricsCalculator::insertDistance( SingleDistancesList* distList, Alignable* j, short int value )
00252 {
00253   SingleDistancesList::iterator itL = distList->find( j );
00254   if ( itL != distList->end() ) { // Entry associated to index j found.
00255     if ( itL->second > value ) itL->second = value;
00256   } else { // No entry associated to index j found. -> Insert new entry.
00257     (*distList)[j] = value;
00258   }
00259 }
00260 
00261 
00262 void KalmanAlignmentMetricsCalculator::writeDistances( std::string filename )
00263 {
00264 
00265 }
00266 
00267 
00268 void KalmanAlignmentMetricsCalculator::readDistances( std::string filename )
00269 {
00270 
00271 }
00272 
00273 
00274 void KalmanAlignmentMetricsCalculator::createBranches( TTree* tree )
00275 {
00276 
00277 }
00278 
00279 
00280 void KalmanAlignmentMetricsCalculator::setBranchAddresses( TTree* tree )
00281 {
00282 
00283 }
00284