CMS 3D CMS Logo

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