#include <EsIdealFeeTool.h>
Inheritance diagram for EsIdealFeeTool:
Public Types | |
SUCCESS | |
NO_INTERFACE | |
VERSMISMATCH | |
LAST_ERROR | |
SUCCESS | |
NO_INTERFACE | |
VERSMISMATCH | |
LAST_ERROR | |
enum | Status |
Public Member Functions | |
EsIdealFeeTool (const std::string &type, const std::string &name, const IInterface *parent) | |
virtual | ~EsIdealFeeTool () |
virtual StatusCode | generateSignals (DayaBay::ElecPulseCollection *, DayaBay::ElecCrate *) |
This is the extension. Sub classes must provide it. | |
virtual StatusCode | initialize () |
virtual StatusCode | finalize () |
INTupleSvc * | ntupleSvc () const |
INTupleSvc * | evtColSvc () const |
IDataProviderSvc * | detSvc () const |
IDataProviderSvc * | evtSvc () const |
IIncidentSvc * | incSvc () const |
IChronoStatSvc * | chronoSvc () const |
IHistogramSvc * | histoSvc () const |
IAlgContextSvc * | contextSvc () const |
DataObject * | put (IDataProviderSvc *svc, DataObject *object, const std::string &address, const bool useRootInTES=true) const |
DataObject * | put (DataObject *object, const std::string &address, const bool useRootInTES=true) const |
Gaudi::Utils::GetData< TYPE >::return_type | get (IDataProviderSvc *svc, const std::string &location, const bool useRootInTES=true) const |
Gaudi::Utils::GetData< TYPE >::return_type | get (const std::string &location, const bool useRootInTES=true) const |
TYPE * | getDet (IDataProviderSvc *svc, const std::string &location) const |
TYPE * | getDet (const std::string &location) const |
bool | exist (IDataProviderSvc *svc, const std::string &location, const bool useRootInTES=true) const |
bool | exist (const std::string &location, const bool useRootInTES=true) const |
bool | existDet (IDataProviderSvc *svc, const std::string &location) const |
bool | existDet (const std::string &location) const |
TYPE * | getOrCreate (IDataProviderSvc *svc, const std::string &location, const bool useRootInTES=true) const |
TYPE * | getOrCreate (const std::string &location, const bool useRootInTES=true) const |
TOOL * | tool (const std::string &type, const std::string &name, const IInterface *parent=0, bool create=true) const |
TOOL * | tool (const std::string &type, const IInterface *parent=0, bool create=true) const |
SERVICE * | svc (const std::string &name, const bool create=true) const |
IUpdateManagerSvc * | updMgrSvc () const |
IDataProviderSvc * | fastContainersSvc () const |
StatusCode | Error (const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const |
StatusCode | Warning (const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const |
StatusCode | Print (const std::string &msg, const StatusCode st=StatusCode::SUCCESS, const MSG::Level lev=MSG::INFO) const |
StatusCode | Assert (const bool ok, const std::string &message="", const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const |
StatusCode | Assert (const bool ok, const char *message, const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const |
StatusCode | Exception (const std::string &msg, const GaudiException &exc, const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const |
StatusCode | Exception (const std::string &msg, const std::exception &exc, const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const |
StatusCode | Exception (const std::string &msg="no message", const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const |
MsgStream & | msgStream (const MSG::Level level) const |
MsgStream & | always () const |
MsgStream & | fatal () const |
MsgStream & | err () const |
MsgStream & | error () const |
MsgStream & | warning () const |
MsgStream & | info () const |
MsgStream & | debug () const |
MsgStream & | verbose () const |
MsgStream & | msg () const |
const Statistics & | counters () const |
StatEntity & | counter (const std::string &tag) const |
MSG::Level | msgLevel () const |
bool | msgLevel (const MSG::Level level) const |
void | resetMsgStream () const |
bool | typePrint () const |
bool | propsPrint () const |
bool | statPrint () const |
bool | errorsPrint () const |
long | printStat (const MSG::Level level=MSG::ALWAYS) const |
long | printErrors (const MSG::Level level=MSG::ALWAYS) const |
long | printProps (const MSG::Level level=MSG::ALWAYS) const |
void | registerCondition (const std::string &condition, StatusCode(CallerClass::*mf)()=NULL) |
void | registerCondition (const std::string &condition, CondType *&condPtrDest, StatusCode(CallerClass::*mf)()=NULL) |
void | registerCondition (char *condition, StatusCode(CallerClass::*mf)()=NULL) |
void | registerCondition (TargetClass *condition, StatusCode(CallerClass::*mf)()=NULL) |
StatusCode | runUpdate () |
TransientFastContainer< T > * | getFastContainer (const std::string &location, typename TransientFastContainer< T >::size_type initial=0) |
StatusCode | release (const IInterface *interface) const |
virtual unsigned long | release () |
const std::string & | context () const |
const std::string & | rootInTES () const |
double | globalTimeOffset () const |
virtual StatusCode | queryInterface (const InterfaceID &riid, void **ppvUnknown) |
virtual unsigned long | addRef () |
virtual const std::string & | name () const |
virtual const std::string & | type () const |
virtual const IInterface * | parent () const |
virtual StatusCode | configure () |
virtual StatusCode | start () |
virtual StatusCode | stop () |
virtual StatusCode | terminate () |
virtual StatusCode | reinitialize () |
virtual StatusCode | restart () |
virtual Gaudi::StateMachine::State | FSMState () const |
virtual Gaudi::StateMachine::State | targetFSMState () const |
virtual StatusCode | sysInitialize () |
virtual StatusCode | sysStart () |
virtual StatusCode | sysStop () |
virtual StatusCode | sysFinalize () |
virtual StatusCode | sysReinitialize () |
virtual StatusCode | sysRestart () |
virtual StatusCode | setProperty (const Property &p) |
virtual StatusCode | setProperty (const std::string &s) |
virtual StatusCode | setProperty (const std::string &n, const std::string &v) |
StatusCode | setProperty (const std::string &name, const TYPE &value) |
virtual StatusCode | getProperty (Property *p) const |
virtual const Property & | getProperty (const std::string &name) const |
virtual StatusCode | getProperty (const std::string &n, std::string &v) const |
virtual const std::vector< Property * > & | getProperties () const |
PropertyMgr * | getPropertyMgr () |
ISvcLocator * | serviceLocator () const |
ISvcLocator * | svcLoc () const |
IMessageSvc * | msgSvc () const |
IToolSvc * | toolSvc () const |
StatusCode | setProperties () |
StatusCode | service (const std::string &name, T *&svc, bool createIf=true) const |
StatusCode | service (const std::string &type, const std::string &name, T *&svc) const |
void | declInterface (const InterfaceID &, void *) |
Property * | declareProperty (const std::string &name, T &property, const std::string &doc="none") const |
Property * | declareRemoteProperty (const std::string &name, IProperty *rsvc, const std::string &rname="") const |
IAuditorSvc * | auditorSvc () const |
IMonitorSvc * | monitorSvc () const |
void | declareInfo (const std::string &name, const T &var, const std::string &desc) const |
void | declareInfo (const std::string &name, const std::string &format, const void *var, int size, const std::string &desc) const |
virtual const std::string & | type () const =0 |
virtual const IInterface * | parent () const =0 |
virtual StatusCode | configure ()=0 |
virtual StatusCode | start ()=0 |
virtual StatusCode | stop ()=0 |
virtual StatusCode | terminate ()=0 |
virtual StatusCode | reinitialize ()=0 |
virtual StatusCode | restart ()=0 |
virtual Gaudi::StateMachine::State | FSMState () const =0 |
virtual StatusCode | sysInitialize ()=0 |
virtual StatusCode | sysStart ()=0 |
virtual StatusCode | sysStop ()=0 |
virtual StatusCode | sysFinalize ()=0 |
virtual StatusCode | sysReinitialize ()=0 |
virtual StatusCode | sysRestart ()=0 |
virtual unsigned long | refCount () const =0 |
virtual const std::string & | name () const =0 |
virtual StatusCode | queryInterface (const InterfaceID &riid, void **ppvInterface)=0 |
virtual unsigned long | addRef ()=0 |
virtual unsigned long | release ()=0 |
Static Public Member Functions | |
static const InterfaceID & | interfaceID () |
static const InterfaceID & | interfaceID () |
static const InterfaceID & | interfaceID () |
static const InterfaceID & | interfaceID () |
Retrieve interface ID. | |
Public Attributes | |
SUCCESS | |
NO_INTERFACE | |
VERSMISMATCH | |
LAST_ERROR | |
Protected Types | |
typedef std::map< std::string, StatEntity > | Statistics |
typedef std::map< std::string, unsigned int > | Counter |
typedef std::vector< IAlgTool * > | AlgTools |
typedef std::pair< IInterface *, std::string > | ServiceEntry |
typedef std::vector< ServiceEntry > | Services |
Protected Member Functions | |
StatusCode | releaseTool (const IAlgTool *tool) const |
StatusCode | releaseSvc (const IInterface *svc) const |
int | outputLevel () const |
virtual unsigned long | refCount () const |
IntegerProperty & | outputLevelProperty () |
void | initOutputLevel (Property &prop) |
Static Protected Attributes | |
static const bool | IgnoreRootInTES |
static const bool | UseRootInTES |
Private Member Functions | |
StatusCode | loadResponse () |
StatusCode | mapPulsesByChannel (const DayaBay::ElecPulseCollection::PulseContainer &pulses, std::map< DayaBay::ElecChannelId, std::vector< DayaBay::ElecPmtPulse * > > &pulseMap, int *hitCountSlices) |
StatusCode | updateBoardSignals (DayaBay::ElecFeeCrate *crate) |
StatusCode | updateEsumSignals (DayaBay::ElecFeeCrate *crate) |
virtual StatusCode | generateOneChannel (const DayaBay::FeeChannelId &, std::vector< DayaBay::ElecPmtPulse * > &, DayaBay::ElecFeeChannel &, double simTime, const ServiceMode &) |
int | convertClock (int clock, int inputFrequency, int outputFrequency) |
DayaBay::ESumComp::ESumComp_t | boardEsumType (int boardId) |
void | convolve (const DayaBay::AnalogSignal &signal, const DayaBay::AnalogSignal &response, DayaBay::AnalogSignal &output) |
void | shape (const DayaBay::AnalogSignal &rawSignal, DayaBay::AnalogSignal &shapedSignal, const DayaBay::AnalogSignal &response, std::map< int, int > convolutionWindows) |
void | digitize (const DayaBay::AnalogSignal &signal, DayaBay::DigitalSignal &output, double range, int bits, double offset) |
void | discriminate (const DayaBay::AnalogSignal &signal, double threshold, std::vector< int > &output, DayaBay::Threshold::Threshold_t mode) |
double | pmtPulse (double deltaT, int nPulse, bool addOvershoot) |
double | overshoot (double deltaT, int nPulse) |
double | ringing (double deltaT, double pulseMax) |
double | satFactor (double amp) |
double | pulseShaping (double deltaT) |
double | esumShaping (double deltaT) |
double | getPulseWidth (int nPulse) |
double | getPulseForm (int nPulse) |
double | getPulseShift (int nPulse) |
double | getOvershootAmp (int nPulse) |
double | noise () |
void | sample (const DayaBay::AnalogSignal &signal, DayaBay::AnalogSignal &output, int inputFrequency, int outputFrequency) |
Private Attributes | |
std::string | m_cableSvcName |
std::string | m_simDataSvcName |
ICableSvc * | m_cableSvc |
ISimDataSvc * | m_simDataSvc |
int | m_triggerWindowCycles |
double | m_gainFactor |
int | m_simFrequency |
int | m_eSumFrequency |
bool | m_enableNonlinearity |
bool | m_enableAcCoupling |
unsigned int | m_linearityThreshold |
bool | m_enablePretrigger |
double | m_eSumTriggerThreshold |
int | m_nHitTriggerThreshold |
int | m_pretriggerThreshold |
bool | m_enableNoise |
bool | m_enableDynamicWaveform |
bool | m_enableSaturation |
bool | m_enableRinging |
bool | m_enableOvershoot |
bool | m_enableESumTotal |
bool | m_enableESumH |
bool | m_enableESumL |
bool | m_enableFastSimMode |
double | m_pulseCountSlotWidth |
int | m_pulseCountWindow |
double | m_noiseAmp |
double | m_speAmp |
double | m_discThreshScale |
double | m_adcRange |
double | m_adcBits |
double | m_adcOffset |
DayaBay::AnalogSignal | m_pmtPulse |
DayaBay::AnalogSignal | m_pmtPulse_noOvershoot |
DayaBay::AnalogSignal | m_shapedPmtPulse |
DayaBay::AnalogSignal | m_shapedPmtPulse_noOvershoot |
DayaBay::AnalogSignal | m_ringing |
DayaBay::AnalogSignal | m_shapedRinging |
DayaBay::AnalogSignal | m_esumResponse |
DayaBay::AnalogSignal | m_shapingResponse |
double | m_shapingSum |
double | m_esumShapingSum |
double | m_pulseMax |
Rndm::Numbers | m_gauss |
DayaBay::AnalogSignal | m_rawSignal |
DayaBay::AnalogSignal | m_esumL |
DayaBay::AnalogSignal | m_esumH |
DayaBay::AnalogSignal | m_esumTotal |
DayaBay::DigitalSignal | m_shapedEsumADC |
DayaBay::AnalogSignal | m_shapedEsumH |
DayaBay::AnalogSignal | m_shapedEsumL |
DayaBay::AnalogSignal | m_shapedEsumTotal |
DayaBay::AnalogSignal | m_discriminatorSignal |
DayaBay::AnalogSignal | m_shapedSignal |
DayaBay::AnalogSignal | m_tdcSignal |
DayaBay::AnalogSignal | m_adcAnalogSignal |
DayaBay::DigitalSignal | m_hitSignal |
DayaBay::DigitalSignal | m_adcHighGain |
DayaBay::DigitalSignal | m_adcLowGain |
DayaBay::AnalogSignal | m_energySignal |
DayaBay::DigitalSignal | m_hitSync |
DayaBay::DigitalSignal | m_hitHold |
std::map< int, int > | m_adcConvolutionWindows |
std::map< int, int > | m_esumConvolutionWindows |
Definition at line 39 of file EsIdealFeeTool.h.
EsIdealFeeTool::EsIdealFeeTool | ( | const std::string & | type, | |
const std::string & | name, | |||
const IInterface * | parent | |||
) |
Definition at line 11 of file EsIdealFeeTool.cc.
00014 : GaudiTool(type,name,parent), 00015 m_cableSvc(0) 00016 { 00017 declareInterface< IEsFrontEndTool >(this); 00018 00019 declareProperty("CableSvcName",m_cableSvcName="StaticCableSvc", 00020 "Name of service to map between detector, hardware, and electronic IDs"); 00021 declareProperty("SimDataSvcName",m_simDataSvcName="StaticSimDataSvc", 00022 "Name of service to provide FEE channel properties for simulation"); 00023 declareProperty("SimFrequency", m_simFrequency = DayaBay::TdcFrequencyHz, 00024 "Simulation Frequency"); 00025 declareProperty("ESumFrequency", m_eSumFrequency = DayaBay::EsumFrequencyHz, 00026 "Esum Frequency"); 00027 declareProperty("TriggerWindowCycles", 00028 m_triggerWindowCycles=DayaBay::TriggerWindowCycles, 00029 "Number of trigger window ccyles"); 00030 declareProperty("GainFactor", 00031 m_gainFactor=2., 00032 "Mean PMT gain (in units of 10^7)"); 00033 declareProperty("NoiseAmp",m_noiseAmp=0.5e-3*Gaudi::Units::volt, 00034 "Voltage amplitude of noise"); 00035 declareProperty("SpeAmp",m_speAmp=0.0035, 00036 "Spe pulse height in V at 1e7 gain"); 00037 declareProperty("DiscThreshScale", m_discThreshScale=1, 00038 "Factor to scale all channels' discriminator threshold"); 00039 declareProperty("EnableNonlinearity", m_enableNonlinearity=true, 00040 "Turns on/off all nonlinear effects"); 00041 declareProperty("EnableNoise",m_enableNoise=false,"Turn on/off noise individually"); 00042 declareProperty("EnableDynamicWaveform", m_enableDynamicWaveform=true, 00043 "Turns on/off dynamic waveform individually"); 00044 declareProperty("EnableRinging", m_enableRinging=true, 00045 "Turns on/off ringing individually"); 00046 declareProperty("EnableOvershoot", m_enableOvershoot=true, 00047 "Turns on/off overshoot individually"); 00048 declareProperty("EnableSaturation", m_enableSaturation=true, 00049 "Turns on/off saturation individually"); 00050 declareProperty("EnableAcCoupling", m_enableAcCoupling=true, 00051 "Turns on/off high pass filter before discriminator"); 00052 declareProperty("EnableESumTotal", m_enableESumTotal=true, 00053 "Turns on/off Total ESum simulation"); 00054 declareProperty("EnableESumH", m_enableESumH=true, "Turns on/off upper ESum simulation"); 00055 declareProperty("EnableESumL", m_enableESumL=true, "Turns on/off lower ESum simulation"); 00056 declareProperty("EnableFastSimMode", m_enableFastSimMode=false, 00057 "Turns on/off fast simulation mode to save CPU time"); 00058 declareProperty("PulseCountSlotWidth", m_pulseCountSlotWidth=5e-9*Gaudi::Units::second, 00059 "pulse count time slot size"); 00060 declareProperty("PulseCountWindow", m_pulseCountWindow=2, 00061 "Number of counted slots before and after a pulse"); 00062 declareProperty("LinearityThreshold", m_linearityThreshold=20, 00063 "Threshold in P.E. for activating nonlinear pulse shape"); 00064 declareProperty("EnablePretrigger", m_enablePretrigger=true, 00065 "Turns on/off pretrigger"); 00066 declareProperty("TotalESumTriggerThreshold", 00067 m_eSumTriggerThreshold=DayaBay::Trigger::kADESumThreshold, 00068 "Total ESum trigger threshold as set in TrigSim"); 00069 declareProperty("NHitTriggerThreshold", 00070 m_nHitTriggerThreshold=DayaBay::Trigger::kADthreshold, 00071 "nHit trigger threshold as set in TrigSim"); 00072 declareProperty("ADCOffset", m_adcOffset = 500, "Esum Frequency"); 00073 declareProperty("ADCRange", m_adcRange = 1, "Esum Range"); 00074 declareProperty("ADCBits", m_adcBits = 10, "Esum Bits"); 00075 }
EsIdealFeeTool::~EsIdealFeeTool | ( | ) | [virtual] |
StatusCode EsIdealFeeTool::generateSignals | ( | DayaBay::ElecPulseCollection * | , | |
DayaBay::ElecCrate * | ||||
) | [virtual] |
This is the extension. Sub classes must provide it.
Implements IEsFrontEndTool.
Definition at line 166 of file EsIdealFeeTool.cc.
00168 { 00169 // Ensure that crate is a FeeCrate 00170 DayaBay::ElecFeeCrate* crate = 0; 00171 crate = dynamic_cast<DayaBay::ElecFeeCrate*>(elecCrate); 00172 if(crate == NULL){ 00173 error() << "generateSignals(): Crate is not a FEE Crate." << endreq; 00174 return StatusCode::FAILURE; 00175 } 00176 00177 // Context, ServiceMode for this data 00178 Context context(pulses->detector().site(), SimFlag::kMC, 00179 pulses->header()->header()->timeStamp(), 00180 pulses->detector().detectorId()); 00181 int task = 0; 00182 ServiceMode svcMode(context, task); 00183 00184 // Initialize crate if necessary 00185 if(crate->channelData().size() == 0){ 00186 // First, get list of all connected FEE channels 00187 const std::vector<DayaBay::DetectorSensor>& pmtList 00188 = m_cableSvc->sensors( svcMode ); 00189 int nPmts = pmtList.size(); 00190 for(int pmtIdx = 0; pmtIdx < nPmts; pmtIdx++){ 00191 // Add channel to crate 00192 DayaBay::FeeChannelId channelId(m_cableSvc->elecChannelId(pmtList[pmtIdx], svcMode).fullPackedData()); 00193 crate->addChannel(channelId); 00194 verbose() << "Adding channel to crate: " << channelId << endreq; 00195 } 00196 } 00197 00198 // Prepare time range of the simulation 00199 TimeStamp earliest = pulses->header()->header()->earliest(); 00200 TimeStamp latest = pulses->header()->header()->latest(); 00201 // The time window for the crate signals 00202 double simTime = latest - earliest; 00203 verbose() << "Simulation time is " << simTime << endreq; 00204 // The number of samples in time given the simulation frequency 00205 int simSamples = int(simTime * m_simFrequency); 00206 verbose() << "Simulation has " << simSamples << " samples at frequency " 00207 << m_simFrequency << " Hz" << endreq; 00208 00209 // Compute time windows that will possibly be readout 00210 int nTimeSlices = int(simTime / 150e-9 + 0.5); 00211 //std::vector<int> hitCountSlices(nTimeSlices,0); 00212 //int* hitCountSlices = new int[nTimeSlices]; 00213 int hitCountSlices[nTimeSlices]; 00214 for ( int i = 0; i < nTimeSlices; ++i ) hitCountSlices[i] = 0; 00215 00216 // Organize Pulses by Channel 00217 std::map<DayaBay::ElecChannelId, std::vector<DayaBay::ElecPmtPulse*> > pulseMap; 00218 StatusCode sc; 00219 sc = mapPulsesByChannel( pulses->pulses(), pulseMap, hitCountSlices ); 00220 if(sc.isFailure()) return sc; 00221 debug() << "Mapped Pulses" << endreq; 00222 00223 // Pretrigger: 00224 // Compute map of time windows that will possibly read out 00225 m_adcConvolutionWindows.clear(); 00226 m_esumConvolutionWindows.clear(); 00227 int adcConvStart, adcConvEnd; 00228 int esumConvStart, esumConvEnd; 00229 std::map<int,int>::reverse_iterator sliceIt; 00230 for(int i = 1; i < nTimeSlices; i++){ 00231 if( hitCountSlices[i] + hitCountSlices[i-1] < m_pretriggerThreshold ) continue; 00232 if (i - 5 < 0) adcConvStart = 0; 00233 else adcConvStart = (i - 5); 00234 if (i - 1 < 0) esumConvStart = 0; 00235 else esumConvStart = (i - 1); 00236 00237 if (i + 5 > nTimeSlices) adcConvEnd = nTimeSlices; 00238 else adcConvEnd = (i + 5); 00239 if (i + 1 > nTimeSlices) esumConvEnd = nTimeSlices; 00240 else esumConvEnd = (i + 1); 00241 00242 if( m_adcConvolutionWindows.empty() ) { 00243 m_adcConvolutionWindows[adcConvStart] = adcConvEnd; 00244 m_esumConvolutionWindows[esumConvStart] = esumConvEnd; 00245 continue; 00246 } 00247 sliceIt = m_adcConvolutionWindows.rbegin(); 00248 if( (adcConvStart - sliceIt->second > 2) ) 00249 m_adcConvolutionWindows[adcConvStart ] = adcConvEnd; 00250 else 00251 m_adcConvolutionWindows[sliceIt->first] = adcConvEnd; 00252 00253 sliceIt = m_esumConvolutionWindows.rbegin(); 00254 if( (esumConvStart - sliceIt->second > 2) ) 00255 m_esumConvolutionWindows[esumConvStart ] = esumConvEnd; 00256 else 00257 m_esumConvolutionWindows[sliceIt->first] = esumConvEnd; 00258 } 00259 debug() << "Number of time windows to be possibly read out: " << m_adcConvolutionWindows.size() << endreq; 00260 00261 // If no time windows is considered of possible interest, skip the entire event 00262 if(m_adcConvolutionWindows.size()==0 && m_enablePretrigger) { 00263 debug() << "Event below pretrigger threshold, no waveform simulation" << endreq; 00264 return StatusCode::SUCCESS; 00265 } 00266 00267 // Loop over channels, and fill with the simulated signals 00268 const DayaBay::ElecFeeCrate::ChannelData& channelData = crate->channelData(); 00269 DayaBay::ElecFeeCrate::ChannelData::const_iterator channelIter, 00270 done = channelData.end(); 00271 for(channelIter = channelData.begin(); channelIter != done; ++channelIter){ 00272 DayaBay::FeeChannelId channelId = channelIter->first; 00273 DayaBay::ElecFeeChannel& channel = crate->channel(channelId); 00274 00275 //Fill each channel with signals 00276 sc = generateOneChannel(channelId, pulseMap[channelId], channel, 00277 simTime, svcMode); 00278 if( !sc.isSuccess() ) return sc; 00279 00280 } // End loop over channels 00281 00282 StatusCode status = updateBoardSignals(crate); 00283 if (status.isFailure()) return status; 00284 status = updateEsumSignals(crate); 00285 if (status.isFailure()) return status; 00286 00287 verbose() << "Crate\n" << *crate << endreq; 00288 00289 return StatusCode::SUCCESS; 00290 }
StatusCode EsIdealFeeTool::initialize | ( | ) | [virtual] |
Reimplemented from GaudiTool.
Definition at line 79 of file EsIdealFeeTool.cc.
00080 { 00081 // Get Cable Service 00082 m_cableSvc = svc<ICableSvc>(m_cableSvcName,true); 00083 00084 // Get PMT simulation input data service 00085 m_simDataSvc = svc<ISimDataSvc>(m_simDataSvcName,true); 00086 00087 StatusCode sc = loadResponse(); 00088 if(sc.isFailure()) return sc; 00089 00090 // Random number service 00091 IRndmGenSvc *rgs = 0; 00092 if (service("RndmGenSvc",rgs,true).isFailure()) { 00093 fatal() << "Failed to get random service" << endreq; 00094 return StatusCode::FAILURE; 00095 } 00096 00097 sc = m_gauss.initialize(rgs, Rndm::Gauss(0,1)); 00098 if (sc.isFailure()) { 00099 fatal() << "Failed to initialize gaussian random numbers" << endreq; 00100 return StatusCode::FAILURE; 00101 } 00102 // Set up pretrigger threshold 00103 int preThr = int(0.8 * m_nHitTriggerThreshold + 0.5); 00104 int esumPreThr = int (0.8 * 1500 * m_eSumTriggerThreshold/Gaudi::Units::volt + 0.5); 00105 if(preThr > esumPreThr) preThr = esumPreThr; 00106 m_pretriggerThreshold = preThr; 00107 if( m_enablePretrigger ){ 00108 info() << "Pretrigger threshold is " << m_pretriggerThreshold << " pe " << endreq; 00109 } 00110 else { 00111 info() << "Pretrigger disabled" << endreq; 00112 info() << "Convolution threshold is " << m_pretriggerThreshold << " pe " << endreq; 00113 } 00114 00115 if( m_enableFastSimMode){ 00116 info() << "Fast electronics simulation mode enabled: Note that Upper and Lower ESum trigger do not yield meaningful results" << endreq; 00117 m_linearityThreshold = 100000; 00118 m_enableESumH = false; 00119 m_enableESumL = false; 00120 } 00121 if( !m_enableNonlinearity ) { 00122 info() << "All nonlinear effects disabled." << endreq; 00123 m_enableOvershoot = false; 00124 m_enableSaturation = false; 00125 m_enableRinging = false; 00126 m_enableDynamicWaveform = false; 00127 m_enableAcCoupling = false; 00128 } 00129 else { 00130 info() << "Nonlinear model enabled for channels with more than " 00131 << m_linearityThreshold << " hits " << endreq; 00132 00133 if( !m_enableAcCoupling ) 00134 info() << "AC coupling disabled" << endreq; 00135 else 00136 debug() << "AC coupling enabled" << endreq; 00137 00138 if( !m_enableOvershoot ) 00139 info() << "Overshoot disabled" << endreq; 00140 else 00141 debug() << "Overshoot enabled" << endreq; 00142 00143 if( !m_enableRinging ) 00144 info() << "Ringing disabled" << endreq; 00145 else 00146 debug() << "Ringing enabled" << endreq; 00147 00148 if( !m_enableSaturation ) 00149 info() << "Saturation disabled" << endreq; 00150 else 00151 debug() << "Saturation enabled" << endreq; 00152 00153 if( !m_enableDynamicWaveform ) 00154 info() << "Dynamic waveform disabled" << endreq; 00155 else 00156 debug() << "Dynamic waveform enabled" << endreq; 00157 } 00158 return StatusCode::SUCCESS; 00159 }
StatusCode EsIdealFeeTool::finalize | ( | ) | [virtual] |
Reimplemented from GaudiTool.
Definition at line 161 of file EsIdealFeeTool.cc.
00162 { 00163 return StatusCode::SUCCESS; 00164 }
StatusCode EsIdealFeeTool::loadResponse | ( | ) | [private] |
Definition at line 578 of file EsIdealFeeTool.cc.
00578 { 00579 // SJ: Load the CR-(RC)^4 response data 00580 double dT_seconds = (1. / m_simFrequency); 00581 double dT_units = dT_seconds*CLHEP::second; 00582 int nShapingSamples = int(DayaBay::preTimeTolerance/dT_units); 00583 int nPulseSamples = 3*nShapingSamples; 00584 int nRingingSamples = int(DayaBay::postTimeTolerance/dT_units); 00585 m_shapingResponse.resize(nShapingSamples); 00586 m_esumResponse.resize(nPulseSamples); 00587 m_pmtPulse.resize(nPulseSamples); 00588 m_pmtPulse_noOvershoot.resize(nPulseSamples); 00589 m_ringing.resize(nRingingSamples); 00590 m_shapingSum = 0; 00591 m_esumShapingSum = 0; 00592 m_pulseMax = 0; 00593 00594 for (int i=0; i<nShapingSamples; i++) { 00595 m_shapingResponse[i] = pulseShaping(i*dT_seconds); 00596 m_shapingSum += m_shapingResponse[i]; 00597 } 00598 00599 for (int i=0; i<nPulseSamples; i++){ 00600 m_esumResponse[i] = esumShaping(i*dT_units/CLHEP::nanosecond); 00601 m_esumShapingSum += m_esumResponse[i]; 00602 } 00603 00604 for (int i=0; i<nPulseSamples; i++) { 00605 m_pmtPulse[i] = pmtPulse(i*dT_seconds,1,true); 00606 m_pmtPulse_noOvershoot[i] = pmtPulse(i*dT_seconds,1,false); 00607 // Keep track of 00608 if( m_pmtPulse[i] < m_pulseMax ) m_pulseMax = m_pmtPulse[i]; 00609 00610 } 00611 // Invert to be a positive-voltage peak 00612 m_pulseMax *= -1; 00613 00614 for (int i=0; i<nRingingSamples; i++) { 00615 m_ringing[i] = ringing(i*dT_seconds, m_pulseMax); 00616 } 00617 00618 // Convolve the pmt pulse with the CR-(RC)^4 shaping response 00619 convolve( m_pmtPulse, m_shapingResponse, m_shapedPmtPulse ); 00620 m_shapedPmtPulse.resize( m_pmtPulse.size() ); 00621 convolve( m_pmtPulse_noOvershoot, m_shapingResponse, m_shapedPmtPulse_noOvershoot ); 00622 m_shapedPmtPulse_noOvershoot.resize( m_pmtPulse.size() ); 00623 // Scale the resulting convolution to preserve the pulse area 00624 for(unsigned int i=0; i < m_pmtPulse.size(); i++) { 00625 m_shapedPmtPulse[i] /= m_shapingSum; 00626 m_shapedPmtPulse_noOvershoot[i] /= m_shapingSum; 00627 } 00628 // Convolve the ringing with the CR-(RC)^4 shaping response 00629 convolve( m_ringing, m_shapingResponse, m_shapedRinging ); 00630 m_shapedRinging.resize( m_ringing.size() ); 00631 // Scale the resulting convolution to preserve normalization 00632 for(unsigned int i=0; i < m_shapedRinging.size(); i++) 00633 m_shapedRinging[i] /= m_shapingSum; 00634 00635 // Dump ideal pulse shapes 00636 { 00637 std::stringstream output; 00638 output << "pmtPulse = [ "; 00639 for(int i=0; i<nPulseSamples; i++){ 00640 if(i!=0) output << ", "; 00641 output << m_pmtPulse[i]; 00642 } 00643 output << " ]"; 00644 verbose() << output.str() << endreq; 00645 } 00646 00647 { 00648 std::stringstream output; 00649 output << "Esum Shaping Pulse = [ "; 00650 for(int i=0; i<nPulseSamples; i++){ 00651 if(i!=0) output << ", "; 00652 output << m_esumResponse[i]; 00653 } 00654 output << " ]"; 00655 verbose() << output.str() << endreq; 00656 } 00657 00658 { 00659 std::stringstream output; 00660 output << "ringing = [ "; 00661 for(int i=0; i<nRingingSamples; i++){ 00662 if(i!=0) output << ", "; 00663 output << m_ringing[i]; 00664 } 00665 output << " ]"; 00666 verbose() << output.str() << endreq; 00667 } 00668 { 00669 std::stringstream output; 00670 output << "shapedPmtPulse = [ "; 00671 for(int i=0; i<nPulseSamples; i++){ 00672 if(i!=0) output << ", "; 00673 output << m_shapedPmtPulse[i]; 00674 } 00675 output << " ]"; 00676 verbose() << output.str() << endreq; 00677 } 00678 { 00679 std::stringstream output; 00680 output << "shapedRinging = [ "; 00681 for(int i=0; i<nRingingSamples; i++){ 00682 if(i!=0) output << ", "; 00683 output << m_shapedRinging[i]; 00684 } 00685 output << " ]"; 00686 verbose() << output.str() << endreq; 00687 } 00688 00689 return StatusCode::SUCCESS; 00690 }
StatusCode EsIdealFeeTool::mapPulsesByChannel | ( | const DayaBay::ElecPulseCollection::PulseContainer & | pulses, | |
std::map< DayaBay::ElecChannelId, std::vector< DayaBay::ElecPmtPulse * > > & | pulseMap, | |||
int * | hitCountSlices | |||
) | [private] |
Definition at line 692 of file EsIdealFeeTool.cc.
00696 { 00697 debug() << "Processing " << pulses.size() << " pmt pulses." << endreq; 00698 DayaBay::ElecPulseCollection::PulseContainer::const_iterator it, 00699 pulseDone = pulses.end(); 00700 int timeSliceNo; 00701 // loop over pulses in collection 00702 for (it=pulses.begin(); it != pulseDone; ++it) { 00703 DayaBay::ElecPmtPulse* pulse = dynamic_cast<DayaBay::ElecPmtPulse*>(*it); 00704 if(pulse == NULL){ 00705 // Catch invalid pulses 00706 error() << "mapPulsesByChannel(): bad pulse." << endreq; 00707 return StatusCode::FAILURE; 00708 } 00709 (pulseMap[pulse->channelId()]).push_back(pulse); 00710 timeSliceNo = int( pulse->time()/150. - 0.5 ); 00711 hitCountSlices[timeSliceNo]+=int(pulse->amplitude()+0.5); 00712 } 00713 return StatusCode::SUCCESS; 00714 }
StatusCode EsIdealFeeTool::updateBoardSignals | ( | DayaBay::ElecFeeCrate * | crate | ) | [private] |
Definition at line 716 of file EsIdealFeeTool.cc.
00717 { 00718 // Update the board Nhit and Esum info, according to the current 00719 // channel info 00720 00721 DayaBay::ElecFeeCrate::DigitalMap& nhitMap = crate->nhit(); 00722 DayaBay::ElecFeeCrate::AnalogMap& esumMap = crate->esum(); 00723 00724 // Loop over channels, and add data to the board-level signals 00725 const DayaBay::ElecFeeCrate::ChannelData& channelData = crate->channelData(); 00726 DayaBay::ElecFeeCrate::ChannelData::const_iterator channelIter, 00727 done = channelData.end(); 00728 for(channelIter = channelData.begin(); channelIter != done; ++channelIter){ 00729 DayaBay::FeeChannelId channelId = channelIter->first; 00730 const DayaBay::ElecFeeChannel& channel = channelIter->second; 00731 const DayaBay::DigitalSignal& hit = channel.hit(); 00732 const DayaBay::AnalogSignal& energy = channel.energy(); 00733 DayaBay::DigitalSignal& boardNhit = nhitMap[channelId.boardId()]; 00734 DayaBay::AnalogSignal& boardEsum = esumMap[channelId.boardId()]; 00735 00736 unsigned int hitSamples = hit.size(); 00737 00738 // Create hitSync to mimic the syncronized discriminator output 00739 //DayaBay::DigitalSignal hitSync( hitSamples,0); 00740 if( m_hitSync.size() != hitSamples ) m_hitSync.resize( hitSamples ); 00741 const int* hitStart = &hit[0]; 00742 int* hitSyncStart = &m_hitSync[0]; 00743 *hitSyncStart = 0; // Set first sample to zero 00744 for (unsigned int i=1; i< hitSamples; i++){ 00745 int* curHitSync = hitSyncStart + i; 00746 int* lastHitSync = curHitSync - 1; 00747 const int* curHit = hitStart + i; 00748 const int* lastHit = curHit - 1; 00749 if( *lastHitSync==0 && *lastHit==0 && *curHit==1 ) *curHitSync = 1; 00750 else *curHitSync = 0; 00751 } 00752 00753 // The logic pulse from the channel level hit is extended for 00754 // multiple clock cycles (triggerWindowCycles) before going to the 00755 // trigger. 00756 //DayaBay::DigitalSignal hitHold( hitSamples , 0 ); 00757 if( m_hitHold.size() != hitSamples ) m_hitHold.resize( hitSamples ); 00758 int* hitHoldStart = &m_hitHold[0]; 00759 for (unsigned int i=0; i< hitSamples; i++) *(hitHoldStart + i) = 0; 00760 00761 if( boardNhit.size() != hitSamples ){ 00762 boardNhit.resize( hitSamples ); 00763 int* boardNhitStart = &boardNhit[0]; 00764 for (unsigned int i=0; i< hitSamples; i++) *(boardNhitStart + i) = 0; 00765 } 00766 00767 for( unsigned int idx = 0; idx < hitSamples; idx++ ){ 00768 unsigned int tempIdx = 0; 00769 if( *(hitSyncStart+idx) != 0 ){ 00770 for( int holdIdx = 0; holdIdx < m_triggerWindowCycles; holdIdx++ ){ 00771 unsigned int currentIdx = idx + holdIdx; 00772 if( currentIdx < hitSamples ) *(hitHoldStart + currentIdx) = 1; 00773 tempIdx++; 00774 } 00775 if(tempIdx !=0) idx = idx +tempIdx-1 ; 00776 } // End hit 00777 } 00778 00779 { 00780 int* boardNhitStart = &boardNhit[0]; 00781 for(unsigned int idx = 0; idx < hitSamples; idx++) 00782 *(boardNhitStart + idx) += *(hitHoldStart + idx); 00783 } 00784 verbose() << "boardNhit " << boardNhit << endreq; 00785 00786 // Add channel energy to board esum 00787 unsigned int esumSamples = energy.size(); 00788 if( boardEsum.size() != esumSamples ){ 00789 boardEsum.resize( esumSamples ); 00790 double* boardEsumStart = &boardEsum[0]; 00791 for (unsigned int i=0; i< esumSamples; i++) *(boardEsumStart + i) = 0; 00792 } 00793 const double* energyStart = &energy[0]; 00794 double* boardEsumStart = &boardEsum[0]; 00795 for( unsigned int idx = 0; idx < esumSamples; idx++ ){ 00796 *(boardEsumStart + idx) += *(energyStart + idx); 00797 } 00798 00799 // warning() << "board esum " << boardEsum << endreq; 00800 // warning() << "energy " << energy << endreq; 00801 00802 } // End loop over channels 00803 00804 return StatusCode::SUCCESS; 00805 }
StatusCode EsIdealFeeTool::updateEsumSignals | ( | DayaBay::ElecFeeCrate * | crate | ) | [private] |
Definition at line 807 of file EsIdealFeeTool.cc.
00807 { 00808 // Loop over all boards in map 00809 DayaBay::ElecFeeCrate::AnalogMap& esumMap = crate->esum(); 00810 DayaBay::ElecFeeCrate::AnalogMap::iterator boardIt = esumMap.begin(); 00811 00812 // Clear transient stores from previous Execution cycles 00813 m_esumH.clear(); 00814 m_esumL.clear(); 00815 m_esumTotal.clear(); 00816 00817 for (;boardIt != esumMap.end(); ++boardIt) 00818 { 00819 DayaBay::FeeChannelId boardId = boardIt->first; 00820 DayaBay::AnalogSignal& boardEnergy = boardIt->second; 00821 int boardNum = boardId.board(); 00822 00823 if( m_esumL.size() != boardEnergy.size() ){ 00824 m_esumL.resize( boardEnergy.size() ); 00825 } 00826 00827 if( m_esumH.size() != boardEnergy.size() ){ 00828 m_esumH.resize( boardEnergy.size() ); 00829 } 00830 00831 if( m_esumTotal.size() != boardEnergy.size() ){ 00832 m_esumTotal.resize( boardEnergy.size() ); 00833 } 00834 00835 debug() << "board number " << boardNum << endreq; 00836 debug() << "Low Esum size " << m_esumL.size() << endreq; 00837 debug() << "board Energy size " << boardEnergy.size() << endreq; 00838 00839 int boardIdx = boardEnergy.size(); 00840 double* boardEsumStart = &boardEnergy[0]; 00841 double* esumHStart = &m_esumH[0]; 00842 double* esumLStart = &m_esumL[0]; 00843 double* esumTtart = &m_esumTotal[0]; 00844 00845 for( int i = 0; i < boardIdx; i++) 00846 { 00847 // update Upper Sum and total sum 00848 if (boardEsumType(boardNum) == DayaBay::ESumComp::kESumHigh){ 00849 *(esumHStart+i) += *(boardEsumStart+i); 00850 *(esumTtart+i) += *(boardEsumStart+i); 00851 //m_esumH[i] += boardEnergy[i]; 00852 //m_esumTotal[i] += boardEnergy[i]; 00853 } 00854 00855 // update Lower Sum and total sum 00856 if (boardEsumType(boardNum) == DayaBay::ESumComp::kESumLow){ 00857 *(esumLStart+i) += *(boardEsumStart+i); 00858 *(esumTtart+i) += *(boardEsumStart+i); 00859 //m_esumL[i] += boardEnergy[i]; 00860 //m_esumTotal[i] += boardEnergy[i]; 00861 } 00862 } 00863 00864 00865 }// END LOOP over boards 00866 00867 00868 verbose() << "Lower ESum " << m_esumL << endreq; 00869 verbose() << "Total ESum " << m_esumTotal << endreq; 00870 00871 // Shape Upper Sum 00872 if(m_enableESumH) { 00873 verbose() << "Upper ESum " << m_esumH << endreq; 00874 shape( m_esumH, m_shapedEsumH, m_esumResponse, m_esumConvolutionWindows ); 00875 m_shapedEsumH.resize( m_esumH.size() ); 00876 00877 // NOTE: They should all be the same lenght so if we need to speed things up 00878 // we could resacle all 3 in the same loop... 00879 00880 // rescale after convolution 00881 double* esumHStart = &m_shapedEsumH[0]; 00882 00883 for(unsigned int i=0; i < m_shapedEsumH.size(); i++) 00884 { 00885 *(esumHStart+i) /= m_esumShapingSum; 00886 //m_shapedEsumH[i] /= m_esumShapingSum; 00887 } 00888 00889 // sample down to appropriate frequency and add to header 00890 sample( m_shapedEsumH, crate->esumUpper(), 00891 m_simFrequency, m_eSumFrequency ); 00892 00893 verbose() << "Shaped upper sum " << crate->esumUpper() << endreq; 00894 } 00895 else { 00896 m_shapedEsumH.resize( m_esumH.size() ); 00897 crate->setEsumUpper(m_shapedEsumH); 00898 } 00899 // Shape Lower Sum 00900 if(m_enableESumL) { 00901 shape( m_esumL, m_shapedEsumL, m_esumResponse, m_esumConvolutionWindows ); 00902 m_shapedEsumL.resize( m_esumL.size() ); 00903 00904 // rescale after convolution 00905 double* esumLStart = &m_shapedEsumL[0]; 00906 00907 for(unsigned int i=0; i < m_shapedEsumL.size(); i++) 00908 { 00909 *(esumLStart+i) /= m_esumShapingSum; 00910 //m_shapedEsumL[i] /= m_esumShapingSum; 00911 } 00912 00913 // sample down to appropriate frequency and add to header 00914 sample( m_shapedEsumL, crate->esumLower(), 00915 m_simFrequency, m_eSumFrequency ); 00916 00917 verbose() << "Shaped lower sum " << crate->esumLower() << endreq; 00918 } 00919 else { 00920 m_shapedEsumL.resize( m_esumL.size() ); 00921 crate->setEsumLower(m_shapedEsumL); 00922 } 00923 // Shape Total Sum 00924 if(m_enableESumTotal) { 00925 shape( m_esumTotal, m_shapedEsumTotal, m_esumResponse, m_esumConvolutionWindows ); 00926 m_shapedEsumTotal.resize( m_esumTotal.size() ); 00927 00928 // rescale after convolution 00929 double* esumTstart = &m_shapedEsumTotal[0]; 00930 00931 for(unsigned int i=0; i < m_shapedEsumTotal.size(); i++) 00932 { 00933 *(esumTstart+i) /= m_esumShapingSum; 00934 //m_shapedEsumTotal[i] /= m_esumShapingSum; 00935 } 00936 00937 // sample down to appropriate frequency and add to header 00938 sample( m_shapedEsumTotal, crate->esumTotal(), 00939 m_simFrequency, m_eSumFrequency ); 00940 00941 verbose() << "Shaped total sum " << crate->esumTotal() << endreq; 00942 } 00943 else { 00944 m_shapedEsumTotal.resize( m_esumTotal.size() ); 00945 crate->setEsumTotal(m_shapedEsumTotal); 00946 } 00947 //Digitize the shaped total sum 00948 //FIXME: This needs to be fixed (edraeger@iit.edu) 00949 // set as properties and/or get from service 00950 digitize(crate->esumTotal(), crate->esumADC(), m_adcRange, m_adcBits, m_adcOffset); 00951 00952 verbose() << "Digitized signal " << crate->esumADC() << endreq; 00953 00954 return StatusCode::SUCCESS; 00955 }
StatusCode EsIdealFeeTool::generateOneChannel | ( | const DayaBay::FeeChannelId & | , | |
std::vector< DayaBay::ElecPmtPulse * > & | , | |||
DayaBay::ElecFeeChannel & | , | |||
double | simTime, | |||
const ServiceMode & | ||||
) | [private, virtual] |
Definition at line 292 of file EsIdealFeeTool.cc.
00298 { 00299 // Generate the FEE signals caused by the PMT pulses for one channel 00300 00301 // Get the simulation properties for this channel 00302 const DayaBay::FeeSimData* feeSimData = 00303 m_simDataSvc->feeSimData(channelId, svcMode); 00304 if(!feeSimData){ 00305 error() << "No Simulation input properties for FEE channel: " 00306 << channelId << endreq; 00307 return StatusCode::FAILURE; 00308 } 00309 00310 // The number of samples in time given the simulation frequency 00311 unsigned int simSamples = int(simTime * m_simFrequency); 00312 00313 // Prepare Raw Signal 00314 if(m_rawSignal.size() != simSamples) m_rawSignal.resize( simSamples ); 00315 if(m_discriminatorSignal.size() != simSamples) m_discriminatorSignal.resize( simSamples ); 00316 if(m_shapedSignal.size() != simSamples) m_shapedSignal.resize( simSamples ); 00317 double* rawStart = &m_rawSignal[0]; 00318 double* discriminatorStart = &m_discriminatorSignal[0]; 00319 double* shapedStart = &m_shapedSignal[0]; 00320 for( unsigned int sigIdx = 0; sigIdx!=simSamples; sigIdx++){ 00321 *(rawStart + sigIdx) = 0; 00322 *(discriminatorStart + sigIdx) = 0; 00323 *(shapedStart + sigIdx) = 0; 00324 } 00325 00326 // Add noise to raw signal if requested 00327 if( m_enableNoise ){ 00328 for(unsigned int index=0; index < simSamples; index++){ 00329 *(rawStart + index) += noise(); 00330 *(discriminatorStart + index) += noise(); 00331 } 00332 } 00333 00334 // Pulses on this channel? 00335 if( channelPulses.size() > 0 ){ 00336 verbose() << "Channel " << channelId << " has " << channelPulses.size() 00337 << " pulses." << endreq; 00338 // Use linear or nonlinear pulse shapes? 00339 if( m_enableNonlinearity && (channelPulses.size() > m_linearityThreshold) ){ 00340 // Use nonlinear pulse shape 00341 00342 verbose() << "Applying nonlinearity:" << channelPulses.size() 00343 << " pulses (threshold=" << m_linearityThreshold << ")" 00344 << endreq; 00345 00346 // SJ: Prepare time slots for pulse counting 00347 int numPulseTimeSlots = int(simTime*Gaudi::Units::second 00348 /m_pulseCountSlotWidth) + 1; 00349 verbose() << "Number of time slots for afterpulse counting = " 00350 << numPulseTimeSlots << std::endl; 00351 std::vector<int> pulseTimeSlots(numPulseTimeSlots); 00352 00353 // SJ: Fill pulse count time slots 00354 // Count the number of pulses for each time slot to model nonlinearity 00355 for (int i = 0; i < numPulseTimeSlots; i++ ) pulseTimeSlots[i] = 0; 00356 std::vector<DayaBay::ElecPmtPulse*>::const_iterator pulseIter, pulseDone 00357 = channelPulses.end(); 00358 for(pulseIter=channelPulses.begin(); pulseIter != pulseDone; ++pulseIter){ 00359 DayaBay::ElecPmtPulse* pulse = *pulseIter; 00360 int timeSlot = int(pulse->time() * Gaudi::Units::nanosecond 00361 / m_pulseCountSlotWidth); 00362 int pulseNo = int(pulse->amplitude()+0.5); 00363 pulseTimeSlots[timeSlot]+=pulseNo; 00364 verbose() << "Added " << pulseNo << " pulses in time slot " << timeSlot << endreq; 00365 } 00366 00367 // Loop over pulses, add each to raw signal 00368 for(pulseIter=channelPulses.begin(); pulseIter != pulseDone; ++pulseIter){ 00369 DayaBay::ElecPmtPulse* pulse = *pulseIter; 00370 int tOffset = int(pulse->time()*1e-9 * m_simFrequency); 00371 float amplitude = pulse->amplitude(); 00372 00373 // SJ: Fill pulse time slots 00374 // Count the total number of pulses within a nearby time window 00375 // This number of pulses is used to determine the nonlinearity 00376 int nPulse=0; 00377 int timeSlot = int(pulse->time() * Gaudi::Units::nanosecond 00378 / m_pulseCountSlotWidth); 00379 for (int i = timeSlot - m_pulseCountWindow; 00380 i <= timeSlot + m_pulseCountWindow; i++){ 00381 if(i>=0 && i<numPulseTimeSlots) nPulse += pulseTimeSlots[i]; 00382 } 00383 verbose() << "Number of pulses in time window: " << nPulse << endreq; 00384 00385 // Now add pulses to the raw signal 00386 int nPulseSamples = m_pmtPulse.size(); 00387 for(int index = 0; index < nPulseSamples; index++){ 00388 unsigned int sampleIdx = tOffset + index; 00389 double idxTime = index * (1. / m_simFrequency); 00390 if(sampleIdx>0 && sampleIdx<simSamples){ 00391 // SJ: Add pulses to raw signal 00392 if( m_enableDynamicWaveform ){ 00393 m_rawSignal[sampleIdx] += - amplitude * pmtPulse( idxTime, nPulse, m_enableOvershoot ); 00394 m_discriminatorSignal[sampleIdx] += - amplitude * pmtPulse( idxTime, nPulse, false ); 00395 }else{ 00396 if(m_enableOvershoot) m_rawSignal[sampleIdx] += - amplitude * m_pmtPulse[index]; 00397 else m_rawSignal[sampleIdx] += - amplitude * m_pmtPulse_noOvershoot[index]; 00398 m_discriminatorSignal[sampleIdx] += - amplitude * m_pmtPulse_noOvershoot[index]; 00399 } 00400 } 00401 } 00402 } // End loop over pulses 00403 00404 // Add saturation and ringing to the raw signal 00405 if( (channelPulses.size() > 0) 00406 && (m_enableSaturation || m_enableRinging) ){ 00407 // Determine the raw signal maximum for use in ringing 00408 // At the same time, add saturation if needed 00409 //double rawMax; 00410 double rawMax; 00411 int maxSample; 00412 rawMax = 0; 00413 for (unsigned int index=0; index<simSamples; index++) { 00414 // SJ: Simulate saturation of the raw signal 00415 if( m_rawSignal[index] > rawMax ) { 00416 rawMax = m_rawSignal[index]; 00417 maxSample = index; 00418 } 00419 if(m_enableSaturation){ 00420 m_rawSignal[index] *= satFactor(m_rawSignal[index]); 00421 m_discriminatorSignal[index] *= satFactor(m_discriminatorSignal[index]); 00422 } 00423 } 00424 00425 // Add ringing if requested 00426 if( m_enableRinging && rawMax != 0 ){ 00427 for (unsigned int index=maxSample; index<simSamples; index++) { 00428 double idxTime = index * (1. / m_simFrequency); 00429 m_rawSignal[index] += - ringing ( idxTime, rawMax ); 00430 } 00431 } 00432 } // End of saturation and ringing 00433 00434 // Generate non-linear shaped signal 00435 shape(m_rawSignal,m_shapedSignal,m_shapingResponse,m_adcConvolutionWindows); 00436 m_shapedSignal.resize( simSamples ); 00437 // SJ: Scale the resulting convolution to preserve the pulse area 00438 for(unsigned int index=0; index < simSamples; index++) { 00439 m_shapedSignal[index] /= m_shapingSum; 00440 } 00441 // End non-linear pulse addition 00442 00443 }else{ 00444 // Use linear pulse shape 00445 00446 double* pmtPulseStart; 00447 if(m_enableOvershoot) pmtPulseStart = &m_pmtPulse[0]; 00448 else pmtPulseStart = &m_pmtPulse_noOvershoot[0]; 00449 double* pmtDiscriminatorPulseStart = &m_pmtPulse_noOvershoot[0]; 00450 double* shapedPmtPulseStart = &m_shapedPmtPulse[0]; 00451 double* ringingStart = &m_ringing[0]; 00452 double* shapedRingingStart = &m_shapedRinging[0]; 00453 00454 // Loop over pulses 00455 std::vector<DayaBay::ElecPmtPulse*>::const_iterator pulseIter, pulseDone 00456 = channelPulses.end(); 00457 for(pulseIter=channelPulses.begin(); pulseIter != pulseDone; ++pulseIter){ 00458 DayaBay::ElecPmtPulse* pulse = *pulseIter; 00459 int tOffset = int(pulse->time()*1e-9 * m_simFrequency); 00460 float amplitude = pulse->amplitude(); 00461 00462 // Now add pulses to the raw and shaped signals 00463 int nPulseSamples = m_pmtPulse.size(); 00464 for(int index = 0; index < nPulseSamples; index++){ 00465 unsigned int sampleIdx = tOffset + index; 00466 00467 if(sampleIdx>0 && sampleIdx<simSamples){ 00468 *(rawStart + sampleIdx) -= amplitude * (*(pmtPulseStart + index)); 00469 *(discriminatorStart + sampleIdx) -= amplitude * (*(pmtDiscriminatorPulseStart + index)); 00470 *(shapedStart + sampleIdx) -= amplitude * (*(shapedPmtPulseStart+index)); 00471 } 00472 } 00473 } // End loop over pulses 00474 00475 // Add ringing to the raw signal 00476 if( (channelPulses.size() > 0) && (m_enableSaturation || m_enableRinging) ){ 00477 // Determine the raw signal maximum for use in ringing 00478 // At the same time, add saturation if needed 00479 double rawMax; 00480 int maxSample; 00481 rawMax = 0; 00482 for (unsigned int index=0; index<simSamples; index++) { 00483 double* curValue = rawStart + index; 00484 if( *curValue > rawMax ) { 00485 rawMax = *curValue; 00486 maxSample = index; 00487 } 00488 if(m_enableFastSimMode && m_enableSaturation){ 00489 *(rawStart + index) *= satFactor(*(rawStart + index)); 00490 *(rawStart + index) *= satFactor(-10 * (*(rawStart + index))); 00491 } 00492 } 00493 // Add ringing and/or saturation if requested 00494 if( m_enableRinging && rawMax != 0 ){ 00495 unsigned int ringEnd = m_ringing.size(); 00496 double ringScaling = -rawMax / m_pulseMax; 00497 if( ringEnd + maxSample > simSamples ) 00498 ringEnd = simSamples - maxSample; 00499 for (unsigned int ringIdx=0; ringIdx<ringEnd; ringIdx++) { 00500 int index = maxSample + ringIdx; 00501 if(m_enableFastSimMode && m_enableSaturation){ 00502 *(discriminatorStart + index) *= satFactor(*(discriminatorStart + index)); 00503 *(shapedStart + index) *= pow(satFactor(15.* (fabs(*(shapedStart + index))) ),0.75); 00504 } 00505 *(rawStart + index) += ringScaling * (*(ringingStart+ringIdx)); 00506 *(shapedStart + index) += ringScaling * (*(shapedRingingStart+ringIdx)); 00507 } 00508 } 00509 } // End saturation and ringing 00510 00511 } // End addition of linear PMT pulse 00512 00513 } // End addition of pulses to raw signal 00514 00515 // Convert raw signals to TDC, hit, ADC, Esum values 00516 // TDC values 00517 if (m_enableAcCoupling) sample( m_discriminatorSignal, m_tdcSignal, 00518 m_simFrequency, DayaBay::TdcFrequencyHz ); 00519 else sample( m_rawSignal, m_tdcSignal, 00520 m_simFrequency, DayaBay::TdcFrequencyHz ); 00521 std::vector<int> tdcValues; 00522 discriminate( m_tdcSignal, feeSimData->m_channelThreshold, tdcValues, 00523 DayaBay::Threshold::kAbove); 00524 channel.setTdc(tdcValues); 00525 verbose() << "Channel " << channelId << ": " << tdcValues.size() 00526 << " TDC values." << endreq; 00527 00528 // Assemble Hit signal (for trigger) based on TDC clock values 00529 // The hit signal is a binary 0 or 1 vs. time at the Nhit frequency. 00530 unsigned int hitSamples = convertClock( m_tdcSignal.size(), 00531 DayaBay::TdcFrequencyHz, 00532 DayaBay::NhitFrequencyHz ) + 1; 00533 // Resize and clear the buffer 00534 if( m_hitSignal.size() != hitSamples) m_hitSignal.resize( hitSamples ); 00535 int* hitStart = &m_hitSignal[0]; 00536 for( unsigned int hitIdx = 0; hitIdx != hitSamples; hitIdx++ ){ 00537 *(hitStart+hitIdx) = 0; 00538 } 00539 if( tdcValues.size() > 0 ){ 00540 std::vector<int>::const_iterator tdcIter, tdcDone = tdcValues.end(); 00541 for(tdcIter = tdcValues.begin(); tdcIter != tdcDone; tdcIter++){ 00542 int tdcClock = *tdcIter; 00543 int hitClock = convertClock( tdcClock, DayaBay::TdcFrequencyHz, 00544 DayaBay::NhitFrequencyHz ); 00545 m_hitSignal[hitClock] = 1; 00546 } 00547 } 00548 channel.setHit(m_hitSignal); 00549 verbose() << "Hit signal size: " << m_hitSignal.size() << endreq; 00550 00551 // ADC Values: Digitized signals vs. time for both the high and low gains 00552 // Reduce shaped pulse to ADC frequency 00553 sample( m_shapedSignal, m_adcAnalogSignal, 00554 m_simFrequency, DayaBay::AdcFrequencyHz ); 00555 // 12-bit ADC after shaped signals. One for adcHigh and one for adcLow. 00556 int adcBits = 12; 00557 digitize( m_adcAnalogSignal, m_adcHighGain, 00558 feeSimData->m_adcRangeHigh, adcBits, 00559 feeSimData->m_adcBaselineHigh ); 00560 digitize( m_adcAnalogSignal, m_adcLowGain, 00561 feeSimData->m_adcRangeLow, adcBits, 00562 feeSimData->m_adcBaselineLow ); 00563 channel.setAdcHigh( m_adcHighGain ); 00564 channel.setAdcLow( m_adcLowGain ); 00565 verbose() << "ADC signal size: " << m_adcHighGain.size() << endreq; 00566 00567 // Channel energy: contribution to the Esum signal 00568 //sample( m_rawSignal, channel.energy(), 00569 // m_simFrequency, m_eSumFrequency ); 00570 //verbose() << "Energy signal size: " << m_energySignal.size() << endreq; 00571 channel.setEnergy(m_rawSignal); 00572 return StatusCode::SUCCESS; 00573 } // End generate One channel
int EsIdealFeeTool::convertClock | ( | int | clock, | |
int | inputFrequency, | |||
int | outputFrequency | |||
) | [private] |
Definition at line 1211 of file EsIdealFeeTool.cc.
01211 { 01212 // Convert a clock cycle from one frequency to another. Round down 01213 // for incoherent frequencies. 01214 return int( ( clock / double(inputFrequency) ) * outputFrequency ); 01215 }
DayaBay::ESumComp::ESumComp_t EsIdealFeeTool::boardEsumType | ( | int | boardId | ) | [private] |
Definition at line 958 of file EsIdealFeeTool.cc.
00958 { 00959 // FIXME: This should probably be moved into a service. 00960 // Probably into the CableMappingSvc 00961 if (boardId >= 1 && boardId < 7) 00962 { 00963 return DayaBay::ESumComp::kESumLow; 00964 } 00965 00966 if (boardId >= 7 && boardId < 13) 00967 { 00968 return DayaBay::ESumComp::kESumHigh; 00969 } 00970 00971 if (boardId == 13) 00972 { 00973 return DayaBay::ESumComp::kESumNone; 00974 } 00975 00976 return DayaBay::ESumComp::kUnknown; 00977 }
void EsIdealFeeTool::convolve | ( | const DayaBay::AnalogSignal & | signal, | |
const DayaBay::AnalogSignal & | response, | |||
DayaBay::AnalogSignal & | output | |||
) | [private] |
Definition at line 980 of file EsIdealFeeTool.cc.
00983 { 00984 // Primitive convolution of signal and response, to produce 00985 // output. Assumes values outside of range are zero. A few simple 00986 // optimizations are use to speed up the process. 00987 int sN = signal.size(); 00988 int rN = response.size(); 00989 output.resize(sN+rN); 00990 const double* sigD = &(signal[0]); 00991 const double* resD = &(response[0]); 00992 double* outD = &(output[0]); 00993 for (int i=0; i<(sN+rN); i++) { 00994 double sum = 0; 00995 for (int j=0; j<rN; j++) { 00996 if (resD[j]==0) 00997 continue; 00998 if (i-j>=0 && i-j<sN) 00999 sum+=sigD[i-j]*resD[j]; 01000 } 01001 outD[i]=sum; 01002 } 01003 }
void EsIdealFeeTool::shape | ( | const DayaBay::AnalogSignal & | rawSignal, | |
DayaBay::AnalogSignal & | shapedSignal, | |||
const DayaBay::AnalogSignal & | response, | |||
std::map< int, int > | convolutionWindows | |||
) | [private] |
Definition at line 1006 of file EsIdealFeeTool.cc.
01008 { 01009 std::map<int,int>::iterator convIt = convolutionWindows.begin(); 01010 int convStart, convEnd; 01011 shapedSignal.clear(); 01012 int samples = rawSignal.size(); 01013 shapedSignal.resize(samples, 0); 01014 DayaBay::AnalogSignal rawFrag; 01015 DayaBay::AnalogSignal shapedFrag; 01016 for(; convIt != convolutionWindows.end(); convIt++){ 01017 convStart = convIt->first * 96; 01018 convEnd = convIt->second * 96; 01019 if (convEnd > samples) convEnd = samples; 01020 rawFrag.resize( (convEnd - convStart) ); 01021 shapedFrag.resize( (convEnd - convStart) ); 01022 std::copy( rawSignal.begin() + convStart, rawSignal.begin() + convEnd , rawFrag.begin() ); 01023 convolve( rawFrag, response, shapedFrag ); 01024 shapedFrag.resize( (convEnd - convStart) ); 01025 std::copy( shapedFrag.begin(), shapedFrag.end(), shapedSignal.begin() + convStart ); 01026 debug() << "Convolve from " << convStart *1.5625 << " ns to " << convEnd * 1.5625 << " ns" << endreq; 01027 } 01028 }
void EsIdealFeeTool::digitize | ( | const DayaBay::AnalogSignal & | signal, | |
DayaBay::DigitalSignal & | output, | |||
double | range, | |||
int | bits, | |||
double | offset | |||
) | [private] |
Definition at line 1088 of file EsIdealFeeTool.cc.
01091 { 01092 // Simple digitization algorithm 01093 if(output.size() != signal.size()) output.resize(signal.size()); 01094 int maxADC = int( pow(2, bits) ); 01095 int signalN = signal.size(); 01096 const double* inputStart = &signal[0]; 01097 int* outputStart = &output[0]; 01098 for (int i=0; i<signalN; i++) { 01099 int* curOutput = outputStart + i; 01100 *(curOutput) = int(((*(inputStart + i))/range)*maxADC + offset); 01101 if (*curOutput>maxADC) 01102 *curOutput=maxADC; 01103 if (*curOutput<0) 01104 *curOutput=0; 01105 /* Slower, but easier to read version of the same calculation 01106 outputStart[i] = int((signal[i]/range)*maxADC + offset); 01107 if (output[i]>maxADC) 01108 output[i]=maxADC; 01109 if (output[i]<0) 01110 output[i]=0; 01111 */ 01112 } 01113 }
void EsIdealFeeTool::discriminate | ( | const DayaBay::AnalogSignal & | signal, | |
double | threshold, | |||
std::vector< int > & | output, | |||
DayaBay::Threshold::Threshold_t | mode | |||
) | [private] |
Definition at line 1115 of file EsIdealFeeTool.cc.
01119 { 01120 // Take input signal array and discriminate using threshold. Return 01121 // vector of indices which satisfy the discriminator. 01122 // Current Modes: 01123 // - Threshold crossed 01124 // - Above threshold 01125 threshold *= m_speAmp; 01126 threshold *= m_gainFactor; 01127 threshold *= m_discThreshScale; 01128 01129 output.clear(); 01130 const double* signalStart = &signal[0]; 01131 unsigned int nSamples = signal.size(); 01132 if (DayaBay::Threshold::kCrossing == mode) { 01133 bool aboveThreshold = false; 01134 for (unsigned int i=0; 01135 i < nSamples; 01136 ++i) { 01137 if (!aboveThreshold && (*(signalStart+i))>=threshold) { 01138 output.push_back(i); 01139 aboveThreshold = true; 01140 } else if (aboveThreshold && (*(signalStart+i))<threshold) 01141 aboveThreshold=false; 01142 } 01143 } else if (DayaBay::Threshold::kAbove == mode) { 01144 for (unsigned int i=0; 01145 i < nSamples; 01146 ++i) 01147 if ((*(signalStart+i))>=threshold) 01148 output.push_back(i); 01149 } else { 01150 error() << "discriminate(): Unknown Discrimination Mode" << endreq; 01151 } 01152 }
double EsIdealFeeTool::pmtPulse | ( | double | deltaT, | |
int | nPulse, | |||
bool | addOvershoot | |||
) | [private] |
Definition at line 1154 of file EsIdealFeeTool.cc.
01154 { 01155 // SJ: New pmt pulse parametrization, cf DocDB 3779 01156 double shift = -2.5e-9; // time shift parameter 01157 if (deltaT-shift<0) return 0.; 01158 double v0 = -m_speAmp; // single p.e. pulse amplitude in V 01159 double width; // pulse width parameter 01160 double mu; // parameter determining the degree of asymmetry 01161 if ( nPulse != 0 ){ 01162 width = getPulseWidth( nPulse); 01163 mu = getPulseForm( nPulse); 01164 } 01165 else { 01166 width = 7.5e-9; 01167 mu = 0.5; 01168 } 01169 if(deltaT > 100 * width) return 0; 01170 double amplitude = 0; 01171 if(deltaT < 10 * width){ 01172 // Add primary pulse 01173 amplitude += m_gainFactor* v0 * exp( -pow( log( (deltaT-shift)/width),2) 01174 / ( 2*pow(mu,2) ) ) * Gaudi::Units::volt; 01175 } 01176 if( addOvershoot ){ 01177 // Add overshoot 01178 amplitude += overshoot( deltaT, nPulse ); 01179 } 01180 return amplitude; 01181 }
double EsIdealFeeTool::overshoot | ( | double | deltaT, | |
int | nPulse | |||
) | [private] |
Definition at line 1228 of file EsIdealFeeTool.cc.
01228 { 01229 // SJ: Simple overshoot parametrization 01230 if (deltaT < 0) return 0.; 01231 double v0 = getOvershootAmp( nPulse ); // Overshoot amplitude in V 01232 double tau = 155.e-9; // Overshoot time constant in s 01233 double expo = v0*exp(-deltaT/tau); 01234 double t0 = 50e-9; // Onset parameters 01235 double t1 = 10e-9; 01236 double fermi = 1. / (exp( (t0 - deltaT) / t1) + 1.); 01237 return fermi * expo * Gaudi::Units::volt; 01238 }
double EsIdealFeeTool::ringing | ( | double | deltaT, | |
double | pulseMax | |||
) | [private] |
Definition at line 1240 of file EsIdealFeeTool.cc.
01240 { 01241 // SJ: Simple ringing parametrization 01242 if (deltaT<0) return 0.; 01243 double v0 = 0.00154 * pulseMax; // Ringing amplitude in V 01244 double period = 1.63e-6; //Ringing period in s 01245 double shift= 0.99e-6; // Phase shift 01246 double expo = exp(-deltaT/12.e-6); 01247 double t0 = 0.6e-6; // Onset parameters 01248 double t1 = 0.1e-6; 01249 double fermi = 1./(exp((t0-deltaT)/t1)+1); 01250 return v0 * fermi * expo * cos(6.28*(deltaT-shift)/period); 01251 }
double EsIdealFeeTool::satFactor | ( | double | amp | ) | [private] |
Definition at line 1217 of file EsIdealFeeTool.cc.
01217 { 01218 //SJ: Returns saturation factor as a function of the raw amplitude 01219 if (amp<0) return 1.; 01220 double y = 1.e6 * amp; 01221 if(y < 1) 01222 return 1. - 0.5311049 * y + 0.1818968 * pow(y,2); 01223 if(y < 9.5) 01224 return 0.778264 - 0.1400074 * y + 0.01303484 * pow(y,2) - 0.0004701175 * pow(y,3) + 0.000002450386 * pow(y,4); 01225 return 0.4212711 - 2.560691e-02 * y + 8.003103e-04 * pow(y,2) - 1.226207e-05 * pow(y,3) + 7.282761e-08 * pow(y,4); 01226 }
double EsIdealFeeTool::pulseShaping | ( | double | deltaT | ) | [private] |
Definition at line 1183 of file EsIdealFeeTool.cc.
01183 { 01184 // Gaussian CR-(RC)^4 pulse shaping 01185 // See Knoll, Radiation Detection and Measurement 01186 // Returns the pulse amplitude at time deltaT after a positive step 01187 // function of amplitude 1 01188 if (deltaT<0) 01189 return 0.; 01190 double t0 = 25.0e-9; // RC time constant in seconds 01191 double r = deltaT/t0; 01192 return pow( r, 4 ) * exp( -r ); 01193 }
double EsIdealFeeTool::esumShaping | ( | double | deltaT | ) | [private] |
Definition at line 1195 of file EsIdealFeeTool.cc.
01195 { 01196 //ESum shaping function 01197 if (deltaT<0) 01198 return 0.; 01199 double t0 = 56.0; // RC time constant in seconds 01200 double r = deltaT/t0; 01201 return exp( -r )*(1/t0); 01202 }
double EsIdealFeeTool::getPulseWidth | ( | int | nPulse | ) | [private] |
Definition at line 1253 of file EsIdealFeeTool.cc.
01253 { 01254 // SJ: Single pulse width as a function of the number of coincidental pulses 01255 if( nPulse > 2000) return 20.7842e-9; 01256 double x = double(nPulse); 01257 double t0 = 1200.; 01258 double t1 = 200.; 01259 double f = 1. / (exp( (t0-x)/t1 ) + 1.); 01260 return (7.+12.*f+x/1000.)*1.e-9; 01261 }
double EsIdealFeeTool::getPulseForm | ( | int | nPulse | ) | [private] |
Definition at line 1263 of file EsIdealFeeTool.cc.
01263 { 01264 // SJ: Single pulse width as a function of the number of coincidental pulses 01265 if( nPulse > 3000) return 0.2; 01266 double x = double(nPulse); 01267 double t0 = 900.; 01268 double t1 = 200.; 01269 double f = 0.45 - 0.25 * 1. / (exp( (t0-x)/t1) + 1.); 01270 return f; 01271 }
double EsIdealFeeTool::getPulseShift | ( | int | nPulse | ) | [private] |
double EsIdealFeeTool::getOvershootAmp | ( | int | nPulse | ) | [private] |
Definition at line 1273 of file EsIdealFeeTool.cc.
01273 { 01274 // SJ: Single pulse overshoot amplitude as a function of the number of coincidental pulses 01275 if( nPulse > 2000) return 2.4033e-4; 01276 double x = double(nPulse); 01277 double t0 = -0.0148227; 01278 double t1 = -1186.36; 01279 double t2 = 287.821; 01280 double t3 = 0.0150628; 01281 double f = t0 / (exp( (t1-x)/t2) + 1.) + t3; 01282 return f; 01283 }
double EsIdealFeeTool::noise | ( | ) | [private] |
Definition at line 1204 of file EsIdealFeeTool.cc.
01204 { 01205 // FIXME: do discrete FT for range of frequencies 01206 // Simple noise model 01207 // Approximate Gaussian-distributed noise 01208 return m_gauss() * m_noiseAmp; // no offset 01209 }
void EsIdealFeeTool::sample | ( | const DayaBay::AnalogSignal & | signal, | |
DayaBay::AnalogSignal & | output, | |||
int | inputFrequency, | |||
int | outputFrequency | |||
) | [private] |
Definition at line 1029 of file EsIdealFeeTool.cc.
01033 { 01034 // Fill the output array using the signal values sampled at a 01035 // regular frequency 01036 if(inputFrequency == outputFrequency){ 01037 if( output.size() != signal.size() ) output.resize( signal.size() ); 01038 memcpy(&output[0],&signal[0],output.size()*sizeof(double)); 01039 return; 01040 } 01041 unsigned int nSamples = convertClock(signal.size(), 01042 inputFrequency, 01043 outputFrequency); 01044 if(output.size() != nSamples){ 01045 if(output.capacity() > nSamples){ 01046 output.resize(nSamples); 01047 }else{ 01048 // Faster memory allocation 01049 DayaBay::AnalogSignal* newSignal = new DayaBay::AnalogSignal(nSamples); 01050 output.swap(*newSignal); 01051 delete newSignal; 01052 } 01053 } 01054 01055 if(inputFrequency < outputFrequency){ 01056 warning() << "sample(): Input frequency " << inputFrequency 01057 << " is less than the sampling frequency " << outputFrequency 01058 << endreq; 01059 } 01060 if( (inputFrequency % outputFrequency) == 0 ){ 01061 // Check for integer relationship between frequencies 01062 int relativeFrequency = inputFrequency / outputFrequency; 01063 double* outputStart = &output[0]; 01064 const double* inputStart = &signal[0]; 01065 int inputIdx = 0; 01066 unsigned int outputIdx = 0; 01067 while(outputIdx != nSamples){ 01068 *(outputStart + outputIdx) = *(inputStart + inputIdx); 01069 outputIdx++; 01070 inputIdx+=relativeFrequency; 01071 } 01072 return; 01073 }else{ 01074 // Frequencies not coherent. Use signal sample with nearest lower index. 01075 double* outputStart = &output[0]; 01076 const double* inputStart = &signal[0]; 01077 int inputIdx = 0; 01078 unsigned int outputIdx = 0; 01079 double freqScale = inputFrequency / outputFrequency; 01080 while( outputIdx != nSamples ){ 01081 inputIdx = int(outputIdx * freqScale); 01082 *(outputStart + outputIdx) = *(inputStart + inputIdx); 01083 outputIdx++; 01084 } 01085 } 01086 }
const InterfaceID & IEsFrontEndTool::interfaceID | ( | ) | [static, inherited] |
Retrieve interface ID.
Reimplemented from IAlgTool.
Definition at line 8 of file IEsFrontEndTool.cc.
00009 { 00010 return IID_IEsFrontEndTool; 00011 }
std::string EsIdealFeeTool::m_cableSvcName [private] |
Definition at line 102 of file EsIdealFeeTool.h.
std::string EsIdealFeeTool::m_simDataSvcName [private] |
Definition at line 104 of file EsIdealFeeTool.h.
ICableSvc* EsIdealFeeTool::m_cableSvc [private] |
Definition at line 106 of file EsIdealFeeTool.h.
ISimDataSvc* EsIdealFeeTool::m_simDataSvc [private] |
Definition at line 108 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_triggerWindowCycles [private] |
Definition at line 110 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_gainFactor [private] |
Definition at line 112 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_simFrequency [private] |
Definition at line 114 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_eSumFrequency [private] |
Definition at line 116 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableNonlinearity [private] |
Definition at line 118 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableAcCoupling [private] |
Definition at line 120 of file EsIdealFeeTool.h.
unsigned int EsIdealFeeTool::m_linearityThreshold [private] |
Definition at line 122 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enablePretrigger [private] |
Definition at line 125 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_eSumTriggerThreshold [private] |
Definition at line 127 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_nHitTriggerThreshold [private] |
Definition at line 128 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_pretriggerThreshold [private] |
Definition at line 130 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableNoise [private] |
Definition at line 132 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableDynamicWaveform [private] |
Definition at line 134 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableSaturation [private] |
Definition at line 136 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableRinging [private] |
Definition at line 138 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableOvershoot [private] |
Definition at line 140 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableESumTotal [private] |
Definition at line 142 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableESumH [private] |
Definition at line 143 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableESumL [private] |
Definition at line 144 of file EsIdealFeeTool.h.
bool EsIdealFeeTool::m_enableFastSimMode [private] |
Definition at line 146 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_pulseCountSlotWidth [private] |
Definition at line 148 of file EsIdealFeeTool.h.
int EsIdealFeeTool::m_pulseCountWindow [private] |
Definition at line 150 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_noiseAmp [private] |
Definition at line 152 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_speAmp [private] |
Definition at line 154 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_discThreshScale [private] |
Definition at line 156 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_adcRange [private] |
Definition at line 158 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_adcBits [private] |
Definition at line 159 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_adcOffset [private] |
Definition at line 160 of file EsIdealFeeTool.h.
Definition at line 162 of file EsIdealFeeTool.h.
Definition at line 164 of file EsIdealFeeTool.h.
Definition at line 166 of file EsIdealFeeTool.h.
Definition at line 168 of file EsIdealFeeTool.h.
Definition at line 170 of file EsIdealFeeTool.h.
Definition at line 172 of file EsIdealFeeTool.h.
Definition at line 174 of file EsIdealFeeTool.h.
Definition at line 176 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_shapingSum [private] |
Definition at line 178 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_esumShapingSum [private] |
Definition at line 180 of file EsIdealFeeTool.h.
double EsIdealFeeTool::m_pulseMax [private] |
Definition at line 182 of file EsIdealFeeTool.h.
Rndm::Numbers EsIdealFeeTool::m_gauss [private] |
Definition at line 185 of file EsIdealFeeTool.h.
Definition at line 187 of file EsIdealFeeTool.h.
DayaBay::AnalogSignal EsIdealFeeTool::m_esumL [private] |
Definition at line 188 of file EsIdealFeeTool.h.
DayaBay::AnalogSignal EsIdealFeeTool::m_esumH [private] |
Definition at line 189 of file EsIdealFeeTool.h.
Definition at line 190 of file EsIdealFeeTool.h.
Definition at line 191 of file EsIdealFeeTool.h.
Definition at line 192 of file EsIdealFeeTool.h.
Definition at line 193 of file EsIdealFeeTool.h.
Definition at line 194 of file EsIdealFeeTool.h.
Definition at line 195 of file EsIdealFeeTool.h.
Definition at line 196 of file EsIdealFeeTool.h.
Definition at line 197 of file EsIdealFeeTool.h.
Definition at line 198 of file EsIdealFeeTool.h.
Definition at line 199 of file EsIdealFeeTool.h.
Definition at line 200 of file EsIdealFeeTool.h.
Definition at line 201 of file EsIdealFeeTool.h.
Definition at line 202 of file EsIdealFeeTool.h.
Definition at line 203 of file EsIdealFeeTool.h.
Definition at line 204 of file EsIdealFeeTool.h.
std::map<int,int> EsIdealFeeTool::m_adcConvolutionWindows [private] |
Definition at line 205 of file EsIdealFeeTool.h.
std::map<int,int> EsIdealFeeTool::m_esumConvolutionWindows [private] |
Definition at line 206 of file EsIdealFeeTool.h.