Skip to content

Commit

Permalink
Merge pull request #27608 from CTPPS/FullSim_SimPPS-RPDigiProducer
Browse files Browse the repository at this point in the history
SimPPS/RPDigiProducer package for PPS Full simulation
  • Loading branch information
cmsbuild committed Sep 29, 2019
2 parents 317e616 + be4b814 commit 8d809c2
Show file tree
Hide file tree
Showing 27 changed files with 1,425 additions and 0 deletions.
2 changes: 2 additions & 0 deletions SimPPS/RPDigiProducer/BuildFile.xml
@@ -0,0 +1,2 @@
<use name="Geometry/VeryForwardRPTopology"/>
<flags EDM_PLUGIN="1"/>
27 changes: 27 additions & 0 deletions SimPPS/RPDigiProducer/interface/RPEnergyDepositUnit.h
@@ -0,0 +1,27 @@
#ifndef SimPPS_RPDigiProducer_RP_ENERGY_DEPOSIT_UNIT_H
#define SimPPS_RPDigiProducer_RP_ENERGY_DEPOSIT_UNIT_H

#include "DataFormats/GeometryVector/interface/LocalPoint.h"
#include "DataFormats/GeometryVector/interface/LocalVector.h"

/**
* Class which allows to "follow" an elementary charge in the silicon.
* It basically defines a quantum of energy, with a position.
*/
class RPEnergyDepositUnit {
public:
RPEnergyDepositUnit() : energy_(0), position_(0, 0, 0) {}
RPEnergyDepositUnit(double energy, double x, double y, double z) : energy_(energy), position_(x, y, z) {}
RPEnergyDepositUnit(double energy, const Local3DPoint& position) : energy_(energy), position_(position) {}
inline double Energy() const { return energy_; }
inline const Local3DPoint& Position() const { return position_; }

inline void setEnergy(double e) { energy_ = e; }
inline void setPosition(Local3DPoint p) { position_ = p; }

private:
double energy_;
Local3DPoint position_;
};

#endif //SimPPS_RPDigiProducer_RP_ENERGY_DEPOSIT_UNIT_H
30 changes: 30 additions & 0 deletions SimPPS/RPDigiProducer/interface/RPSignalPoint.h
@@ -0,0 +1,30 @@
#ifndef SimPPS_RPDigiProducer_RP_SignalPoint_H
#define SimPPS_RPDigiProducer_RP_SignalPoint_H

#include "DataFormats/GeometryVector/interface/LocalPoint.h"
#include "DataFormats/GeometryVector/interface/LocalVector.h"

/**
* An elementar charge point, with position, sigma from diffusion and tof.
*/
class RPSignalPoint {
public:
RPSignalPoint() : pos_(0, 0), sigma_(0), charge_(0) {}

RPSignalPoint(double x, double y, double s, double charge) : pos_(x, y), sigma_(s), charge_(charge) {}

inline const LocalPoint& Position() const { return pos_; }
inline double Sigma() const { return sigma_; }
inline double Charge() const { return charge_; }

inline void setSigma(double s) { sigma_ = s; }
inline void setPosition(LocalPoint p) { pos_ = p; }
inline void setCharge(double charge) { charge_ = charge; }

private:
LocalPoint pos_;
double sigma_;
double charge_;
};

#endif //SimPPS_RPDigiProducer_RP_SignalPoint_H
33 changes: 33 additions & 0 deletions SimPPS/RPDigiProducer/interface/RPSimTypes.h
@@ -0,0 +1,33 @@
#ifndef SimPPS_RPDigiProducer_RPSimTypes_H
#define SimPPS_RPDigiProducer_RPSimTypes_H

#include <map>
#include <vector>
#include <set>

#include "SimPPS/RPDigiProducer/interface/RPEnergyDepositUnit.h"
#include "SimPPS/RPDigiProducer/interface/RPSignalPoint.h"

typedef uint32_t RPDetId;

namespace simromanpot {
typedef std::map<unsigned short, double> strip_charge_map;
typedef std::vector<RPSignalPoint> charge_induced_on_surface;
typedef std::vector<RPEnergyDepositUnit> energy_path_distribution;
typedef std::set<short, std::less<short> > HitsContainer;
typedef std::set<short, std::less<short> >::const_iterator HitsContainerIter;
typedef std::set<short, std::less<short> > TriggerContainer;
typedef std::set<short, std::less<short> >::const_iterator TriggerContainerIter;
typedef std::vector<std::vector<std::pair<int, double> > >
DigiPrimaryMapType; //for each digi in the output the vector of the number of PSimHit and its weight
typedef std::vector<std::pair<int, double> >
SingleDigiPrimaryMapType; //for one digi in the output the vector of the number of PSimHit and its weight
typedef std::vector<std::vector<std::pair<int, double> > >
TriggerPrimaryMapType; //for each digi in the output the vector of the number of PSimHit and its weight
typedef std::map<unsigned short, std::vector<std::pair<int, double> > >
strip_charge_map_links_type; //for each strip the indeces of PSimHit and amounts of charge generated by it is given
typedef std::map<unsigned short, std::map<int, double> >
TriggerContainerLinkMap; //for each strip the indeces of PSimHit and amounts of charge generated by it is given
} // namespace simromanpot

#endif //SimPPS_RPDigiProducer_RPSimTypes_H
9 changes: 9 additions & 0 deletions SimPPS/RPDigiProducer/plugins/BuildFile.xml
@@ -0,0 +1,9 @@
<use name="SimTracker/Common"/>
<use name="DataFormats/CTPPSDetId"/>
<use name="CondFormats/CTPPSReadoutObjects"/>
<use name="Geometry/VeryForwardGeometryBuilder"/>
<use name="Geometry/VeryForwardRPTopology"/>

<library name="SimPPSRPDigiProducerPlugins" file="*.cc">
<flags EDM_PLUGIN="1"/>
</library>
54 changes: 54 additions & 0 deletions SimPPS/RPDigiProducer/plugins/DeadChannelsManager.cc
@@ -0,0 +1,54 @@
#include "SimPPS/RPDigiProducer/plugins/DeadChannelsManager.h"
#include "CondFormats/CTPPSReadoutObjects/interface/TotemSymbId.h"
#include "CondFormats/CTPPSReadoutObjects/interface/TotemDAQMapping.h"
#include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
#include "SimPPS/RPDigiProducer/plugins/RPDisplacementGenerator.h"
#include <map>
#include "FWCore/MessageLogger/interface/MessageLogger.h"

DeadChannelsManager::DeadChannelsManager() { analysisMaskPresent = false; }

DeadChannelsManager::DeadChannelsManager(edm::ESHandle<TotemAnalysisMask> _analysisMask) {
analysisMask = _analysisMask;
analysisMaskPresent = true;
}

bool DeadChannelsManager::isChannelDead(RPDetId detectorId, unsigned short stripNumber) {
unsigned int symbolicId = RPDisplacementGenerator::rawToDecId(detectorId) * 10; //convert to symbolic ID

unsigned int vfat = stripNumber / 128;
symbolicId += vfat; //add vfatID to symbolic ID
stripNumber = stripNumber - vfat * 128; //convert strip number to a number from range <0; 127>
TotemSymbID totemSymbolicId;
totemSymbolicId.symbolicID = symbolicId;
if (analysisMaskPresent) {
std::map<TotemSymbID, TotemVFATAnalysisMask>::const_iterator vfatIter =
analysisMask->analysisMask.find(totemSymbolicId);
if (vfatIter != analysisMask->analysisMask.end()) {
TotemVFATAnalysisMask vfatMask = vfatIter->second;
//if channel is dead return true
if (vfatMask.fullMask || vfatMask.maskedChannels.find(stripNumber) != vfatMask.maskedChannels.end()) {
return true;
}
}
}
return false;
}

void DeadChannelsManager::displayMap() {
if (analysisMaskPresent) {
std::map<TotemSymbID, TotemVFATAnalysisMask>::const_iterator vfatIter;
for (vfatIter = analysisMask->analysisMask.begin(); vfatIter != analysisMask->analysisMask.end(); vfatIter++) {
LogDebug("PPSDigiProducer::DeadChannelsManager") << vfatIter->first.symbolicID << "\n";
TotemVFATAnalysisMask am = vfatIter->second;
if (am.fullMask) {
LogDebug("PPSDigiProducer::DeadChannelsManager") << " full mask\n";
} else {
std::set<unsigned char>::iterator setIterator;
for (setIterator = am.maskedChannels.begin(); setIterator != am.maskedChannels.end(); setIterator++) {
LogDebug("PPSDigiProducer::DeadChannelsManager") << " " << (int)(*setIterator) << "\n";
}
}
}
}
}
43 changes: 43 additions & 0 deletions SimPPS/RPDigiProducer/plugins/DeadChannelsManager.h
@@ -0,0 +1,43 @@
#ifndef SimPPS_RPDigiProducer_DEAD_CHANNELS_MANAGER
#define SimPPS_RPDigiProducer_DEAD_CHANNELS_MANAGER

#include "FWCore/Framework/interface/ESHandle.h"
#include "SimPPS/RPDigiProducer/interface/RPSimTypes.h"
#include "CondFormats/CTPPSReadoutObjects/interface/TotemAnalysisMask.h"

/*
* This purpose of this class is to answer the question whether a channel (given by detectorId
* and stripNumber) is dead or not. This class uses analysisMask which is provided
* by DAQMappingSourceXML.
* @author Jakub Smajek
*/
class DeadChannelsManager {
private:
edm::ESHandle<TotemAnalysisMask> analysisMask;
bool analysisMaskPresent; //this variable indicates whether analysisMask is present or not

public:
/**
* This constructor allows us to set analysisMask. The analysisMask can be read from
* EventSetup.
*/
DeadChannelsManager(edm::ESHandle<TotemAnalysisMask> analysisMask);
DeadChannelsManager();
/**
* This function answers the question whether given channel is dead or not.
* RPDetId - detector ID given in raw form, this function has to convert raw ID to symbolic
* stripNumber - ID of the strip, it is a number from range <0; 511>, this function has to convert
* it into a vfat ID and a number from range <0; 127>
*
* It is assumed that:
* channels 0 - 127 are in vfat number 0
* channels 128 - 255 are in vfat number 1
* channels 256 - 383 are in vfat number 2
* channels 384 - 511 are in vfat number 3
*/
bool isChannelDead(RPDetId detectorId, unsigned short stripNumber);
void displayMap();
static uint32_t rawToDecId(uint32_t raw);
};

#endif
65 changes: 65 additions & 0 deletions SimPPS/RPDigiProducer/plugins/RPDetDigitizer.cc
@@ -0,0 +1,65 @@
#include <vector>
#include <iostream>

#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "SimPPS/RPDigiProducer/plugins/RPDetDigitizer.h"
#include "Geometry/VeryForwardRPTopology/interface/RPTopology.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"

RPDetDigitizer::RPDetDigitizer(const edm::ParameterSet &params,
CLHEP::HepRandomEngine &eng,
RPDetId det_id,
const edm::EventSetup &iSetup)
: det_id_(det_id) {
verbosity_ = params.getParameter<int>("RPVerbosity");
numStrips_ = RPTopology().DetStripNo();
theNoiseInElectrons = params.getParameter<double>("RPEquivalentNoiseCharge300um");
theStripThresholdInE = params.getParameter<double>("RPVFATThreshold");
noNoise_ = params.getParameter<bool>("RPNoNoise");
misalignment_simulation_on_ = params.getParameter<bool>("RPDisplacementOn");
links_persistence_ = params.getParameter<bool>("RPDigiSimHitRelationsPresistence");

theRPGaussianTailNoiseAdder = std::make_unique<RPGaussianTailNoiseAdder>(
numStrips_, theNoiseInElectrons, theStripThresholdInE, eng, verbosity_);
theRPPileUpSignals = std::make_unique<RPPileUpSignals>(params, det_id_);
theRPVFATSimulator = std::make_unique<RPVFATSimulator>(params, det_id_);
theRPHitChargeConverter = std::make_unique<RPHitChargeConverter>(params, eng, det_id_);
theRPDisplacementGenerator = std::make_unique<RPDisplacementGenerator>(params, det_id_, iSetup);
}

void RPDetDigitizer::run(const std::vector<PSimHit> &input,
const std::vector<int> &input_links,
std::vector<TotemRPDigi> &output_digi,
simromanpot::DigiPrimaryMapType &output_digi_links) {
if (verbosity_)
LogDebug("RPDetDigitizer ") << det_id_ << " received input.size()=" << input.size() << "\n";
theRPPileUpSignals->reset();

bool links_persistence_checked = links_persistence_ && input_links.size() == input.size();

int input_size = input.size();
for (int i = 0; i < input_size; ++i) {
simromanpot::strip_charge_map the_strip_charge_map;
if (misalignment_simulation_on_)
the_strip_charge_map = theRPHitChargeConverter->processHit(theRPDisplacementGenerator->displace(input[i]));
else
the_strip_charge_map = theRPHitChargeConverter->processHit(input[i]);

if (verbosity_)
LogDebug("RPHitChargeConverter ") << det_id_ << " returned hits=" << the_strip_charge_map.size() << "\n";
if (links_persistence_checked)
theRPPileUpSignals->add(the_strip_charge_map, input_links[i]);
else
theRPPileUpSignals->add(the_strip_charge_map, 0);
}

const simromanpot::strip_charge_map &theSignal = theRPPileUpSignals->dumpSignal();
simromanpot::strip_charge_map_links_type &theSignalProvenance = theRPPileUpSignals->dumpLinks();
simromanpot::strip_charge_map afterNoise;
if (noNoise_)
afterNoise = theSignal;
else
afterNoise = theRPGaussianTailNoiseAdder->addNoise(theSignal);

theRPVFATSimulator->ConvertChargeToHits(afterNoise, theSignalProvenance, output_digi, output_digi_links);
}
53 changes: 53 additions & 0 deletions SimPPS/RPDigiProducer/plugins/RPDetDigitizer.h
@@ -0,0 +1,53 @@
#ifndef SimPPS_RPDigiProducer_RP_DET_DIGITIZER_H
#define SimPPS_RPDigiProducer_RP_DET_DIGITIZER_H

#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "DataFormats/CTPPSDigi/interface/TotemRPDigi.h"
#include "SimDataFormats/TrackingHit/interface/PSimHit.h"

#include "SimGeneral/NoiseGenerators/interface/GaussianTailNoiseGenerator.h"

#include "SimPPS/RPDigiProducer/interface/RPSimTypes.h"
#include "SimPPS/RPDigiProducer/plugins/RPHitChargeConverter.h"
#include "SimPPS/RPDigiProducer/plugins/RPVFATSimulator.h"
#include "SimPPS/RPDigiProducer/plugins/RPDisplacementGenerator.h"
#include "SimPPS/RPDigiProducer/plugins/RPGaussianTailNoiseAdder.h"
#include "SimPPS/RPDigiProducer/plugins/RPPileUpSignals.h"

#include <vector>
#include <string>

namespace CLHEP {
class HepRandomEngine;
}

class RPDetDigitizer {
public:
RPDetDigitizer(const edm::ParameterSet &params,
CLHEP::HepRandomEngine &eng,
RPDetId det_id,
const edm::EventSetup &iSetup);
void run(const std::vector<PSimHit> &input,
const std::vector<int> &input_links,
std::vector<TotemRPDigi> &output_digi,
simromanpot::DigiPrimaryMapType &output_digi_links);

private:
std::unique_ptr<RPGaussianTailNoiseAdder> theRPGaussianTailNoiseAdder;
std::unique_ptr<RPPileUpSignals> theRPPileUpSignals;
std::unique_ptr<RPHitChargeConverter> theRPHitChargeConverter;
std::unique_ptr<RPVFATSimulator> theRPVFATSimulator;
std::unique_ptr<RPDisplacementGenerator> theRPDisplacementGenerator;

private:
int numStrips_;
double theNoiseInElectrons; // Noise (RMS) in units of electrons.
double theStripThresholdInE; // Strip noise treshold in electorns.
bool noNoise_; //if the nos is included
RPDetId det_id_;
bool misalignment_simulation_on_;
int verbosity_;
bool links_persistence_;
};

#endif //SimCTPPS_RPDigiProducer_RP_DET_DIGITIZER_H

0 comments on commit 8d809c2

Please sign in to comment.