diff --git a/CMakeLists.txt b/CMakeLists.txt index 98171a42..2a752793 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required( VERSION 3.1 ) # Define the project cmake_policy( SET CMP0048 NEW ) # version in project() -project( locust_mc VERSION 2.6.2) +project( locust_mc VERSION 2.7.0) list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/Scarab/cmake ) diff --git a/Source/Generators/LMCArraySignalGenerator.cc b/Source/Generators/LMCArraySignalGenerator.cc index 4cb76862..f72060ac 100644 --- a/Source/Generators/LMCArraySignalGenerator.cc +++ b/Source/Generators/LMCArraySignalGenerator.cc @@ -48,103 +48,117 @@ namespace locust fKassNeverStarted( false ), fSkippedSamples( false ), fAllowFastSampling( false ), - fInterface( new KassLocustInterface() ) + fInterface( nullptr ) // Initialize fInterface to (nullptr) instead of to (new KassLocustInterface()) { fRequiredSignalState = Signal::kTime; - - KLInterfaceBootstrapper::get_instance()->SetInterface( fInterface ); } ArraySignalGenerator::~ArraySignalGenerator() { } - bool ArraySignalGenerator::Configure( const scarab::param_node& aParam ) + void ArraySignalGenerator::SetParameters( const scarab::param_node& aParam ) { + fParam = &aParam; + } + - if (aParam.has( "power-combining-feed" )) + const scarab::param_node* ArraySignalGenerator::GetParameters() + { + return fParam; + } + + bool ArraySignalGenerator::ConfigureInterface( Signal* aSignal ) + { + + if ( fInterface == nullptr ) fInterface.reset( new KassLocustInterface() ); + KLInterfaceBootstrapper::get_instance()->SetInterface( fInterface ); + + const scarab::param_node& tParam = *GetParameters(); + + if (tParam.has( "power-combining-feed" )) { int npowercombiners = 0; - if(aParam["power-combining-feed"]().as_string() == "voltage-divider") + if(tParam["power-combining-feed"]().as_string() == "voltage-divider") { npowercombiners += 1; fPowerCombiner = new VoltageDivider; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring voltage divider."); exit(-1); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); } } - if(aParam["power-combining-feed"]().as_string() == "slotted-waveguide") + if(tParam["power-combining-feed"]().as_string() == "slotted-waveguide") { npowercombiners += 1; fPowerCombiner = new SlottedWaveguide; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring slotted waveguide."); exit(-1); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); } } - if(aParam["power-combining-feed"]().as_string() == "single-patch") + if(tParam["power-combining-feed"]().as_string() == "single-patch") { npowercombiners += 1; fPowerCombiner = new SinglePatch; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring single patch."); exit(-1); } fAntennaElementPositioner = new SinglePatchPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring single patch positioner."); exit(-1); } } - if(aParam["power-combining-feed"]().as_string() == "corporate") + if(tParam["power-combining-feed"]().as_string() == "corporate") { npowercombiners += 1; fPowerCombiner = new CorporateFeed; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring corporate feed."); exit(-1); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); } } - if(aParam["power-combining-feed"]().as_string() == "s-matrix") + if(tParam["power-combining-feed"]().as_string() == "s-matrix") { npowercombiners += 1; fPowerCombiner = new SMatrix; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring s matrix."); exit(-1); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); @@ -152,19 +166,19 @@ namespace locust } - if((aParam["power-combining-feed"]().as_string() == "unit-cell-one-quarter")|| - (aParam["power-combining-feed"]().as_string() == "unit-cell-seven-eighths")|| - (aParam["power-combining-feed"]().as_string() == "unit-cell-nine-sixteenths")) + if((tParam["power-combining-feed"]().as_string() == "unit-cell-one-quarter")|| + (tParam["power-combining-feed"]().as_string() == "unit-cell-seven-eighths")|| + (tParam["power-combining-feed"]().as_string() == "unit-cell-nine-sixteenths")) { npowercombiners += 1; fPowerCombiner = new UnitCell; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring unit cell."); exit(-1); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); @@ -172,16 +186,16 @@ namespace locust } - if(aParam["power-combining-feed"]().as_string() == "series-feed") + if(tParam["power-combining-feed"]().as_string() == "series-feed") { npowercombiners += 1; fPowerCombiner = new SeriesFeed; - if(!fPowerCombiner->Configure(aParam)) + if(!fPowerCombiner->Configure(tParam)) { LERROR(lmclog,"Error configuring series feed."); } fAntennaElementPositioner = new AntennaElementPositioner; - if(!fAntennaElementPositioner->Configure(aParam)) + if(!fAntennaElementPositioner->Configure(tParam)) { LERROR(lmclog,"Error configuring antenna element positioner."); exit(-1); @@ -203,15 +217,15 @@ namespace locust } - if( aParam.has( "transmitter" )) + if( tParam.has( "transmitter" )) { int ntransmitters = 0; - if(aParam["transmitter"]().as_string() == "antenna") + if(tParam["transmitter"]().as_string() == "antenna") { ntransmitters += 1; fTransmitter = new AntennaSignalTransmitter; - if(!fTransmitter->Configure(aParam)) + if(!fTransmitter->Configure(tParam)) { LERROR(lmclog,"Error Configuring antenna signal transmitter class"); } @@ -221,22 +235,22 @@ namespace locust } } - if(aParam["transmitter"]().as_string() == "planewave") + if(tParam["transmitter"]().as_string() == "planewave") { ntransmitters += 1; fTransmitter = new PlaneWaveTransmitter; - if(!fTransmitter->Configure(aParam)) + if(!fTransmitter->Configure(tParam)) { LERROR(lmclog,"Error Configuring planewave transmitter class"); } } - if(aParam["transmitter"]().as_string() == "kassiopeia") + if(tParam["transmitter"]().as_string() == "kassiopeia") { ntransmitters += 1; fTransmitter = new KassTransmitter; - if(!fTransmitter->Configure(aParam)) + if(!fTransmitter->Configure(tParam)) { LERROR(lmclog,"Error Configuring kassiopeia transmitter class"); } @@ -256,22 +270,40 @@ namespace locust } - if(!fTFReceiverHandler.Configure(aParam)) + if(!fTFReceiverHandler.Configure(tParam)) { LERROR(lmclog,"Error configuring receiver FIRHandler class"); } - if( aParam.has( "buffer-size" ) ) + if( tParam.has( "buffer-size" ) ) { - fFieldBufferSize = aParam["buffer-size"]().as_int(); - fHilbertTransform.SetBufferSize(aParam["buffer-size"]().as_int()); + fFieldBufferSize = tParam["buffer-size"]().as_int(); + fHilbertTransform.SetBufferSize(tParam["buffer-size"]().as_int()); } - if(!fHilbertTransform.Configure(aParam)) + if(!fHilbertTransform.Configure(tParam)) { LERROR(lmclog,"Error configuring buffer sizes in receiver HilbertTransform class"); } + + + + fInterface->fConfigureKass = new ConfigureKass(); + fInterface->fConfigureKass->SetParameters( tParam ); + + return true; + } + + + + + bool ArraySignalGenerator::Configure( const scarab::param_node& aParam ) + { + + SetParameters( aParam ); + + if( aParam.has( "lo-frequency" ) ) { fLO_Frequency = aParam["lo-frequency"]().as_double(); @@ -328,6 +360,17 @@ namespace locust return true; } + bool ArraySignalGenerator::RecordRunParameters( Signal* aSignal ) + { + fInterface->aRunParameter = new RunParameters(); + fInterface->aRunParameter->fSamplingRateMHz = fAcquisitionRate; + fInterface->aRunParameter->fDecimationFactor = aSignal->DecimationFactor(); + fInterface->aRunParameter->fLOfrequency = fLO_Frequency; + + return true; + } + + void ArraySignalGenerator::Accept( GeneratorVisitor* aVisitor ) const { aVisitor->Visit( this ); @@ -620,6 +663,9 @@ namespace locust bool ArraySignalGenerator::DoGenerate( Signal* aSignal ) { + ConfigureInterface( aSignal ); + RecordRunParameters( aSignal ); + if(!InitializeElementArray()) { LERROR(lmclog,"Error configuring Element array"); diff --git a/Source/Generators/LMCArraySignalGenerator.hh b/Source/Generators/LMCArraySignalGenerator.hh index 912446d4..4f629b85 100644 --- a/Source/Generators/LMCArraySignalGenerator.hh +++ b/Source/Generators/LMCArraySignalGenerator.hh @@ -64,6 +64,11 @@ namespace locust virtual ~ArraySignalGenerator(); bool Configure( const scarab::param_node& aNode ); + bool ConfigureInterface(Signal* aSignal); + bool RecordRunParameters(Signal* aSignal); + const scarab::param_node* GetParameters(); + void SetParameters( const scarab::param_node& aNode ); + void Accept( GeneratorVisitor* aVisitor ) const; @@ -124,6 +129,8 @@ namespace locust HilbertTransform fHilbertTransform; kl_interface_ptr_t fInterface; + const scarab::param_node* fParam; + }; diff --git a/Source/Generators/LMCCavitySignalGenerator.cc b/Source/Generators/LMCCavitySignalGenerator.cc index 016c624c..a8ea83d3 100644 --- a/Source/Generators/LMCCavitySignalGenerator.cc +++ b/Source/Generators/LMCCavitySignalGenerator.cc @@ -266,6 +266,8 @@ namespace locust } else { + // Delay SetSeed to allow time stamp to advance between randomized tracks. + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); SetSeed (time(NULL) ); } } @@ -298,6 +300,18 @@ namespace locust return true; } + bool CavitySignalGenerator::RecordRunParameters( Signal* aSignal ) + { + fInterface->aRunParameter = new RunParameters(); + fInterface->aRunParameter->fSamplingRateMHz = fAcquisitionRate; + fInterface->aRunParameter->fDecimationFactor = aSignal->DecimationFactor(); + fInterface->aRunParameter->fLOfrequency = fLO_Frequency; + + return true; + } + + + bool CavitySignalGenerator::SetSeed(int aSeed) { LPROG(lmclog,"Setting random seed for track delay to " << aSeed); @@ -564,6 +578,7 @@ namespace locust bool CavitySignalGenerator::DoGenerateTime( Signal* aSignal ) { ConfigureInterface( aSignal ); + RecordRunParameters( aSignal ); if (fRandomPreEventSamples) RandomizeStartDelay(); diff --git a/Source/Generators/LMCCavitySignalGenerator.hh b/Source/Generators/LMCCavitySignalGenerator.hh index b0470852..cb8efd13 100644 --- a/Source/Generators/LMCCavitySignalGenerator.hh +++ b/Source/Generators/LMCCavitySignalGenerator.hh @@ -73,6 +73,7 @@ namespace locust bool Configure( const scarab::param_node& aNode ); bool ConfigureInterface(Signal* aSignal); + bool RecordRunParameters(Signal* aSignal); bool CrossCheckCavityConfig(); bool CrossCheckAliasing(Signal* aSignal, double dopplerFrequency ); diff --git a/Source/Generators/LMCGaussianNoiseGenerator.cc b/Source/Generators/LMCGaussianNoiseGenerator.cc index 9aa03223..4ea6daf9 100644 --- a/Source/Generators/LMCGaussianNoiseGenerator.cc +++ b/Source/Generators/LMCGaussianNoiseGenerator.cc @@ -26,9 +26,7 @@ namespace locust fMean( 0. ), fSigma( 1. ), fRandomSeed( 0 ), - fNormDist( fMean, fSigma ), - fWriteRootTree( false ), - fRootFilename( "LocustNoise.root") + fNormDist( fMean, fSigma ) { fRequiredSignalState = Signal::kFreq; } @@ -60,19 +58,6 @@ namespace locust return false; } - if (aParam.has( "write-root-tree" )) - { - if (aParam["write-root-tree"]().as_bool()) - { - fWriteRootTree = true; - } - } - - if( aParam.has( "root-filename" ) ) - { - fRootFilename = aParam["root-filename"]().as_string(); - } - if (aParam.has( "random-seed") ) { @@ -173,24 +158,6 @@ namespace locust return; } - - bool GaussianNoiseGenerator::WriteRootTree() - { - #ifdef ROOT_FOUND - FileWriter* aRootTreeWriter = RootTreeWriter::get_instance(); - aRootTreeWriter->SetFilename(fRootFilename); - aRootTreeWriter->OpenFile("UPDATE"); - RunParameters* aRunParameter = new RunParameters(); - aRunParameter->fNoise = fSigma*fSigma; - aRootTreeWriter->WriteRunParameters(aRunParameter, "Noise"); - aRootTreeWriter->CloseFile(); - delete aRunParameter; - #endif - - return true; - } - - bool GaussianNoiseGenerator::DoGenerate( Signal* aSignal ) { return (this->*fDoGenerateFunc)( aSignal ); @@ -212,7 +179,6 @@ namespace locust std::default_random_engine generator(random_seed_val); SetMeanAndSigma( fMean, fSigma, fSigma * sqrt(fAcquisitionRate * 1.e6) ); - if (fWriteRootTree) WriteRootTree(); double gain=1.; const unsigned nchannels = fNChannels; diff --git a/Source/Generators/LMCGaussianNoiseGenerator.hh b/Source/Generators/LMCGaussianNoiseGenerator.hh index bdea9339..bd095f2d 100644 --- a/Source/Generators/LMCGaussianNoiseGenerator.hh +++ b/Source/Generators/LMCGaussianNoiseGenerator.hh @@ -12,11 +12,6 @@ #include "LMCRunLengthCalculator.hh" #include "LMCConst.hh" -#ifdef ROOT_FOUND - #include "LMCRunParameters.hh" - #include "LMCRootTreeWriter.hh" -#endif - #include namespace locust @@ -38,13 +33,8 @@ namespace locust - "noise-temperature": double -- Noise temperature in K. - "domain": string -- Determines whether the noise is generated in the time or frequency domain Available options: "time" and "freq" [default] - - "write-root-tree": boolean -- Flag to control whether or not value of noise power is written - to output Root file as a LMCRunParameter. - "random-seed": int -- Random seed used to generate random noise. If this is omitted then the noise spectrum is reproducible. - - "root-filename": string -- Name of output Root file. This can have the same name as other - generators' output Root files, in which case all of the Root objects will - be written to the same output file. */ class GaussianNoiseGenerator : public Generator @@ -76,7 +66,6 @@ namespace locust void SetDomain( Signal::State aDomain ); private: - bool WriteRootTree(); bool DoGenerate( Signal* aSignal ); bool DoGenerateTime( Signal* aSignal ); @@ -87,8 +76,6 @@ namespace locust double fMean; double fSigma; int fRandomSeed; - bool fWriteRootTree; - std::string fRootFilename; mutable std::normal_distribution< double > fNormDist; }; diff --git a/Source/IO/LMCFileWriter.hh b/Source/IO/LMCFileWriter.hh index 5b41f770..fbe54989 100644 --- a/Source/IO/LMCFileWriter.hh +++ b/Source/IO/LMCFileWriter.hh @@ -43,7 +43,7 @@ namespace locust virtual double GetTestVar() {return 0.;}; virtual void SetTestVar(double aValue) {}; virtual void WriteEvent(Event* anEvent) {}; - virtual void WriteRunParameters( RunParameters* aRunParameter, const char* aParameterName ) {}; + virtual void WriteRunParameters( RunParameters* aRunParameter) {}; virtual void Write1DHisto(TH1D* aHisto) {}; virtual void Write2DHisto(TH2D* aHisto) {}; virtual void WriteVector1DHisto(std::vector aVector, double xmin, double xmax) {}; diff --git a/Source/IO/LMCRootTreeWriter.cc b/Source/IO/LMCRootTreeWriter.cc index 1643c8c3..433ee72c 100644 --- a/Source/IO/LMCRootTreeWriter.cc +++ b/Source/IO/LMCRootTreeWriter.cc @@ -35,22 +35,16 @@ namespace locust return true; } - void RootTreeWriter::WriteRunParameters( RunParameters* aRunParameter, const char* aParameterName ) + void RootTreeWriter::WriteRunParameters( RunParameters* aRunParameter) { TTree *aTree = new TTree("Run Parameters","Locust Tree"); - - if (aParameterName=="Noise") - { - aTree->Branch("Noise", &aRunParameter->fNoise, "Noise/D"); - } - if (aParameterName=="LOfrequency") - { - aTree->Branch("LO frequency", &aRunParameter->fLOfrequency, "LOfrequency/D"); - } - + aTree->Branch("LOFrequency", &aRunParameter->fLOfrequency, "LOfrequency/D"); + aTree->Branch("SamplingFrequencyMHz", &aRunParameter->fSamplingRateMHz, "SamplingFrequency/D"); + aTree->Branch("DecimationRate", &aRunParameter->fDecimationFactor, "DecimationFactor/D"); aTree->Fill(); aTree->Write(); delete aTree; + } void RootTreeWriter::WriteEvent(Event* anEvent) diff --git a/Source/IO/LMCRootTreeWriter.hh b/Source/IO/LMCRootTreeWriter.hh index ee642069..f1ef7bbc 100644 --- a/Source/IO/LMCRootTreeWriter.hh +++ b/Source/IO/LMCRootTreeWriter.hh @@ -34,7 +34,7 @@ namespace locust allow_singleton_access( RootTreeWriter ); virtual void WriteEvent(Event* anEvent); - virtual void WriteRunParameters( RunParameters* aRunParameter, const char* aParameterName ); + virtual void WriteRunParameters( RunParameters* aRunParameter); private: diff --git a/Source/IO/LMCRunParameters.hh b/Source/IO/LMCRunParameters.hh index 5bde8157..867202de 100644 --- a/Source/IO/LMCRunParameters.hh +++ b/Source/IO/LMCRunParameters.hh @@ -28,6 +28,8 @@ namespace locust double fNoise; double fLOfrequency; + double fSamplingRateMHz; + double fDecimationFactor; ClassDef(RunParameters,1) // Root syntax. diff --git a/Source/Kassiopeia/LMCCyclotronRadiationExtractor.cc b/Source/Kassiopeia/LMCCyclotronRadiationExtractor.cc index 89683e2c..937cf839 100644 --- a/Source/Kassiopeia/LMCCyclotronRadiationExtractor.cc +++ b/Source/Kassiopeia/LMCCyclotronRadiationExtractor.cc @@ -54,6 +54,50 @@ namespace locust fInterface->fProject8Phase = P8Phase; } + bool CyclotronRadiationExtractor::UpdateTrackProperties( Kassiopeia::KSParticle &aFinalParticle, unsigned index, bool bStart ) + { + double tTime = index / fInterface->aRunParameter->fSamplingRateMHz / 1.e6 / fInterface->aRunParameter->fDecimationFactor; +#ifdef ROOT_FOUND + if (bStart) + { + fInterface->aTrack.StartTime = tTime; + fInterface->aTrack.StartFrequency = aFinalParticle.GetCyclotronFrequency(); + double tX = aFinalParticle.GetPosition().X(); + double tY = aFinalParticle.GetPosition().Y(); + fInterface->aTrack.Radius = pow(tX*tX + tY*tY, 0.5); + fInterface->aTrack.RadialPhase = calcOrbitPhase(tX, tY); + } + else + { + fInterface->aTrack.EndTime = tTime; + } +#endif + + return true; + } + + double CyclotronRadiationExtractor::calcOrbitPhase(double tX, double tY) + { + double phase = 0.; + if ((fabs(tX) > 0.)) + { + phase = atan(tY/tX); + } + + phase += quadrantOrbitCorrection(phase, tY); + return phase; + } + + double CyclotronRadiationExtractor::quadrantOrbitCorrection(double phase, double tY) + { + double phaseCorrection = 0.; + if (((phase < 0.)&&(tY > 0.)) || ((phase > 0.)&&(tY < 0.))) + phaseCorrection = LMCConst::Pi(); + + return phaseCorrection; + } + + locust::Particle CyclotronRadiationExtractor::ExtractKassiopeiaParticle( Kassiopeia::KSParticle &anInitialParticle, Kassiopeia::KSParticle &aFinalParticle) @@ -83,6 +127,7 @@ namespace locust if (anInitialParticle.GetPosition().GetZ()/aFinalParticle.GetPosition().GetZ() < 0.) // trap center { fPitchAngle = aFinalParticle.GetPolarAngleToB(); + fInterface->aTrack.PitchAngle = aFinalParticle.GetPolarAngleToB(); } } aNewParticle.SetPitchAngle(fPitchAngle); @@ -143,6 +188,7 @@ namespace locust fPitchAngle = -99.; // new electron needs central pitch angle reset. double dt = aFinalParticle.GetTime() - anInitialParticle.GetTime(); fFieldCalculator->SetNFilterBinsRequired( dt ); + UpdateTrackProperties( aFinalParticle, fInterface->fSampleIndex, 1 ); } double t_poststep = aFinalParticle.GetTime(); @@ -152,6 +198,7 @@ namespace locust { fSampleIndex = fInterface->fSampleIndex; // record Locust sample index before locking + UpdateTrackProperties( aFinalParticle, fSampleIndex, 0 ); // Keep recording the track candidate end time. std::unique_lock< std::mutex >tLock( fInterface->fMutexDigitizer, std::defer_lock ); // lock access to mutex before writing to globals. tLock.lock(); @@ -196,7 +243,7 @@ namespace locust { // If the Locust sample index has not advanced yet, keep checking it. tTriggerConfirm += 1; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if ( 0 < 1 ) continue; // wait small amount of time. if ( tTriggerConfirm % 1000 == 0 ) { LPROG(lmclog,"Checking the digitizer synchronization, tTriggerConfirm index = " << tTriggerConfirm ); diff --git a/Source/Kassiopeia/LMCCyclotronRadiationExtractor.hh b/Source/Kassiopeia/LMCCyclotronRadiationExtractor.hh index bf9fdbf5..fad5a630 100644 --- a/Source/Kassiopeia/LMCCyclotronRadiationExtractor.hh +++ b/Source/Kassiopeia/LMCCyclotronRadiationExtractor.hh @@ -10,6 +10,11 @@ #include "LMCParticle.hh" #include "LMCException.hh" +#ifdef ROOT_FOUND + #include "LMCRootTreeWriter.hh" +#endif + + #include @@ -42,6 +47,11 @@ namespace locust void SetTrajectory( Kassiopeia::KSTrajectory* aTrajectory ); void SetP8Phase( int P8Phase ); + bool UpdateTrackProperties( Kassiopeia::KSParticle &aFinalParticle, unsigned index, bool bStart ); + double calcOrbitPhase(double tX, double tY); + double quadrantOrbitCorrection(double phase, double vx); + + private: diff --git a/Source/Kassiopeia/LMCEventHold.cc b/Source/Kassiopeia/LMCEventHold.cc index d026c769..d98cc7d7 100644 --- a/Source/Kassiopeia/LMCEventHold.cc +++ b/Source/Kassiopeia/LMCEventHold.cc @@ -15,11 +15,13 @@ namespace locust LOGGER( lmclog, "EventHold" ); EventHold::EventHold() : + fTruthOutputFilename("LocustEventProperties.root"), fInterface( KLInterfaceBootstrapper::get_instance()->GetInterface() ) { } EventHold::EventHold( const EventHold& aOrig ) : KSComponent(), + fTruthOutputFilename("LocustEventProperties.root"), fInterface( aOrig.fInterface ) { } @@ -33,9 +35,80 @@ namespace locust return new EventHold( *this ); } + bool EventHold::ConfigureByInterface() + { + OpenEvent(); + + if (fInterface->fConfigureKass) + { + const scarab::param_node* aParam = fInterface->fConfigureKass->GetParameters(); + if (!this->Configure( *aParam )) + { + LERROR(lmclog,"Error configuring EventHold class"); + return false; + } + } + else + { + LPROG(lmclog,"EventHold class did not need to be configured."); + return true; + } + return true; + } + + bool EventHold::Configure( const scarab::param_node& aParam ) + { + if ( aParam.has( "random-track-seed" ) ) + { + fInterface->anEvent->fRandomSeed = aParam["random-track-seed"]().as_int(); + } + if ( aParam.has( "truth-output-filename" ) ) + { + fTruthOutputFilename = aParam["truth-output-filename"]().as_string(); + } + + + return true; + } + + + + bool EventHold::OpenEvent() + { +#ifdef ROOT_FOUND + fInterface->anEvent = new Event(); + fInterface->anEvent->fEventID = 0; + fInterface->anEvent->fRandomSeed = -99; + fInterface->anEvent->fLOFrequency = -99.; + fInterface->anEvent->fRandomSeed = -99; +#endif + + return true; + } + + + bool EventHold::WriteEvent() + { + std::string tOutputPath = TOSTRING(PB_OUTPUT_DIR); + std::string sFileName = tOutputPath+"/"+fTruthOutputFilename; +#ifdef ROOT_FOUND + FileWriter* aRootTreeWriter = RootTreeWriter::get_instance(); + aRootTreeWriter->SetFilename(sFileName); + aRootTreeWriter->OpenFile("RECREATE"); + fInterface->anEvent->AddTrack( fInterface->aTrack ); + aRootTreeWriter->WriteEvent( fInterface->anEvent ); + aRootTreeWriter->WriteRunParameters(fInterface->aRunParameter); + aRootTreeWriter->CloseFile(); +#endif + return true; + } bool EventHold::ExecutePreEventModification(Kassiopeia::KSEvent &anEvent) { + if ( !ConfigureByInterface() ) + { + return false; + } LPROG( lmclog, "Kass is waiting for event trigger" ); @@ -62,6 +135,7 @@ namespace locust bool EventHold::ExecutePostEventModification(Kassiopeia::KSEvent &anEvent) { + WriteEvent(); fInterface->fEventInProgress = false; fInterface->fDigitizerCondition.notify_one(); // unlock LPROG( lmclog, "Kass is waking after event" ); diff --git a/Source/Kassiopeia/LMCEventHold.hh b/Source/Kassiopeia/LMCEventHold.hh index 24471e11..3f02d4ff 100644 --- a/Source/Kassiopeia/LMCEventHold.hh +++ b/Source/Kassiopeia/LMCEventHold.hh @@ -13,6 +13,11 @@ #include "LMCKassLocustInterface.hh" +#ifdef ROOT_FOUND + #include "LMCRootTreeWriter.hh" +#endif + + namespace locust { @@ -22,9 +27,15 @@ namespace locust public: EventHold(); EventHold( const EventHold& aOrig ); + bool OpenEvent(); + bool WriteEvent(); virtual ~EventHold(); EventHold* Clone() const; + bool ConfigureByInterface(); + bool Configure( const scarab::param_node& aParam ); + std::string fTruthOutputFilename; + public: diff --git a/Source/Kassiopeia/LMCKassLocustInterface.hh b/Source/Kassiopeia/LMCKassLocustInterface.hh index 73fc6c9d..7e5c3287 100644 --- a/Source/Kassiopeia/LMCKassLocustInterface.hh +++ b/Source/Kassiopeia/LMCKassLocustInterface.hh @@ -20,6 +20,9 @@ #include #include +#ifdef ROOT_FOUND + #include "LMCRootTreeWriter.hh" +#endif namespace locust { @@ -69,6 +72,14 @@ namespace locust int fTriggerConfirm; int fFastRecordLength; +#ifdef ROOT_FOUND + Event* anEvent; + Track aTrack; + RunParameters* aRunParameter; +#endif + + + }; @@ -91,6 +102,7 @@ namespace locust ~KLInterfaceBootstrapper(); kl_interface_ptr_t fInterface; + }; } /* namespace locust */ diff --git a/Source/Kassiopeia/LMCRunPause.cc b/Source/Kassiopeia/LMCRunPause.cc index 1d8e4c15..44e29aba 100644 --- a/Source/Kassiopeia/LMCRunPause.cc +++ b/Source/Kassiopeia/LMCRunPause.cc @@ -272,8 +272,15 @@ namespace locust { double tMaxTrackLength = 0.; + double tMinTrackLengthFraction = 0.1; fLocustMaxTimeTerminator = new Kassiopeia::KSTermMaxTime(); + if ( aParam.has( "min-track-length-fraction" ) ) + { + tMinTrackLengthFraction = aParam["min-track-length-fraction"]().as_double(); + LPROG(lmclog,"Setting minimum track length fraction to " << tMinTrackLengthFraction); + } + if ( aParam.has( "track-length" ) ) { tMaxTrackLength = aParam["track-length"]().as_double(); @@ -290,7 +297,8 @@ namespace locust if ( aParam["random-track-length"]().as_bool() == true) { srand ( GetSeed( aParam )); - double tRandomTime = tMaxTrackLength/10. * ( 1 + rand() % 10 ); // 0.1*tMaxTrackLength < t < 1.1*tMaxTrackLength + double tMinTrackLength = tMaxTrackLength * tMinTrackLengthFraction; + double tRandomTime = tMinTrackLength + (tMaxTrackLength - tMinTrackLength) * (rand() % 10) / 9.; fLocustMaxTimeTerminator->SetTime( tRandomTime ); LPROG(lmclog,"Randomizing the track length to " << tRandomTime); }