CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Alignment/HIPAlignmentAlgorithm/src/HIPAlignmentAlgorithm.cc

Go to the documentation of this file.
00001 #include <fstream>
00002 
00003 #include "TFile.h"
00004 #include "TTree.h"
00005 
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 
00009 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00010 #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h"
00011 
00012 #include "Alignment/CommonAlignment/interface/Alignable.h"  
00013 #include "Alignment/CommonAlignment/interface/AlignableNavigator.h"  
00014 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"  
00015 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
00016 #include "Alignment/CommonAlignment/interface/SurveyResidual.h"
00017 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h"
00018 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00019 #include "Alignment/HIPAlignmentAlgorithm/interface/HIPUserVariables.h"
00020 #include "Alignment/HIPAlignmentAlgorithm/interface/HIPUserVariablesIORoot.h"
00021 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00022 #include <DataFormats/GeometrySurface/interface/LocalError.h> 
00023 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00024 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
00025 #include "DataFormats/TrackReco/interface/Track.h"
00026 
00027 #include "Alignment/HIPAlignmentAlgorithm/interface/HIPAlignmentAlgorithm.h"
00028 
00029 // using namespace std;
00030 
00031 // Constructor ----------------------------------------------------------------
00032 
00033 HIPAlignmentAlgorithm::HIPAlignmentAlgorithm(const edm::ParameterSet& cfg):
00034   AlignmentAlgorithmBase( cfg )
00035 {
00036   
00037   // parse parameters
00038   
00039   verbose = cfg.getParameter<bool>("verbosity");
00040   
00041   outpath = cfg.getParameter<string>("outpath");
00042   outfile = cfg.getParameter<string>("outfile");
00043   outfile2 = cfg.getParameter<string>("outfile2");
00044   struefile = cfg.getParameter<string>("trueFile");
00045   smisalignedfile = cfg.getParameter<string>("misalignedFile");
00046   salignedfile = cfg.getParameter<string>("alignedFile");
00047   siterationfile = cfg.getParameter<string>("iterationFile");
00048   suvarfile = cfg.getParameter<string>("uvarFile");
00049   sparameterfile = cfg.getParameter<string>("parameterFile");
00050   ssurveyfile = cfg.getParameter<string>("surveyFile");
00051         
00052   outfile        =outpath+outfile;//Eventwise tree
00053   outfile2       =outpath+outfile2;//Alignablewise tree
00054   struefile      =outpath+struefile;
00055   smisalignedfile=outpath+smisalignedfile;
00056   salignedfile   =outpath+salignedfile;
00057   siterationfile =outpath+siterationfile;
00058   suvarfile      =outpath+suvarfile;
00059   sparameterfile =outpath+sparameterfile;
00060   ssurveyfile    =outpath+ssurveyfile;
00061         
00062   // parameters for APE
00063   theApplyAPE = cfg.getParameter<bool>("applyAPE");
00064   theAPEParameterSet = cfg.getParameter<std::vector<edm::ParameterSet> >("apeParam");
00065         
00066   theMaxAllowedHitPull = cfg.getParameter<double>("maxAllowedHitPull");
00067   theMinimumNumberOfHits = cfg.getParameter<int>("minimumNumberOfHits");
00068   theMaxRelParameterError = cfg.getParameter<double>("maxRelParameterError");
00069         
00070   // for collector mode (parallel processing)
00071   isCollector=cfg.getParameter<bool>("collectorActive");
00072   theCollectorNJobs=cfg.getParameter<int>("collectorNJobs");
00073   theCollectorPath=cfg.getParameter<string>("collectorPath");
00074   theFillTrackMonitoring=cfg.getUntrackedParameter<bool>("fillTrackMonitoring");
00075         
00076   if (isCollector) edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Collector mode";
00077         
00078   theEventPrescale = cfg.getParameter<int>("eventPrescale");
00079   theCurrentPrescale = theEventPrescale;
00080         
00081   AlignableObjectId dummy;
00082         
00083   const std::vector<std::string>& levels = cfg.getUntrackedParameter<std::vector<std::string> >("surveyResiduals");
00084         
00085   for (unsigned int l = 0; l < levels.size(); ++l) {
00086     theLevels.push_back( dummy.nameToType(levels[l]) );
00087   }
00088         
00089   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] constructed.";
00090         
00091 }
00092 
00093 // Call at beginning of job ---------------------------------------------------
00094 
00095 void 
00096 HIPAlignmentAlgorithm::initialize( const edm::EventSetup& setup, 
00097                                    AlignableTracker* tracker, AlignableMuon* muon, AlignableExtras* extras,
00098                                    AlignmentParameterStore* store )
00099 {
00100   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Initializing...";
00101         
00102   // accessor Det->AlignableDet
00103   if ( !muon )
00104     theAlignableDetAccessor = new AlignableNavigator(tracker);
00105   else if ( !tracker )
00106     theAlignableDetAccessor = new AlignableNavigator(muon);
00107   else 
00108     theAlignableDetAccessor = new AlignableNavigator(tracker, muon);
00109   
00110   // set alignmentParameterStore
00111   theAlignmentParameterStore=store;
00112         
00113   // get alignables
00114   theAlignables = theAlignmentParameterStore->alignables();
00115         
00116   // clear theAPEParameters, if necessary
00117   theAPEParameters.clear();
00118         
00119   // get APE parameters
00120   if(theApplyAPE){
00121     AlignmentParameterSelector selector(tracker, muon);
00122     for (std::vector<edm::ParameterSet>::const_iterator setiter = theAPEParameterSet.begin();
00123          setiter != theAPEParameterSet.end();
00124          ++setiter) {
00125       std::vector<Alignable*> alignables;
00126       
00127       selector.clear();
00128       edm::ParameterSet selectorPSet = setiter->getParameter<edm::ParameterSet>("Selector");
00129       std::vector<std::string> alignParams = selectorPSet.getParameter<std::vector<std::string> >("alignParams");
00130       if (alignParams.size() == 1  &&  alignParams[0] == std::string("selected")) {
00131         alignables = theAlignables;
00132       }
00133       else {
00134         selector.addSelections(selectorPSet);
00135         alignables = selector.selectedAlignables();
00136       }
00137                         
00138       std::vector<double> apeSPar = setiter->getParameter<std::vector<double> >("apeSPar");
00139       std::vector<double> apeRPar = setiter->getParameter<std::vector<double> >("apeRPar");
00140       std::string function = setiter->getParameter<std::string>("function");
00141                         
00142       if (apeSPar.size() != 3  ||  apeRPar.size() != 3)
00143         throw cms::Exception("BadConfig") << "apeSPar and apeRPar must have 3 values each" << std::endl;
00144                         
00145       for (std::vector<double>::const_iterator i = apeRPar.begin();  i != apeRPar.end();  ++i) {
00146         apeSPar.push_back(*i);
00147       }
00148                         
00149       if (function == std::string("linear")) {
00150         apeSPar.push_back(0.); // c.f. note in calcAPE
00151       }
00152       else if (function == std::string("exponential")) {
00153         apeSPar.push_back(1.); // c.f. note in calcAPE
00154       }
00155       else if (function == std::string("step")) {
00156         apeSPar.push_back(2.); // c.f. note in calcAPE
00157       }
00158       else {
00159         throw cms::Exception("BadConfig") << "APE function must be \"linear\" or \"exponential\"." << std::endl;
00160       }
00161 
00162       theAPEParameters.push_back(std::pair<std::vector<Alignable*>, std::vector<double> >(alignables, apeSPar));
00163     }
00164   }
00165 }
00166 
00167 // Call at new loop -------------------------------------------------------------
00168 void HIPAlignmentAlgorithm::startNewLoop( void )
00169 {
00170         
00171   // iterate over all alignables and attach user variables
00172   for( vector<Alignable*>::const_iterator it=theAlignables.begin(); 
00173        it!=theAlignables.end(); it++ )
00174     {
00175       AlignmentParameters* ap = (*it)->alignmentParameters();
00176       int npar=ap->numSelected();
00177       HIPUserVariables* userpar = new HIPUserVariables(npar);
00178       ap->setUserVariables(userpar);
00179     }
00180         
00181   // try to read in alignment parameters from a previous iteration
00182   AlignablePositions theAlignablePositionsFromFile =
00183     theIO.readAlignableAbsolutePositions(theAlignables,
00184                                          (char*)salignedfile.c_str(),-1,ioerr);
00185         
00186   int numAlignablesFromFile = theAlignablePositionsFromFile.size();
00187         
00188   if (numAlignablesFromFile==0) { // file not there: first iteration 
00189                 
00190     // set iteration number to 1
00191     if (isCollector) theIteration=0;
00192     else theIteration=1;
00193     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] File not found => iteration "<<theIteration;
00194                 
00195     // get true (de-misaligned positions) and write to root file
00196     // hardcoded iteration=1
00197     theIO.writeAlignableOriginalPositions(theAlignables,
00198                                           (char*)struefile.c_str(),1,false,ioerr);
00199                 
00200     // get misaligned positions and write to root file
00201     // hardcoded iteration=1
00202     theIO.writeAlignableAbsolutePositions(theAlignables,
00203                                           (char*)smisalignedfile.c_str(),1,false,ioerr);
00204                 
00205   }
00206         
00207   else { // there have been previous iterations
00208                 
00209     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Alignables Read " 
00210                                  << numAlignablesFromFile;
00211                 
00212     // get iteration number from file     
00213     theIteration = readIterationFile(siterationfile);
00214                 
00215     // increase iteration
00216     theIteration++;
00217     edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm] Iteration increased by one!";
00218                 
00219     // now apply psotions of file from prev iteration
00220     edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm] Apply positions from file ...";
00221     theAlignmentParameterStore->applyAlignableAbsolutePositions(theAlignables, 
00222                                                                 theAlignablePositionsFromFile,ioerr);
00223                 
00224   }
00225         
00226   edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm] Current Iteration number: " 
00227                                << theIteration;
00228         
00229         
00230   // book root trees
00231   bookRoot();
00232         
00233         
00234   /*---------------------moved to terminate------------------------------
00235     if (theLevels.size() > 0)
00236     {
00237     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Using survey constraint";
00238          
00239     unsigned int nAlignable = theAlignables.size();
00240          
00241     for (unsigned int i = 0; i < nAlignable; ++i)
00242     {
00243     const Alignable* ali = theAlignables[i];
00244          
00245     AlignmentParameters* ap = ali->alignmentParameters();
00246          
00247     HIPUserVariables* uservar =
00248     dynamic_cast<HIPUserVariables*>(ap->userVariables());
00249          
00250     for (unsigned int l = 0; l < theLevels.size(); ++l)
00251     {
00252     SurveyResidual res(*ali, theLevels[l], true);
00253          
00254     if ( res.valid() )
00255     {
00256     AlgebraicSymMatrix invCov = res.inverseCovariance();
00257          
00258     // variable for tree
00259     AlgebraicVector sensResid = res.sensorResidual();
00260     m3_Id = ali->id();
00261     m3_ObjId = theLevels[l];
00262     m3_par[0] = sensResid[0]; m3_par[1] = sensResid[1]; m3_par[2] = sensResid[2];
00263     m3_par[3] = sensResid[3]; m3_par[4] = sensResid[4]; m3_par[5] = sensResid[5];
00264          
00265     uservar->jtvj += invCov;
00266     uservar->jtve += invCov * sensResid;
00267          
00268     theTree3->Fill();
00269     }
00270     }
00271          
00272     //  align::LocalVectors residuals = res1.pointsResidual();
00273          
00274     //  unsigned int nPoints = residuals.size();
00275          
00276     //  for (unsigned int k = 0; k < nPoints; ++k)
00277     //  {
00278     //    AlgebraicMatrix J = term->survey()->derivatives(k);
00279     //    AlgebraicVector e(3); // local residual
00280          
00281     //    const align::LocalVector& lr = residuals[k];
00282          
00283     //    e(1) = lr.x(); e(2) = lr.y(); e(3) = lr.z();
00284          
00285     //    uservar->jtvj += invCov1.similarity(J);
00286     //    uservar->jtve += J * (invCov1 * e);
00287     //  }
00288          
00289     }
00290     }
00291     //------------------------------------------------------*/
00292         
00293   // set alignment position error 
00294   setAlignmentPositionError();
00295         
00296   // run collector job if we are in parallel mode
00297   if (isCollector) collector();
00298         
00299 }
00300 
00301 // Call at end of job ---------------------------------------------------------
00302 
00303 void HIPAlignmentAlgorithm::terminate(void)
00304 {
00305         
00306   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Terminating";
00307         
00308   // calculating survey residuals
00309   if (theLevels.size() > 0)
00310     {
00311       edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Using survey constraint";
00312                 
00313       unsigned int nAlignable = theAlignables.size();
00314                 
00315       for (unsigned int i = 0; i < nAlignable; ++i)
00316         {
00317           const Alignable* ali = theAlignables[i];
00318                         
00319           AlignmentParameters* ap = ali->alignmentParameters();
00320                         
00321           HIPUserVariables* uservar =
00322             dynamic_cast<HIPUserVariables*>(ap->userVariables());
00323                         
00324           for (unsigned int l = 0; l < theLevels.size(); ++l)
00325             {
00326               SurveyResidual res(*ali, theLevels[l], true);
00327                                 
00328               if ( res.valid() )
00329                 {
00330                   AlgebraicSymMatrix invCov = res.inverseCovariance();
00331                                         
00332                   // variable for tree
00333                   AlgebraicVector sensResid = res.sensorResidual();
00334                   m3_Id = ali->id();
00335                   m3_ObjId = theLevels[l];
00336                   m3_par[0] = sensResid[0]; m3_par[1] = sensResid[1]; m3_par[2] = sensResid[2];
00337                   m3_par[3] = sensResid[3]; m3_par[4] = sensResid[4]; m3_par[5] = sensResid[5];
00338                                         
00339                   uservar->jtvj += invCov;
00340                   uservar->jtve += invCov * sensResid;
00341                                         
00342                   theTree3->Fill();
00343                 }
00344             }
00345                         
00346           //    align::LocalVectors residuals = res1.pointsResidual();
00347                         
00348           //    unsigned int nPoints = residuals.size();
00349                         
00350           //    for (unsigned int k = 0; k < nPoints; ++k)
00351           //    {
00352           //      AlgebraicMatrix J = term->survey()->derivatives(k);
00353           //      AlgebraicVector e(3); // local residual
00354                         
00355           //      const align::LocalVector& lr = residuals[k];
00356                         
00357           //      e(1) = lr.x(); e(2) = lr.y(); e(3) = lr.z();
00358                         
00359           //      uservar->jtvj += invCov1.similarity(J);
00360           //      uservar->jtve += J * (invCov1 * e);
00361           //    }
00362                         
00363         }
00364     }
00365         
00366   // write user variables
00367   HIPUserVariablesIORoot HIPIO;
00368   HIPIO.writeHIPUserVariables (theAlignables,(char*)suvarfile.c_str(),
00369                                theIteration,false,ioerr);
00370         
00371   // now calculate alignment corrections ...
00372   int ialigned=0;
00373   // iterate over alignment parameters
00374   for(vector<Alignable*>::const_iterator
00375         it=theAlignables.begin(); it!=theAlignables.end(); it++) {
00376     Alignable* ali=(*it);
00377     // Alignment parameters
00378     AlignmentParameters* par = ali->alignmentParameters();
00379 
00380     // try to calculate parameters
00381     bool test = calcParameters(ali);
00382 
00383     // if successful, apply parameters
00384     if (test) { 
00385       edm::LogInfo("Alignment") << "now apply params";
00386       theAlignmentParameterStore->applyParameters(ali);
00387       // set these parameters 'valid'
00388       ali->alignmentParameters()->setValid(true);
00389       // increase counter
00390       ialigned++;
00391     }
00392     else par->setValid(false);
00393   }
00394   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::terminate] Aligned units: " << ialigned;
00395         
00396   // fill alignable wise root tree
00397   fillRoot();
00398         
00399   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm] Writing aligned parameters to file: " << theAlignables.size();
00400         
00401   // write new absolute positions to disk
00402   theIO.writeAlignableAbsolutePositions(theAlignables,
00403                                         (char*)salignedfile.c_str(),theIteration,false,ioerr);
00404         
00405   // write alignment parameters to disk
00406   theIO.writeAlignmentParameters(theAlignables, 
00407                                  (char*)sparameterfile.c_str(),theIteration,false,ioerr);
00408         
00409   // write iteration number to file
00410   writeIterationFile(siterationfile,theIteration);
00411         
00412   // write out trees and close root file
00413         
00414   // eventwise tree
00415   theFile->cd();
00416   theTree->Write();
00417   delete theFile;
00418         
00419   if (theLevels.size() > 0){
00420     theFile3->cd();
00421     theTree3->Write();
00422     delete theFile3;
00423   }
00424         
00425   // alignable-wise tree is only filled once
00426   if (theIteration==1) { // only for 1st iteration
00427     theFile2->cd();
00428     theTree2->Write(); 
00429     delete theFile2;
00430   }  
00431         
00432 }
00433 
00434 bool HIPAlignmentAlgorithm::processHit1D(const AlignableDetOrUnitPtr alidet,
00435                                          const Alignable* ali,
00436                                          const TrajectoryStateOnSurface & tsos,
00437                                          const TransientTrackingRecHit* hit)
00438 {
00439   static const unsigned int hitDim = 1;
00440 
00441   // get trajectory impact point
00442   LocalPoint alvec = tsos.localPosition();
00443   AlgebraicVector pos(hitDim);
00444   pos[0] = alvec.x();
00445 
00446   // get impact point covariance
00447   AlgebraicSymMatrix ipcovmat(hitDim);
00448   ipcovmat[0][0] = tsos.localError().positionError().xx();
00449 
00450   // get hit local position and covariance
00451   AlgebraicVector coor(hitDim);
00452   coor[0] = hit->localPosition().x();
00453 
00454   AlgebraicSymMatrix covmat(hitDim);
00455   covmat[0][0] = hit->localPositionError().xx();
00456   
00457   // add hit and impact point covariance matrices
00458   covmat = covmat + ipcovmat;
00459 
00460   // calculate the x pull of this hit
00461   double xpull = 0.;
00462   if (covmat[0][0] != 0.) xpull = (pos[0] - coor[0])/sqrt(fabs(covmat[0][0]));
00463 
00464   // get Alignment Parameters
00465   AlignmentParameters* params = ali->alignmentParameters();
00466   // get derivatives
00467   AlgebraicMatrix derivs2D = params->selectedDerivatives(tsos, alidet);
00468   // calculate user parameters
00469   int npar = derivs2D.num_row();
00470   // std::cout << "Dumping derivsSEL: \n" << derivs2D <<std::endl;
00471   AlgebraicMatrix derivs(npar, hitDim, 0);
00472   
00473   for (int ipar=0;ipar<npar;ipar++) {
00474     for (unsigned int idim=0;idim<hitDim;idim++) {
00475       derivs[ipar][idim] = derivs2D[ipar][idim];
00476     }
00477   }
00478   // std::cout << "Dumping derivs: \n" << derivs << std::endl;
00479   // invert covariance matrix
00480   int ierr;
00481   // if (covmat[1][1]>4.0) nhitDim = hitDim;
00482                                   
00483   covmat.invert(ierr);
00484   if (ierr != 0) {
00485     edm::LogError("Alignment") << "Matrix inversion failed!"; 
00486     return false; 
00487   }
00488 
00489   bool useThisHit = (theMaxAllowedHitPull <= 0.);
00490   
00491   useThisHit |= (fabs(xpull) < theMaxAllowedHitPull);
00492   
00493   // bailing out
00494   if (!useThisHit) return false;
00495 
00496   // std::cout << "We use this hit in " << subDet << std::endl;
00497   // std::cout << "Npars= " << npar << "  NhitDim=1 Size of derivs: "
00498   //           << derivs.num_row() << " x " << derivs.num_col() << std::endl;
00499 
00500   // AlgebraicMatrix jtvjtmp();
00501   AlgebraicMatrix covtmp(covmat);
00502   // std::cout << "Preapring JTVJTMP -> " << std::flush;
00503   AlgebraicMatrix jtvjtmp(derivs * covtmp *derivs.T());
00504   // std::cout << "TMP JTVJ= \n" << jtvjtmp << std::endl;
00505   AlgebraicSymMatrix thisjtvj(npar);
00506   AlgebraicVector thisjtve(npar);
00507   // std::cout << "Preparing ThisJtVJ" << std::flush;
00508   // thisjtvj = covmat.similarity(derivs);
00509   thisjtvj.assign(jtvjtmp);
00510   // cout<<" ThisJtVE"<<std::endl;
00511   thisjtve=derivs * covmat * (pos-coor);
00512   
00513   AlgebraicVector hitresidual(hitDim);
00514   hitresidual[0] = (pos[0] - coor[0]);
00515   
00516   AlgebraicMatrix hitresidualT;
00517   hitresidualT = hitresidual.T();
00518   // std::cout << "HitResidualT = \n" << hitresidualT << std::endl;
00519 
00520   // access user variables (via AlignmentParameters)
00521   HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(params->userVariables());
00522   uservar->jtvj += thisjtvj;
00523   uservar->jtve += thisjtve;
00524   uservar->nhit++;
00525   // The following variable is needed for the extended 1D/2D hit fix using
00526   // matrix shrinkage and expansion
00527   // uservar->hitdim = hitDim;
00528 
00529   //for alignable chi squared
00530   float thischi2;
00531   thischi2 = (hitresidualT *covmat *hitresidual)[0]; 
00532                                         
00533   if ( verbose && ((thischi2/ static_cast<float>(uservar->nhit)) >10.0) ) {
00534     edm::LogWarning("Alignment") << "Added to Chi2 the number " << thischi2 <<" having "
00535                                  << uservar->nhit << "  dof  " << std::endl << "X-resid " 
00536                                  << hitresidual[0] << "  Y-resid " 
00537                                  << hitresidual[1] << std::endl << "  Cov^-1 matr (covmat): [0][0]= "
00538                                  << covmat[0][0] << " [0][1]= "
00539                                  << covmat[0][1] << " [1][0]= "
00540                                  << covmat[1][0] << " [1][1]= "
00541                                  << covmat[1][1] << std::endl;
00542   }
00543                                         
00544   uservar->alichi2 += thischi2; // a bit weird, but vector.transposed * matrix * vector doesn't give a double in CMSSW's opinion
00545   uservar->alindof += hitDim;   // 2D hits contribute twice to the ndofs
00546 
00547   return true;
00548 }
00549 
00550 bool HIPAlignmentAlgorithm::processHit2D(const AlignableDetOrUnitPtr alidet,
00551                                          const Alignable* ali,
00552                                          const TrajectoryStateOnSurface & tsos,
00553                                          const TransientTrackingRecHit* hit)
00554 {
00555   static const unsigned int hitDim = 2;
00556 
00557   // get trajectory impact point
00558   LocalPoint alvec = tsos.localPosition();
00559   AlgebraicVector pos(hitDim);
00560   pos[0] = alvec.x();
00561   pos[1] = alvec.y();
00562   
00563   // get impact point covariance
00564   AlgebraicSymMatrix ipcovmat(hitDim);
00565   ipcovmat[0][0] = tsos.localError().positionError().xx();
00566   ipcovmat[1][1] = tsos.localError().positionError().yy();
00567   ipcovmat[0][1] = tsos.localError().positionError().xy();
00568   
00569   // get hit local position and covariance
00570   AlgebraicVector coor(hitDim);
00571   coor[0] = hit->localPosition().x();
00572   coor[1] = hit->localPosition().y();
00573 
00574   AlgebraicSymMatrix covmat(hitDim);
00575   covmat[0][0] = hit->localPositionError().xx();
00576   covmat[1][1] = hit->localPositionError().yy();
00577   covmat[0][1] = hit->localPositionError().xy();
00578 
00579   // add hit and impact point covariance matrices
00580   covmat = covmat + ipcovmat;
00581 
00582   // calculate the x pull and y pull of this hit
00583   double xpull = 0.;
00584   double ypull = 0.;
00585   if (covmat[0][0] != 0.) xpull = (pos[0] - coor[0])/sqrt(fabs(covmat[0][0]));
00586   if (covmat[1][1] != 0.) ypull = (pos[1] - coor[1])/sqrt(fabs(covmat[1][1]));
00587 
00588   // get Alignment Parameters
00589   AlignmentParameters* params = ali->alignmentParameters();
00590   // get derivatives
00591   AlgebraicMatrix derivs2D = params->selectedDerivatives(tsos, alidet);
00592   // calculate user parameters
00593   int npar = derivs2D.num_row();
00594   // std::cout << "Dumping derivsSEL: \n"<< derivs2D <<std::endl;
00595   AlgebraicMatrix derivs(npar, hitDim, 0);
00596   
00597   for (int ipar=0;ipar<npar;ipar++) {
00598     for (unsigned int idim=0;idim<hitDim;idim++) {
00599       derivs[ipar][idim] = derivs2D[ipar][idim];
00600     }
00601   }
00602   // std::cout << "Dumping derivs: \n" << derivs << std::endl;
00603   // invert covariance matrix
00604   int ierr;
00605   // if (covmat[1][1]>4.0) nhitDim = hitDim;
00606                                   
00607   covmat.invert(ierr);
00608   if (ierr != 0) { 
00609     edm::LogError("Alignment") << "Matrix inversion failed!"; 
00610     return false; 
00611   }
00612 
00613   bool useThisHit = (theMaxAllowedHitPull <= 0.);
00614   
00615   useThisHit |= (fabs(xpull) < theMaxAllowedHitPull  &&  fabs(ypull) < theMaxAllowedHitPull);
00616   
00617   // bailing out
00618   if (!useThisHit) return false;
00619   
00620   // std::cout << "We use this hit in " << subDet << std::endl;
00621   // std::cout << "Npars= " << npar << "  NhitDim=2 Size of derivs: "
00622   //           << derivs.num_row() << " x " << derivs.num_col() << std::endl;
00623 
00624   // AlgebraicMatrix jtvjtmp();
00625   AlgebraicMatrix covtmp(covmat);
00626   // std::cout << "Preapring JTVJTMP -> " << std::flush;
00627   AlgebraicMatrix jtvjtmp(derivs * covtmp *derivs.T());
00628   // std::cout << "TMP JTVJ= \n" << jtvjtmp << std::endl;
00629   AlgebraicSymMatrix thisjtvj(npar);
00630   AlgebraicVector thisjtve(npar);
00631   // std::cout << "Preparing ThisJtVJ" << std::flush;
00632   // thisjtvj = covmat.similarity(derivs);
00633   thisjtvj.assign(jtvjtmp);
00634   // cout<<" ThisJtVE"<<std::endl;
00635   thisjtve=derivs * covmat * (pos-coor);
00636   
00637   AlgebraicVector hitresidual(hitDim);
00638   hitresidual[0] = (pos[0] - coor[0]);
00639   hitresidual[1] = (pos[1] - coor[1]);
00640   // if(nhitDim>1)  {
00641   //  hitresidual[1] =0.0;
00642   //  nhitDim=1;
00643   // }
00644          
00645   AlgebraicMatrix hitresidualT;
00646   hitresidualT = hitresidual.T();
00647   // std::cout << "HitResidualT = \n" << hitresidualT << std::endl;
00648   // access user variables (via AlignmentParameters)
00649   HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(params->userVariables());
00650   uservar->jtvj += thisjtvj;
00651   uservar->jtve += thisjtve;
00652   uservar->nhit++;
00653   // The following variable is needed for the extended 1D/2D hit fix using
00654   // matrix shrinkage and expansion
00655   // uservar->hitdim = hitDim;
00656 
00657   //for alignable chi squared
00658   float thischi2;
00659   thischi2 = (hitresidualT *covmat *hitresidual)[0]; 
00660                                         
00661   if ( verbose && ((thischi2/ static_cast<float>(uservar->nhit)) >10.0) ) {
00662     edm::LogWarning("Alignment") << "Added to Chi2 the number " << thischi2 <<" having "
00663                                  << uservar->nhit << "  dof  " << std::endl << "X-resid " 
00664                                  << hitresidual[0] << "  Y-resid " 
00665                                  << hitresidual[1] << std::endl << "  Cov^-1 matr (covmat): [0][0]= "
00666                                  << covmat[0][0] << " [0][1]= "
00667                                  << covmat[0][1] << " [1][0]= "
00668                                  << covmat[1][0] << " [1][1]= "
00669                                  << covmat[1][1] << std::endl;
00670   }
00671                                         
00672   uservar->alichi2 += thischi2; // a bit weird, but vector.transposed * matrix * vector doesn't give a double in CMSSW's opinion
00673   uservar->alindof += hitDim;   // 2D hits contribute twice to the ndofs
00674 
00675   return true;
00676 }
00677 
00678 // Run the algorithm on trajectories and tracks -------------------------------
00679 void HIPAlignmentAlgorithm::run(const edm::EventSetup& setup, const EventInfo &eventInfo)
00680 {
00681   if (isCollector) return;
00682         
00683   TrajectoryStateCombiner tsoscomb;
00684   
00685   // AM: not really needed
00686   // AM: m_Ntracks = 0 should be sufficient
00687   int itr=0;
00688   m_Ntracks=0;
00689   for(itr=0;itr<MAXREC;++itr){
00690     m_Nhits[itr]=0;
00691     m_Pt[itr]=-5.0;
00692     m_P[itr]=-5.0;
00693     m_nhPXB[itr]=0;
00694     m_nhPXF[itr]=0;
00695     m_Eta[itr]=-99.0;
00696     m_Phi[itr]=-4.0;
00697     m_Chi2n[itr]=-11.0;
00698     m_d0[itr]=-999;
00699     m_dz[itr]=-999;
00700   }
00701   itr=0;
00702         
00703   // AM: what is this needed for?
00704   theFile->cd();
00705         
00706   // loop over tracks  
00707   const ConstTrajTrackPairCollection &tracks = eventInfo.trajTrackPairs_;
00708   for (ConstTrajTrackPairCollection::const_iterator it=tracks.begin();
00709        it!=tracks.end();
00710        ++it) {
00711                 
00712     const Trajectory* traj = (*it).first;
00713     const reco::Track* track = (*it).second;
00714                 
00715     float pt    = track->pt();
00716     float eta   = track->eta();
00717     float phi   = track->phi();
00718     float p     = track->p();
00719     float chi2n = track->normalizedChi2();
00720     int   nhit  = track->numberOfValidHits();
00721     float d0    = track->d0();
00722     float dz    = track->dz();
00723 
00724     int nhpxb   = track->hitPattern().numberOfValidPixelBarrelHits();
00725     int nhpxf   = track->hitPattern().numberOfValidPixelEndcapHits();
00726 
00727     if (verbose) edm::LogInfo("Alignment") << "New track pt,eta,phi,chi2n,hits: "
00728                                            << pt << ","
00729                                            << eta << ","
00730                                            << phi << ","
00731                                            << chi2n << ","
00732                                            << nhit;
00733     // edm::LogWarning("Alignment") << "New track pt,eta,phi,chi2n,hits: " 
00734     //                          << pt << ","
00735     //                          << eta << ","
00736     //                          << phi << ","
00737     //                          << chi2n << ","
00738     //                          << nhit;
00739                 
00740     // fill track parameters in root tree
00741     if (itr<MAXREC) {
00742       m_Nhits[itr]=nhit;
00743       m_Pt[itr]=pt;
00744       m_P[itr]=p;
00745       m_Eta[itr]=eta;
00746       m_Phi[itr]=phi;
00747       m_Chi2n[itr]=chi2n;
00748       m_nhPXB[itr]=nhpxb;
00749       m_nhPXF[itr]=nhpxf;
00750       m_d0[itr]=d0;
00751       m_dz[itr]=dz;
00752       itr++;
00753       m_Ntracks=itr;
00754     }
00755     // AM: Can be simplified
00756                 
00757     vector<const TransientTrackingRecHit*> hitvec;
00758     vector<TrajectoryStateOnSurface> tsosvec;
00759                 
00760     // loop over measurements   
00761     vector<TrajectoryMeasurement> measurements = traj->measurements();
00762     for (vector<TrajectoryMeasurement>::iterator im=measurements.begin();
00763          im!=measurements.end();
00764          ++im) {
00765    
00766       TrajectoryMeasurement meas = *im;
00767 
00768       // const TransientTrackingRecHit* ttrhit = &(*meas.recHit());
00769       // const TrackingRecHit *hit = ttrhit->hit();
00770       const TransientTrackingRecHit* hit = &(*meas.recHit());
00771 
00772       if (hit->isValid() && theAlignableDetAccessor->detAndSubdetInMap( hit->geographicalId() )) {
00773 
00774         // this is the updated state (including the current hit)
00775         // TrajectoryStateOnSurface tsos=meas.updatedState();
00776         // combine fwd and bwd predicted state to get state 
00777         // which excludes current hit
00778         
00780         bool skiphit = false;    
00781         if (eventInfo.clusterValueMap_) {        
00782           // check from the PrescalingMap if the hit was taken.          
00783           // If not skip to the next TM          
00784           // bool hitTaken=false;        
00785           AlignmentClusterFlag myflag;   
00786           
00787           int subDet = hit->geographicalId().subdetId();
00788           //take the actual RecHit out of the Transient one
00789           const TrackingRecHit *rechit=hit->hit();
00790           if (subDet>2) { // AM: if possible use enum instead of hard-coded value        
00791             const std::type_info &type = typeid(*rechit);        
00792             
00793             if (type == typeid(SiStripRecHit1D)) {       
00794               
00795               const SiStripRecHit1D* stripHit1D = dynamic_cast<const SiStripRecHit1D*>(rechit);          
00796               if (stripHit1D) {          
00797                 SiStripRecHit1D::ClusterRef stripclust(stripHit1D->cluster());   
00798                 // myflag=PrescMap[stripclust];          
00799                 myflag = (*eventInfo.clusterValueMap_)[stripclust];      
00800               } else {   
00801                 edm::LogError("HIPAlignmentAlgorithm") 
00802                   << "ERROR in <HIPAlignmentAlgorithm::run>: Dynamic cast of Strip RecHit failed! "
00803                   << "TypeId of the RecHit: " << className(*hit) <<endl;         
00804               }          
00805               
00806             }//end if type = SiStripRecHit1D     
00807             else if(type == typeid(SiStripRecHit2D)){    
00808               
00809               const SiStripRecHit2D* stripHit2D = dynamic_cast<const SiStripRecHit2D*>(rechit);          
00810               if (stripHit2D) {          
00811                 SiStripRecHit2D::ClusterRef stripclust(stripHit2D->cluster());   
00812                 // myflag=PrescMap[stripclust];          
00813                 myflag = (*eventInfo.clusterValueMap_)[stripclust];      
00814               } else {   
00815                 edm::LogError("HIPAlignmentAlgorithm") 
00816                   << "ERROR in <HIPAlignmentAlgorithm::run>: Dynamic cast of Strip RecHit failed! "
00817                   // << "TypeId of the TTRH: " << className(*ttrhit) << endl;    
00818                   << "TypeId of the TTRH: " << className(*hit) << endl;          
00819               } 
00820             } //end if type == SiStripRecHit2D   
00821           } //end if hit from strips     
00822           else {         
00823             const SiPixelRecHit* pixelhit= dynamic_cast<const SiPixelRecHit*>(rechit);   
00824             if (pixelhit) {      
00825               SiPixelClusterRefNew  pixelclust(pixelhit->cluster());     
00826               // myflag=PrescMap[pixelclust];    
00827               myflag = (*eventInfo.clusterValueMap_)[pixelclust];        
00828             }
00829             else {       
00830               edm::LogError("HIPAlignmentAlgorithm")
00831                 << "ERROR in <HIPAlignmentAlgorithm::run>: Dynamic cast of Pixel RecHit failed! "
00832                 // << "TypeId of the TTRH: " << className(*ttrhit) << endl;      
00833                 << "TypeId of the TTRH: " << className(*hit) << endl;    
00834             }
00835           } //end 'else' it is a pixel hit       
00836             // bool hitTaken=myflag.isTaken();   
00837           if (!myflag.isTaken()) {       
00838             skiphit=true;
00839             //cout<<"Hit from subdet "<<rechit->geographicalId().subdetId()<<" prescaled out."<<endl;
00840             continue;
00841           }
00842         }//end if Prescaled Hits         
00844         if (skiphit) {   
00845           throw cms::Exception("LogicError")
00846             << "ERROR  in <HIPAlignmentAlgorithm::run>: this hit should have been skipped!"
00847             << endl;     
00848         }
00849         
00850         TrajectoryStateOnSurface tsos = tsoscomb.combine(meas.forwardPredictedState(),
00851                                                          meas.backwardPredictedState());
00852         
00853         if(tsos.isValid()){
00854           // hitvec.push_back(ttrhit);
00855           hitvec.push_back(hit);
00856           tsosvec.push_back(tsos);
00857         }
00858 
00859       } //hit valid
00860     }
00861     
00862     // transform RecHit vector to AlignableDet vector
00863     vector <AlignableDetOrUnitPtr> alidetvec = theAlignableDetAccessor->alignablesFromHits(hitvec);
00864                 
00865     // get concatenated alignment parameters for list of alignables
00866     CompositeAlignmentParameters aap = theAlignmentParameterStore->selectParameters(alidetvec);
00867                 
00868     vector<TrajectoryStateOnSurface>::const_iterator itsos=tsosvec.begin();
00869     vector<const TransientTrackingRecHit*>::const_iterator ihit=hitvec.begin();
00870     
00871     // loop over vectors(hit,tsos)
00872     while (itsos != tsosvec.end()) {
00873 
00874       // get AlignableDet for this hit
00875       const GeomDet* det = (*ihit)->det();
00876       // int subDet= (*ihit)->geographicalId().subdetId();
00877       uint32_t nhitDim = (*ihit)->dimension();
00878       
00879       AlignableDetOrUnitPtr alidet = theAlignableDetAccessor->alignableFromGeomDet(det);
00880                         
00881       // get relevant Alignable
00882       Alignable* ali = aap.alignableFromAlignableDet(alidet);
00883       
00884       if (ali!=0) {
00885         bool processHitReturnValue;
00886         if (nhitDim==1) {
00887           processHitReturnValue = processHit1D(alidet, ali, *itsos, *ihit);
00888         } else if (nhitDim==2) {
00889           processHitReturnValue = processHit2D(alidet, ali, *itsos, *ihit);
00890         }
00891       }
00892                         
00893       itsos++;
00894       ihit++;
00895     } 
00896   } // end of track loop
00897         
00898   // fill eventwise root tree (with prescale defined in pset)
00899   if (theFillTrackMonitoring) {
00900     theCurrentPrescale--;
00901     if (theCurrentPrescale<=0) {
00902       theTree->Fill();
00903       theCurrentPrescale = theEventPrescale;
00904     }
00905   }
00906 }
00907 
00908 // ----------------------------------------------------------------------------
00909 
00910 int HIPAlignmentAlgorithm::readIterationFile(string filename)
00911 {
00912   int result;
00913   
00914   ifstream inIterFile((char*)filename.c_str(), ios::in);
00915   if (!inIterFile) {
00916     edm::LogError("Alignment") << "[HIPAlignmentAlgorithm::readIterationFile] ERROR! "
00917                                << "Unable to open Iteration file";
00918     result = -1;
00919   }
00920   else {
00921     inIterFile >> result;
00922     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::readIterationFile] "
00923                                  << "Read last iteration number from file: " << result;
00924   }
00925   inIterFile.close();
00926         
00927   return result;
00928 }
00929 
00930 // ----------------------------------------------------------------------------
00931 
00932 void HIPAlignmentAlgorithm::writeIterationFile(string filename,int iter)
00933 {
00934   ofstream outIterFile((char*)(filename.c_str()), ios::out);
00935   if (!outIterFile) {
00936     edm::LogError("Alignment") << "[HIPAlignmentAlgorithm::writeIterationFile] ERROR: Unable to write Iteration file";
00937   }
00938   else {
00939     outIterFile << iter;
00940     edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::writeIterationFile] writing iteration number to file: " << iter;
00941   }
00942   outIterFile.close();
00943 }
00944 
00945 
00946 // ----------------------------------------------------------------------------
00947 // set alignment position error
00948 
00949 void HIPAlignmentAlgorithm::setAlignmentPositionError(void)
00950 {
00951         
00952         
00953   // Check if user wants to override APE
00954   if ( !theApplyAPE )
00955     {
00956       edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::setAlignmentPositionError] No APE applied";
00957       return; // NO APE APPLIED
00958     }
00959         
00960         
00961   edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::setAlignmentPositionError] Apply APE!";
00962         
00963   double apeSPar[3], apeRPar[3];
00964   for (std::vector<std::pair<std::vector<Alignable*>, std::vector<double> > >::const_iterator alipars = theAPEParameters.begin();
00965        alipars != theAPEParameters.end();
00966        ++alipars) {
00967     const std::vector<Alignable*> &alignables = alipars->first;
00968     const std::vector<double> &pars = alipars->second;
00969                 
00970     apeSPar[0] = pars[0];
00971     apeSPar[1] = pars[1];
00972     apeSPar[2] = pars[2];
00973     apeRPar[0] = pars[3];
00974     apeRPar[1] = pars[4];
00975     apeRPar[2] = pars[5];
00976                 
00977     double function = pars[6];
00978                 
00979     // Printout for debug
00980     printf("APE: %u alignables\n", (unsigned int)alignables.size());
00981     for ( int i=0; i<21; ++i ) {
00982       double apelinstest=calcAPE(apeSPar,i,0.);
00983       double apeexpstest=calcAPE(apeSPar,i,1.);
00984       double apelinrtest=calcAPE(apeRPar,i,0.);
00985       double apeexprtest=calcAPE(apeRPar,i,1.);
00986       printf("APE: iter slin sexp rlin rexp: %5d %12.5f %12.5f %12.5f %12.5f\n",
00987              i,apelinstest,apeexpstest,apelinrtest,apeexprtest);
00988     }
00989                 
00990     // set APE
00991     double apeshift=calcAPE(apeSPar,theIteration,function);
00992     double aperot  =calcAPE(apeRPar,theIteration,function);
00993     theAlignmentParameterStore->setAlignmentPositionError( alignables, apeshift, aperot );
00994   }
00995         
00996 }
00997 
00998 // ----------------------------------------------------------------------------
00999 // calculate APE
01000 
01001 double 
01002 HIPAlignmentAlgorithm::calcAPE(double* par, int iter, double function)
01003 {
01004   double diter=(double)iter;
01005         
01006   // The following floating-point equality check is safe because this
01007   // "0." and this "1." are generated by the compiler, in the very
01008   // same file.  Whatever approximization scheme it uses to turn "1."
01009   // into 0.9999999999998 in the HIPAlignmentAlgorithm::initialize is
01010   // also used here.  If I'm wrong, you'll get an assertion.
01011   if (function == 0.) {
01012     return max(par[1],par[0]+((par[1]-par[0])/par[2])*diter);
01013   }
01014   else if (function == 1.) {
01015     return max(0.,par[0]*(exp(-pow(diter,par[1])/par[2])));
01016   }
01017   else if (function == 2.) {
01018     int ipar2 = (int) par[2];
01019     int step = iter/ipar2;
01020     double dstep = (double) step;
01021     return max(0.0, par[0] - par[1]*dstep);
01022   }
01023   else assert(false);  // should have been caught in the constructor
01024 }
01025 
01026 
01027 // ----------------------------------------------------------------------------
01028 // book root trees
01029 
01030 void HIPAlignmentAlgorithm::bookRoot(void)
01031 {
01032   // create ROOT files
01033   theFile = new TFile(outfile.c_str(),"update");
01034   theFile->cd();
01035         
01036   // book event-wise ROOT Tree
01037         
01038   TString tname="T1";
01039   char iterString[5];
01040   sprintf(iterString, "%i",theIteration);
01041   tname.Append("_");
01042   tname.Append(iterString);
01043         
01044   theTree  = new TTree(tname,"Eventwise tree");
01045         
01046   //theTree->Branch("Run",     &m_Run,     "Run/I");
01047   //theTree->Branch("Event",   &m_Event,   "Event/I");
01048   theTree->Branch("Ntracks", &m_Ntracks, "Ntracks/I");
01049   theTree->Branch("Nhits",    m_Nhits,   "Nhits[Ntracks]/I");       
01050   theTree->Branch("nhPXB",    m_nhPXB,   "nhPXB[Ntracks]/I");       
01051   theTree->Branch("nhPXF",    m_nhPXF,   "nhPXF[Ntracks]/I");       
01052   theTree->Branch("Pt",       m_Pt,      "Pt[Ntracks]/F");
01053   theTree->Branch("P",        m_P,       "P[Ntracks]/F");
01054   theTree->Branch("Eta",      m_Eta,     "Eta[Ntracks]/F");
01055   theTree->Branch("Phi",      m_Phi,     "Phi[Ntracks]/F");
01056   theTree->Branch("Chi2n",    m_Chi2n,   "Chi2n[Ntracks]/F");
01057   theTree->Branch("d0",       m_d0,      "d0[Ntracks]/F");
01058   theTree->Branch("dz",       m_dz,      "dz[Ntracks]/F");
01059   
01060   // book Alignable-wise ROOT Tree
01061         
01062   theFile2 = new TFile(outfile2.c_str(),"update");
01063   theFile2->cd();
01064         
01065   theTree2 = new TTree("T2","Alignablewise tree");
01066         
01067   theTree2->Branch("Nhit",   &m2_Nhit,    "Nhit/I");
01068   theTree2->Branch("Type",   &m2_Type,    "Type/I");
01069   theTree2->Branch("Layer",  &m2_Layer,   "Layer/I");
01070   theTree2->Branch("Xpos",   &m2_Xpos,    "Xpos/F");
01071   theTree2->Branch("Ypos",   &m2_Ypos,    "Ypos/F");
01072   theTree2->Branch("Zpos",   &m2_Zpos,    "Zpos/F");
01073   theTree2->Branch("Eta",    &m2_Eta,     "Eta/F");
01074   theTree2->Branch("Phi",    &m2_Phi,     "Phi/F");
01075   theTree2->Branch("Id",     &m2_Id,      "Id/i");
01076   theTree2->Branch("ObjId",  &m2_ObjId,   "ObjId/I");
01077         
01078   // book survey-wise ROOT Tree only if survey is enabled
01079   if (theLevels.size() > 0){
01080                 
01081     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::bookRoot] Survey trees booked.";
01082     theFile3 = new TFile(ssurveyfile.c_str(),"update");
01083     theFile3->cd();
01084     theTree3 = new TTree(tname, "Survey Tree");
01085     theTree3->Branch("Id", &m3_Id, "Id/i");
01086     theTree3->Branch("ObjId", &m3_ObjId, "ObjId/I");
01087     theTree3->Branch("Par", &m3_par, "Par[6]/F");
01088   }
01089         
01090   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::bookRoot] Root trees booked.";
01091         
01092 }
01093 
01094 // ----------------------------------------------------------------------------
01095 // fill alignable-wise root tree
01096 
01097 void HIPAlignmentAlgorithm::fillRoot(void)
01098 {
01099   theFile2->cd();
01100         
01101   int naligned=0;
01102         
01103   for (vector<Alignable*>::const_iterator it=theAlignables.begin();
01104        it!=theAlignables.end();
01105        ++it) {
01106     Alignable* ali = (*it);
01107     AlignmentParameters* dap = ali->alignmentParameters();
01108                 
01109     // consider only those parameters classified as 'valid'
01110     if (dap->isValid()) {
01111                         
01112       // get number of hits from user variable
01113       HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(dap->userVariables());
01114       m2_Nhit = uservar->nhit;
01115                         
01116       // get type/layer
01117       std::pair<int,int> tl = theAlignmentParameterStore->typeAndLayer(ali);
01118       m2_Type = tl.first;
01119       m2_Layer = tl.second;
01120                         
01121       // get identifier (as for IO)
01122       m2_Id    = ali->id();
01123       m2_ObjId = ali->alignableObjectId();
01124                         
01125       // get position
01126       GlobalPoint pos = ali->surface().position();
01127       m2_Xpos = pos.x();
01128       m2_Ypos = pos.y();
01129       m2_Zpos = pos.z();
01130       m2_Eta = pos.eta();
01131       m2_Phi = pos.phi();
01132                         
01133       AlgebraicVector pars = dap->parameters();
01134                         
01135       if (verbose) {
01136         edm::LogVerbatim("Alignment")
01137           << "------------------------------------------------------------------------\n"
01138           << " ALIGNABLE: " << setw(6) << naligned
01139           << '\n'
01140           << "hits: "   << setw(4) << m2_Nhit
01141           << " type: "  << setw(4) << m2_Type
01142           << " layer: " << setw(4) << m2_Layer
01143           << " id: "    << setw(4) << m2_Id
01144           << " objId: " << setw(4) << m2_ObjId
01145           << '\n'
01146           << fixed << setprecision(5)
01147           << "x,y,z: "
01148           << setw(12) << m2_Xpos
01149           << setw(12) << m2_Ypos 
01150           << setw(12) << m2_Zpos
01151           << " eta,phi: "
01152           << setw(12) << m2_Eta
01153           << setw(12) << m2_Phi
01154           << '\n'
01155           << "params: "
01156           << setw(12) << pars[0]
01157           << setw(12) << pars[1]
01158           << setw(12) << pars[2]
01159           << setw(12) << pars[3]
01160           << setw(12) << pars[4]
01161           << setw(12) << pars[5];
01162       }
01163       
01164       naligned++;
01165       theTree2->Fill();
01166     }
01167   }
01168 }
01169 
01170 // ----------------------------------------------------------------------------
01171 
01172 bool HIPAlignmentAlgorithm::calcParameters(Alignable* ali)
01173 {
01174   // Alignment parameters
01175   AlignmentParameters* par = ali->alignmentParameters();
01176   // access user variables
01177   HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(par->userVariables());
01178   int nhit = uservar->nhit;
01179   // The following variable is needed for the extended 1D/2D hit fix using
01180   // matrix shrinkage and expansion
01181   // int hitdim = uservar->hitdim;
01182   
01183   if (nhit < theMinimumNumberOfHits) {
01184     par->setValid(false);
01185     return false;
01186   }
01187 
01188   AlgebraicSymMatrix jtvj = uservar->jtvj;
01189   AlgebraicVector jtve = uservar->jtve;
01190 
01191   // Shrink input in case of 1D hits and 'v' selected
01192   // in alignment parameters
01193   //   if (hitdim==1 && selector[1]==true) {
01194   //     int iremove = 1;
01195   //     if (selector[0]==false) iremove--;
01196   
01197   //     AlgebraicSymMatrix tempjtvj(jtvj.num_row()-1);
01198   //     int nr = 0, nc = 0;
01199   //     for (int r=0;r<jtvj.num_row();r++) {
01200   //       if (r==iremove) continue;
01201   //       nc = 0;
01202   //       for (int c=0;c<jtvj.num_col();c++) {
01203   //    if (c==iremove) continue;
01204   //    tempjtvj[nr][nc] = jtvj[r][c];
01205   //    nc++;
01206   //       }
01207   //       nr++;
01208   //     }
01209   //     jtvj = tempjtvj;
01210   
01211   //     AlgebraicVector tempjtve(jtve.num_row()-1);
01212   //     nr = 0;
01213   //     for (int r=0;r<jtve.num_row();r++) {
01214   //       if (r==iremove) continue;
01215   //       tempjtve[nr] = jtve[r];
01216   //       nr++;
01217   //     }
01218   //     jtve = tempjtve;
01219   //   }
01220   
01221   int ierr;
01222   AlgebraicSymMatrix jtvjinv = jtvj.inverse(ierr);
01223 
01224   if (ierr !=0) {
01225     edm::LogError("Alignment") << "Matrix inversion failed!"; 
01226     return false;
01227   }
01228   
01229   // these are the alignment corrections+covariance (for selected params)
01230   AlgebraicVector params = - (jtvjinv * jtve);
01231   AlgebraicSymMatrix cov = jtvjinv;
01232 
01233   edm::LogInfo("Alignment") << "parameters " << params;
01234         
01235   // errors of parameters
01236   int npar = params.num_row();    
01237   AlgebraicVector paramerr(npar);
01238   AlgebraicVector relerr(npar);
01239   for (int i=0;i<npar;i++) {
01240     if (abs(cov[i][i])>0) paramerr[i] = sqrt(abs(cov[i][i]));
01241     else paramerr[i] = params[i];
01242     relerr[i] = abs(paramerr[i]/params[i]);
01243     if (relerr[i] >= theMaxRelParameterError) { 
01244       params[i] = 0; 
01245       paramerr[i]=0; 
01246     }
01247   }
01248 
01249   // expand output in case of 1D hits and 'v' selected
01250   // in alignment parameters
01251   //   if (hitdim==1 && selector[1]==true) {
01252   //     int iremove = 1;
01253   //     if (selector[0]==false) iremove--;
01254   
01255   //     AlgebraicSymMatrix tempcov(cov.num_row()+1,0);
01256   //     int nr = 0, nc = 0;
01257   //     for (int r=0;r<cov.num_row();r++) {
01258   //       if (r==iremove) nr++;
01259   //       nc = 0;
01260   //       for (int c=0;c<cov.num_col();c++) {
01261   //    if (c==iremove) nc++;
01262   //    tempcov[nr][nc] = cov[r][c];
01263   //    nc++;
01264   //       }
01265   //       nr++;
01266   //     }
01267   //     cov = tempcov;
01268   
01269   //     AlgebraicVector tempparams(params.num_row()+1,0);
01270   //     nr = 0;
01271   //     for (int r=0;r<params.num_row();r++) {
01272   //       if (r==iremove) nr++;
01273   //       tempparams[nr] = params[r];
01274   //       nr++;
01275   //     }
01276   //     params = tempparams;
01277   //   }
01278   
01279   // store alignment parameters
01280   AlignmentParameters* parnew = par->cloneFromSelected(params,cov);
01281   ali->setAlignmentParameters(parnew);
01282   parnew->setValid(true);
01283 
01284   return true;
01285 }
01286 
01287 //-----------------------------------------------------------------------------
01288 
01289 void HIPAlignmentAlgorithm::collector(void)
01290 {
01291   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::collector] called for iteration "
01292                                << theIteration << std::endl;
01293         
01294   HIPUserVariablesIORoot HIPIO;
01295         
01296   for (int ijob=1;ijob<=theCollectorNJobs;ijob++) {
01297                 
01298     edm::LogWarning("Alignment") << "reading uservar for job " << ijob;
01299     
01300     stringstream ss;
01301     string str;
01302     ss << ijob;
01303     ss >> str;
01304     string uvfile = theCollectorPath+"/job"+str+"/IOUserVariables.root";
01305                 
01306     vector<AlignmentUserVariables*> uvarvec = 
01307       HIPIO.readHIPUserVariables(theAlignables, (char*)uvfile.c_str(),
01308                                  theIteration, ioerr);
01309     
01310     if (ioerr!=0) { 
01311       edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::collector] could not read user variable files for job " 
01312                                    << ijob;
01313       continue;
01314     }
01315                 
01316     // add
01317     vector<AlignmentUserVariables*> uvarvecadd;
01318     vector<AlignmentUserVariables*>::const_iterator iuvarnew=uvarvec.begin(); 
01319     for (vector<Alignable*>::const_iterator it=theAlignables.begin(); 
01320          it!=theAlignables.end();
01321          ++it) {
01322       Alignable* ali = *it;
01323       AlignmentParameters* ap = ali->alignmentParameters();
01324                         
01325       HIPUserVariables* uvarold = dynamic_cast<HIPUserVariables*>(ap->userVariables());
01326       HIPUserVariables* uvarnew = dynamic_cast<HIPUserVariables*>(*iuvarnew);
01327                         
01328       HIPUserVariables* uvar = uvarold->clone();
01329       if (uvarnew!=0) {
01330         uvar->nhit = (uvarold->nhit)+(uvarnew->nhit);
01331         uvar->jtvj = (uvarold->jtvj)+(uvarnew->jtvj);
01332         uvar->jtve = (uvarold->jtve)+(uvarnew->jtve);
01333         uvar->alichi2 = (uvarold->alichi2)+(uvarnew->alichi2);
01334         uvar->alindof = (uvarold->alindof)+(uvarnew->alindof);
01335         delete uvarnew;
01336       }
01337                         
01338       uvarvecadd.push_back(uvar);
01339       iuvarnew++;
01340     }
01341     
01342     theAlignmentParameterStore->attachUserVariables(theAlignables, uvarvecadd, ioerr);
01343                 
01344     //fill Eventwise Tree
01345     if (theFillTrackMonitoring) {
01346       uvfile = theCollectorPath+"/job"+str+"/HIPAlignmentEvents.root";
01347       edm::LogWarning("Alignment") << "Added to the tree "
01348                                    << fillEventwiseTree(uvfile.c_str(), theIteration, ioerr)
01349                                    << "tracks";
01350     }
01351                 
01352   }//end loop on jobs
01353 }
01354 
01355 //------------------------------------------------------------------------------------
01356 
01357 int HIPAlignmentAlgorithm::fillEventwiseTree(const char* filename, int iter, int ierr)
01358 {       
01359   int totntrk = 0;
01360   char treeName[64];
01361   sprintf(treeName, "T1_%d", iter);
01362   //open the file "HIPAlignmentEvents.root" in the job directory
01363   TFile *jobfile = new TFile(filename, "READ");
01364   //grab the tree corresponding to this iteration
01365   TTree *jobtree = (TTree*)jobfile->Get(treeName);
01366   //address and read the variables 
01367   static const int nmaxtrackperevent = 1000;
01368   int jobNtracks, jobNhitspertrack[nmaxtrackperevent], jobnhPXB[nmaxtrackperevent], jobnhPXF[nmaxtrackperevent];
01369   float jobP[nmaxtrackperevent], jobPt[nmaxtrackperevent], jobEta[nmaxtrackperevent] , jobPhi[nmaxtrackperevent];
01370   float jobd0[nmaxtrackperevent], jobdz[nmaxtrackperevent] , jobChi2n[nmaxtrackperevent];
01371         
01372   jobtree->SetBranchAddress("Ntracks", &jobNtracks);
01373   jobtree->SetBranchAddress("Nhits",   jobNhitspertrack);
01374   jobtree->SetBranchAddress("nhPXB",   jobnhPXB);
01375   jobtree->SetBranchAddress("nhPXF",   jobnhPXF);
01376   jobtree->SetBranchAddress("Pt",      jobPt);
01377   jobtree->SetBranchAddress("P",       jobP);
01378   jobtree->SetBranchAddress("d0",      jobd0);
01379   jobtree->SetBranchAddress("dz",      jobdz);
01380   jobtree->SetBranchAddress("Eta",     jobEta);
01381   jobtree->SetBranchAddress("Phi",     jobPhi);
01382   jobtree->SetBranchAddress("Chi2n",   jobChi2n);
01383   int ievent = 0;
01384   for (ievent=0;ievent<jobtree->GetEntries();++ievent) {
01385     jobtree->GetEntry(ievent);
01386                 
01387     //fill the collector tree with them
01388     
01389     //  TO BE IMPLEMENTED: a prescale factor like in run()
01390     m_Ntracks = jobNtracks;
01391     int ntrk = 0;
01392     while (ntrk<m_Ntracks) {
01393       if (ntrk<MAXREC) {
01394         totntrk = ntrk+1;
01395         m_Nhits[ntrk] = jobNhitspertrack[ntrk];
01396         m_Pt[ntrk] = jobPt[ntrk];
01397         m_P[ntrk] = jobP[ntrk];
01398         m_nhPXB[ntrk] = jobnhPXB[ntrk];
01399         m_nhPXF[ntrk] = jobnhPXF[ntrk];
01400         m_Eta[ntrk] = jobEta[ntrk];
01401         m_Phi[ntrk] = jobPhi[ntrk];
01402         m_Chi2n[ntrk] = jobChi2n[ntrk];
01403         m_d0[ntrk] = jobd0[ntrk];
01404         m_dz[ntrk] = jobdz[ntrk];
01405       }//end if j<MAXREC
01406       else{
01407         edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::fillEventwiseTree] Number of tracks in Eventwise tree exceeds MAXREC: "
01408                                      << m_Ntracks << "  Skipping exceeding tracks.";
01409         ntrk = m_Ntracks+1;
01410       }
01411       ++ntrk;
01412     }//end while loop
01413     theTree->Fill();
01414   }//end loop on i - entries in the job tree
01415 
01416   //clean up
01417   delete jobtree;
01418   delete jobfile;
01419   
01420   return totntrk;
01421 }//end fillEventwiseTree