/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Alignment/LaserAlignment/plugins/LaserAlignment.cc
1 771 строка
72 KB
Ernesto Migliore
revert PR 40443 w/o introduction bricked pixels
24 апр 2024, 13:20
24 апр 2024, 13:20
4eaef34
Код
Авторство
О чём код?
/** \file LaserAlignment.cc * LAS reconstruction module * * $Date: 2013/01/07 20:26:37 $ * $Revision: 1.47 $ * \author Maarten Thomas * \author Jan Olzem */ #include "Alignment/LaserAlignment/plugins/LaserAlignment.h" #include "FWCore/Framework/interface/Run.h" #include "Geometry/Records/interface/TrackerTopologyRcd.h" #include "CondFormats/GeometryObjects/interface/PTrackerParameters.h" #include "CondFormats/GeometryObjects/interface/PTrackerAdditionalParametersPerDet.h" #include "Geometry/Records/interface/PTrackerParametersRcd.h" #include "Geometry/Records/interface/PTrackerAdditionalParametersPerDetRcd.h" /// /// /// LaserAlignment::LaserAlignment(edm::ParameterSet const& theConf) : topoToken_(esConsumes()), geomToken_(esConsumes()), geomDetToken_(esConsumes()), ptpToken_(esConsumes()), ptitpToken_(esConsumes()), gprToken_(esConsumes()), stripPedestalsToken_(esConsumes()), theEvents(0), theDoPedestalSubtraction(theConf.getUntrackedParameter<bool>("SubtractPedestals", true)), theUseMinuitAlgorithm(theConf.getUntrackedParameter<bool>("RunMinuitAlignmentTubeAlgorithm", false)), theApplyBeamKinkCorrections(theConf.getUntrackedParameter<bool>("ApplyBeamKinkCorrections", true)), peakFinderThreshold(theConf.getUntrackedParameter<double>("PeakFinderThreshold", 10.)), enableJudgeZeroFilter(theConf.getUntrackedParameter<bool>("EnableJudgeZeroFilter", true)), judgeOverdriveThreshold(theConf.getUntrackedParameter<unsigned int>("JudgeOverdriveThreshold", 220)), updateFromInputGeometry(theConf.getUntrackedParameter<bool>("UpdateFromInputGeometry", false)), misalignedByRefGeometry(theConf.getUntrackedParameter<bool>("MisalignedByRefGeometry", false)), theStoreToDB(theConf.getUntrackedParameter<bool>("SaveToDbase", false)), theDigiProducersList(theConf.getParameter<std::vector<edm::ParameterSet> >("DigiProducersList")), theSaveHistograms(theConf.getUntrackedParameter<bool>("SaveHistograms", false)), theCompression(theConf.getUntrackedParameter<int>("ROOTFileCompression", 1)), theFileName(theConf.getUntrackedParameter<std::string>("ROOTFileName", "test.root")), theMaskTecModules(theConf.getUntrackedParameter<std::vector<unsigned int> >("MaskTECModules")), theMaskAtModules(theConf.getUntrackedParameter<std::vector<unsigned int> >("MaskATModules")), theSetNominalStrips(theConf.getUntrackedParameter<bool>("ForceFitterToNominalStrips", false)), theLasConstants(theConf.getUntrackedParameter<std::vector<edm::ParameterSet> >("LaserAlignmentConstants")), theFile(), theAlignableTracker(), theAlignRecordName("TrackerAlignmentRcd"), theErrorRecordName("TrackerAlignmentErrorExtendedRcd"), firstEvent_(true) { std::cout << std::endl; std::cout << "==============================================================" << "\n=== LaserAlignment module configuration ===" << "\n" << "\n Write histograms to file = " << (theSaveHistograms ? "true" : "false") << "\n Histogram file name = " << theFileName << "\n Histogram file compression = " << theCompression << "\n Subtract pedestals = " << (theDoPedestalSubtraction ? "true" : "false") << "\n Run Minuit AT algorithm = " << (theUseMinuitAlgorithm ? "true" : "false") << "\n Apply beam kink corrections = " << (theApplyBeamKinkCorrections ? "true" : "false") << "\n Peak Finder Threshold = " << peakFinderThreshold << "\n EnableJudgeZeroFilter = " << (enableJudgeZeroFilter ? "true" : "false") << "\n JudgeOverdriveThreshold = " << judgeOverdriveThreshold << "\n Update from input geometry = " << (updateFromInputGeometry ? "true" : "false") << "\n Misalignment from ref geometry = " << (misalignedByRefGeometry ? "true" : "false") << "\n Number of TEC modules masked = " << theMaskTecModules.size() << " (s. below list if > 0)" << "\n Number of AT modules masked = " << theMaskAtModules.size() << " (s. below list if > 0)" << "\n Store to database = " << (theStoreToDB ? "true" : "false") << "\n ----------------------------------------------- ----------" << (theSetNominalStrips ? "\n Set strips to nominal = true" : "\n") << "\n=============================================================" << std::endl; // tell about masked modules if (!theMaskTecModules.empty()) { std::cout << " ===============================================================================================\n" << std::flush; std::cout << " The following " << theMaskTecModules.size() << " TEC modules have been masked out and will not be considered by the TEC algorithm:\n " << std::flush; for (std::vector<unsigned int>::iterator moduleIt = theMaskTecModules.begin(); moduleIt != theMaskTecModules.end(); ++moduleIt) { std::cout << *moduleIt << (moduleIt != --theMaskTecModules.end() ? ", " : "") << std::flush; } std::cout << std::endl << std::flush; std::cout << " ===============================================================================================\n\n" << std::flush; } if (!theMaskAtModules.empty()) { std::cout << " ===============================================================================================\n" << std::flush; std::cout << " The following " << theMaskAtModules.size() << " AT modules have been masked out and will not be considered by the AT algorithm:\n " << std::flush; for (std::vector<unsigned int>::iterator moduleIt = theMaskAtModules.begin(); moduleIt != theMaskAtModules.end(); ++moduleIt) { std::cout << *moduleIt << (moduleIt != --theMaskAtModules.end() ? ", " : "") << std::flush; } std::cout << std::endl << std::flush; std::cout << " ===============================================================================================\n\n" << std::flush; } // alias for the Branches in the root files std::string alias(theConf.getParameter<std::string>("@module_label")); // declare the product to produce produces<TkLasBeamCollection, edm::Transition::EndRun>("tkLaserBeams").setBranchAlias(alias + "TkLasBeamCollection"); // switch judge's zero filter depending on cfg judge.EnableZeroFilter(enableJudgeZeroFilter); // set the upper threshold for zero suppressed data judge.SetOverdriveThreshold(judgeOverdriveThreshold); } /// /// /// LaserAlignment::~LaserAlignment() { if (theSaveHistograms) theFile->Write(); if (theFile) { delete theFile; } if (theAlignableTracker) { delete theAlignableTracker; } } /// /// /// void LaserAlignment::beginJob() { // write sumed histograms to file (if selected in cfg) if (theSaveHistograms) { // creating a new file theFile = new TFile(theFileName.c_str(), "RECREATE", "CMS ROOT file"); // initialize the histograms if (theFile) { theFile->SetCompressionLevel(theCompression); singleModulesDir = theFile->mkdir("single modules"); } else throw cms::Exception(" [LaserAlignment::beginJob]") << " ** ERROR: could not open file:" << theFileName.c_str() << " for writing." << std::endl; } // detector id maps (hard coded) fillDetectorId(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PROFILE, HISTOGRAM & FITFUNCTION INITIALIZATION // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // object used to build various strings for names and labels std::stringstream nameBuilder; // loop variables for use with LASGlobalLoop object int det, ring, beam, disk, pos; // loop TEC modules det = 0; ring = 0; beam = 0; disk = 0; do { // loop using LASGlobalLoop functionality // init the profiles pedestalProfiles.GetTECEntry(det, ring, beam, disk).SetAllValuesTo(0.); currentDataProfiles.GetTECEntry(det, ring, beam, disk).SetAllValuesTo(0.); collectedDataProfiles.GetTECEntry(det, ring, beam, disk).SetAllValuesTo(0.); // init the hit maps isAcceptedProfile.SetTECEntry(det, ring, beam, disk, 0); numberOfAcceptedProfiles.SetTECEntry(det, ring, beam, disk, 0); // create strings for histo names nameBuilder.clear(); nameBuilder.str(""); nameBuilder << "TEC"; if (det == 0) nameBuilder << "+"; else nameBuilder << "-"; nameBuilder << "_Ring"; if (ring == 0) nameBuilder << "4"; else nameBuilder << "6"; nameBuilder << "_Beam" << beam; nameBuilder << "_Disk" << disk; theProfileNames.SetTECEntry(det, ring, beam, disk, nameBuilder.str()); // init the histograms if (theSaveHistograms) { nameBuilder << "_Histo"; summedHistograms.SetTECEntry( det, ring, beam, disk, new TH1D(nameBuilder.str().c_str(), nameBuilder.str().c_str(), 512, 0, 512)); summedHistograms.GetTECEntry(det, ring, beam, disk)->SetDirectory(singleModulesDir); } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // TIB & TOB section det = 2; beam = 0; pos = 0; do { // loop using LASGlobalLoop functionality // init the profiles pedestalProfiles.GetTIBTOBEntry(det, beam, pos).SetAllValuesTo(0.); currentDataProfiles.GetTIBTOBEntry(det, beam, pos).SetAllValuesTo(0.); collectedDataProfiles.GetTIBTOBEntry(det, beam, pos).SetAllValuesTo(0.); // init the hit maps isAcceptedProfile.SetTIBTOBEntry(det, beam, pos, 0); numberOfAcceptedProfiles.SetTIBTOBEntry(det, beam, pos, 0); // create strings for histo names nameBuilder.clear(); nameBuilder.str(""); if (det == 2) nameBuilder << "TIB"; else nameBuilder << "TOB"; nameBuilder << "_Beam" << beam; nameBuilder << "_Zpos" << pos; theProfileNames.SetTIBTOBEntry(det, beam, pos, nameBuilder.str()); // init the histograms if (theSaveHistograms) { nameBuilder << "_Histo"; summedHistograms.SetTIBTOBEntry( det, beam, pos, new TH1D(nameBuilder.str().c_str(), nameBuilder.str().c_str(), 512, 0, 512)); summedHistograms.GetTIBTOBEntry(det, beam, pos)->SetDirectory(singleModulesDir); } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // TEC2TEC AT section det = 0; beam = 0; disk = 0; do { // loop using LASGlobalLoop functionality // init the profiles pedestalProfiles.GetTEC2TECEntry(det, beam, disk).SetAllValuesTo(0.); currentDataProfiles.GetTEC2TECEntry(det, beam, disk).SetAllValuesTo(0.); collectedDataProfiles.GetTEC2TECEntry(det, beam, disk).SetAllValuesTo(0.); // init the hit maps isAcceptedProfile.SetTEC2TECEntry(det, beam, disk, 0); numberOfAcceptedProfiles.SetTEC2TECEntry(det, beam, disk, 0); // create strings for histo names nameBuilder.clear(); nameBuilder.str(""); nameBuilder << "TEC(AT)"; if (det == 0) nameBuilder << "+"; else nameBuilder << "-"; nameBuilder << "_Beam" << beam; nameBuilder << "_Disk" << disk; theProfileNames.SetTEC2TECEntry(det, beam, disk, nameBuilder.str()); // init the histograms if (theSaveHistograms) { nameBuilder << "_Histo"; summedHistograms.SetTEC2TECEntry( det, beam, disk, new TH1D(nameBuilder.str().c_str(), nameBuilder.str().c_str(), 512, 0, 512)); summedHistograms.GetTEC2TECEntry(det, beam, disk)->SetDirectory(singleModulesDir); } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); firstEvent_ = true; } /// /// /// void LaserAlignment::produce(edm::Event& theEvent, edm::EventSetup const& theSetup) { if (firstEvent_) { //Retrieve tracker topology from geometry const TrackerTopology* const tTopo = &theSetup.getData(topoToken_); // access the tracker gD = theSetup.getHandle(geomDetToken_); theTrackerGeometry = theSetup.getHandle(geomToken_); // access pedestals (from db..) if desired edm::ESHandle<SiStripPedestals> pedestalsHandle; if (theDoPedestalSubtraction) { pedestalsHandle = theSetup.getHandle(stripPedestalsToken_); fillPedestalProfiles(pedestalsHandle); } // global positions theGlobalPositionRcd = &theSetup.getData(gprToken_); // select the reference geometry if (!updateFromInputGeometry) { // the AlignableTracker object is initialized with the ideal geometry const GeometricDet* theGeometricDet = &theSetup.getData(geomDetToken_); const PTrackerParameters* ptp = &theSetup.getData(ptpToken_); const PTrackerAdditionalParametersPerDet* ptitp = &theSetup.getData(ptitpToken_); TrackerGeomBuilderFromGeometricDet trackerBuilder; TrackerGeometry* theRefTracker = trackerBuilder.build(&*theGeometricDet, &*ptitp, *ptp, tTopo); theAlignableTracker = new AlignableTracker(&(*theRefTracker), tTopo); } else { // the AlignableTracker object is initialized with the input geometry from DB theAlignableTracker = new AlignableTracker(&(*theTrackerGeometry), tTopo); } firstEvent_ = false; } LogDebug("LaserAlignment") << "===========================================================" << "\n Private analysis of event #" << theEvent.id().event() << " in run #" << theEvent.id().run(); // do the Tracker Statistics to retrieve the current profiles fillDataProfiles(theEvent, theSetup); // index variables for the LASGlobalLoop object int det, ring, beam, disk, pos; // // first pre-loop on selected entries to find out // whether the TEC or the AT beams have fired // (pedestal profiles are left empty if false in cfg) // // TEC+- (only ring 6) ring = 1; for (det = 0; det < 2; ++det) { for (beam = 0; beam < 8; ++beam) { for (disk = 0; disk < 9; ++disk) { if (judge.IsSignalIn(currentDataProfiles.GetTECEntry(det, ring, beam, disk) - pedestalProfiles.GetTECEntry(det, ring, beam, disk), 0)) { isAcceptedProfile.SetTECEntry(det, ring, beam, disk, 1); } else { // assume no initialization isAcceptedProfile.SetTECEntry(det, ring, beam, disk, 0); } } } } // TIBTOB det = 2; beam = 0; pos = 0; do { // add current event's data and subtract pedestals if (judge.IsSignalIn( currentDataProfiles.GetTIBTOBEntry(det, beam, pos) - pedestalProfiles.GetTIBTOBEntry(det, beam, pos), getTIBTOBNominalBeamOffset(det, beam, pos))) { isAcceptedProfile.SetTIBTOBEntry(det, beam, pos, 1); } else { // dto. isAcceptedProfile.SetTIBTOBEntry(det, beam, pos, 0); } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // now come the beam finders bool isTECMode = isTECBeam(); // LogDebug( " [LaserAlignment::produce]" ) << "LaserAlignment::isTECBeam declares this event " << ( isTECMode ? "" : "NOT " ) << "a TEC event." << std::endl; std::cout << " [LaserAlignment::produce] -- LaserAlignment::isTECBeam declares this event " << (isTECMode ? "" : "NOT ") << "a TEC event." << std::endl; bool isATMode = isATBeam(); // LogDebug( " [LaserAlignment::produce]" ) << "LaserAlignment::isATBeam declares this event " << ( isATMode ? "" : "NOT " ) << "an AT event." << std::endl; std::cout << " [LaserAlignment::produce] -- LaserAlignment::isATBeam declares this event " << (isATMode ? "" : "NOT ") << "an AT event." << std::endl; // // now pass the pedestal subtracted profiles to the judge // if they're accepted, add them on the collectedDataProfiles // (pedestal profiles are left empty if false in cfg) // // loop TEC+- modules det = 0; ring = 0; beam = 0; disk = 0; do { LogDebug("[LaserAlignment::produce]") << "Profile is: " << theProfileNames.GetTECEntry(det, ring, beam, disk) << "." << std::endl; // this now depends on the AT/TEC mode, is this a doubly hit module? -> look for it in vector<int> tecDoubleHitDetId // (ring == 0 not necessary but makes it a little faster) if (ring == 0 && find(tecDoubleHitDetId.begin(), tecDoubleHitDetId.end(), detectorId.GetTECEntry(det, ring, beam, disk)) != tecDoubleHitDetId.end()) { if (isTECMode) { // add profile to TEC collection // add current event's data and subtract pedestals if (judge.JudgeProfile(currentDataProfiles.GetTECEntry(det, ring, beam, disk) - pedestalProfiles.GetTECEntry(det, ring, beam, disk), 0)) { collectedDataProfiles.GetTECEntry(det, ring, beam, disk) += currentDataProfiles.GetTECEntry(det, ring, beam, disk) - pedestalProfiles.GetTECEntry(det, ring, beam, disk); numberOfAcceptedProfiles.GetTECEntry(det, ring, beam, disk)++; } } } else { // not a doubly hit module, don't care about the mode // add current event's data and subtract pedestals if (judge.JudgeProfile(currentDataProfiles.GetTECEntry(det, ring, beam, disk) - pedestalProfiles.GetTECEntry(det, ring, beam, disk), 0)) { collectedDataProfiles.GetTECEntry(det, ring, beam, disk) += currentDataProfiles.GetTECEntry(det, ring, beam, disk) - pedestalProfiles.GetTECEntry(det, ring, beam, disk); numberOfAcceptedProfiles.GetTECEntry(det, ring, beam, disk)++; } } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // loop TIB/TOB modules det = 2; beam = 0; pos = 0; do { LogDebug("[LaserAlignment::produce]") << "Profile is: " << theProfileNames.GetTIBTOBEntry(det, beam, pos) << "." << std::endl; // add current event's data and subtract pedestals if (judge.JudgeProfile( currentDataProfiles.GetTIBTOBEntry(det, beam, pos) - pedestalProfiles.GetTIBTOBEntry(det, beam, pos), getTIBTOBNominalBeamOffset(det, beam, pos))) { collectedDataProfiles.GetTIBTOBEntry(det, beam, pos) += currentDataProfiles.GetTIBTOBEntry(det, beam, pos) - pedestalProfiles.GetTIBTOBEntry(det, beam, pos); numberOfAcceptedProfiles.GetTIBTOBEntry(det, beam, pos)++; } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // loop TEC2TEC modules det = 0; beam = 0; disk = 0; do { LogDebug("[LaserAlignment::produce]") << "Profile is: " << theProfileNames.GetTEC2TECEntry(det, beam, disk) << "." << std::endl; // this again depends on the AT/TEC mode, is this a doubly hit module? // (ring == 0 not necessary but makes it a little faster) if (ring == 0 && find(tecDoubleHitDetId.begin(), tecDoubleHitDetId.end(), detectorId.GetTECEntry(det, ring, beam, disk)) != tecDoubleHitDetId.end()) { if (isATMode) { // add profile to TEC2TEC collection // add current event's data and subtract pedestals if (judge.JudgeProfile(currentDataProfiles.GetTEC2TECEntry(det, beam, disk) - pedestalProfiles.GetTEC2TECEntry(det, beam, disk), 0)) { collectedDataProfiles.GetTEC2TECEntry(det, beam, disk) += currentDataProfiles.GetTEC2TECEntry(det, beam, disk) - pedestalProfiles.GetTEC2TECEntry(det, beam, disk); numberOfAcceptedProfiles.GetTEC2TECEntry(det, beam, disk)++; } } } else { // not a doubly hit module, don't care about the mode // add current event's data and subtract pedestals if (judge.JudgeProfile( currentDataProfiles.GetTEC2TECEntry(det, beam, disk) - pedestalProfiles.GetTEC2TECEntry(det, beam, disk), 0)) { collectedDataProfiles.GetTEC2TECEntry(det, beam, disk) += currentDataProfiles.GetTEC2TECEntry(det, beam, disk) - pedestalProfiles.GetTEC2TECEntry(det, beam, disk); numberOfAcceptedProfiles.GetTEC2TECEntry(det, beam, disk)++; } } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); // total event number counter theEvents++; } /// /// /// void LaserAlignment::endRunProduce(edm::Run& theRun, const edm::EventSetup& theSetup) { std::cout << " [LaserAlignment::endRun] -- Total number of events processed: " << theEvents << std::endl; // for debugging only.. DumpHitmaps(numberOfAcceptedProfiles); // index variables for the LASGlobalLoop objects int det, ring, beam, disk, pos; // measured positions container for the algorithms LASGlobalData<LASCoordinateSet> measuredCoordinates; // fitted peak positions in units of strips (pair for value,error) LASGlobalData<std::pair<float, float> > measuredStripPositions; // the peak finder, a pair (pos/posErr in units of strips) for its results, and the success confirmation LASPeakFinder peakFinder; peakFinder.SetAmplitudeThreshold(peakFinderThreshold); std::pair<double, double> peakFinderResults; bool isGoodFit; // tracker geom. object for calculating the global beam positions const TrackerGeometry& theTracker(*theTrackerGeometry); // fill LASGlobalData<LASCoordinateSet> nominalCoordinates CalculateNominalCoordinates(); // for determining the phi errors // ErrorFrameTransformer errorTransformer; // later... // do the fits for TEC+- internal det = 0; ring = 0; beam = 0; disk = 0; do { // do the fit isGoodFit = peakFinder.FindPeakIn(collectedDataProfiles.GetTECEntry(det, ring, beam, disk), peakFinderResults, summedHistograms.GetTECEntry(det, ring, beam, disk), 0); // offset is 0 for TEC // now we have the measured positions in units of strips. if (!isGoodFit) std::cout << " [LaserAlignment::endRun] ** WARNING: Fit failed for TEC det: " << det << ", ring: " << ring << ", beam: " << beam << ", disk: " << disk << " (id: " << detectorId.GetTECEntry(det, ring, beam, disk) << ")." << std::endl; // <- here we will later implement the kink corrections // access the tracker geometry for this module const DetId theDetId(detectorId.GetTECEntry(det, ring, beam, disk)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { // first, set the measured coordinates to their nominal values measuredCoordinates.SetTECEntry(det, ring, beam, disk, nominalCoordinates.GetTECEntry(det, ring, beam, disk)); if (isGoodFit) { // convert strip position to global phi and replace the nominal phi value/error measuredStripPositions.GetTECEntry(det, ring, beam, disk) = peakFinderResults; const float positionInStrips = theSetNominalStrips ? 256. : peakFinderResults.first; // implementation of "ForceFitterToNominalStrips" config parameter const GlobalPoint& globalPoint = theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(positionInStrips)); measuredCoordinates.GetTECEntry(det, ring, beam, disk).SetPhi(ConvertAngle(globalPoint.barePhi())); // const GlobalError& globalError = errorTransformer.transform( theStripDet->specificTopology().localError( peakFinderResults.first, pow( peakFinderResults.second, 2 ) ), theStripDet->surface() ); // measuredCoordinates.GetTECEntry( det, ring, beam, disk ).SetPhiError( globalError.phierr( globalPoint ) ); measuredCoordinates.GetTECEntry(det, ring, beam, disk).SetPhiError(0.00046); // PRELIMINARY ESTIMATE } else { // keep nominal position (middle-of-module) but set a giant phi error so that the module can be ignored by the alignment algorithm measuredStripPositions.GetTECEntry(det, ring, beam, disk) = std::pair<float, float>(256., 1000.); const GlobalPoint& globalPoint = theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(256.)); measuredCoordinates.GetTECEntry(det, ring, beam, disk).SetPhi(ConvertAngle(globalPoint.barePhi())); measuredCoordinates.GetTECEntry(det, ring, beam, disk).SetPhiError(1000.); } } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // do the fits for TIB/TOB det = 2; beam = 0; pos = 0; do { // do the fit isGoodFit = peakFinder.FindPeakIn(collectedDataProfiles.GetTIBTOBEntry(det, beam, pos), peakFinderResults, summedHistograms.GetTIBTOBEntry(det, beam, pos), getTIBTOBNominalBeamOffset(det, beam, pos)); // now we have the measured positions in units of strips. if (!isGoodFit) std::cout << " [LaserAlignment::endJob] ** WARNING: Fit failed for TIB/TOB det: " << det << ", beam: " << beam << ", pos: " << pos << " (id: " << detectorId.GetTIBTOBEntry(det, beam, pos) << ")." << std::endl; // <- here we will later implement the kink corrections // access the tracker geometry for this module const DetId theDetId(detectorId.GetTIBTOBEntry(det, beam, pos)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { // first, set the measured coordinates to their nominal values measuredCoordinates.SetTIBTOBEntry(det, beam, pos, nominalCoordinates.GetTIBTOBEntry(det, beam, pos)); if (isGoodFit) { // convert strip position to global phi and replace the nominal phi value/error measuredStripPositions.GetTIBTOBEntry(det, beam, pos) = peakFinderResults; const float positionInStrips = theSetNominalStrips ? 256. + getTIBTOBNominalBeamOffset(det, beam, pos) : peakFinderResults.first; // implementation of "ForceFitterToNominalStrips" config parameter const GlobalPoint& globalPoint = theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(positionInStrips)); measuredCoordinates.GetTIBTOBEntry(det, beam, pos).SetPhi(ConvertAngle(globalPoint.barePhi())); measuredCoordinates.GetTIBTOBEntry(det, beam, pos).SetPhiError(0.00028); // PRELIMINARY ESTIMATE } else { // keep nominal position but set a giant phi error so that the module can be ignored by the alignment algorithm measuredStripPositions.GetTIBTOBEntry(det, beam, pos) = std::pair<float, float>(256. + getTIBTOBNominalBeamOffset(det, beam, pos), 1000.); const GlobalPoint& globalPoint = theStripDet->surface().toGlobal( theStripDet->specificTopology().localPosition(256. + getTIBTOBNominalBeamOffset(det, beam, pos))); measuredCoordinates.GetTIBTOBEntry(det, beam, pos).SetPhi(ConvertAngle(globalPoint.barePhi())); measuredCoordinates.GetTIBTOBEntry(det, beam, pos).SetPhiError(1000.); } } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // do the fits for TEC AT det = 0; beam = 0; disk = 0; do { // do the fit isGoodFit = peakFinder.FindPeakIn(collectedDataProfiles.GetTEC2TECEntry(det, beam, disk), peakFinderResults, summedHistograms.GetTEC2TECEntry(det, beam, disk), getTEC2TECNominalBeamOffset(det, beam, disk)); // now we have the positions in units of strips. if (!isGoodFit) std::cout << " [LaserAlignment::endRun] ** WARNING: Fit failed for TEC2TEC det: " << det << ", beam: " << beam << ", disk: " << disk << " (id: " << detectorId.GetTEC2TECEntry(det, beam, disk) << ")." << std::endl; // <- here we will later implement the kink corrections // access the tracker geometry for this module const DetId theDetId(detectorId.GetTEC2TECEntry(det, beam, disk)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { // first, set the measured coordinates to their nominal values measuredCoordinates.SetTEC2TECEntry(det, beam, disk, nominalCoordinates.GetTEC2TECEntry(det, beam, disk)); if (isGoodFit) { // convert strip position to global phi and replace the nominal phi value/error measuredStripPositions.GetTEC2TECEntry(det, beam, disk) = peakFinderResults; const float positionInStrips = theSetNominalStrips ? 256. + getTEC2TECNominalBeamOffset(det, beam, disk) : peakFinderResults.first; // implementation of "ForceFitterToNominalStrips" config parameter const GlobalPoint& globalPoint = theStripDet->surface().toGlobal(theStripDet->specificTopology().localPosition(positionInStrips)); measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhi(ConvertAngle(globalPoint.barePhi())); measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhiError(0.00047); // PRELIMINARY ESTIMATE } else { // keep nominal position but set a giant phi error so that the module can be ignored by the alignment algorithm measuredStripPositions.GetTEC2TECEntry(det, beam, disk) = std::pair<float, float>(256. + getTEC2TECNominalBeamOffset(det, beam, disk), 1000.); const GlobalPoint& globalPoint = theStripDet->surface().toGlobal( theStripDet->specificTopology().localPosition(256. + getTEC2TECNominalBeamOffset(det, beam, disk))); measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhi(ConvertAngle(globalPoint.barePhi())); measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhiError(1000.); } } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); // see what we got (for debugging) // DumpStripFileSet( measuredStripPositions ); // DumpPosFileSet( measuredCoordinates ); // CALCULATE PARAMETERS AND UPDATE DB OBJECT // for beam kink corrections, reconstructing the geometry and updating the db object LASGeometryUpdater geometryUpdater(nominalCoordinates, theLasConstants); // apply all beam corrections if (theApplyBeamKinkCorrections) geometryUpdater.ApplyBeamKinkCorrections(measuredCoordinates); // if we start with input geometry instead of IDEAL, // reverse the adjustments in the AlignableTracker object if (updateFromInputGeometry) geometryUpdater.SetReverseDirection(true); // if we have "virtual" misalignment which is introduced via the reference geometry, // tell the LASGeometryUpdater to reverse x & y adjustments if (misalignedByRefGeometry) geometryUpdater.SetMisalignmentFromRefGeometry(true); // run the endcap algorithm LASEndcapAlgorithm endcapAlgorithm; LASEndcapAlignmentParameterSet endcapParameters; // this basically sets all the endcap modules to be masked // to their nominal positions (since endcapParameters is overall zero) if (!theMaskTecModules.empty()) { ApplyEndcapMaskingCorrections(measuredCoordinates, nominalCoordinates, endcapParameters); } // run the algorithm endcapParameters = endcapAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); // // loop to mask out events // DESCRIPTION: // // do this only if there are modules to be masked.. if (!theMaskTecModules.empty()) { const unsigned int nIterations = 30; for (unsigned int iteration = 0; iteration < nIterations; ++iteration) { // set the endcap modules to be masked to their positions // according to the reconstructed parameters ApplyEndcapMaskingCorrections(measuredCoordinates, nominalCoordinates, endcapParameters); // modifications applied, so re-run the algorithm endcapParameters = endcapAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); } } // these are now final, so: endcapParameters.Print(); // do a pre-alignment of the endcaps (TEC2TEC only) // so that the alignment tube algorithms finds orderly disks geometryUpdater.EndcapUpdate(endcapParameters, measuredCoordinates); // the alignment tube algorithms, choose from config LASBarrelAlignmentParameterSet alignmentTubeParameters; // the MINUIT-BASED alignment tube algorithm LASBarrelAlgorithm barrelAlgorithm; // the ANALYTICAL alignment tube algorithm LASAlignmentTubeAlgorithm alignmentTubeAlgorithm; // this basically sets all the modules to be masked // to their nominal positions (since alignmentTubeParameters is overall zero) if (!theMaskAtModules.empty()) { ApplyATMaskingCorrections(measuredCoordinates, nominalCoordinates, alignmentTubeParameters); } if (theUseMinuitAlgorithm) { // run the MINUIT-BASED alignment tube algorithm alignmentTubeParameters = barrelAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); } else { // the ANALYTICAL alignment tube algorithm alignmentTubeParameters = alignmentTubeAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); } // // loop to mask out events // DESCRIPTION: // // do this only if there are modules to be masked.. if (!theMaskAtModules.empty()) { const unsigned int nIterations = 30; for (unsigned int iteration = 0; iteration < nIterations; ++iteration) { // set the AT modules to be masked to their positions // according to the reconstructed parameters ApplyATMaskingCorrections(measuredCoordinates, nominalCoordinates, alignmentTubeParameters); // modifications applied, so re-run the algorithm if (theUseMinuitAlgorithm) { alignmentTubeParameters = barrelAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); } else { alignmentTubeParameters = alignmentTubeAlgorithm.CalculateParameters(measuredCoordinates, nominalCoordinates); } } } // these are now final, so: alignmentTubeParameters.Print(); // combine the results and update the db object geometryUpdater.TrackerUpdate(endcapParameters, alignmentTubeParameters, *theAlignableTracker); /// laser hit section for trackbased interface /// /// due to the peculiar order of beams in TkLasBeamCollection, /// we cannot use the LASGlobalLoop object here // the collection container auto laserBeams = std::make_unique<TkLasBeamCollection>(); // first for the endcap internal beams for (det = 0; det < 2; ++det) { for (ring = 0; ring < 2; ++ring) { for (beam = 0; beam < 8; ++beam) { // the beam and its identifier (see TkLasTrackBasedInterface TWiki) TkLasBeam currentBeam(100 * det + 10 * beam + ring); // order the hits in the beam by increasing z const int firstDisk = det == 0 ? 0 : 8; const int lastDisk = det == 0 ? 8 : 0; // count upwards or downwards for (disk = firstDisk; det == 0 ? disk <= lastDisk : disk >= lastDisk; det == 0 ? ++disk : --disk) { // detId for the SiStripLaserRecHit2D const SiStripDetId theDetId(detectorId.GetTECEntry(det, ring, beam, disk)); // need this to calculate the localPosition and its error const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); // the hit container const SiStripLaserRecHit2D currentHit(theStripDet->specificTopology().localPosition( measuredStripPositions.GetTECEntry(det, ring, beam, disk).first), theStripDet->specificTopology().localError( measuredStripPositions.GetTECEntry(det, ring, beam, disk).first, measuredStripPositions.GetTECEntry(det, ring, beam, disk).second), theDetId); currentBeam.push_back(currentHit); } laserBeams->push_back(currentBeam); } } } // then, following the convention in TkLasTrackBasedInterface TWiki, the alignment tube beams; // they comprise hits in TIBTOB & TEC2TEC for (beam = 0; beam < 8; ++beam) { // the beam and its identifier (see TkLasTrackBasedInterface TWiki) TkLasBeam currentBeam(100 * 2 /*beamGroup=AT=2*/ + 10 * beam + 0 /*ring=0*/); // first: tec- det = 1; for (disk = 4; disk >= 0; --disk) { // detId for the SiStripLaserRecHit2D const SiStripDetId theDetId(detectorId.GetTEC2TECEntry(det, beam, disk)); // need this to calculate the localPosition and its error const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); // the hit container const SiStripLaserRecHit2D currentHit( theStripDet->specificTopology().localPosition(measuredStripPositions.GetTEC2TECEntry(det, beam, disk).first), theStripDet->specificTopology().localError(measuredStripPositions.GetTEC2TECEntry(det, beam, disk).first, measuredStripPositions.GetTEC2TECEntry(det, beam, disk).second), theDetId); currentBeam.push_back(currentHit); } // now TIB and TOB in one go for (det = 2; det < 4; ++det) { for (pos = 5; pos >= 0; --pos) { // stupidly, pos is defined from +z to -z in LASGlobalLoop // detId for the SiStripLaserRecHit2D const SiStripDetId theDetId(detectorId.GetTIBTOBEntry(det, beam, pos)); // need this to calculate the localPosition and its error const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); // the hit container const SiStripLaserRecHit2D currentHit( theStripDet->specificTopology().localPosition(measuredStripPositions.GetTIBTOBEntry(det, beam, pos).first), theStripDet->specificTopology().localError(measuredStripPositions.GetTIBTOBEntry(det, beam, pos).first, measuredStripPositions.GetTIBTOBEntry(det, beam, pos).second), theDetId); currentBeam.push_back(currentHit); } } // then: tec+ det = 0; for (disk = 0; disk < 5; ++disk) { // detId for the SiStripLaserRecHit2D const SiStripDetId theDetId(detectorId.GetTEC2TECEntry(det, beam, disk)); // need this to calculate the localPosition and its error const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); // the hit container const SiStripLaserRecHit2D currentHit( theStripDet->specificTopology().localPosition(measuredStripPositions.GetTEC2TECEntry(det, beam, disk).first), theStripDet->specificTopology().localError(measuredStripPositions.GetTEC2TECEntry(det, beam, disk).first, measuredStripPositions.GetTEC2TECEntry(det, beam, disk).second), theDetId); currentBeam.push_back(currentHit); } // save this beam to the beamCollection laserBeams->push_back(currentBeam); } // (close beam loop) // now attach the collection to the run theRun.put(std::move(laserBeams), "tkLaserBeams"); // store the estimated alignment parameters into the DB // first get them Alignments alignments = *(theAlignableTracker->alignments()); AlignmentErrorsExtended alignmentErrors = *(theAlignableTracker->alignmentErrors()); if (theStoreToDB) { std::cout << " [LaserAlignment::endRun] -- Storing the calculated alignment parameters to the DataBase:" << std::endl; // Call service edm::Service<cond::service::PoolDBOutputService> poolDbService; if (!poolDbService.isAvailable()) // Die if not available throw cms::Exception("NotAvailable") << "PoolDBOutputService not available"; // Store // if ( poolDbService->isNewTagRequest(theAlignRecordName) ) { // poolDbService->createOneIOV<Alignments>( alignments, poolDbService->currentTime(), theAlignRecordName ); // } // else { // poolDbService->appendOneIOV<Alignments>( alignments, poolDbService->currentTime(), theAlignRecordName ); // } poolDbService->writeOneIOV<Alignments>(alignments, poolDbService->beginOfTime(), theAlignRecordName); // if ( poolDbService->isNewTagRequest(theErrorRecordName) ) { // poolDbService->createOneIOV<AlignmentErrorsExtended>( alignmentErrors, poolDbService->currentTime(), poolDbService->endOfTime(), theErrorRecordName ); // } // else { // poolDbService->appendOneIOV<AlignmentErrorsExtended>( alignmentErrors, poolDbService->currentTime(), theErrorRecordName ); // } poolDbService->writeOneIOV<AlignmentErrorsExtended>( alignmentErrors, poolDbService->beginOfTime(), theErrorRecordName); std::cout << " [LaserAlignment::endRun] -- Storing done." << std::endl; } } /// /// /// void LaserAlignment::endJob() {} /// /// fills the module profiles (LASGlobalLoop<LASModuleProfile> currentDataProfiles) /// from the event digi containers, distinguishing between SiStripDigi or SiStripRawDigi. /// void LaserAlignment::fillDataProfiles(edm::Event const& theEvent, edm::EventSetup const& theSetup) { // two handles for the two different kinds of digis edm::Handle<edm::DetSetVector<SiStripRawDigi> > theStripRawDigis; edm::Handle<edm::DetSetVector<SiStripDigi> > theStripDigis; bool isRawDigi = false; // indices for the LASGlobalLoop object int det = 0, ring = 0, beam = 0, disk = 0, pos = 0; // query config set and loop over all PSets in the VPSet for (std::vector<edm::ParameterSet>::iterator itDigiProducersList = theDigiProducersList.begin(); itDigiProducersList != theDigiProducersList.end(); ++itDigiProducersList) { std::string digiProducer = itDigiProducersList->getParameter<std::string>("DigiProducer"); std::string digiLabel = itDigiProducersList->getParameter<std::string>("DigiLabel"); std::string digiType = itDigiProducersList->getParameter<std::string>("DigiType"); // now branch according to digi type (raw or processed); // first we go for raw digis => SiStripRawDigi if (digiType == "Raw") { theEvent.getByLabel(digiProducer, digiLabel, theStripRawDigis); isRawDigi = true; } else if (digiType == "Processed") { theEvent.getByLabel(digiProducer, digiLabel, theStripDigis); isRawDigi = false; } else { throw cms::Exception(" [LaserAlignment::fillDataProfiles]") << " ** ERROR: Invalid digi type: \"" << digiType << "\" specified in configuration." << std::endl; } // loop TEC internal modules det = 0; ring = 0; beam = 0; disk = 0; do { // first clear the profile currentDataProfiles.GetTECEntry(det, ring, beam, disk).SetAllValuesTo(0.); // retrieve the raw id of that module const int detRawId = detectorId.GetTECEntry(det, ring, beam, disk); if (isRawDigi) { // we have raw SiStripRawDigis // search the digis for the raw id edm::DetSetVector<SiStripRawDigi>::const_iterator detSetIter = theStripRawDigis->find(detRawId); if (detSetIter == theStripRawDigis->end()) { throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: No raw DetSet found for det: " << detRawId << "." << std::endl; } // fill the digis to the profiles edm::DetSet<SiStripRawDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop edm::DetSet<SiStripRawDigi>::const_iterator digiRangeStart = digiRangeIterator; // save starting positions // loop all digis for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripRawDigi& digi = *digiRangeIterator; const int channel = distance(digiRangeStart, digiRangeIterator); if (channel >= 0 && channel < 512) currentDataProfiles.GetTECEntry(det, ring, beam, disk).SetValue(channel, digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: raw digi channel: " << channel << " out of range for det: " << detRawId << "." << std::endl; } } else { // we have zero suppressed SiStripDigis // search the digis for the raw id edm::DetSetVector<SiStripDigi>::const_iterator detSetIter = theStripDigis->find(detRawId); // processed DetSets may be missing, just skip if (detSetIter == theStripDigis->end()) continue; // fill the digis to the profiles edm::DetSet<SiStripDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripDigi& digi = *digiRangeIterator; if (digi.strip() < 512) currentDataProfiles.GetTECEntry(det, ring, beam, disk).SetValue(digi.strip(), digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: digi strip: " << digi.strip() << " out of range for det: " << detRawId << "." << std::endl; } } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // loop TIBTOB modules det = 2; beam = 0; pos = 0; do { // first clear the profile currentDataProfiles.GetTIBTOBEntry(det, beam, pos).SetAllValuesTo(0.); // retrieve the raw id of that module const int detRawId = detectorId.GetTIBTOBEntry(det, beam, pos); if (isRawDigi) { // we have raw SiStripRawDigis // search the digis for the raw id edm::DetSetVector<SiStripRawDigi>::const_iterator detSetIter = theStripRawDigis->find(detRawId); if (detSetIter == theStripRawDigis->end()) { throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: No raw DetSet found for det: " << detRawId << "." << std::endl; } // fill the digis to the profiles edm::DetSet<SiStripRawDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop edm::DetSet<SiStripRawDigi>::const_iterator digiRangeStart = digiRangeIterator; // save starting positions // loop all digis for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripRawDigi& digi = *digiRangeIterator; const int channel = distance(digiRangeStart, digiRangeIterator); if (channel >= 0 && channel < 512) currentDataProfiles.GetTIBTOBEntry(det, beam, pos).SetValue(channel, digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: raw digi channel: " << channel << " out of range for det: " << detRawId << "." << std::endl; } } else { // we have zero suppressed SiStripDigis // search the digis for the raw id edm::DetSetVector<SiStripDigi>::const_iterator detSetIter = theStripDigis->find(detRawId); // processed DetSets may be missing, just skip if (detSetIter == theStripDigis->end()) continue; // fill the digis to the profiles edm::DetSet<SiStripDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripDigi& digi = *digiRangeIterator; if (digi.strip() < 512) currentDataProfiles.GetTIBTOBEntry(det, beam, pos).SetValue(digi.strip(), digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: digi strip: " << digi.strip() << " out of range for det: " << detRawId << "." << std::endl; } } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // loop TEC AT modules det = 0; beam = 0; disk = 0; do { // first clear the profile currentDataProfiles.GetTEC2TECEntry(det, beam, disk).SetAllValuesTo(0.); // retrieve the raw id of that module const int detRawId = detectorId.GetTEC2TECEntry(det, beam, disk); if (isRawDigi) { // we have raw SiStripRawDigis // search the digis for the raw id edm::DetSetVector<SiStripRawDigi>::const_iterator detSetIter = theStripRawDigis->find(detRawId); if (detSetIter == theStripRawDigis->end()) { throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: No raw DetSet found for det: " << detRawId << "." << std::endl; } // fill the digis to the profiles edm::DetSet<SiStripRawDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop edm::DetSet<SiStripRawDigi>::const_iterator digiRangeStart = digiRangeIterator; // save starting positions // loop all digis for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripRawDigi& digi = *digiRangeIterator; const int channel = distance(digiRangeStart, digiRangeIterator); if (channel >= 0 && channel < 512) currentDataProfiles.GetTEC2TECEntry(det, beam, disk).SetValue(channel, digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: raw digi channel: " << channel << " out of range for det: " << detRawId << "." << std::endl; } } else { // we have zero suppressed SiStripDigis // search the digis for the raw id edm::DetSetVector<SiStripDigi>::const_iterator detSetIter = theStripDigis->find(detRawId); // processed DetSets may be missing, just skip if (detSetIter == theStripDigis->end()) continue; // fill the digis to the profiles edm::DetSet<SiStripDigi>::const_iterator digiRangeIterator = detSetIter->data.begin(); // for the loop for (; digiRangeIterator != detSetIter->data.end(); ++digiRangeIterator) { const SiStripDigi& digi = *digiRangeIterator; if (digi.strip() < 512) currentDataProfiles.GetTEC2TECEntry(det, beam, disk).SetValue(digi.strip(), digi.adc()); else throw cms::Exception("[Laser Alignment::fillDataProfiles]") << " ** ERROR: digi strip: " << digi.strip() << " out of range for det: " << detRawId << "." << std::endl; } } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); } // theDigiProducersList loop } /// /// This function fills the pedestal profiles (LASGlobalData<LASModuleProfiles> pedestalProfiles) /// from the ESHandle (from file or DB) /// /// Argument: readily connected SiStripPedestals object (get() alredy called) /// The functionality inside the loops is basically taken from: /// CommonTools/SiStripZeroSuppression/src/SiStripPedestalsSubtractor.cc /// void LaserAlignment::fillPedestalProfiles(edm::ESHandle<SiStripPedestals>& pedestalsHandle) { int det, ring, beam, disk, pos; // loop TEC modules (yet without AT) det = 0; ring = 0; beam = 0; disk = 0; do { // loop using LASGlobalLoop functionality SiStripPedestals::Range pedRange = pedestalsHandle->getRange(detectorId.GetTECEntry(det, ring, beam, disk)); for (int strip = 0; strip < 512; ++strip) { int thePedestal = int(pedestalsHandle->getPed(strip, pedRange)); if (thePedestal > 895) thePedestal -= 1024; pedestalProfiles.GetTECEntry(det, ring, beam, disk).SetValue(strip, thePedestal); } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // TIB & TOB section det = 2; beam = 0; pos = 0; do { // loop using LASGlobalLoop functionality SiStripPedestals::Range pedRange = pedestalsHandle->getRange(detectorId.GetTIBTOBEntry(det, beam, pos)); for (int strip = 0; strip < 512; ++strip) { int thePedestal = int(pedestalsHandle->getPed(strip, pedRange)); if (thePedestal > 895) thePedestal -= 1024; pedestalProfiles.GetTIBTOBEntry(det, beam, pos).SetValue(strip, thePedestal); } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // TEC2TEC AT section det = 0; beam = 0; disk = 0; do { // loop using LASGlobalLoop functionality SiStripPedestals::Range pedRange = pedestalsHandle->getRange(detectorId.GetTEC2TECEntry(det, beam, disk)); for (int strip = 0; strip < 512; ++strip) { int thePedestal = int(pedestalsHandle->getPed(strip, pedRange)); if (thePedestal > 895) thePedestal -= 1024; pedestalProfiles.GetTEC2TECEntry(det, beam, disk).SetValue(strip, thePedestal); } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); } /// /// count useable profiles in TEC, /// operates on LASGlobalData<int> LaserAlignment::isAcceptedProfile /// to allow for more elaborate patterns in the future /// bool LaserAlignment::isTECBeam(void) { int numberOfProfiles = 0; int ring = 1; // search all ring6 modules for signals for (int det = 0; det < 2; ++det) { for (int beam = 0; beam < 8; ++beam) { for (int disk = 0; disk < 9; ++disk) { if (isAcceptedProfile.GetTECEntry(det, ring, beam, disk) == 1) numberOfProfiles++; } } } LogDebug("[LaserAlignment::isTECBeam]") << " Found: " << numberOfProfiles << "hits." << std::endl; std::cout << " [LaserAlignment::isTECBeam] -- Found: " << numberOfProfiles << " hits." << std::endl; //// if (numberOfProfiles > 10) return (true); return (false); } /// /// count useable profiles in TIBTOB, /// operates on LASGlobalData<bool> LaserAlignment::isAcceptedProfile /// to allow for more elaborate patterns in the future /// bool LaserAlignment::isATBeam(void) { int numberOfProfiles = 0; int det = 2; int beam = 0; int pos = 0; // search all TIB/TOB for signals do { if (isAcceptedProfile.GetTIBTOBEntry(det, beam, pos) == 1) numberOfProfiles++; } while (moduleLoop.TIBTOBLoop(det, beam, pos)); LogDebug("[LaserAlignment::isATBeam]") << " Found: " << numberOfProfiles << "hits." << std::endl; std::cout << " [LaserAlignment::isATBeam] -- Found: " << numberOfProfiles << " hits." << std::endl; ///// if (numberOfProfiles > 10) return (true); return (false); } /// /// not all TIB & TOB modules are hit in the center; /// this func returns the nominal beam offset locally on a module (in strips) /// for the ProfileJudge and the LASPeakFinder in strips. /// (offset = middle of module - nominal position) /// /// the hard coded numbers will later be supplied by a special geometry class.. /// double LaserAlignment::getTIBTOBNominalBeamOffset(unsigned int det, unsigned int beam, unsigned int pos) { if (det < 2 || det > 3 || beam > 7 || pos > 5) { throw cms::Exception("[LaserAlignment::getTIBTOBNominalBeamOffset]") << " ERROR ** Called with nonexisting parameter set: det " << det << " beam " << beam << " pos " << pos << "." << std::endl; } const double nominalOffsetsTIB[8] = { 0.00035, 2.10687, -2.10827, -0.00173446, 2.10072, -0.00135114, 2.10105, -2.10401}; // in tob, modules have alternating orientations along the rods. // this is described by the following pattern. // (even more confusing, this pattern is inversed for beams 0, 5, 6, 7) const int orientationPattern[6] = {-1, 1, 1, -1, -1, 1}; const double nominalOffsetsTOB[8] = {0.00217408, 1.58678, 117.733, 119.321, 120.906, 119.328, 117.743, 1.58947}; if (det == 2) return (-1. * nominalOffsetsTIB[beam]); else { if (beam == 0 or beam > 4) return (nominalOffsetsTOB[beam] * orientationPattern[pos]); else return (-1. * nominalOffsetsTOB[beam] * orientationPattern[pos]); } } /// /// not all TEC-AT modules are hit in the center; /// this func returns the nominal beam offset locally on a module (in strips) /// for the ProfileJudge and the LASPeakFinder in strips. /// (offset = middle of module - nominal position) /// /// the hard coded numbers will later be supplied by a special geometry class.. /// double LaserAlignment::getTEC2TECNominalBeamOffset(unsigned int det, unsigned int beam, unsigned int disk) { if (det > 1 || beam > 7 || disk > 5) { throw cms::Exception("[LaserAlignment::getTEC2TECNominalBeamOffset]") << " ERROR ** Called with nonexisting parameter set: det " << det << " beam " << beam << " disk " << disk << "." << std::endl; } const double nominalOffsets[8] = {0., 2.220, -2.221, 0., 2.214, 0., 2.214, -2.217}; if (det == 0) return -1. * nominalOffsets[beam]; else return nominalOffsets[beam]; } /// /// /// void LaserAlignment::CalculateNominalCoordinates(void) { // // hard coded data yet... // // nominal phi values of tec beam / alignment tube hits (parameter is beam 0-7) const double tecPhiPositions[8] = { 0.392699, 1.178097, 1.963495, 2.748894, 3.534292, 4.319690, 5.105088, 5.890486}; // new values calculated by maple const double atPhiPositions[8] = { 0.392699, 1.289799, 1.851794, 2.748894, 3.645995, 4.319690, 5.216791, 5.778784}; // new values calculated by maple // nominal r values (mm) of hits const double tobRPosition = 600.; const double tibRPosition = 514.; const double tecRPosition[2] = {564., 840.}; // ring 4,6 // nominal z values (mm) of hits in barrel (parameter is pos 0-6) const double tobZPosition[6] = {1040., 580., 220., -140., -500., -860.}; const double tibZPosition[6] = {620., 380., 180., -100., -340., -540.}; // nominal z values (mm) of hits in tec (parameter is disk 0-8); FOR TEC-: (* -1.) const double tecZPosition[9] = {1322.5, 1462.5, 1602.5, 1742.5, 1882.5, 2057.5, 2247.5, 2452.5, 2667.5}; // // now we fill these into the nominalCoordinates container; // errors are zero for nominal values.. // // loop object and its variables LASGlobalLoop moduleLoop; int det, ring, beam, disk, pos; // TEC+- section det = 0; ring = 0, beam = 0; disk = 0; do { if (det == 0) { // this is TEC+ nominalCoordinates.SetTECEntry( det, ring, beam, disk, LASCoordinateSet(tecPhiPositions[beam], 0., tecRPosition[ring], 0., tecZPosition[disk], 0.)); } else { // now TEC- nominalCoordinates.SetTECEntry( det, ring, beam, disk, LASCoordinateSet( tecPhiPositions[beam], 0., tecRPosition[ring], 0., -1. * tecZPosition[disk], 0.)); // just * -1. } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // TIB & TOB section det = 2; beam = 0; pos = 0; do { if (det == 2) { // this is TIB nominalCoordinates.SetTIBTOBEntry( det, beam, pos, LASCoordinateSet(atPhiPositions[beam], 0., tibRPosition, 0., tibZPosition[pos], 0.)); } else { // now TOB nominalCoordinates.SetTIBTOBEntry( det, beam, pos, LASCoordinateSet(atPhiPositions[beam], 0., tobRPosition, 0., tobZPosition[pos], 0.)); } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // TEC2TEC AT section det = 0; beam = 0; disk = 0; do { if (det == 0) { // this is TEC+, ring4 only nominalCoordinates.SetTEC2TECEntry( det, beam, disk, LASCoordinateSet(atPhiPositions[beam], 0., tecRPosition[0], 0., tecZPosition[disk], 0.)); } else { // now TEC- nominalCoordinates.SetTEC2TECEntry( det, beam, disk, LASCoordinateSet(atPhiPositions[beam], 0., tecRPosition[0], 0., -1. * tecZPosition[disk], 0.)); // just * -1. } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); } /// /// convert an angle in the [-pi,pi] range /// to the [0,2*pi] range /// double LaserAlignment::ConvertAngle(double angle) { if (angle < -1. * M_PI || angle > M_PI) { throw cms::Exception(" [LaserAlignment::ConvertAngle] ") << "** ERROR: Called with illegal input angle: " << angle << "." << std::endl; } if (angle >= 0.) return angle; else return (angle + 2. * M_PI); } /// /// debug only, will disappear /// void LaserAlignment::DumpPosFileSet(LASGlobalData<LASCoordinateSet>& coordinates) { LASGlobalLoop loop; int det, ring, beam, disk, pos; std::cout << std::endl << " [LaserAlignment::DumpPosFileSet] -- Dump: " << std::endl; // TEC INTERNAL det = 0; ring = 0; beam = 0; disk = 0; do { std::cout << "POS " << det << "\t" << beam << "\t" << disk << "\t" << ring << "\t" << coordinates.GetTECEntry(det, ring, beam, disk).GetPhi() << "\t" << coordinates.GetTECEntry(det, ring, beam, disk).GetPhiError() << std::endl; } while (loop.TECLoop(det, ring, beam, disk)); // TIBTOB det = 2; beam = 0; pos = 0; do { std::cout << "POS " << det << "\t" << beam << "\t" << pos << "\t" << "-1" << "\t" << coordinates.GetTIBTOBEntry(det, beam, pos).GetPhi() << "\t" << coordinates.GetTIBTOBEntry(det, beam, pos).GetPhiError() << std::endl; } while (loop.TIBTOBLoop(det, beam, pos)); // TEC2TEC det = 0; beam = 0; disk = 0; do { std::cout << "POS " << det << "\t" << beam << "\t" << disk << "\t" << "-1" << "\t" << coordinates.GetTEC2TECEntry(det, beam, disk).GetPhi() << "\t" << coordinates.GetTEC2TECEntry(det, beam, disk).GetPhiError() << std::endl; } while (loop.TEC2TECLoop(det, beam, disk)); std::cout << std::endl << " [LaserAlignment::DumpPosFileSet] -- End dump: " << std::endl; } /// /// /// void LaserAlignment::DumpStripFileSet(LASGlobalData<std::pair<float, float> >& measuredStripPositions) { LASGlobalLoop loop; int det, ring, beam, disk, pos; std::cout << std::endl << " [LaserAlignment::DumpStripFileSet] -- Dump: " << std::endl; // TEC INTERNAL det = 0; ring = 0; beam = 0; disk = 0; do { std::cout << "STRIP " << det << "\t" << beam << "\t" << disk << "\t" << ring << "\t" << measuredStripPositions.GetTECEntry(det, ring, beam, disk).first << "\t" << measuredStripPositions.GetTECEntry(det, ring, beam, disk).second << std::endl; } while (loop.TECLoop(det, ring, beam, disk)); // TIBTOB det = 2; beam = 0; pos = 0; do { std::cout << "STRIP " << det << "\t" << beam << "\t" << pos << "\t" << "-1" << "\t" << measuredStripPositions.GetTIBTOBEntry(det, beam, pos).first << "\t" << measuredStripPositions.GetTIBTOBEntry(det, beam, pos).second << std::endl; } while (loop.TIBTOBLoop(det, beam, pos)); // TEC2TEC det = 0; beam = 0; disk = 0; do { std::cout << "STRIP " << det << "\t" << beam << "\t" << disk << "\t" << "-1" << "\t" << measuredStripPositions.GetTEC2TECEntry(det, beam, disk).first << "\t" << measuredStripPositions.GetTEC2TECEntry(det, beam, disk).second << std::endl; } while (loop.TEC2TECLoop(det, beam, disk)); std::cout << std::endl << " [LaserAlignment::DumpStripFileSet] -- End dump: " << std::endl; } /// /// /// void LaserAlignment::DumpHitmaps(LASGlobalData<int>& numberOfAcceptedProfiles) { std::cout << " [LaserAlignment::DumpHitmaps] -- Dumping hitmap for TEC+:" << std::endl; std::cout << " [LaserAlignment::DumpHitmaps] -- Ring4:" << std::endl; std::cout << " disk0 disk1 disk2 disk3 disk4 disk5 disk6 disk7 disk8" << std::endl; for (int beam = 0; beam < 8; ++beam) { std::cout << " beam" << beam << ":"; for (int disk = 0; disk < 9; ++disk) { std::cout << "\t" << numberOfAcceptedProfiles.GetTECEntry(0, 0, beam, disk); } std::cout << std::endl; } std::cout << " [LaserAlignment::DumpHitmaps] -- Ring6:" << std::endl; std::cout << " disk0 disk1 disk2 disk3 disk4 disk5 disk6 disk7 disk8" << std::endl; for (int beam = 0; beam < 8; ++beam) { std::cout << " beam" << beam << ":"; for (int disk = 0; disk < 9; ++disk) { std::cout << "\t" << numberOfAcceptedProfiles.GetTECEntry(0, 1, beam, disk); } std::cout << std::endl; } std::cout << " [LaserAlignment::DumpHitmaps] -- Dumping hitmap for TEC-:" << std::endl; std::cout << " [LaserAlignment::DumpHitmaps] -- Ring4:" << std::endl; std::cout << " disk0 disk1 disk2 disk3 disk4 disk5 disk6 disk7 disk8" << std::endl; for (int beam = 0; beam < 8; ++beam) { std::cout << " beam" << beam << ":"; for (int disk = 0; disk < 9; ++disk) { std::cout << "\t" << numberOfAcceptedProfiles.GetTECEntry(1, 0, beam, disk); } std::cout << std::endl; } std::cout << " [LaserAlignment::DumpHitmaps] -- Ring6:" << std::endl; std::cout << " disk0 disk1 disk2 disk3 disk4 disk5 disk6 disk7 disk8" << std::endl; for (int beam = 0; beam < 8; ++beam) { std::cout << " beam" << beam << ":"; for (int disk = 0; disk < 9; ++disk) { std::cout << "\t" << numberOfAcceptedProfiles.GetTECEntry(1, 1, beam, disk); } std::cout << std::endl; } std::cout << " [LaserAlignment::DumpHitmaps] -- End of dump." << std::endl << std::endl; } /// /// loop the list of endcap modules to be masked and /// apply the corrections from the "endcapParameters" to them /// void LaserAlignment::ApplyEndcapMaskingCorrections(LASGlobalData<LASCoordinateSet>& measuredCoordinates, LASGlobalData<LASCoordinateSet>& nominalCoordinates, LASEndcapAlignmentParameterSet& endcapParameters) { // loop the list of modules to be masked for (std::vector<unsigned int>::iterator moduleIt = theMaskTecModules.begin(); moduleIt != theMaskTecModules.end(); ++moduleIt) { // loop variables LASGlobalLoop moduleLoop; int det, ring, beam, disk; // this will calculate the corrections from the alignment parameters LASEndcapAlgorithm endcapAlgorithm; // find the location of the respective module in the container with this loop det = 0; ring = 0; beam = 0; disk = 0; do { // here we got it if (detectorId.GetTECEntry(det, ring, beam, disk) == *moduleIt) { // the nominal phi value for this module const double nominalPhi = nominalCoordinates.GetTECEntry(det, ring, beam, disk).GetPhi(); // the offset from the alignment parameters const double phiCorrection = endcapAlgorithm.GetAlignmentParameterCorrection( det, ring, beam, disk, nominalCoordinates, endcapParameters); // apply the corrections measuredCoordinates.GetTECEntry(det, ring, beam, disk).SetPhi(nominalPhi - phiCorrection); } } while (moduleLoop.TECLoop(det, ring, beam, disk)); } } /// /// loop the list of alignment tube modules to be masked and /// apply the corrections from the "barrelParameters" to them /// void LaserAlignment::ApplyATMaskingCorrections(LASGlobalData<LASCoordinateSet>& measuredCoordinates, LASGlobalData<LASCoordinateSet>& nominalCoordinates, LASBarrelAlignmentParameterSet& atParameters) { // loop the list of modules to be masked for (std::vector<unsigned int>::iterator moduleIt = theMaskAtModules.begin(); moduleIt != theMaskAtModules.end(); ++moduleIt) { // loop variables LASGlobalLoop moduleLoop; int det, beam, disk, pos; // this will calculate the corrections from the alignment parameters LASAlignmentTubeAlgorithm atAlgorithm; // find the location of the respective module in the container with these loops: // first TIB+TOB det = 2; beam = 0; pos = 0; do { // here we got it if (detectorId.GetTIBTOBEntry(det, beam, pos) == *moduleIt) { // the nominal phi value for this module const double nominalPhi = nominalCoordinates.GetTIBTOBEntry(det, beam, pos).GetPhi(); // the offset from the alignment parameters const double phiCorrection = atAlgorithm.GetTIBTOBAlignmentParameterCorrection(det, beam, pos, nominalCoordinates, atParameters); // apply the corrections measuredCoordinates.GetTIBTOBEntry(det, beam, pos).SetPhi(nominalPhi - phiCorrection); } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // then TEC(AT) det = 0; beam = 0; disk = 0; do { // here we got it if (detectorId.GetTEC2TECEntry(det, beam, disk) == *moduleIt) { // the nominal phi value for this module const double nominalPhi = nominalCoordinates.GetTEC2TECEntry(det, beam, disk).GetPhi(); // the offset from the alignment parameters const double phiCorrection = atAlgorithm.GetTEC2TECAlignmentParameterCorrection(det, beam, disk, nominalCoordinates, atParameters); // apply the corrections measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhi(nominalPhi - phiCorrection); } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); } } /// /// this function is for debugging and testing only /// and will disappear.. /// void LaserAlignment::testRoutine(void) { // tracker geom. object for calculating the global beam positions const TrackerGeometry& theTracker(*theTrackerGeometry); const double atPhiPositions[8] = {0.392699, 1.289799, 1.851794, 2.748894, 3.645995, 4.319690, 5.216791, 5.778784}; const double tecPhiPositions[8] = {0.392699, 1.178097, 1.963495, 2.748894, 3.534292, 4.319690, 5.105088, 5.890486}; const double zPositions[9] = {125.0, 139.0, 153.0, 167.0, 181.0, 198.5, 217.5, 238.0, 259.5}; const double zPositionsTIB[6] = {62.0, 38.0, 18.0, -10.0, -34.0, -54.0}; const double zPositionsTOB[6] = {104.0, 58.0, 22.0, -14.0, -50.0, -86.0}; int det, beam, disk, pos, ring; // loop TEC+- internal det = 0; ring = 0; beam = 0; disk = 0; do { const double radius = ring ? 84.0 : 56.4; // access the tracker geometry for this module const DetId theDetId(detectorId.GetTECEntry(det, ring, beam, disk)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { const GlobalPoint gp(GlobalPoint::Cylindrical(radius, tecPhiPositions[beam], zPositions[disk])); const LocalPoint lp(theStripDet->surface().toLocal(gp)); std::cout << "__TEC: " << 256. - theStripDet->specificTopology().strip(lp) << std::endl; ///////////////////////////////// } } while (moduleLoop.TECLoop(det, ring, beam, disk)); // loop TIBTOB det = 2; beam = 0; pos = 0; do { const double radius = (det == 2 ? 51.4 : 58.4); ///////////////////////////////////////////////////////////////////////////// const double theZ = (det == 2 ? zPositionsTIB[pos] : zPositionsTOB[pos]); // access the tracker geometry for this module const DetId theDetId(detectorId.GetTIBTOBEntry(det, beam, pos)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { const GlobalPoint gp(GlobalPoint::Cylindrical(radius, atPhiPositions[beam], theZ)); const LocalPoint lp(theStripDet->surface().toLocal(gp)); std::cout << "__TIBTOB det " << det << " beam " << beam << " pos " << pos << " " << 256. - theStripDet->specificTopology().strip(lp); std::cout << " " << theStripDet->position().perp() << std::endl; ///////////////////////////////// } } while (moduleLoop.TIBTOBLoop(det, beam, pos)); // loop TEC2TEC det = 0; beam = 0; disk = 0; do { const double radius = 56.4; // access the tracker geometry for this module const DetId theDetId(detectorId.GetTEC2TECEntry(det, beam, disk)); const StripGeomDetUnit* const theStripDet = dynamic_cast<const StripGeomDetUnit*>(theTracker.idToDet(theDetId)); if (theStripDet) { const GlobalPoint gp(GlobalPoint::Cylindrical(radius, atPhiPositions[beam], zPositions[disk])); const LocalPoint lp(theStripDet->surface().toLocal(gp)); std::cout << "__TEC2TEC det " << det << " beam " << beam << " disk " << disk << " " << 256. - theStripDet->specificTopology().strip(lp) << std::endl; ///////////////////////////////// } } while (moduleLoop.TEC2TECLoop(det, beam, disk)); } // define the SEAL module #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(LaserAlignment); // the ATTIC