text: // -*- C++ -*-
  //
  // Package:     CommonAlignmentMonitor
  // Class  :     AlignmentMonitorBase
  //
  // Implementation:
  //     <Notes on implementation>
  //
  // Original Author:  Jim Pivarski
  //         Created:  Fri Mar 30 12:21:07 CDT 2007
  // $Id: AlignmentMonitorBase.cc,v 1.11 2010/01/06 15:23:09 mussgill Exp $
  //
  
  #include "Alignment/CommonAlignmentMonitor/interface/AlignmentMonitorBase.h"
  #include "FWCore/ParameterSet/interface/ParameterSet.h"
  #include "FWCore/MessageLogger/interface/MessageLogger.h"
  #include "FWCore/ServiceRegistry/interface/Service.h"
  #include "CommonTools/UtilAlgos/interface/TFileService.h"
  
  AlignmentMonitorBase::AlignmentMonitorBase(const edm::ParameterSet &cfg,
                                             const edm::ConsumesCollector &iC,
                                             std::string name)
      : m_beamSpotTag(cfg.getUntrackedParameter<edm::InputTag>("beamSpotTag", edm::InputTag("offlineBeamSpot"))),
        m_iteration(0),
        mp_tracker(nullptr),
        mp_muon(nullptr),
        mp_store(nullptr) {
    edm::Service<TFileService> tFileService;
    m_baseDirMap[std::vector<std::string>()] = new TFileDirectory(tFileService->mkdir(name));
  }
  
  void AlignmentMonitorBase::beginOfJob(AlignableTracker *pTracker,
                                        AlignableMuon *pMuon,
                                        AlignmentParameterStore *pStore) {
    mp_tracker = pTracker;
    mp_muon = pMuon;
    mp_store = pStore;
  
    if (!pMuon)
      mp_navigator = new AlignableNavigator(pTracker);
    else if (!pTracker)
      mp_navigator = new AlignableNavigator(pMuon);
    else
      mp_navigator = new AlignableNavigator(pTracker, pMuon);
  }
  
  void AlignmentMonitorBase::startingNewLoop() {
    m_iteration++;
  
    for (std::map<std::vector<std::string>, TFileDirectory *>::const_iterator i = m_iterDirMap.begin();
         i != m_iterDirMap.end();
         ++i) {
      delete i->second;
    }
    m_iterDirMap.clear();
  
    std::ostringstream dirName;
    dirName << "iter" << iteration();
    m_iterDirMap[std::vector<std::string>()] =
        new TFileDirectory(m_baseDirMap[std::vector<std::string>()]->mkdir(dirName.str()));
  
    book();
  }
  
  void AlignmentMonitorBase::duringLoop(const edm::Event &iEvent,
                                        const edm::EventSetup &iSetup,
                                        const ConstTrajTrackPairCollection &iTrajTracks) {
    event(iEvent, iSetup, iTrajTracks);
  }
  
  void AlignmentMonitorBase::endOfLoop() { afterAlignment(); }
  
  TFileDirectory *AlignmentMonitorBase::directory(std::string dir) {
    std::string::size_type lastPos = dir.find_first_not_of('/', 0);
    std::string::size_type pos = dir.find_first_of('/', lastPos);
    std::vector<std::string> dirs;
  
    bool isIter = false;
    if (dir.substr(lastPos, pos - lastPos) == std::string("iterN")) {
      isIter = true;
      lastPos = dir.find_first_not_of('/', pos);
      pos = dir.find_first_of('/', lastPos);
    }
  
    while (std::string::npos != pos || std::string::npos != lastPos) {
      dirs.push_back(dir.substr(lastPos, pos - lastPos));
      lastPos = dir.find_first_not_of('/', pos);
      pos = dir.find_first_of('/', lastPos);
    }
  
    std::map<std::vector<std::string>, TFileDirectory *> *theMap;
    if (isIter)
      theMap = &m_iterDirMap;
    else
      theMap = &m_baseDirMap;
  
    std::vector<std::string> partial;
    TFileDirectory *last = (*theMap)[partial];
    for (unsigned int i = 0; i < dirs.size(); i++) {
      partial.push_back(dirs[i]);
      if (theMap->find(partial) == theMap->end()) {
        (*theMap)[partial] = new TFileDirectory(last->mkdir(dirs[i]));
      }
      last = (*theMap)[partial];
    }
    return last;
  }
  
  TH1F *AlignmentMonitorBase::book1D(
      std::string dir, std::string name, std::string title, int nchX, double lowX, double highX) {
    return directory(dir)->make<TH1F>(name.c_str(), title.c_str(), nchX, lowX, highX);
  }
  
  TProfile *AlignmentMonitorBase::bookProfile(std::string dir,
                                              std::string name,
                                              std::string title,
                                              int nchX,
                                              double lowX,
                                              double highX,
                                              int nchY,
                                              double lowY,
                                              double highY,
                                              const char *option) {
    if (lowY == highY) {
      return directory(dir)->make<TProfile>(name.c_str(), title.c_str(), nchX, lowX, highX, option);
    } else {
      return directory(dir)->make<TProfile>(name.c_str(), title.c_str(), nchX, lowX, highX, lowY, highY, option);
    }
  }
  
  TH2F *AlignmentMonitorBase::book2D(std::string dir,
                                     std::string name,
                                     std::string title,
                                     int nchX,
                                     double lowX,
                                     double highX,
                                     int nchY,
                                     double lowY,
                                     double highY) {
    return directory(dir)->make<TH2F>(name.c_str(), title.c_str(), nchX, lowX, highX, nchY, lowY, highY);
  }
  