CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_8_patch3/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         if (nhitDim==1) {
00886           processHit1D(alidet, ali, *itsos, *ihit);
00887         } else if (nhitDim==2) {
00888           processHit2D(alidet, ali, *itsos, *ihit);
00889         }
00890       }
00891                         
00892       itsos++;
00893       ihit++;
00894     } 
00895   } // end of track loop
00896         
00897   // fill eventwise root tree (with prescale defined in pset)
00898   if (theFillTrackMonitoring) {
00899     theCurrentPrescale--;
00900     if (theCurrentPrescale<=0) {
00901       theTree->Fill();
00902       theCurrentPrescale = theEventPrescale;
00903     }
00904   }
00905 }
00906 
00907 // ----------------------------------------------------------------------------
00908 
00909 int HIPAlignmentAlgorithm::readIterationFile(string filename)
00910 {
00911   int result;
00912   
00913   ifstream inIterFile((char*)filename.c_str(), ios::in);
00914   if (!inIterFile) {
00915     edm::LogError("Alignment") << "[HIPAlignmentAlgorithm::readIterationFile] ERROR! "
00916                                << "Unable to open Iteration file";
00917     result = -1;
00918   }
00919   else {
00920     inIterFile >> result;
00921     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::readIterationFile] "
00922                                  << "Read last iteration number from file: " << result;
00923   }
00924   inIterFile.close();
00925         
00926   return result;
00927 }
00928 
00929 // ----------------------------------------------------------------------------
00930 
00931 void HIPAlignmentAlgorithm::writeIterationFile(string filename,int iter)
00932 {
00933   ofstream outIterFile((char*)(filename.c_str()), ios::out);
00934   if (!outIterFile) {
00935     edm::LogError("Alignment") << "[HIPAlignmentAlgorithm::writeIterationFile] ERROR: Unable to write Iteration file";
00936   }
00937   else {
00938     outIterFile << iter;
00939     edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::writeIterationFile] writing iteration number to file: " << iter;
00940   }
00941   outIterFile.close();
00942 }
00943 
00944 
00945 // ----------------------------------------------------------------------------
00946 // set alignment position error
00947 
00948 void HIPAlignmentAlgorithm::setAlignmentPositionError(void)
00949 {
00950         
00951         
00952   // Check if user wants to override APE
00953   if ( !theApplyAPE )
00954     {
00955       edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::setAlignmentPositionError] No APE applied";
00956       return; // NO APE APPLIED
00957     }
00958         
00959         
00960   edm::LogWarning("Alignment") <<"[HIPAlignmentAlgorithm::setAlignmentPositionError] Apply APE!";
00961         
00962   double apeSPar[3], apeRPar[3];
00963   for (std::vector<std::pair<std::vector<Alignable*>, std::vector<double> > >::const_iterator alipars = theAPEParameters.begin();
00964        alipars != theAPEParameters.end();
00965        ++alipars) {
00966     const std::vector<Alignable*> &alignables = alipars->first;
00967     const std::vector<double> &pars = alipars->second;
00968                 
00969     apeSPar[0] = pars[0];
00970     apeSPar[1] = pars[1];
00971     apeSPar[2] = pars[2];
00972     apeRPar[0] = pars[3];
00973     apeRPar[1] = pars[4];
00974     apeRPar[2] = pars[5];
00975                 
00976     double function = pars[6];
00977                 
00978     // Printout for debug
00979     printf("APE: %u alignables\n", (unsigned int)alignables.size());
00980     for ( int i=0; i<21; ++i ) {
00981       double apelinstest=calcAPE(apeSPar,i,0.);
00982       double apeexpstest=calcAPE(apeSPar,i,1.);
00983       double apelinrtest=calcAPE(apeRPar,i,0.);
00984       double apeexprtest=calcAPE(apeRPar,i,1.);
00985       printf("APE: iter slin sexp rlin rexp: %5d %12.5f %12.5f %12.5f %12.5f\n",
00986              i,apelinstest,apeexpstest,apelinrtest,apeexprtest);
00987     }
00988                 
00989     // set APE
00990     double apeshift=calcAPE(apeSPar,theIteration,function);
00991     double aperot  =calcAPE(apeRPar,theIteration,function);
00992     theAlignmentParameterStore->setAlignmentPositionError( alignables, apeshift, aperot );
00993   }
00994         
00995 }
00996 
00997 // ----------------------------------------------------------------------------
00998 // calculate APE
00999 
01000 double 
01001 HIPAlignmentAlgorithm::calcAPE(double* par, int iter, double function)
01002 {
01003   double diter=(double)iter;
01004         
01005   // The following floating-point equality check is safe because this
01006   // "0." and this "1." are generated by the compiler, in the very
01007   // same file.  Whatever approximization scheme it uses to turn "1."
01008   // into 0.9999999999998 in the HIPAlignmentAlgorithm::initialize is
01009   // also used here.  If I'm wrong, you'll get an assertion.
01010   if (function == 0.) {
01011     return max(par[1],par[0]+((par[1]-par[0])/par[2])*diter);
01012   }
01013   else if (function == 1.) {
01014     return max(0.,par[0]*(exp(-pow(diter,par[1])/par[2])));
01015   }
01016   else if (function == 2.) {
01017     int ipar2 = (int) par[2];
01018     int step = iter/ipar2;
01019     double dstep = (double) step;
01020     return max(0.0, par[0] - par[1]*dstep);
01021   }
01022   else assert(false);  // should have been caught in the constructor
01023 }
01024 
01025 
01026 // ----------------------------------------------------------------------------
01027 // book root trees
01028 
01029 void HIPAlignmentAlgorithm::bookRoot(void)
01030 {
01031   // create ROOT files
01032   theFile = new TFile(outfile.c_str(),"update");
01033   theFile->cd();
01034         
01035   // book event-wise ROOT Tree
01036         
01037   TString tname="T1";
01038   char iterString[5];
01039   snprintf(iterString, sizeof(iterString), "%i",theIteration);
01040   tname.Append("_");
01041   tname.Append(iterString);
01042         
01043   theTree  = new TTree(tname,"Eventwise tree");
01044         
01045   //theTree->Branch("Run",     &m_Run,     "Run/I");
01046   //theTree->Branch("Event",   &m_Event,   "Event/I");
01047   theTree->Branch("Ntracks", &m_Ntracks, "Ntracks/I");
01048   theTree->Branch("Nhits",    m_Nhits,   "Nhits[Ntracks]/I");       
01049   theTree->Branch("nhPXB",    m_nhPXB,   "nhPXB[Ntracks]/I");       
01050   theTree->Branch("nhPXF",    m_nhPXF,   "nhPXF[Ntracks]/I");       
01051   theTree->Branch("Pt",       m_Pt,      "Pt[Ntracks]/F");
01052   theTree->Branch("P",        m_P,       "P[Ntracks]/F");
01053   theTree->Branch("Eta",      m_Eta,     "Eta[Ntracks]/F");
01054   theTree->Branch("Phi",      m_Phi,     "Phi[Ntracks]/F");
01055   theTree->Branch("Chi2n",    m_Chi2n,   "Chi2n[Ntracks]/F");
01056   theTree->Branch("d0",       m_d0,      "d0[Ntracks]/F");
01057   theTree->Branch("dz",       m_dz,      "dz[Ntracks]/F");
01058   
01059   // book Alignable-wise ROOT Tree
01060         
01061   theFile2 = new TFile(outfile2.c_str(),"update");
01062   theFile2->cd();
01063         
01064   theTree2 = new TTree("T2","Alignablewise tree");
01065         
01066   theTree2->Branch("Nhit",   &m2_Nhit,    "Nhit/I");
01067   theTree2->Branch("Type",   &m2_Type,    "Type/I");
01068   theTree2->Branch("Layer",  &m2_Layer,   "Layer/I");
01069   theTree2->Branch("Xpos",   &m2_Xpos,    "Xpos/F");
01070   theTree2->Branch("Ypos",   &m2_Ypos,    "Ypos/F");
01071   theTree2->Branch("Zpos",   &m2_Zpos,    "Zpos/F");
01072   theTree2->Branch("Eta",    &m2_Eta,     "Eta/F");
01073   theTree2->Branch("Phi",    &m2_Phi,     "Phi/F");
01074   theTree2->Branch("Id",     &m2_Id,      "Id/i");
01075   theTree2->Branch("ObjId",  &m2_ObjId,   "ObjId/I");
01076         
01077   // book survey-wise ROOT Tree only if survey is enabled
01078   if (theLevels.size() > 0){
01079                 
01080     edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::bookRoot] Survey trees booked.";
01081     theFile3 = new TFile(ssurveyfile.c_str(),"update");
01082     theFile3->cd();
01083     theTree3 = new TTree(tname, "Survey Tree");
01084     theTree3->Branch("Id", &m3_Id, "Id/i");
01085     theTree3->Branch("ObjId", &m3_ObjId, "ObjId/I");
01086     theTree3->Branch("Par", &m3_par, "Par[6]/F");
01087   }
01088         
01089   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::bookRoot] Root trees booked.";
01090         
01091 }
01092 
01093 // ----------------------------------------------------------------------------
01094 // fill alignable-wise root tree
01095 
01096 void HIPAlignmentAlgorithm::fillRoot(void)
01097 {
01098   theFile2->cd();
01099         
01100   int naligned=0;
01101         
01102   for (vector<Alignable*>::const_iterator it=theAlignables.begin();
01103        it!=theAlignables.end();
01104        ++it) {
01105     Alignable* ali = (*it);
01106     AlignmentParameters* dap = ali->alignmentParameters();
01107                 
01108     // consider only those parameters classified as 'valid'
01109     if (dap->isValid()) {
01110                         
01111       // get number of hits from user variable
01112       HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(dap->userVariables());
01113       m2_Nhit = uservar->nhit;
01114                         
01115       // get type/layer
01116       std::pair<int,int> tl = theAlignmentParameterStore->typeAndLayer(ali);
01117       m2_Type = tl.first;
01118       m2_Layer = tl.second;
01119                         
01120       // get identifier (as for IO)
01121       m2_Id    = ali->id();
01122       m2_ObjId = ali->alignableObjectId();
01123                         
01124       // get position
01125       GlobalPoint pos = ali->surface().position();
01126       m2_Xpos = pos.x();
01127       m2_Ypos = pos.y();
01128       m2_Zpos = pos.z();
01129       m2_Eta = pos.eta();
01130       m2_Phi = pos.phi();
01131                         
01132       AlgebraicVector pars = dap->parameters();
01133                         
01134       if (verbose) {
01135         edm::LogVerbatim("Alignment")
01136           << "------------------------------------------------------------------------\n"
01137           << " ALIGNABLE: " << setw(6) << naligned
01138           << '\n'
01139           << "hits: "   << setw(4) << m2_Nhit
01140           << " type: "  << setw(4) << m2_Type
01141           << " layer: " << setw(4) << m2_Layer
01142           << " id: "    << setw(4) << m2_Id
01143           << " objId: " << setw(4) << m2_ObjId
01144           << '\n'
01145           << fixed << setprecision(5)
01146           << "x,y,z: "
01147           << setw(12) << m2_Xpos
01148           << setw(12) << m2_Ypos 
01149           << setw(12) << m2_Zpos
01150           << " eta,phi: "
01151           << setw(12) << m2_Eta
01152           << setw(12) << m2_Phi
01153           << '\n'
01154           << "params: "
01155           << setw(12) << pars[0]
01156           << setw(12) << pars[1]
01157           << setw(12) << pars[2]
01158           << setw(12) << pars[3]
01159           << setw(12) << pars[4]
01160           << setw(12) << pars[5];
01161       }
01162       
01163       naligned++;
01164       theTree2->Fill();
01165     }
01166   }
01167 }
01168 
01169 // ----------------------------------------------------------------------------
01170 
01171 bool HIPAlignmentAlgorithm::calcParameters(Alignable* ali)
01172 {
01173   // Alignment parameters
01174   AlignmentParameters* par = ali->alignmentParameters();
01175   // access user variables
01176   HIPUserVariables* uservar = dynamic_cast<HIPUserVariables*>(par->userVariables());
01177   int nhit = uservar->nhit;
01178   // The following variable is needed for the extended 1D/2D hit fix using
01179   // matrix shrinkage and expansion
01180   // int hitdim = uservar->hitdim;
01181   
01182   if (nhit < theMinimumNumberOfHits) {
01183     par->setValid(false);
01184     return false;
01185   }
01186 
01187   AlgebraicSymMatrix jtvj = uservar->jtvj;
01188   AlgebraicVector jtve = uservar->jtve;
01189 
01190   // Shrink input in case of 1D hits and 'v' selected
01191   // in alignment parameters
01192   //   if (hitdim==1 && selector[1]==true) {
01193   //     int iremove = 1;
01194   //     if (selector[0]==false) iremove--;
01195   
01196   //     AlgebraicSymMatrix tempjtvj(jtvj.num_row()-1);
01197   //     int nr = 0, nc = 0;
01198   //     for (int r=0;r<jtvj.num_row();r++) {
01199   //       if (r==iremove) continue;
01200   //       nc = 0;
01201   //       for (int c=0;c<jtvj.num_col();c++) {
01202   //    if (c==iremove) continue;
01203   //    tempjtvj[nr][nc] = jtvj[r][c];
01204   //    nc++;
01205   //       }
01206   //       nr++;
01207   //     }
01208   //     jtvj = tempjtvj;
01209   
01210   //     AlgebraicVector tempjtve(jtve.num_row()-1);
01211   //     nr = 0;
01212   //     for (int r=0;r<jtve.num_row();r++) {
01213   //       if (r==iremove) continue;
01214   //       tempjtve[nr] = jtve[r];
01215   //       nr++;
01216   //     }
01217   //     jtve = tempjtve;
01218   //   }
01219   
01220   int ierr;
01221   AlgebraicSymMatrix jtvjinv = jtvj.inverse(ierr);
01222 
01223   if (ierr !=0) {
01224     edm::LogError("Alignment") << "Matrix inversion failed!"; 
01225     return false;
01226   }
01227   
01228   // these are the alignment corrections+covariance (for selected params)
01229   AlgebraicVector params = - (jtvjinv * jtve);
01230   AlgebraicSymMatrix cov = jtvjinv;
01231 
01232   edm::LogInfo("Alignment") << "parameters " << params;
01233         
01234   // errors of parameters
01235   int npar = params.num_row();    
01236   AlgebraicVector paramerr(npar);
01237   AlgebraicVector relerr(npar);
01238   for (int i=0;i<npar;i++) {
01239     if (abs(cov[i][i])>0) paramerr[i] = sqrt(abs(cov[i][i]));
01240     else paramerr[i] = params[i];
01241     relerr[i] = abs(paramerr[i]/params[i]);
01242     if (relerr[i] >= theMaxRelParameterError) { 
01243       params[i] = 0; 
01244       paramerr[i]=0; 
01245     }
01246   }
01247 
01248   // expand output in case of 1D hits and 'v' selected
01249   // in alignment parameters
01250   //   if (hitdim==1 && selector[1]==true) {
01251   //     int iremove = 1;
01252   //     if (selector[0]==false) iremove--;
01253   
01254   //     AlgebraicSymMatrix tempcov(cov.num_row()+1,0);
01255   //     int nr = 0, nc = 0;
01256   //     for (int r=0;r<cov.num_row();r++) {
01257   //       if (r==iremove) nr++;
01258   //       nc = 0;
01259   //       for (int c=0;c<cov.num_col();c++) {
01260   //    if (c==iremove) nc++;
01261   //    tempcov[nr][nc] = cov[r][c];
01262   //    nc++;
01263   //       }
01264   //       nr++;
01265   //     }
01266   //     cov = tempcov;
01267   
01268   //     AlgebraicVector tempparams(params.num_row()+1,0);
01269   //     nr = 0;
01270   //     for (int r=0;r<params.num_row();r++) {
01271   //       if (r==iremove) nr++;
01272   //       tempparams[nr] = params[r];
01273   //       nr++;
01274   //     }
01275   //     params = tempparams;
01276   //   }
01277   
01278   // store alignment parameters
01279   AlignmentParameters* parnew = par->cloneFromSelected(params,cov);
01280   ali->setAlignmentParameters(parnew);
01281   parnew->setValid(true);
01282 
01283   return true;
01284 }
01285 
01286 //-----------------------------------------------------------------------------
01287 
01288 void HIPAlignmentAlgorithm::collector(void)
01289 {
01290   edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::collector] called for iteration "
01291                                << theIteration << std::endl;
01292         
01293   HIPUserVariablesIORoot HIPIO;
01294         
01295   for (int ijob=1;ijob<=theCollectorNJobs;ijob++) {
01296                 
01297     edm::LogWarning("Alignment") << "reading uservar for job " << ijob;
01298     
01299     stringstream ss;
01300     string str;
01301     ss << ijob;
01302     ss >> str;
01303     string uvfile = theCollectorPath+"/job"+str+"/IOUserVariables.root";
01304                 
01305     vector<AlignmentUserVariables*> uvarvec = 
01306       HIPIO.readHIPUserVariables(theAlignables, (char*)uvfile.c_str(),
01307                                  theIteration, ioerr);
01308     
01309     if (ioerr!=0) { 
01310       edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::collector] could not read user variable files for job " 
01311                                    << ijob;
01312       continue;
01313     }
01314                 
01315     // add
01316     vector<AlignmentUserVariables*> uvarvecadd;
01317     vector<AlignmentUserVariables*>::const_iterator iuvarnew=uvarvec.begin(); 
01318     for (vector<Alignable*>::const_iterator it=theAlignables.begin(); 
01319          it!=theAlignables.end();
01320          ++it) {
01321       Alignable* ali = *it;
01322       AlignmentParameters* ap = ali->alignmentParameters();
01323                         
01324       HIPUserVariables* uvarold = dynamic_cast<HIPUserVariables*>(ap->userVariables());
01325       HIPUserVariables* uvarnew = dynamic_cast<HIPUserVariables*>(*iuvarnew);
01326                         
01327       HIPUserVariables* uvar = uvarold->clone();
01328       if (uvarnew!=0) {
01329         uvar->nhit = (uvarold->nhit)+(uvarnew->nhit);
01330         uvar->jtvj = (uvarold->jtvj)+(uvarnew->jtvj);
01331         uvar->jtve = (uvarold->jtve)+(uvarnew->jtve);
01332         uvar->alichi2 = (uvarold->alichi2)+(uvarnew->alichi2);
01333         uvar->alindof = (uvarold->alindof)+(uvarnew->alindof);
01334         delete uvarnew;
01335       }
01336                         
01337       uvarvecadd.push_back(uvar);
01338       iuvarnew++;
01339     }
01340     
01341     theAlignmentParameterStore->attachUserVariables(theAlignables, uvarvecadd, ioerr);
01342                 
01343     //fill Eventwise Tree
01344     if (theFillTrackMonitoring) {
01345       uvfile = theCollectorPath+"/job"+str+"/HIPAlignmentEvents.root";
01346       edm::LogWarning("Alignment") << "Added to the tree "
01347                                    << fillEventwiseTree(uvfile.c_str(), theIteration, ioerr)
01348                                    << "tracks";
01349     }
01350                 
01351   }//end loop on jobs
01352 }
01353 
01354 //------------------------------------------------------------------------------------
01355 
01356 int HIPAlignmentAlgorithm::fillEventwiseTree(const char* filename, int iter, int ierr)
01357 {       
01358   int totntrk = 0;
01359   char treeName[64];
01360   snprintf(treeName, sizeof(treeName), "T1_%d", iter);
01361   //open the file "HIPAlignmentEvents.root" in the job directory
01362   TFile *jobfile = new TFile(filename, "READ");
01363   //grab the tree corresponding to this iteration
01364   TTree *jobtree = (TTree*)jobfile->Get(treeName);
01365   //address and read the variables 
01366   static const int nmaxtrackperevent = 1000;
01367   int jobNtracks, jobNhitspertrack[nmaxtrackperevent], jobnhPXB[nmaxtrackperevent], jobnhPXF[nmaxtrackperevent];
01368   float jobP[nmaxtrackperevent], jobPt[nmaxtrackperevent], jobEta[nmaxtrackperevent] , jobPhi[nmaxtrackperevent];
01369   float jobd0[nmaxtrackperevent], jobdz[nmaxtrackperevent] , jobChi2n[nmaxtrackperevent];
01370         
01371   jobtree->SetBranchAddress("Ntracks", &jobNtracks);
01372   jobtree->SetBranchAddress("Nhits",   jobNhitspertrack);
01373   jobtree->SetBranchAddress("nhPXB",   jobnhPXB);
01374   jobtree->SetBranchAddress("nhPXF",   jobnhPXF);
01375   jobtree->SetBranchAddress("Pt",      jobPt);
01376   jobtree->SetBranchAddress("P",       jobP);
01377   jobtree->SetBranchAddress("d0",      jobd0);
01378   jobtree->SetBranchAddress("dz",      jobdz);
01379   jobtree->SetBranchAddress("Eta",     jobEta);
01380   jobtree->SetBranchAddress("Phi",     jobPhi);
01381   jobtree->SetBranchAddress("Chi2n",   jobChi2n);
01382   int ievent = 0;
01383   for (ievent=0;ievent<jobtree->GetEntries();++ievent) {
01384     jobtree->GetEntry(ievent);
01385                 
01386     //fill the collector tree with them
01387     
01388     //  TO BE IMPLEMENTED: a prescale factor like in run()
01389     m_Ntracks = jobNtracks;
01390     int ntrk = 0;
01391     while (ntrk<m_Ntracks) {
01392       if (ntrk<MAXREC) {
01393         totntrk = ntrk+1;
01394         m_Nhits[ntrk] = jobNhitspertrack[ntrk];
01395         m_Pt[ntrk] = jobPt[ntrk];
01396         m_P[ntrk] = jobP[ntrk];
01397         m_nhPXB[ntrk] = jobnhPXB[ntrk];
01398         m_nhPXF[ntrk] = jobnhPXF[ntrk];
01399         m_Eta[ntrk] = jobEta[ntrk];
01400         m_Phi[ntrk] = jobPhi[ntrk];
01401         m_Chi2n[ntrk] = jobChi2n[ntrk];
01402         m_d0[ntrk] = jobd0[ntrk];
01403         m_dz[ntrk] = jobdz[ntrk];
01404       }//end if j<MAXREC
01405       else{
01406         edm::LogWarning("Alignment") << "[HIPAlignmentAlgorithm::fillEventwiseTree] Number of tracks in Eventwise tree exceeds MAXREC: "
01407                                      << m_Ntracks << "  Skipping exceeding tracks.";
01408         ntrk = m_Ntracks+1;
01409       }
01410       ++ntrk;
01411     }//end while loop
01412     theTree->Fill();
01413   }//end loop on i - entries in the job tree
01414 
01415   //clean up
01416   delete jobtree;
01417   delete jobfile;
01418   
01419   return totntrk;
01420 }//end fillEventwiseTree