CMS 3D CMS Logo

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