CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/Alignment/MuonAlignment/plugins/MuonGeometryArrange.cc

Go to the documentation of this file.
00001 #include "CondFormats/Alignment/interface/Alignments.h"
00002 #include "CondFormats/Alignment/interface/AlignmentErrors.h"
00003 #include "CLHEP/Vector/RotationInterfaces.h" 
00004 #include "CondFormats/Alignment/interface/AlignmentSorter.h"
00005 
00006 #include "FWCore/Framework/interface/MakerMacros.h"
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 #include "FWCore/Framework/interface/EventSetup.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 
00011 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
00012 
00013 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00014 #include "Geometry/TrackerNumberingBuilder/interface/GeometricDet.h" 
00015 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00016 // The following looks generic enough to use
00017 #include "Alignment/CommonAlignment/interface/Utilities.h"
00018 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
00019 #include "Alignment/CommonAlignment/interface/Alignable.h"
00020 #include "DataFormats/DetId/interface/DetId.h"
00021 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00022 #include "CondFormats/AlignmentRecord/interface/GlobalPositionRcd.h"
00023 #include "CondFormats/Alignment/interface/DetectorGlobalPosition.h"
00024 
00025 #include "Alignment/MuonAlignment/interface/MuonAlignmentInputXML.h"
00026 #include "Alignment/MuonAlignment/interface/MuonAlignment.h"
00027 
00028 #include "MuonGeometryArrange.h"
00029 #include "TFile.h" 
00030 #include "TLatex.h"
00031 #include "TArrow.h"
00032 #include "TGraph.h"
00033 #include "TH1F.h" 
00034 #include "TH2F.h" 
00035 #include "CLHEP/Vector/ThreeVector.h"
00036 
00037 // Database
00038 #include "FWCore/ServiceRegistry/interface/Service.h"
00039 
00040 #include <iostream>
00041 #include <fstream>
00042 
00043 MuonGeometryArrange::MuonGeometryArrange(const edm::ParameterSet& cfg) :
00044   theSurveyIndex(0), _writeToDB(false), _commonMuonLevel(align::invalid), firstEvent_(true)
00045 {
00046         referenceMuon=0x0;
00047         currentMuon=0x0;
00048         // Input is XML
00049         _inputXMLCurrent = cfg.getUntrackedParameter<std::string> ("inputXMLCurrent");
00050         _inputXMLReference = cfg.getUntrackedParameter<std::string> ("inputXMLReference");
00051 
00052         //input is ROOT
00053         _inputFilename1 = cfg.getUntrackedParameter< std::string >
00054                                 ("inputROOTFile1");
00055         _inputFilename2 = cfg.getUntrackedParameter< std::string >
00056                                 ("inputROOTFile2");
00057         _inputTreename = cfg.getUntrackedParameter< std::string > ("treeName");
00058         
00059         //output file
00060         _filename = cfg.getUntrackedParameter< std::string > ("outputFile");
00061         
00062         
00063         const std::vector<std::string>& levels = 
00064             cfg.getUntrackedParameter< std::vector<std::string> > ("levels");
00065         
00066         _weightBy = cfg.getUntrackedParameter< std::string > ("weightBy");
00067         _detIdFlag = cfg.getUntrackedParameter< bool > ("detIdFlag");
00068         _detIdFlagFile = cfg.getUntrackedParameter< std::string >
00069                           ("detIdFlagFile");
00070         _weightById  = cfg.getUntrackedParameter< bool > ("weightById");
00071         _weightByIdFile = cfg.getUntrackedParameter< std::string >
00072                          ("weightByIdFile");
00073         _endcap  = cfg.getUntrackedParameter<int> ("endcapNumber");
00074         _station = cfg.getUntrackedParameter<int> ("stationNumber");
00075         _ring    = cfg.getUntrackedParameter<int> ("ringNumber");
00076         
00077         //setting the levels being used in the geometry comparator
00078         AlignableObjectId dummy;
00079         edm::LogInfo("MuonGeometryArrange") << "levels: " << levels.size();
00080         for (unsigned int l = 0; l < levels.size(); ++l){
00081                 theLevels.push_back( dummy.nameToType(levels[l]));
00082                 edm::LogInfo("MuonGeometryArrange") << "level: " << levels[l];
00083         }
00084         
00085                 
00086         // if want to use, make id cut list
00087         if (_detIdFlag){
00088         ifstream fin;
00089         fin.open( _detIdFlagFile.c_str() );
00090         
00091         while (!fin.eof() && fin.good() ){
00092                         
00093                         uint32_t id;
00094                         fin >> id;
00095                         _detIdFlagVector.push_back(id);
00096         }
00097         fin.close();
00098         }               
00099         
00100         // turn weightByIdFile into weightByIdVector
00101         unsigned int lastID=999999999;
00102         if (_weightById){
00103                 std::ifstream inFile;
00104                 inFile.open( _weightByIdFile.c_str() );
00105                 int ctr = 0;
00106                 while ( !inFile.eof() ){
00107                         ctr++;
00108                         unsigned int listId;
00109                         inFile >> listId;
00110                         inFile.ignore(256, '\n');
00111                         if(listId!=lastID){
00112                           _weightByIdVector.push_back( listId );
00113                         }
00114                         lastID=listId;
00115                 }
00116                 inFile.close();
00117         }
00118         
00119         
00120         
00121         //root configuration
00122         _theFile = new TFile(_filename.c_str(),"RECREATE");
00123         _alignTree = new TTree("alignTree","alignTree");
00124         _alignTree->Branch("id", &_id, "id/I");
00125         _alignTree->Branch("level", &_level, "level/I");
00126         _alignTree->Branch("mid", &_mid, "mid/I");
00127         _alignTree->Branch("mlevel", &_mlevel, "mlevel/I");
00128         _alignTree->Branch("sublevel", &_sublevel, "sublevel/I");
00129         _alignTree->Branch("x", &_xVal, "x/F");
00130         _alignTree->Branch("y", &_yVal, "y/F");
00131         _alignTree->Branch("z", &_zVal, "z/F");
00132         _alignTree->Branch("r", &_rVal, "r/F");
00133         _alignTree->Branch("phi", &_phiVal, "phi/F");
00134         _alignTree->Branch("eta", &_etaVal, "eta/F");
00135         _alignTree->Branch("alpha", &_alphaVal, "alpha/F");
00136         _alignTree->Branch("beta", &_betaVal, "beta/F");
00137         _alignTree->Branch("gamma", &_gammaVal, "gamma/F");
00138         _alignTree->Branch("dx", &_dxVal, "dx/F");
00139         _alignTree->Branch("dy", &_dyVal, "dy/F");
00140         _alignTree->Branch("dz", &_dzVal, "dz/F");
00141         _alignTree->Branch("dr", &_drVal, "dr/F");
00142         _alignTree->Branch("dphi", &_dphiVal, "dphi/F");
00143         _alignTree->Branch("dalpha", &_dalphaVal, "dalpha/F");
00144         _alignTree->Branch("dbeta", &_dbetaVal, "dbeta/F");
00145         _alignTree->Branch("dgamma", &_dgammaVal, "dgamma/F");
00146         _alignTree->Branch("ldx", &_ldxVal, "ldx/F");
00147         _alignTree->Branch("ldy", &_ldyVal, "ldy/F");
00148         _alignTree->Branch("ldz", &_ldzVal, "ldz/F");
00149         _alignTree->Branch("ldr", &_ldrVal, "ldr/F");
00150         _alignTree->Branch("ldphi", &_ldphiVal, "ldphi/F");
00151         _alignTree->Branch("useDetId", &_useDetId, "useDetId/I");
00152         _alignTree->Branch("detDim", &_detDim, "detDim/I");
00153         _alignTree->Branch("rotx",&_rotxVal, "rotx/F"); 
00154         _alignTree->Branch("roty",&_rotyVal, "roty/F"); 
00155         _alignTree->Branch("rotz",&_rotzVal, "rotz/F"); 
00156         _alignTree->Branch("drotx",&_drotxVal, "drotx/F");      
00157         _alignTree->Branch("droty",&_drotyVal, "droty/F");      
00158         _alignTree->Branch("drotz",&_drotzVal, "drotz/F");      
00159         _alignTree->Branch("surW", &_surWidth, "surW/F");
00160         _alignTree->Branch("surL", &_surLength, "surL/F");
00161         _alignTree->Branch("surRot", &_surRot, "surRot[9]/D");
00162 
00163         _mgacollection.clear(); 
00164 }
00166 void MuonGeometryArrange::endHist(){
00167  // Unpack the list and create ntuples here.
00168 
00169    int size=_mgacollection.size();
00170    if(size<=0) return;  // nothing to do here.
00171    float* xp = new float[size+1];
00172    float* yp = new float[size+1];
00173    int i;
00174    float minV, maxV;
00175    int minI, maxI;
00176 
00177    minV=99999999.; maxV=-minV;  minI=9999999; maxI=-minI;
00178    TGraph* grx=0x0;
00179    TH2F* dxh=0x0;
00180 
00181 // for position plots:
00182    for(i=0; i<size; i++){
00183      if(_mgacollection[i].phipos<minI) minI=_mgacollection[i].phipos;
00184      if(_mgacollection[i].phipos>maxI) maxI=_mgacollection[i].phipos;
00185      xp[i]=_mgacollection[i].phipos;
00186    }
00187    if(minI>=maxI) return;       // can't do anything?
00188    xp[size]=xp[size-1]+1;       // wraparound point
00189 
00190    if(1<minI) minI=1;
00191    if(size>maxI) maxI=size;
00192    maxI++;      // allow for wraparound to show neighbors
00193    int sizeI=maxI+1-minI;
00194    float smi=minI-1;
00195    float sma=maxI+1;
00196  
00197 
00198 // Dx plot
00199 
00200    for(i=0; i<size; i++){
00201      if(_mgacollection[i].ldx<minV) minV=_mgacollection[i].ldx;
00202      if(_mgacollection[i].ldx>maxV) maxV=_mgacollection[i].ldx;
00203      yp[i]=_mgacollection[i].ldx;
00204    }
00205    yp[size]=yp[0];      // wraparound point
00206    
00207    makeGraph(sizeI, smi, sma, minV, maxV,
00208        dxh, grx, "delX_vs_position", "Local #delta X vs position", 
00209        "GdelX_vs_position","#delta x in cm", xp, yp, size);
00210 // Dy plot
00211    minV=99999999.; maxV=-minV;
00212    for(i=0; i<size; i++){
00213      if(_mgacollection[i].ldy<minV) minV=_mgacollection[i].ldy;
00214      if(_mgacollection[i].ldy>maxV) maxV=_mgacollection[i].ldy;
00215      yp[i]=_mgacollection[i].ldy;
00216    }
00217    yp[size]=yp[0];      // wraparound point
00218    
00219    makeGraph(sizeI, smi, sma, minV, maxV,
00220        dxh, grx, "delY_vs_position", "Local #delta Y vs position", 
00221        "GdelY_vs_position","#delta y in cm", xp, yp, size);
00222 
00223 // Dz plot
00224    minV=99999999.; maxV=-minV;
00225    for(i=0; i<size; i++){
00226      if(_mgacollection[i].dz<minV) minV=_mgacollection[i].dz;
00227      if(_mgacollection[i].dz>maxV) maxV=_mgacollection[i].dz;
00228      yp[i]=_mgacollection[i].dz;
00229    }
00230    yp[size]=yp[0];      // wraparound point
00231    
00232    makeGraph(sizeI, smi, sma, minV, maxV,
00233        dxh, grx, "delZ_vs_position", "Local #delta Z vs position", 
00234        "GdelZ_vs_position","#delta z in cm", xp, yp, size);
00235 
00236 // Dphi plot
00237    minV=99999999.; maxV=-minV;
00238    for(i=0; i<size; i++){
00239      if(_mgacollection[i].dphi<minV) minV=_mgacollection[i].dphi;
00240      if(_mgacollection[i].dphi>maxV) maxV=_mgacollection[i].dphi;
00241      yp[i]=_mgacollection[i].dphi;
00242    }
00243    yp[size]=yp[0];      // wraparound point
00244    
00245    makeGraph(sizeI, smi, sma, minV, maxV,
00246        dxh, grx, "delphi_vs_position", "#delta #phi vs position", 
00247        "Gdelphi_vs_position","#delta #phi in radians", xp, yp, size);
00248 
00249 // Dr plot
00250    minV=99999999.; maxV=-minV;
00251    for(i=0; i<size; i++){
00252      if(_mgacollection[i].dr<minV) minV=_mgacollection[i].dr;
00253      if(_mgacollection[i].dr>maxV) maxV=_mgacollection[i].dr;
00254      yp[i]=_mgacollection[i].dr;
00255    }
00256    yp[size]=yp[0];      // wraparound point
00257    
00258    makeGraph(sizeI, smi, sma, minV, maxV,
00259        dxh, grx, "delR_vs_position", "#delta R vs position", 
00260        "GdelR_vs_position","#delta R in cm", xp, yp, size);
00261 
00262 // Drphi plot
00263    minV=99999999.; maxV=-minV;
00264    for(i=0; i<size; i++){
00265      float ttemp=_mgacollection[i].r*_mgacollection[i].dphi;
00266      if(ttemp<minV) minV=ttemp;
00267      if(ttemp>maxV) maxV=ttemp;
00268      yp[i]=ttemp;
00269    }
00270    yp[size]=yp[0];      // wraparound point
00271    
00272    makeGraph(sizeI, smi, sma, minV, maxV,
00273        dxh, grx, "delRphi_vs_position", "R #delta #phi vs position", 
00274        "GdelRphi_vs_position","R #delta #phi in cm", xp, yp, size);
00275 
00276 // Dalpha plot
00277    minV=99999999.; maxV=-minV;
00278    for(i=0; i<size; i++){
00279      if(_mgacollection[i].dalpha<minV) minV=_mgacollection[i].dalpha;
00280      if(_mgacollection[i].dalpha>maxV) maxV=_mgacollection[i].dalpha;
00281      yp[i]=_mgacollection[i].dalpha;
00282    }
00283    yp[size]=yp[0];      // wraparound point
00284    
00285    makeGraph(sizeI, smi, sma, minV, maxV,
00286        dxh, grx, "delalpha_vs_position", "#delta #alpha vs position", 
00287        "Gdelalpha_vs_position","#delta #alpha in rad", xp, yp, size);
00288 
00289 // Dbeta plot
00290    minV=99999999.; maxV=-minV;
00291    for(i=0; i<size; i++){
00292      if(_mgacollection[i].dbeta<minV) minV=_mgacollection[i].dbeta;
00293      if(_mgacollection[i].dbeta>maxV) maxV=_mgacollection[i].dbeta;
00294      yp[i]=_mgacollection[i].dbeta;
00295    }
00296    yp[size]=yp[0];      // wraparound point
00297    
00298    makeGraph(sizeI, smi, sma, minV, maxV,
00299        dxh, grx, "delbeta_vs_position", "#delta #beta vs position", 
00300        "Gdelbeta_vs_position","#delta #beta in rad", xp, yp, size);
00301 
00302 // Dgamma plot
00303    minV=99999999.; maxV=-minV;
00304    for(i=0; i<size; i++){
00305      if(_mgacollection[i].dgamma<minV) minV=_mgacollection[i].dgamma;
00306      if(_mgacollection[i].dgamma>maxV) maxV=_mgacollection[i].dgamma;
00307      yp[i]=_mgacollection[i].dgamma;
00308    }
00309    yp[size]=yp[0];      // wraparound point
00310    
00311    makeGraph(sizeI, smi, sma, minV, maxV,
00312        dxh, grx, "delgamma_vs_position", "#delta #gamma vs position", 
00313        "Gdelgamma_vs_position","#delta #gamma in rad", xp, yp, size);
00314 
00315 // Drotx plot
00316    minV=99999999.; maxV=-minV;
00317    for(i=0; i<size; i++){
00318      if(_mgacollection[i].drotx<minV) minV=_mgacollection[i].drotx;
00319      if(_mgacollection[i].drotx>maxV) maxV=_mgacollection[i].drotx;
00320      yp[i]=_mgacollection[i].drotx;
00321    }
00322    yp[size]=yp[0];      // wraparound point
00323    
00324    makeGraph(sizeI, smi, sma, minV, maxV,
00325        dxh, grx, "delrotX_vs_position", "#delta rotX vs position", 
00326        "GdelrotX_vs_position","#delta rotX in rad", xp, yp, size);
00327 
00328 // Droty plot
00329    minV=99999999.; maxV=-minV;
00330    for(i=0; i<size; i++){
00331      if(_mgacollection[i].droty<minV) minV=_mgacollection[i].droty;
00332      if(_mgacollection[i].droty>maxV) maxV=_mgacollection[i].droty;
00333      yp[i]=_mgacollection[i].droty;
00334    }
00335    yp[size]=yp[0];      // wraparound point
00336    
00337    makeGraph(sizeI, smi, sma, minV, maxV,
00338        dxh, grx, "delrotY_vs_position", "#delta rotY vs position", 
00339        "GdelrotY_vs_position","#delta rotY in rad", xp, yp, size);
00340 
00341 // Drotz plot
00342    minV=99999999.; maxV=-minV;
00343    for(i=0; i<size; i++){
00344      if(_mgacollection[i].drotz<minV) minV=_mgacollection[i].drotz;
00345      if(_mgacollection[i].drotz>maxV) maxV=_mgacollection[i].drotz;
00346      yp[i]=_mgacollection[i].drotz;
00347    }
00348    yp[size]=yp[0];      // wraparound point
00349    
00350    makeGraph(sizeI, smi, sma, minV, maxV,
00351        dxh, grx, "delrotZ_vs_position", "#delta rotZ vs position", 
00352        "GdelrotZ_vs_position","#delta rotZ in rad", xp, yp, size);
00353 
00354 
00355 
00356 // Vector plots
00357 // First find the maximum length of sqrt(dx*dx+dy*dy):  we'll have to
00358 // scale these for visibility
00359    maxV=-99999999.;
00360    float ttemp, rtemp;
00361    float maxR=-9999999.;
00362    for(i=0; i<size; i++){
00363      ttemp= sqrt(_mgacollection[i].dx*_mgacollection[i].dx+
00364         _mgacollection[i].dy*_mgacollection[i].dy);
00365      rtemp= sqrt(_mgacollection[i].x*_mgacollection[i].x+
00366         _mgacollection[i].y*_mgacollection[i].y);
00367      if(ttemp>maxV) maxV=ttemp;
00368      if(rtemp>maxR) maxR=rtemp;
00369    }
00370    
00371   // Don't try to scale rediculously small values 
00372    float smallestVcm=.001;      // 10 microns
00373    if(maxV<smallestVcm) maxV=smallestVcm;
00374    float scale=0.;
00375    float lside=1.1*maxR;
00376    if(lside<=0) lside=100.;
00377    if(maxV>0){scale=.09*lside/maxV;}    // units of pad length!
00378    char scalename[50];
00379    int ret=snprintf(scalename,50,"#delta #bar{x}   length =%f cm",maxV);
00380   // If ret<=0 we don't want to print the scale!
00381   
00382    if(ret>0){
00383      dxh=new TH2F("vecdrplot",scalename,80,-lside,lside,80,-lside,lside);
00384    }
00385    else{
00386      dxh=new TH2F("vecdrplot","delta #bar{x} Bad scale",80,-lside,lside,80,-lside,lside);
00387    }
00388    dxh->GetXaxis()->SetTitle("x in cm");
00389    dxh->GetYaxis()->SetTitle("y in cm");
00390    dxh->SetStats(kFALSE);
00391    dxh->Draw();
00392    TArrow* arrow;
00393    for(i=0; i<size; i++){
00394      ttemp= sqrt(_mgacollection[i].dx*_mgacollection[i].dx+
00395        _mgacollection[i].dy*_mgacollection[i].dy);
00396 //     ttemp=ttemp*scale;
00397      float nx=_mgacollection[i].x+scale*_mgacollection[i].dx;
00398      float ny=_mgacollection[i].y+scale*_mgacollection[i].dy;
00399      arrow = new TArrow(_mgacollection[i].x, 
00400                    _mgacollection[i].y, nx, ny);// ttemp*.3*.05, "->");
00401      arrow->SetLineWidth(2); arrow->SetArrowSize(ttemp*.2*.05/maxV);
00402      arrow->SetLineColor(1); arrow->SetLineStyle(1);
00403      arrow->Paint();
00404      dxh->GetListOfFunctions()->Add(static_cast<TObject*>(arrow));
00405 //     arrow->Draw();
00406 //     arrow->Write();
00407    }
00408    dxh->Write();
00409  
00410    _theFile->Write();   
00411    _theFile->Close();
00412 
00413    delete [] yp;  delete [] xp;
00414 
00415 }
00417 void MuonGeometryArrange::makeGraph(int sizeI, float smi, float sma, 
00418         float minV, float maxV,
00419         TH2F* dxh, TGraph* grx, const char* name, const char* title, 
00420         const char* titleg, const char* axis,
00421         float* xp, float* yp, int size){
00422 
00423   if(minV>=maxV || smi>=sma || sizeI<=1 || xp==0x0 || yp==0x0) return;
00424         // out of bounds, bail
00425   float diff=maxV-minV;
00426   float over=.05*diff;
00427   double ylo=minV-over;
00428   double yhi=maxV+over;
00429   double dsmi, dsma;
00430   dsmi=smi; dsma=sma;
00431   dxh= new TH2F(name, title,
00432     sizeI+2, dsmi, dsma, 50, ylo, yhi);
00433   dxh->GetXaxis()->SetTitle("Position around ring");
00434   dxh->GetYaxis()->SetTitle(axis);
00435   dxh->SetStats(kFALSE);
00436   dxh->Draw();
00437   grx = new TGraph(size, xp, yp);
00438   grx->SetName(titleg);
00439   grx->SetTitle(title);
00440   grx->SetMarkerColor(2); grx->SetMarkerStyle(3);
00441   grx->GetXaxis()->SetLimits(dsmi, dsma);
00442   grx->GetXaxis()->SetTitle("position number");
00443   grx->GetYaxis()->SetLimits(ylo,yhi);
00444   grx->GetYaxis()->SetTitle(axis);
00445   grx->Draw("A*");
00446   grx->Write();
00447   return; 
00448 }
00450 void MuonGeometryArrange::beginJob(){
00451   firstEvent_ = true;
00452 }
00453 
00455 void MuonGeometryArrange::createROOTGeometry(const edm::EventSetup& iSetup){}
00457 void MuonGeometryArrange::analyze(const edm::Event&, 
00458                                   const edm::EventSetup& iSetup){
00459   if (firstEvent_) {
00460     
00461     // My stuff
00462     MuonAlignmentInputXML inputMethod1(_inputXMLCurrent);
00463     inputAlign1 = new MuonAlignment(iSetup, inputMethod1);
00464     inputAlign1->fillGapsInSurvey(0, 0);
00465     MuonAlignmentInputXML inputMethod2(_inputXMLReference);
00466     inputAlign2 = new MuonAlignment(iSetup, inputMethod2);
00467     inputAlign2->fillGapsInSurvey(0, 0);
00468     MuonAlignmentInputXML inputMethod3(_inputXMLReference);
00469     inputAlign2a = new MuonAlignment(iSetup, inputMethod3);
00470     inputAlign2a->fillGapsInSurvey(0, 0);
00471     
00472     inputGeometry1 = static_cast<Alignable*> (inputAlign1->getAlignableMuon());
00473     inputGeometry2 = static_cast<Alignable*> (inputAlign2->getAlignableMuon());
00474     Alignable* inputGeometry2Copy2 = 
00475       static_cast<Alignable*> (inputAlign2a->getAlignableMuon());
00476     
00477     //compare the goemetries
00478     compare(inputGeometry1, inputGeometry2, inputGeometry2Copy2);
00479     
00480     //write out ntuple
00481     //might be better to do within output module
00482     _theFile->cd();
00483     _alignTree->Write();
00484     endHist();
00485     //   _theFile->Close();
00486     
00487     firstEvent_ = false;
00488   }
00489 }
00490 
00492 void MuonGeometryArrange::compare(Alignable* refAli, Alignable* curAli,
00493                 Alignable* curAliCopy2){
00494 
00495  // First sanity
00496   if(refAli==0x0){return;}      
00497   if(curAli==0x0){return;}
00498   
00499   const std::vector<Alignable*>& refComp = refAli->components();
00500   const std::vector<Alignable*>& curComp = curAli->components();
00501   const std::vector<Alignable*>& curComp2 = curAliCopy2->components();
00502   compareGeometries(refAli, curAli, curAliCopy2);
00503 
00504   int nComp=refComp.size();
00505   for(int i=0; i<nComp; i++){
00506     compare(refComp[i], curComp[i], curComp2[i]);
00507   }
00508   return;
00509 }
00510   
00512 void MuonGeometryArrange::compareGeometries(Alignable* refAli, 
00513                 Alignable* curAli, Alignable* curCopy){
00514  // First sanity
00515   if(refAli==0x0){return;}      
00516   if(curAli==0x0){return;}
00517  // Is this the Ring we want to align?  If so it will contain the
00518  // chambers specified in the configuration file        
00519   if(!isMother(refAli)) return; // Not the desired alignable object
00520  // But... There are granddaughters involved--and I don't want to monkey with
00521  // the layers of the chambers.  So, if the mother of this is also an approved
00522  // mother, bail.
00523   if(isMother(refAli->mother() )) return;
00524   const std::vector<Alignable*>& refComp = refAli->components();
00525   const std::vector<Alignable*>& curComp = curCopy->components();
00526   if(refComp.size()!=curComp.size()){
00527      return;
00528   }
00529  // GlobalVectors is a vector of GlobalVector which is a 3D vector
00530   align::GlobalVectors originalVectors;
00531   align::GlobalVectors currentVectors;
00532   align::GlobalVectors originalRelativeVectors;
00533   align::GlobalVectors currentRelativeVectors;
00534 
00535         
00536   int nComp = refComp.size();
00537   int nUsed = 0;
00538  // Use the total displacements here:
00539   CLHEP::Hep3Vector TotalX, TotalL;
00540   TotalX.set(0.,0.,0.);   TotalL.set(0., 0., 0.);
00541 //  CLHEP::Hep3Vector* Rsubtotal, Wsubtotal, DRsubtotal, DWsubtotal;
00542   std::vector<CLHEP::Hep3Vector> Positions;
00543   std::vector<CLHEP::Hep3Vector> DelPositions;
00544 
00545   double xrcenter=0.;
00546   double yrcenter=0.;
00547   double zrcenter=0.;
00548   double xccenter=0.;
00549   double yccenter=0.;
00550   double zccenter=0.;
00551 
00552   bool useIt;
00553  // Create the "center" for the reference alignment chambers, and
00554  // load a vector of their centers
00555   for(int ich=0; ich<nComp; ich++){
00556     useIt=true;
00557     if(_weightById){
00558       if(!align::readModuleList(curComp[ich]->id(), curComp[ich]->id(), _weightByIdVector))
00559          useIt=false;
00560     }
00561     if(!useIt) continue;
00562     align::GlobalVectors curVs;
00563     align::createPoints(&curVs, refComp[ich], 
00564       _weightBy, _weightById, _weightByIdVector);
00565     align::GlobalVector pointsCM = align::centerOfMass(curVs);
00566     originalVectors.push_back(pointsCM);
00567     nUsed++;
00568     xrcenter+= pointsCM.x();
00569     yrcenter+= pointsCM.y();
00570     zrcenter+= pointsCM.z();
00571   }
00572   xrcenter=xrcenter/nUsed;
00573   yrcenter=yrcenter/nUsed;
00574   zrcenter=zrcenter/nUsed;
00575 
00576  // Create the "center" for the current alignment chambers, and
00577  // load a vector of their centers
00578    for(int ich=0; ich<nComp; ich++){
00579     useIt=true;
00580     if(_weightById){
00581       if(!align::readModuleList(curComp[ich]->id(), curComp[ich]->id(), _weightByIdVector))
00582          useIt=false;
00583     }
00584     if(!useIt)continue;
00585     align::GlobalVectors curVs;
00586     align::createPoints(&curVs, curComp[ich], 
00587       _weightBy, _weightById, _weightByIdVector);
00588     align::GlobalVector pointsCM = align::centerOfMass(curVs);
00589     currentVectors.push_back(pointsCM);
00590 
00591     xccenter+= pointsCM.x();
00592     yccenter+= pointsCM.y();
00593     zccenter+= pointsCM.z();
00594   }
00595   xccenter=xccenter/nUsed;
00596   yccenter=yccenter/nUsed;
00597   zccenter=zccenter/nUsed;
00598 
00599 
00600  // OK, now load the <very approximate> vectors from the ring "centers"
00601   align::GlobalVector CCur(xccenter, yccenter, zccenter);
00602   align::GlobalVector CRef(xrcenter, yrcenter, zrcenter);
00603   int nCompR = currentVectors.size();
00604   for(int ich=0; ich<nCompR; ich++){
00605     originalRelativeVectors.push_back(originalVectors[ich]-CRef);
00606     currentRelativeVectors.push_back(currentVectors[ich]-CCur);
00607   }
00608 
00609  // All right.  Now let the hacking begin.
00610  // First out of the gate let's try using the raw values and see what
00611  // diffRot does for us.
00612 
00613  
00614   align::RotationType rtype3=align::diffRot(currentRelativeVectors,
00615                                             originalRelativeVectors);
00616 
00617 
00618   align::EulerAngles angles(3);
00619   angles = align::toAngles(rtype3);
00620 
00621   for(int ich=0; ich<nComp; ich++){
00622     if(_weightById){
00623       if(!align::readModuleList(curComp[ich]->id(), curComp[ich]->id(), _weightByIdVector))
00624          continue;
00625     }
00626       CLHEP::Hep3Vector Rtotal, Wtotal;
00627       Rtotal.set(0.,0.,0.); Wtotal.set(0.,0.,0.);
00628       for (int i = 0; i < 100; i++){
00629         AlgebraicVector diff = align::diffAlignables(refComp[ich],curComp[ich],
00630                            _weightBy, _weightById, _weightByIdVector);
00631         CLHEP::Hep3Vector dR(diff[0],diff[1],diff[2]);
00632         Rtotal+=dR;
00633         CLHEP::Hep3Vector dW(diff[3],diff[4],diff[5]);
00634         CLHEP::HepRotation rot(Wtotal.unit(),Wtotal.mag());
00635         CLHEP::HepRotation drot(dW.unit(),dW.mag());
00636         rot*=drot;
00637         Wtotal.set(rot.axis().x()*rot.delta(),
00638                    rot.axis().y()*rot.delta(), rot.axis().z()*rot.delta());
00639         align::moveAlignable(curComp[ich], diff);
00640         float tolerance = 1e-7;
00641         AlgebraicVector check = align::diffAlignables(refComp[ich],curComp[ich],
00642                         _weightBy, _weightById, _weightByIdVector);
00643         align::GlobalVector checkR(check[0],check[1],check[2]);
00644         align::GlobalVector checkW(check[3],check[4],check[5]);
00645         DetId detid(refComp[ich]->id());
00646         if ((checkR.mag() > tolerance)||(checkW.mag() > tolerance)){
00647 //       edm::LogInfo("CompareGeoms") << "Tolerance Exceeded!(alObjId: " 
00648 //       << refAli->alignableObjectId()
00649 //       << ", rawId: " << refComp[ich]->geomDetId().rawId()
00650 //       << ", subdetId: "<< detid.subdetId() << "): " << diff;
00651         }
00652         else{
00653          TotalX+=Rtotal;
00654          break;
00655         }         // end of else
00656       }  // end of for on int i
00657   }     // end of for on ich
00658 
00659   // At this point we should have a total displacement and total L
00660    TotalX=TotalX/nUsed;
00661 
00662   // Now start again!
00663    AlgebraicVector change(6);
00664    change(1)=TotalX.x();
00665    change(2)=TotalX.y();
00666    change(3)=TotalX.z();
00667 
00668    change(4)=angles[0];
00669    change(5)=angles[1];
00670    change(6)=angles[2];
00671    align::moveAlignable(curAli, change);        // move as a chunk
00672 
00673   // Now get the components again.  They should be in new locations
00674    const std::vector<Alignable*>& curComp2 = curAli->components();
00675 
00676   for(int ich=0; ich<nComp; ich++){
00677      CLHEP::Hep3Vector Rtotal, Wtotal;
00678      Rtotal.set(0.,0.,0.); Wtotal.set(0.,0.,0.);
00679      if(_weightById){
00680        if(!align::readModuleList(curComp[ich]->id(), curComp[ich]->id(), _weightByIdVector))
00681          continue;
00682      }
00683     
00684      for (int i = 0; i < 100; i++){
00685        AlgebraicVector diff = align::diffAlignables(refComp[ich],curComp2[ich],
00686                           _weightBy, _weightById, _weightByIdVector);
00687        CLHEP::Hep3Vector dR(diff[0],diff[1],diff[2]);
00688        Rtotal+=dR;
00689        CLHEP::Hep3Vector dW(diff[3],diff[4],diff[5]);
00690        CLHEP::HepRotation rot(Wtotal.unit(),Wtotal.mag());
00691        CLHEP::HepRotation drot(dW.unit(),dW.mag());
00692        rot*=drot;
00693        Wtotal.set(rot.axis().x()*rot.delta(), rot.axis().y()*rot.delta(),
00694                   rot.axis().z()*rot.delta());
00695        align::moveAlignable(curComp2[ich], diff);
00696        float tolerance = 1e-7;
00697        AlgebraicVector check = align::diffAlignables(refComp[ich],curComp2[ich],
00698                        _weightBy, _weightById, _weightByIdVector);
00699        align::GlobalVector checkR(check[0],check[1],check[2]);
00700        align::GlobalVector checkW(check[3],check[4],check[5]);
00701        if ((checkR.mag() > tolerance)||(checkW.mag() > tolerance)){}
00702        else{break;}
00703      }   // end of for on int i
00704      AlgebraicVector TRtot(6);
00705      TRtot(1) = Rtotal.x(); TRtot(2) = Rtotal.y(); TRtot(3) = Rtotal.z();
00706      TRtot(4) = Wtotal.x(); TRtot(5) = Wtotal.y(); TRtot(6) = Wtotal.z();
00707      fillTree(refComp[ich], TRtot);
00708   }    // end of for on ich
00709 
00710 
00711 
00712 }
00713 
00715 
00716 void MuonGeometryArrange::fillTree(Alignable *refAli, AlgebraicVector diff){
00717         
00718         
00719         _id = refAli->id();
00720         _level = refAli->alignableObjectId();
00721         //need if ali has no mother
00722         if (refAli->mother()){
00723                 _mid = refAli->mother()->geomDetId().rawId();
00724                 _mlevel = refAli->mother()->alignableObjectId();
00725         }
00726         else{
00727                 _mid = -1;
00728                 _mlevel = -1;
00729         }
00730         DetId detid(_id);
00731         _sublevel = detid.subdetId();
00732         int ringPhiPos=-99;
00733         if(detid.det()==DetId::Muon && detid.subdetId()== MuonSubdetId::CSC){
00734            CSCDetId cscId(refAli->geomDetId());
00735            ringPhiPos = cscId.chamber();
00736         }
00737         _xVal = refAli->globalPosition().x();
00738         _yVal = refAli->globalPosition().y();
00739         _zVal = refAli->globalPosition().z();
00740         align::GlobalVector vec(_xVal,_yVal,_zVal);
00741         _rVal = vec.perp();
00742         _phiVal = vec.phi();
00743         _etaVal = vec.eta();
00744         align::RotationType rot = refAli->globalRotation();
00745         align::EulerAngles eulerAngles = align::toAngles(rot);
00746         _rotxVal = atan2(rot.yz(), rot.zz());
00747         float ttt=-rot.xz();
00748         if(ttt>1.) ttt=1.;
00749         if(ttt<-1.) ttt=-1.;
00750         _rotyVal = asin(ttt);
00751         _rotzVal = atan2(rot.xy(), rot.xx());
00752         _alphaVal = eulerAngles[0];
00753         _betaVal = eulerAngles[1];
00754         _gammaVal = eulerAngles[2];
00755         _dxVal = diff[0];
00756         _dyVal = diff[1];
00757         _dzVal = diff[2];
00758         //getting dR and dPhi
00759         align::GlobalVector vRef(_xVal,_yVal,_zVal);
00760         align::GlobalVector vCur(_xVal - _dxVal, _yVal-_dyVal, _zVal - _dzVal);
00761         _drVal = vCur.perp() - vRef.perp();
00762         _dphiVal = vCur.phi() - vRef.phi();
00763         
00764         _dalphaVal = diff[3];
00765         _dbetaVal = diff[4];
00766         _dgammaVal = diff[5];
00767         _drotxVal=-999.; _drotyVal=-999.; _drotzVal=-999.; 
00768 
00769         align::EulerAngles deuler(3);
00770         deuler(1)=_dalphaVal;
00771         deuler(2)= _dbetaVal;
00772         deuler(3)= _dgammaVal;
00773         align::RotationType drot = align::toMatrix(deuler);
00774         double xx=rot.xx();
00775         double xy=rot.xy();
00776         double xz=rot.xz();
00777         double yx=rot.yx();
00778         double yy=rot.yy();
00779         double yz=rot.yz();
00780         double zx=rot.zx();
00781         double zy=rot.zy();
00782         double zz=rot.zz();
00783         double detrot=(zz*yy - zy*yz)*xx + (-zz*yx + zx*yz)*xy + (zy*yx - zx*yy)*xz;
00784         detrot=1/detrot;
00785         double ixx=(zz*yy - zy*yz)*detrot;
00786         double ixy=(-zz*xy + zy*xz)*detrot;
00787         double ixz=(yz*xy - yy*xz)*detrot;
00788         double iyx=(-zz*yx + zx*yz)*detrot;
00789         double iyy=(zz*xx - zx*xz)*detrot;
00790         double iyz=(-yz*xx + yx*xz)*detrot;
00791         double izx=(zy*yx - zx*yy)*detrot;
00792         double izy=(-zy*xx + zx*xy)*detrot;
00793         double izz=(yy*xx - yx*xy)*detrot;
00794         align::RotationType invrot(ixx,ixy,ixz, iyx,iyy,iyz, izx,izy,izz);
00795         align::RotationType prot = rot*drot*invrot;
00796 //      align::RotationType prot = rot*drot;
00797         float protx; //, proty, protz;
00798         protx = atan2(prot.yz(), prot.zz());
00799         _drotxVal = protx;//_rotxVal-protx; //atan2(drot.yz(), drot.zz());
00800         ttt=-prot.xz();
00801         if(ttt>1.) ttt=1.;
00802         if(ttt<-1.) ttt=-1.;
00803         _drotyVal = asin(ttt);// -_rotyVal;
00804         _drotzVal = atan2(prot.xy(), prot.xx());// - _rotzVal;
00805 // Above does not account for 2Pi wraparounds!
00806 // Prior knowledge:  these are supposed to be small rotations.  Therefore:
00807         if(_drotxVal>3.141592656) _drotxVal=-6.2831853072+_drotxVal;
00808         if(_drotxVal<-3.141592656) _drotxVal=6.2831853072+_drotxVal;
00809         if(_drotyVal>3.141592656) _drotyVal=-6.2831853072+_drotyVal;
00810         if(_drotyVal<-3.141592656) _drotyVal=6.2831853072+_drotyVal;
00811         if(_drotzVal>3.141592656) _drotzVal=-6.2831853072+_drotzVal;
00812         if(_drotzVal<-3.141592656) _drotzVal=6.2831853072+_drotzVal;
00813         
00814         _ldxVal=-999.; _ldyVal=-999.; _ldxVal=-999.; 
00815         _ldrVal=-999.; _ldphiVal=-999; // set fake
00816 
00817 //      if(refAli->alignableObjectId() == align::AlignableDetUnit){
00818          align::GlobalVector dV(_dxVal, _dyVal, _dzVal); 
00819          align::LocalVector pointL = refAli->surface().toLocal(dV);
00820          //align::LocalVector pointL = (refAli->mother())->surface().toLocal(dV);
00821          _ldxVal=pointL.x(); _ldyVal=pointL.y(); _ldzVal=pointL.z();
00822          _ldphiVal=pointL.phi(); _ldrVal=pointL.perp();
00823 //      }
00824         //detIdFlag
00825         if (refAli->alignableObjectId() == align::AlignableDetUnit){
00826           if (_detIdFlag){
00827            if ((passIdCut(refAli->id()))||(passIdCut(refAli->mother()->id()))){
00828                 _useDetId = 1;
00829            }
00830            else{
00831                 _useDetId = 0;
00832            }
00833           }
00834         }
00835         // det module dimension
00836         if (refAli->alignableObjectId() == align::AlignableDetUnit){
00837            if (refAli->mother()->alignableObjectId() != align::AlignableDet){
00838              _detDim = 1;}
00839            else if (refAli->mother()->alignableObjectId() == 
00840                                        align::AlignableDet) {_detDim = 2;}
00841         }
00842         else _detDim = 0;
00843         
00844         
00845         
00846         _surWidth = refAli->surface().width();
00847         _surLength = refAli->surface().length();
00848         align::RotationType rt = refAli->globalRotation();
00849         _surRot[0] = rt.xx(); _surRot[1] = rt.xy(); _surRot[2] = rt.xz();
00850         _surRot[3] = rt.yx(); _surRot[4] = rt.yy(); _surRot[5] = rt.yz();
00851         _surRot[6] = rt.zx(); _surRot[7] = rt.zy(); _surRot[8] = rt.zz();
00852 
00853         MGACollection holdit;
00854         holdit.id=_id;  holdit.level=_level;  holdit.mid=_mid;
00855         holdit.mlevel=_mlevel;
00856         holdit.sublevel=_sublevel;
00857         holdit.x=_xVal;  holdit.y=_yVal;  holdit.z=_zVal;       
00858         holdit.r=_rVal;  holdit.phi=_phiVal;  holdit.eta=_etaVal;
00859         holdit.alpha=_alphaVal;  holdit.beta=_betaVal;  holdit.gamma=_gammaVal;
00860         holdit.dx=_dxVal;  holdit.dy=_dyVal;  holdit.dz=_dzVal; 
00861         holdit.dr=_drVal;  holdit.dphi=_dphiVal; 
00862         holdit.dalpha=_dalphaVal;  holdit.dbeta=_dbetaVal;  
00863         holdit.dgamma=_dgammaVal;
00864         holdit.useDetId=_useDetId; holdit.detDim=_detDim;
00865         holdit.surW=_surWidth; holdit.surL=_surLength;
00866         holdit.ldx=_ldxVal; holdit.ldy=_ldyVal; holdit.ldz=_ldzVal;
00867         holdit.ldr=_ldrVal; holdit.ldphi=_ldphiVal;
00868         holdit.rotx=_rotxVal; holdit.roty=_rotyVal; holdit.rotz=_rotzVal;
00869         holdit.drotx=_drotxVal; holdit.droty=_drotyVal; holdit.drotz=_drotzVal;
00870         for(int i=0; i<9; i++){holdit.surRot[i]=_surRot[i];}
00871         holdit.phipos=ringPhiPos;
00872         _mgacollection.push_back(holdit);
00873 
00874         
00875         //Fill
00876         _alignTree->Fill();
00877         
00878 }
00879 
00881 bool MuonGeometryArrange::isMother(Alignable* ali){
00882   // Is this the mother ring?
00883  if(ali==0x0) return false;     // elementary sanity
00884  const std::vector<Alignable*>& aliComp = ali->components();
00885 
00886  int size=aliComp.size();
00887  if(size<=0) return false;      // no subcomponents
00888  
00889  for(int i=0; i<size; i++){
00890    if(checkChosen(aliComp[i])) return true;     // A ring has CSC chambers
00891  }                                      // as subcomponents
00892  return false;          // 1'st layer of subcomponents weren't CSC chambers
00893 } 
00895 
00896 bool MuonGeometryArrange::checkChosen(Alignable* ali){
00897  // Check whether the item passed satisfies the criteria given.
00898   if(ali==0x0) return false;    // elementary sanity
00899  // Is this in the CSC section?  If not, bail.  Later may extend.
00900   if(ali->geomDetId().det()!=DetId::Muon ||
00901      ali->geomDetId().subdetId()!=MuonSubdetId::CSC) return false;
00902  // If it is a CSC alignable, then check that the station, etc are
00903  // those requested.
00904  // One might think of aligning more than a single ring at a time,
00905  // by using a vector of ring numbers.  I don't see the sense in
00906  // trying to align more than one station at a time for comparison.
00907   CSCDetId cscId(ali->geomDetId());
00908 #ifdef jnbdebug
00909 std::cout<<"JNB "<<ali->id()<<" "<<cscId.endcap()<<" "
00910 <<cscId.station()<<" "<<cscId.ring()<<" "<<cscId.chamber()<<"   "
00911 <<_endcap<<" "<<_station<<" "<<_ring
00912 <<"\n"<<std::flush;
00913 #endif
00914   if(cscId.endcap()==_endcap && cscId.station()==_station &&
00915      cscId.ring()==_ring) {
00916       return true;
00917   }
00918   return false;
00919 }
00921   
00922 bool MuonGeometryArrange::passChosen( Alignable* ali ){
00923 
00924  // Check to see if this contains CSC components of the appropriate ring
00925  // Ring will contain N Alignables which represent chambers, each of which
00926  // in turn contains M planes.  For our purposes we don't care about the
00927  // planes.
00928  // Hmm.  Interesting question:  Do I want to try to fit the chamber as
00929  // such, or use the geometry?
00930  // I want to fit the chamber, so I'll try to use its presence as the marker.
00931  // What specifically identifies a chamber as a chamber, and not as a layer?
00932  // The fact that it has layers as sub components, or the fact that it is
00933  // the first item with a non-zero ID breakdown?  Pick the latter.
00934  //
00935  if(ali==0x0) return false;
00936  if(checkChosen(ali)) return true;      // If this is one of the desired
00937                                         // CSC chambers, accept it
00938  const std::vector<Alignable*>& aliComp = ali->components();
00939 
00940  int size=aliComp.size();
00941  if(size<=0) return false;      // no subcomponents
00942  
00943  for(int i=0; i<size; i++){
00944    if(checkChosen(aliComp[i])) return true;     // A ring has CSC chambers
00945  }                                      // as subcomponents
00946  return false;          // 1'st layer of subcomponents weren't CSC chambers
00947 }
00949 bool MuonGeometryArrange::passIdCut( uint32_t id ){
00950         
00951         bool pass = false;
00952         DetId detid(id);
00953 //      if(detid.det()==DetId::Muon && detid.subdetId()== MuonSubdetId::CSC){
00954 //         CSCDetId cscId(refAli->geomDetId());
00955 //         if(cscId.layer()!=1) return false;           // ONLY FIRST LAYER!
00956 //      }
00957         int nEntries = _detIdFlagVector.size();
00958         
00959         for (int i = 0; i < nEntries; i++){
00960                 if (_detIdFlagVector[i] == id) pass = true;
00961         }
00962         
00963         return pass;
00964         
00965 }
00966 
00967 
00969 DEFINE_FWK_MODULE(MuonGeometryArrange);