-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Here's a new BeamFetcher tool that grabs things based on the trigger timestamp * Committing the other files to make the new BeamFetcher work
- Loading branch information
Showing
8 changed files
with
882 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
// standard library includes | ||
#include <ctime> | ||
#include <limits> | ||
|
||
// ToolAnalysis includes | ||
#include "BeamFetcherV2.h" | ||
#include "IFBeamDBInterfaceV2.h" | ||
|
||
namespace { | ||
constexpr uint64_t TWO_HOURS = 7200000ull; // ms | ||
constexpr uint64_t THIRTY_SECONDS = 30000ull; // ms | ||
} | ||
|
||
BeamFetcherV2::BeamFetcherV2():Tool() | ||
{} | ||
|
||
//------------------------------------------------------------------------------ | ||
bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) | ||
{ | ||
// Load configuration file variables | ||
if ( !config_filename.empty() ) m_variables.Initialise(config_filename); | ||
|
||
// Assign a transient data pointer | ||
m_data = &data; | ||
|
||
// Get the things | ||
bool got_verbosity = m_variables.Get("verbose", verbosity); | ||
bool got_bundleflag = m_variables.Get("IsBundle", fIsBundle); | ||
bool got_devicesfile = m_variables.Get("DevicesFile", fDevicesFile); | ||
bool got_saveroot = m_variables.Get("SaveROOT", fSaveROOT); | ||
bool got_chunkMSec = m_variables.Get("TimeChunkStepInMilliseconds", fChunkStepMSec); | ||
|
||
|
||
// Check the config parameters and set default values if necessary | ||
if (!got_verbosity) verbosity = 1; | ||
|
||
if (!got_devicesfile) { | ||
logmessage = ("Error (BeamFetcherV2): You must define which devices to poll" | ||
" via a DevicesFile."); | ||
Log(logmessage, v_error, verbosity); | ||
return false; | ||
} else { | ||
// Grab the stuff from the file | ||
std::ifstream devicesFile(fDevicesFile); | ||
if ( devicesFile.good() ) { | ||
std::string line; | ||
while (std::getline(devicesFile, line)) | ||
fDevices.push_back(line); | ||
|
||
if (!fDevices.size()) { | ||
logmessage = ("Error (BeamFetcherV2): No devices specified in your" | ||
" Devices file."); | ||
Log(logmessage, v_error, verbosity); | ||
return false; | ||
} | ||
} else{ | ||
logmessage = ("Error (BeamFetcherV2): Devices file " | ||
"\"" + fDevicesFile + "\"" | ||
" does not exists"); | ||
Log(logmessage, v_error, verbosity); | ||
return false; | ||
} | ||
devicesFile.close(); | ||
} | ||
|
||
if (!got_saveroot) { | ||
logmessage = ("Warning (BeamFetcherV2): SaveROOT was not" | ||
" set in the config file. Using default \"false\""); | ||
Log(logmessage, v_warning, verbosity); | ||
fSaveROOT = false; | ||
} | ||
|
||
|
||
if (!got_chunkMSec) { | ||
logmessage = ("Warning (BeamFetcherV2): TimeChunkStepInMilliseconds was not" | ||
" set in the config file. Using default \"7200000\""); | ||
Log(logmessage, v_warning, verbosity); | ||
fChunkStepMSec = 7200000; | ||
} | ||
|
||
|
||
if (!got_bundleflag || (fIsBundle !=0 && fIsBundle != 1)) { | ||
logmessage = ("Error (BeamFetcherV2): IsBundle flag was not set correctly" | ||
" in the config file."); | ||
Log(logmessage, v_error, verbosity); | ||
return 0; | ||
} | ||
|
||
if (fSaveROOT) this->SetupROOTFile(); | ||
|
||
return true; | ||
} | ||
|
||
|
||
//------------------------------------------------------------------------------ | ||
bool BeamFetcherV2::Execute() | ||
{ | ||
// Do the things | ||
bool goodFetch = this->FetchFromTrigger(); | ||
|
||
if (goodFetch) { | ||
// Emplace fBeamDataToSave to CStore for other tools to use | ||
m_data->CStore.Set("BeamData",fBeamDataToSave); | ||
goodFetch = true; | ||
} | ||
|
||
if (fSaveROOT) this->WriteTrees(); | ||
|
||
// Clear for the next Fetch | ||
fBeamDataToSave.clear(); | ||
|
||
|
||
return goodFetch; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
bool BeamFetcherV2::Finalise() | ||
{ | ||
if (fSaveROOT) this->SaveROOTFile(); | ||
|
||
std::cout << "BeamFetcherV2 tool exitting" << std::endl; | ||
|
||
return true; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
bool BeamFetcherV2::FetchFromTrigger() | ||
{ | ||
// Get a const reference to the beam database interface | ||
const auto& db = IFBeamDBInterfaceV2::Instance(); | ||
|
||
// Need to get the trigger times | ||
std::map<uint64_t,std::vector<uint32_t>>* TimeToTriggerWordMap=nullptr; | ||
bool get_ok = m_data->CStore.Get("TimeToTriggerWordMap",TimeToTriggerWordMap); | ||
|
||
// Now loop over the CTC timestamps | ||
if (get_ok && TimeToTriggerWordMap) { | ||
for (auto iterator : *TimeToTriggerWordMap) { | ||
// We only want to get beam info for beam triggers (word 5) | ||
bool hasBeamTrig = false; | ||
for (auto word : iterator.second) | ||
if (word == 5) hasBeamTrig = true; | ||
if (!hasBeamTrig) continue; | ||
|
||
uint64_t trigTimestamp = iterator.first; | ||
|
||
// Need to drop from ns to ms. This means that some timestamps will | ||
// already be recorded. We can skip these cases | ||
trigTimestamp = trigTimestamp/1E6; | ||
if (fBeamDataToSave.find(trigTimestamp) != fBeamDataToSave.end()) | ||
continue; | ||
|
||
// Check if we already have the info we need | ||
bool fetch = false; | ||
std::map<uint64_t, std::map<std::string, BeamDataPoint> >::iterator low, prev; | ||
low = fBeamData.lower_bound(trigTimestamp); | ||
if (low == fBeamData.end()) { | ||
fetch = true; | ||
logmessage = ("BeamFetcherV2: I'm going to query the DB"); | ||
Log(logmessage, v_message, verbosity); | ||
} | ||
|
||
// We'll pull fChunkStepMSec worth of data at a time to avoid rapid queries | ||
if (fetch) { | ||
if (fIsBundle) { | ||
fBeamData = db.QueryBeamDBBundleSpan(fDevices[0], trigTimestamp, trigTimestamp+fChunkStepMSec); | ||
} else { | ||
std::map<uint64_t, std::map<std::string, BeamDataPoint> > tempMap; | ||
|
||
for (auto device : fDevices) { | ||
auto tempMap = db.QueryBeamDBSingleSpan(device, trigTimestamp, trigTimestamp+fChunkStepMSec); | ||
fBeamData.insert(tempMap.begin(), tempMap.end()); | ||
} | ||
} | ||
} | ||
|
||
// Now we can match the Beam info to CTC timestamps for saving to the CStore | ||
low = fBeamData.lower_bound(trigTimestamp); | ||
if (low == fBeamData.end()) { | ||
logmessage = ("Error (BeamFetcherV2): We fetched the data based on the CTC" | ||
" but somehow didn't turn anything up!?"); | ||
Log(logmessage, v_error, verbosity); | ||
return false; | ||
} else if (low == fBeamData.begin()) { | ||
fBeamDataToSave[trigTimestamp] = low->second; | ||
} else { | ||
// Check the previous DB timestamp to see if it's closer in time | ||
prev = std::prev(low); | ||
if ((trigTimestamp - prev->first) < (low->first - trigTimestamp)) | ||
fBeamDataToSave[trigTimestamp] = prev->second; | ||
else | ||
fBeamDataToSave[trigTimestamp] = low->second; | ||
} | ||
}// end loop over trigger times | ||
} else { | ||
logmessage = ("Error (BeamFetcherV2): Could not load CTC information for" | ||
" timestamps. Did you run TriggerDataDecoder?"); | ||
Log(logmessage, v_error, verbosity); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
bool BeamFetcherV2::SaveToFile() | ||
{ | ||
BoostStore fBeamDBStore(false, BOOST_STORE_MULTIEVENT_FORMAT); | ||
fBeamDBStore.Set("BeamData", fBeamData); | ||
fBeamDBStore.Save(fOutFileName); | ||
fBeamDBStore.Delete(); | ||
|
||
fBeamDBStore.Header->Set("BeamDBIndex", fBeamDBIdx); | ||
|
||
// Find the range of times covered by the entire downloaded database | ||
uint64_t overall_start_ms = std::numeric_limits<uint64_t>::max(); | ||
uint64_t overall_end_ms = 0ull; | ||
|
||
for (const auto& pair : fBeamDBIdx) { | ||
uint64_t temp_start_ms = pair.second.first; | ||
uint64_t temp_end_ms = pair.second.second; | ||
if (temp_start_ms < overall_start_ms) overall_start_ms = temp_start_ms; | ||
if (temp_end_ms > overall_end_ms) overall_end_ms = temp_end_ms; | ||
} | ||
|
||
fBeamDBStore.Header->Set("StartMillisecondsSinceEpoch", overall_start_ms); | ||
fBeamDBStore.Header->Set("EndMillisecondsSinceEpoch", overall_end_ms); | ||
|
||
fBeamDBStore.Close(); | ||
|
||
logmessage = "Retrieval of beam status data complete"; | ||
Log(logmessage, v_warning, verbosity); | ||
|
||
return true; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
void BeamFetcherV2::SetupROOTFile() | ||
{ | ||
fOutFile = new TFile("beamfetcher_tree.root", "RECREATE"); | ||
fOutTree = new TTree("BeamTree", "BeamTree"); | ||
fOutTree->Branch("Timestamp", &fTimestamp); | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
void BeamFetcherV2::WriteTrees() | ||
{ | ||
// Loop over timestamps | ||
int devCounter = 0; | ||
for (const auto iterTS : fBeamDataToSave) { | ||
fTimestamp = iterTS.first; | ||
|
||
// Loop over devices | ||
for (const auto iterDev : iterTS.second) { | ||
std::string device = iterDev.first; | ||
std::replace( device.begin(), device.end(), ':', '_'); | ||
|
||
BeamDataPoint tempPoint = iterDev.second; | ||
|
||
// Dynamically create branches for each new device | ||
if (fDevIdx.find(device) == fDevIdx.end()) { | ||
fDevIdx[device] = devCounter; | ||
fOutTree->Branch(device.c_str(), | ||
&fValues[fDevIdx.at(device)]); | ||
++devCounter; | ||
} | ||
|
||
fValues[fDevIdx.at(device)] = tempPoint.value; | ||
}// end loop over devices | ||
|
||
fOutTree->Fill(); | ||
}// end loop over timestamps | ||
|
||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
void BeamFetcherV2::SaveROOTFile() | ||
{ | ||
fOutFile->cd(); | ||
fOutTree->Write(); | ||
fOutFile->Close(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Tool to download beam information from the Intensity Frontier | ||
// beam database and save it to the CStore. Modified from the original BeamFetcher | ||
// | ||
// Steven Gardiner <[email protected]> | ||
// Andrew Sutton <[email protected]> | ||
|
||
#pragma once | ||
|
||
// standard library includes | ||
#include <iostream> | ||
#include <string> | ||
|
||
// Boost includes | ||
#include <boost/date_time/posix_time/posix_time.hpp> | ||
#include <boost/date_time/gregorian/gregorian.hpp> | ||
|
||
// ToolAnalysis includes | ||
#include "Tool.h" | ||
|
||
// ROOT includes | ||
#include "TFile.h" | ||
#include "TTree.h" | ||
|
||
|
||
class BeamFetcherV2: public Tool { | ||
|
||
public: | ||
BeamFetcherV2(); | ||
bool Initialise(std::string configfile, DataModel& data); | ||
bool Execute(); | ||
bool Finalise(); | ||
|
||
protected: | ||
bool FetchFromTrigger(); | ||
bool SaveToFile(); | ||
|
||
void SetupROOTFile(); | ||
void WriteTrees(); | ||
void SaveROOTFile(); | ||
|
||
|
||
// Holder for the retrieved data and the stuff we'll save | ||
std::map<uint64_t, std::map<std::string, BeamDataPoint> > fBeamData; | ||
std::map<uint64_t, std::map<std::string, BeamDataPoint> > fBeamDataToSave; | ||
|
||
// For saving out to a file | ||
std::map<int, std::pair<uint64_t, uint64_t> > fBeamDBIdx; | ||
|
||
// Holder for the devices we're going to look up | ||
std::vector<std::string> fDevices; | ||
|
||
// For ROOT file | ||
TFile *fOutFile; | ||
TTree *fOutTree; | ||
uint64_t fTimestamp; | ||
double fValues[100]; | ||
std::map<std::string, int> fDevIdx; // map from device string to idx in fValues | ||
|
||
|
||
// Configuration variables | ||
int verbosity; | ||
bool fIsBundle; | ||
bool fSaveROOT; | ||
std::string fDevicesFile; | ||
std::string fOutFileName; | ||
uint64_t fChunkStepMSec; | ||
|
||
// Verbosity things | ||
int v_error = 0; | ||
int v_warning = 1; | ||
int v_message = 2; | ||
int v_debug = 3; | ||
int vv_debug = 4; | ||
std::string logmessage; | ||
}; |
Oops, something went wrong.