CMS 3D CMS Logo

RunManagerMTWorker.cc
Go to the documentation of this file.
13 
20 
27 
33 
37 
40 
42 
44 
46 
47 #include "G4Event.hh"
48 #include "G4Run.hh"
49 #include "G4SystemOfUnits.hh"
50 #include "G4Threading.hh"
51 #include "G4UImanager.hh"
52 #include "G4WorkerThread.hh"
53 #include "G4WorkerRunManagerKernel.hh"
54 #include "G4StateManager.hh"
55 #include "G4TransportationManager.hh"
56 
57 #include <atomic>
58 #include <thread>
59 #include <sstream>
60 #include <vector>
61 
62 // from https://hypernews.cern.ch/HyperNews/CMS/get/edmFramework/3302/2.html
63 namespace {
64  static std::atomic<int> thread_counter{ 0 };
65 
66  int get_new_thread_index() {
67  return thread_counter++;
68  }
69 
70  static thread_local int s_thread_index = get_new_thread_index();
71 
72  int getThreadIndex() { return s_thread_index; }
73 
74  void createWatchers(const edm::ParameterSet& iP,
75  SimActivityRegistry& iReg,
76  std::vector<std::shared_ptr<SimWatcher> >& oWatchers,
77  std::vector<std::shared_ptr<SimProducer> >& oProds,
78  int thisThreadID
79  )
80  {
81  using namespace std;
82  using namespace edm;
83  if(!iP.exists("Watchers")) { return; }
84 
85  vector<ParameterSet> watchers = iP.getParameter<vector<ParameterSet> >("Watchers");
86 
87  if(thisThreadID > 0) {
88  throw edm::Exception(edm::errors::Configuration) << "SimWatchers are not supported for more than 1 thread. If this use case is needed, RunManagerMTWorker has to be updated, and SimWatchers and SimProducers have to be made thread safe.";
89  }
90 
91  for(vector<ParameterSet>::iterator itWatcher = watchers.begin();
92  itWatcher != watchers.end();
93  ++itWatcher) {
94  std::unique_ptr<SimWatcherMakerBase> maker(
95  SimWatcherFactory::get()->create(itWatcher->getParameter<std::string>("type"))
96  );
97  if(maker.get()==nullptr) {
99  << "Unable to find the requested Watcher";
100  }
101 
102  std::shared_ptr<SimWatcher> watcherTemp;
103  std::shared_ptr<SimProducer> producerTemp;
104  maker->make(*itWatcher,iReg,watcherTemp,producerTemp);
105  oWatchers.push_back(watcherTemp);
106  if(producerTemp) {
107  oProds.push_back(producerTemp);
108  }
109  }
110  }
111 }
112 
114  std::unique_ptr<CustomUIsession> UIsession;
115  std::unique_ptr<RunAction> userRunAction;
116  std::unique_ptr<SimRunInterface> runInterface;
118  std::unique_ptr<SimTrackManager> trackManager;
119  std::vector<SensitiveTkDetector*> sensTkDets;
120  std::vector<SensitiveCaloDetector*> sensCaloDets;
121  std::vector<std::shared_ptr<SimWatcher> > watchers;
122  std::vector<std::shared_ptr<SimProducer> > producers;
123  std::unique_ptr<G4Run> currentRun;
124  std::unique_ptr<G4Event> currentEvent;
125  edm::RunNumber_t currentRunNumber = 0;
126  G4RunManagerKernel* kernel = nullptr;
127  bool threadInitialized = false;
128  bool runTerminated = false;
129 };
130 
132 
134  m_generator(iConfig.getParameter<edm::ParameterSet>("Generator")),
135  m_InToken(iC.consumes<edm::HepMCProduct>(iConfig.getParameter<edm::ParameterSet>("Generator").getParameter<std::string>("HepMCProductLabel"))),
136  m_theLHCTlinkToken(iC.consumes<edm::LHCTransportLinkContainer>(iConfig.getParameter<edm::InputTag>("theLHCTlinkTag"))),
137  m_nonBeam(iConfig.getParameter<bool>("NonBeamEvent")),
138  m_pUseMagneticField(iConfig.getParameter<bool>("UseMagneticField")),
139  m_EvtMgrVerbosity(iConfig.getUntrackedParameter<int>("G4EventManagerVerbosity",0)),
140  m_pField(iConfig.getParameter<edm::ParameterSet>("MagneticField")),
141  m_pRunAction(iConfig.getParameter<edm::ParameterSet>("RunAction")),
142  m_pEventAction(iConfig.getParameter<edm::ParameterSet>("EventAction")),
143  m_pStackingAction(iConfig.getParameter<edm::ParameterSet>("StackingAction")),
144  m_pTrackingAction(iConfig.getParameter<edm::ParameterSet>("TrackingAction")),
145  m_pSteppingAction(iConfig.getParameter<edm::ParameterSet>("SteppingAction")),
146  m_pCustomUIsession(iConfig.getUntrackedParameter<edm::ParameterSet>("CustomUIsession")),
147  m_p(iConfig)
148 {
149  initializeTLS();
150  m_sVerbose.reset(nullptr);
151  std::vector<edm::ParameterSet> watchers =
152  iConfig.getParameter<std::vector<edm::ParameterSet> >("Watchers");
153  m_hasWatchers = (watchers.empty()) ? false : true;
154 }
155 
157  if(m_tls && !m_tls->runTerminated) { terminateRun(); }
158 }
159 
161  terminateRun();
162 }
163 
165  if(m_tls) { return; }
166  m_tls = new TLSData;
167 
168  edm::Service<SimActivityRegistry> otherRegistry;
169  //Look for an outside SimActivityRegistry
170  // this is used by the visualization code
171  int thisID = getThreadIndex();
172  if(otherRegistry){
173  m_tls->registry.connect(*otherRegistry);
174  if(thisID > 0) {
175  throw edm::Exception(edm::errors::Configuration) << "SimActivityRegistry service (i.e. visualization) is not supported for more than 1 thread. If this use case is needed, RunManagerMTWorker has to be updated.";
176  }
177  }
178  if(m_hasWatchers) {
180  }
181 }
182 
184  // I guess everything initialized here should be in thread_local storage
185  initializeTLS();
186 
187  int thisID = getThreadIndex();
188 
189  edm::LogInfo("SimG4CoreApplication")
190  << "RunManagerMTWorker::initializeThread " << thisID;
191 
192  // Initialize per-thread output
193  G4Threading::G4SetThreadId( thisID );
194  G4UImanager::GetUIpointer()->SetUpForAThread( thisID );
196  if(uitype == "MessageLogger") {
197  m_tls->UIsession.reset(new CustomUIsession());
198  }
199  else if(uitype == "MessageLoggerThreadPrefix") {
201  }
202  else if(uitype == "FilePerThread") {
204  }
205  else {
207  << "Invalid value of CustomUIsession.Type '" << uitype
208  << "', valid are MessageLogger, MessageLoggerThreadPrefix, FilePerThread";
209  }
210 
211  // Initialize worker part of shared resources (geometry, physics)
212  G4WorkerThread::BuildGeometryAndPhysicsVector();
213 
214  // Create worker run manager
215  m_tls->kernel = G4WorkerRunManagerKernel::GetRunManagerKernel();
216  if(!m_tls->kernel) { m_tls->kernel = new G4WorkerRunManagerKernel(); }
217 
218  // Set the geometry for the worker, share from master
220 
221  // we need the track manager now
222  m_tls->trackManager.reset(new SimTrackManager());
223 
224  // Get DDCompactView, or would it be better to get the object from
225  // runManagerMaster instead of EventSetup in here?
227  es.get<IdealGeometryRecord>().get(pDD);
228 
229  // setup the magnetic field
231  {
232  const GlobalPoint g(0.,0.,0.);
233 
235  es.get<IdealMagneticFieldRecord>().get(pMF);
236 
237  sim::FieldBuilder fieldBuilder(pMF.product(), m_pField);
238  CMSFieldManager* fieldManager = new CMSFieldManager();
239  G4TransportationManager * tM =
240  G4TransportationManager::GetTransportationManager();
241  tM->SetFieldManager(fieldManager);
242  fieldBuilder.build( fieldManager, tM->GetPropagatorInField());
243  }
244 
245  // attach sensitive detector
246  AttachSD attach;
247  std::pair< std::vector<SensitiveTkDetector*>,
248  std::vector<SensitiveCaloDetector*> > sensDets =
249  attach.create(runManagerMaster.world(),
250  (*pDD),
251  runManagerMaster.catalog(),
252  m_p,
253  m_tls->trackManager.get(),
254  m_tls->registry);
255 
256  m_tls->sensTkDets.swap(sensDets.first);
257  m_tls->sensCaloDets.swap(sensDets.second);
258 
259  edm::LogInfo("SimG4CoreApplication")
260  << " RunManagerMTWorker: Sensitive Detector "
261  << "building finished; found "
262  << m_tls->sensTkDets.size()
263  << " Tk type Producers, and "
264  << m_tls->sensCaloDets.size()
265  << " Calo type producers ";
266 
267  // Set the physics list for the worker, share from master
268  PhysicsList *physicsList = runManagerMaster.physicsListForWorker();
269 
270  edm::LogInfo("SimG4CoreApplication")
271  << "RunManagerMTWorker: start initialisation of PhysicsList for a thread";
272 
273  physicsList->InitializeWorker();
274  m_tls->kernel->SetPhysics(physicsList);
275  m_tls->kernel->InitializePhysics();
276 
277  const bool kernelInit = m_tls->kernel->RunInitialization();
278  if(!kernelInit) {
279  throw SimG4Exception("G4WorkerRunManagerKernel initialization failed");
280  }
281  //tell all interesting parties that we are beginning the job
282  BeginOfJob aBeginOfJob(&es);
283  m_tls->registry.beginOfJobSignal_(&aBeginOfJob);
284 
285  G4int sv = m_p.getParameter<int>("SteppingVerbosity");
286  G4double elim = m_p.getParameter<double>("StepVerboseThreshold")*CLHEP::GeV;
287  std::vector<int> ve = m_p.getParameter<std::vector<int> >("VerboseEvents");
288  std::vector<int> vn = m_p.getParameter<std::vector<int> >("VertexNumber");
289  std::vector<int> vt = m_p.getParameter<std::vector<int> >("VerboseTracks");
290 
291  if(sv > 0) {
292  m_sVerbose.reset(new CMSSteppingVerbose(sv, elim, ve, vn, vt));
293  }
295 
296  edm::LogInfo("SimG4CoreApplication")
297  << "RunManagerMTWorker::initializeThread done for the thread " << thisID;
298 
299  for(const std::string& command: runManagerMaster.G4Commands()) {
300  edm::LogInfo("SimG4CoreApplication") << "RunManagerMTWorker:: Requests UI: "
301  << command;
302  G4UImanager::GetUIpointer()->ApplyCommand(command);
303  }
304 }
305 
307  m_tls->runInterface.reset(new SimRunInterface(this, false));
309  m_tls->runInterface.get(),false));
310  m_tls->userRunAction->SetMaster(false);
311  Connect(m_tls->userRunAction.get());
312 
313  G4EventManager * eventManager = m_tls->kernel->GetEventManager();
314  eventManager->SetVerboseLevel(m_EvtMgrVerbosity);
315 
316  EventAction * userEventAction =
318  m_tls->trackManager.get(), m_sVerbose.get());
319  Connect(userEventAction);
320  eventManager->SetUserAction(userEventAction);
321 
322  TrackingAction* userTrackingAction =
323  new TrackingAction(userEventAction, m_pTrackingAction, m_sVerbose.get());
324  Connect(userTrackingAction);
325  eventManager->SetUserAction(userTrackingAction);
326 
327  SteppingAction* userSteppingAction =
328  new SteppingAction(userEventAction,m_pSteppingAction,m_sVerbose.get(),m_hasWatchers);
329  Connect(userSteppingAction);
330  eventManager->SetUserAction(userSteppingAction);
331 
332  eventManager->SetUserAction(new StackingAction(userTrackingAction,
334 
335 }
336 
338 {
341 }
342 
344 {
347 }
348 
350 {
353 }
354 
356 {
358 }
359 
361  initializeTLS();
362  return m_tls->trackManager.get();
363 }
364 std::vector<SensitiveTkDetector*>& RunManagerMTWorker::sensTkDetectors() {
365  initializeTLS();
366  return m_tls->sensTkDets;
367 }
368 std::vector<SensitiveCaloDetector*>& RunManagerMTWorker::sensCaloDetectors() {
369  initializeTLS();
370  return m_tls->sensCaloDets;
371 }
372 std::vector<std::shared_ptr<SimProducer> > RunManagerMTWorker::producers() {
373  initializeTLS();
374  return m_tls->producers;
375 }
376 
378  m_tls->currentRun.reset(new G4Run());
379  G4StateManager::GetStateManager()->SetNewState(G4State_GeomClosed);
380  if (m_tls->userRunAction) { m_tls->userRunAction->BeginOfRunAction(m_tls->currentRun.get()); }
381 }
382 
384  if(!m_tls || m_tls->runTerminated) { return; }
385  if(m_tls->userRunAction) {
386  m_tls->userRunAction->EndOfRunAction(m_tls->currentRun.get());
387  m_tls->userRunAction.reset();
388  }
389  m_tls->currentEvent.reset();
390  m_simEvent.reset();
391 
392  if(m_tls->kernel) {
393  m_tls->kernel->RunTermination();
394  }
395 
396  m_tls->runTerminated = true;
397 }
398 
400  RunManagerMT& runManagerMaster) {
401  // The initialization and begin/end run is a bit convoluted due to
402  // - Geant4 deals per-thread
403  // - OscarMTProducer deals per-stream
404  // and framework/TBB is free to schedule work in streams to the
405  // threads as it likes.
406  //
407  // We have to do the per-thread initialization, and per-thread
408  // per-run initialization here by ourselves.
409 
410  if(!(m_tls && m_tls->threadInitialized)) {
411  LogDebug("SimG4CoreApplication")
412  << "RunManagerMTWorker::produce(): stream "
413  << inpevt.streamID() << " thread " << getThreadIndex() << " initializing";
414  initializeThread(runManagerMaster, es);
415  m_tls->threadInitialized = true;
416  }
417  // Initialize run
418  if(inpevt.id().run() != m_tls->currentRunNumber) {
419  if(m_tls->currentRunNumber != 0 && !m_tls->runTerminated) {
420  // If previous run in this thread was not terminated via endRun() call, terminate it now
421  terminateRun();
422  }
423  initializeRun();
424  m_tls->currentRunNumber = inpevt.id().run();
425  }
426  m_tls->runInterface->setRunManagerMTWorker(this); // For UserActions
427 
428  m_tls->currentEvent.reset(generateEvent(inpevt));
429 
430  m_simEvent.reset(new G4SimEvent());
431  m_simEvent->hepEvent(m_generator.genEvent());
433  if (m_generator.genVertex() != nullptr ) {
434  auto genVertex = m_generator.genVertex();
435  m_simEvent->collisionPoint(
436  math::XYZTLorentzVectorD(genVertex->x()/centimeter,
437  genVertex->y()/centimeter,
438  genVertex->z()/centimeter,
439  genVertex->t()/second));
440  }
441  if (m_tls->currentEvent->GetNumberOfPrimaryVertex()==0) {
442  std::stringstream ss;
443  ss << "RunManagerMTWorker::produce(): event " << inpevt.id().event()
444  << " with no G4PrimaryVertices \n" ;
445  throw SimG4Exception(ss.str());
446 
447  } else {
448  if(!m_tls->kernel) {
449  std::stringstream ss;
450  ss << " RunManagerMT::produce(): "
451  << " no G4WorkerRunManagerKernel yet for thread index"
452  << getThreadIndex() << ", id " << std::hex
453  << std::this_thread::get_id() << " \n";
454  throw SimG4Exception(ss.str());
455  }
456 
457  edm::LogInfo("SimG4CoreApplication")
458  << " RunManagerMTWorker::produce: start Event " << inpevt.id().event()
459  << " stream id " << inpevt.streamID()
460  << " thread index " << getThreadIndex()
461  << " of weight " << m_simEvent->weight()
462  << " with " << m_simEvent->nTracks() << " tracks and "
463  << m_simEvent->nVertices()
464  << " vertices, generated by " << m_simEvent->nGenParts() << " particles ";
465 
466  m_tls->kernel->GetEventManager()->ProcessOneEvent(m_tls->currentEvent.get());
467 
468  edm::LogInfo("SimG4CoreApplication")
469  << " RunManagerMTWorker::produce: ended Event " << inpevt.id().event();
470  }
471 }
472 
474  if(m_tls->runTerminated) { return; }
475  G4Track* t = m_tls->kernel->GetEventManager()->GetTrackingManager()->GetTrack();
476  t->SetTrackStatus(fStopAndKill) ;
477 
478  // CMS-specific act
479  //
480  TrackingAction* uta =
481  static_cast<TrackingAction *>(m_tls->kernel->GetEventManager()->GetUserTrackingAction());
482  uta->PostUserTrackingAction(t) ;
483 
484  m_tls->currentEvent->SetEventAborted();
485  m_tls->kernel->GetEventManager()->GetStackManager()->clear();
486  m_tls->kernel->GetEventManager()->GetTrackingManager()->EventAborted();
487 }
488 
489 void RunManagerMTWorker::abortRun(bool softAbort) {
490  if (!softAbort) { abortEvent(); }
491  m_tls->currentRun.reset();
492  terminateRun();
493 }
494 
496  m_tls->currentEvent.reset();
497  m_simEvent.reset();
498 
499  // 64 bits event ID in CMSSW converted into Geant4 event ID
500  G4int evtid = (G4int)inpevt.id().event();
501  G4Event * evt = new G4Event(evtid);
502 
504 
505  inpevt.getByToken(m_InToken, HepMCEvt);
506 
507  m_generator.setGenEvent(HepMCEvt->GetEvent());
508 
509  // required to reset the GenParticle Id for particles transported
510  // along the beam pipe
511  // to their original value for SimTrack creation
512  resetGenParticleId( inpevt );
513 
514  if (!m_nonBeam)
515  {
516  m_generator.HepMC2G4(HepMCEvt->GetEvent(),evt);
517  }
518  else
519  {
520  m_generator.nonBeamEvent2G4(HepMCEvt->GetEvent(),evt);
521  }
522 
523  return evt;
524 }
525 
527 {
529  inpevt.getByToken( m_theLHCTlinkToken, theLHCTlink );
530  if ( theLHCTlink.isValid() ) {
531  m_tls->trackManager->setLHCTransportLink( theLHCTlink.product() );
532  }
533 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:39
edm::ParameterSet m_pSteppingAction
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
std::vector< std::shared_ptr< SimWatcher > > watchers
const SensitiveDetectorCatalog & catalog() const
Definition: RunManagerMT.h:83
T getUntrackedParameter(std::string const &, T const &) const
virtual const math::XYZTLorentzVector * genVertex() const
Definition: Generator.h:30
const double GeV
Definition: MathUtil.h:16
std::unique_ptr< G4Event > currentEvent
virtual const double eventWeight() const
Definition: Generator.h:31
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
def create(alignables, pedeDump, additionalData, outputFile, config)
virtual const HepMC::GenEvent * genEvent() const
Definition: Generator.h:29
SimActivityRegistry::G4StepSignal m_g4StepSignal
SimTrackManager * GetSimTrackManager()
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
void connect(Observer< const BeginOfJob * > *iObject)
void HepMC2G4(const HepMC::GenEvent *g, G4Event *e)
Definition: Generator.cc:100
EndOfEventSignal endOfEventSignal_
std::unique_ptr< SimRunInterface > runInterface
std::unique_ptr< CMSSteppingVerbose > m_sVerbose
SimActivityRegistry::EndOfRunSignal m_endOfRunSignal
Definition: RunAction.h:26
bool exists(std::string const &parameterName) const
checks if a parameter exists
BeginOfRunSignal beginOfRunSignal_
std::vector< SensitiveTkDetector * > sensTkDets
SimActivityRegistry::EndOfEventSignal m_endOfEventSignal
Definition: EventAction.h:54
static void createWatchers(const edm::ParameterSet &iP, SimActivityRegistry &iReg, std::vector< std::shared_ptr< SimWatcher > > &oWatchers, std::vector< std::shared_ptr< SimProducer > > &oProds)
Definition: RunManager.cc:83
#define nullptr
edm::EDGetTokenT< edm::HepMCProduct > m_InToken
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
BeginOfJobSignal beginOfJobSignal_
U second(std::pair< T, U > const &p)
edm::ParameterSet m_pEventAction
const DDDWorld & world() const
Definition: RunManagerMT.h:79
std::unique_ptr< SimTrackManager > trackManager
std::unique_ptr< CustomUIsession > UIsession
std::unique_ptr< G4SimEvent > m_simEvent
static thread_local TLSData * m_tls
edm::ParameterSet m_pRunAction
std::vector< SensitiveCaloDetector * > sensCaloDets
std::vector< SensitiveTkDetector * > & sensTkDetectors()
void resetGenParticleId(const edm::Event &inpevt)
std::unique_ptr< RunAction > userRunAction
void initializeThread(RunManagerMT &runManagerMaster, const edm::EventSetup &es)
void setGenEvent(const HepMC::GenEvent *inpevt)
Definition: Generator.h:25
BeginOfEventSignal beginOfEventSignal_
SimActivityRegistry::EndOfTrackSignal m_endOfTrackSignal
bool isValid() const
Definition: HandleBase.h:74
EndOfRunSignal endOfRunSignal_
std::vector< std::shared_ptr< SimProducer > > producers
void abortRun(bool softAbort=false)
RunManagerMTWorker(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&i)
void connect(Observer< const T * > *iObs)
does not take ownership of memory
Definition: Signaler.h:59
PhysicsList * physicsListForWorker() const
Definition: RunManagerMT.h:94
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:38
T const * product() const
Definition: Handle.h:81
virtual void PostUserTrackingAction(const G4Track *aTrack)
std::vector< SensitiveCaloDetector * > & sensCaloDetectors()
edm::ParameterSet m_pTrackingAction
void produce(const edm::Event &inpevt, const edm::EventSetup &es, RunManagerMT &runManagerMaster)
std::unique_ptr< G4Run > currentRun
edm::ParameterSet m_pField
const T & get() const
Definition: EventSetup.h:56
std::pair< std::vector< SensitiveTkDetector * >, std::vector< SensitiveCaloDetector * > > create(const DDDWorld &w, const DDCompactView &cpv, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *m, SimActivityRegistry &reg) const
Definition: AttachSD.cc:23
G4VPhysicalVolume * GetWorldVolumeForWorker() const
Definition: DDDWorld.h:24
G4Event * generateEvent(const edm::Event &inpevt)
edm::EDGetTokenT< edm::LHCTransportLinkContainer > m_theLHCTlinkToken
void nonBeamEvent2G4(const HepMC::GenEvent *g, G4Event *e)
Definition: Generator.cc:529
static void WorkerSetAsWorld(G4VPhysicalVolume *pv)
Definition: DDDWorld.cc:38
SimActivityRegistry::BeginOfRunSignal m_beginOfRunSignal
Definition: RunAction.h:25
const std::vector< std::string > & G4Commands() const
Definition: RunManagerMT.h:87
edm::EventID id() const
Definition: EventBase.h:60
HLT enums.
edm::ParameterSet m_pCustomUIsession
std::vector< std::shared_ptr< SimProducer > > producers()
StreamID streamID() const
Definition: Event.h:81
std::vector< LHCTransportLink > LHCTransportLinkContainer
unsigned int RunNumber_t
EndOfTrackSignal endOfTrackSignal_
edm::ParameterSet m_p
T const * product() const
Definition: ESHandle.h:86
SimActivityRegistry::BeginOfEventSignal m_beginOfEventSignal
Definition: EventAction.h:53
T get(const Candidate &c)
Definition: component.h:55
BeginOfTrackSignal beginOfTrackSignal_
edm::ParameterSet m_pStackingAction
void Connect(RunAction *)
SimActivityRegistry::BeginOfTrackSignal m_beginOfTrackSignal