CMS 3D CMS Logo

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