/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
// NOTE: Equipment list to be changed
// when tracker moved to MICE Hall.
// A few assertions to be removed.
// ES
#include "src/common_cpp/Recon/SciFi/RealDataDigitization.hh"
#include "src/common_cpp/DataStructure/DAQData.hh"
namespace MAUS {
RealDataDigitization::RealDataDigitization() {}
RealDataDigitization::~RealDataDigitization() {}
void RealDataDigitization::initialise() {
// -------------------------------------------------
// Load calibration, mapping and bad channel list.
// These calls are to be replaced by CDB interface...
bool map = load_mapping("mapping_7.txt");
bool calib = load_calibration("scifi_calibration_jan2013.txt");
bool bad_channels = load_bad_channels();
if ( !calib || !map || !bad_channels ) {
throw(Exception(Exception::recoverable,
"Could not load Tracker calibration, mapping or bad channel list.",
"RealDataDigitization::process"));
}
}
void RealDataDigitization::process(Spill *spill, Json::Value const &daq) {
// Check for existant pointers to ReconEvents and DAQData
if ( spill->GetDAQData() == NULL )
spill->SetDAQData(new DAQData());
if (spill->GetReconEvents() == NULL)
spill->SetReconEvents(new ReconEventPArray());
// Pick up JSON daq events.
Json::Value tracker_event = daq["tracker1"];
Tracker0DaqArray tracker0;
Tracker1DaqArray tracker1;
for ( unsigned int i = 0; i < tracker_event.size(); ++i ) { // loop over events
SciFiEvent* event = new SciFiEvent();
TrackerDaq *tracker0daq_event = new TrackerDaq();
TrackerDaq *tracker1daq_event = new TrackerDaq();
if ( tracker_event[i].isMember("VLSB_C") ) {
Json::Value input_event = tracker_event[i]["VLSB_C"];
// Merge tracker events.
for ( size_t idig = 0; idig < daq["tracker2"][i]["VLSB_C"].size(); ++idig ) {
input_event[input_event.size()] = daq["tracker2"][i]["VLSB_C"][idig];
}
process_VLSB_c(input_event, event, tracker0daq_event, tracker1daq_event);
} else if ( tracker_event[i].isMember("VLSB") ) {
Json::Value input_event = tracker_event[i]["VLSB"];
// Merge tracker events.
for ( size_t idig = 0; idig < daq["tracker2"][i]["VLSB"].size(); ++idig ) {
input_event[input_event.size()] = daq["tracker2"][i]["VLSB"][idig];
}
process_VLSB(input_event, event, tracker0daq_event, tracker1daq_event);
} else {
continue;
}
tracker0.push_back(tracker0daq_event); // end of event. push back.
tracker1.push_back(tracker1daq_event); // end of event. push back.
ReconEvent * revt = new ReconEvent();
// revt->SetSciFiEvent(new SciFiEvent(*event));
revt->SetSciFiEvent(event);
spill->GetReconEvents()->push_back(revt);
// delete event;
} // ends loop over events (i)
spill->GetDAQData()->SetTracker0DaqArray(tracker0);
spill->GetDAQData()->SetTracker1DaqArray(tracker1);
}
void RealDataDigitization::process_VLSB(Json::Value input_event,
SciFiEvent* event,
TrackerDaq *tracker0daq_event,
TrackerDaq *tracker1daq_event) {
VLSBArray vlsb_tracker0_array;
VLSBArray vlsb_tracker1_array;
// Loop over the VLSB channels of this event.
for ( unsigned int j = 0; j < input_event.size(); ++j ) {
Json::Value channel_in = input_event[j];
int ldc = channel_in["ldc_id"].asInt();
std::string detector = channel_in["detector"].asString();
int discriminator = channel_in["discriminator"].asInt();
int equip_type = channel_in["equip_type"].asInt();
int time_stamp = channel_in["time_stamp"].asInt();
int spill = channel_in["phys_event_number"].asInt();
int eventNo = channel_in["part_event_number"].asInt();
int bank = channel_in["bank"].asInt();
int channel_ro = channel_in["channel"].asInt();
int adc = channel_in["adc"].asInt();
int tdc = channel_in["tdc"].asInt();
VLSB vlsb;
vlsb.SetEquipType(equip_type);
vlsb.SetPhysEventNumber(spill);
vlsb.SetTimeStamp(time_stamp);
vlsb.SetDetector(detector);
vlsb.SetPartEventNumber(eventNo);
vlsb.SetChannel(channel_ro);
vlsb.SetBankID(bank);
vlsb.SetADC(adc);
vlsb.SetTDC(tdc);
vlsb.SetDiscriminator(discriminator);
vlsb.SetLdcId(ldc);
if ( bank < 32 ) {
vlsb_tracker0_array.push_back(vlsb);
} else {
vlsb_tracker1_array.push_back(vlsb);
}
if ( !is_good_channel(bank, channel_ro) ) {
continue;
}
// Get pedestal and gain from calibration.
// int new_bank = bank + 4*board;
double adc_pedestal = calibration_[bank][channel_ro]["adc_pedestal"].asDouble();
double adc_gain = calibration_[bank][channel_ro]["adc_gain"].asDouble();
double tdc_pedestal = calibration_[bank][channel_ro]["tdc_pedestal"].asDouble();
double tdc_gain = calibration_[bank][channel_ro]["tdc_gain"].asDouble();
// Calculate the number of photoelectrons.
double pe;
if ( adc_pedestal > _min && adc_gain > _min ) {
pe = (adc-adc_pedestal)/adc_gain;
} else {
pe = -10.0;
}
double time = -10.0;
/* No TDC calibration yet.
if ( tdc_pedestal > tdc_pedestal_min && tdc_gain > 0 ) {
time = (tdc-tdc_pedestal)/tdc_gain;
} else {
time = -10.0;
}
*/
// Find tracker, station, plane, channel.
int board = floor(bank/4);
int old_bank = bank%4;
int tracker, station, plane, channel;
bool found = false; // get_StatPlaneChannel(board, old_bank, channel_ro,
// tracker, station, plane, channel);
// Exclude missing modules.
if ( found ) { // pe > 1.0 &&
SciFiDigit *digit = new SciFiDigit(spill, eventNo,
tracker, station, plane, channel, pe, time);
event->add_digit(digit);
}
} // ends loop over channels (j)
tracker0daq_event->SetVLSBArray(vlsb_tracker0_array); // fill event with all vlsb digits
tracker1daq_event->SetVLSBArray(vlsb_tracker1_array); // fill event with all vlsb digits
}
void RealDataDigitization::process_VLSB_c(Json::Value input_event,
SciFiEvent* event,
TrackerDaq *tracker0daq_event,
TrackerDaq *tracker1daq_event) {
VLSB_CArray vlsb_c_tracker0_array;
VLSB_CArray vlsb_c_tracker1_array;
// Loop over the VLSB channels of this event.
for ( unsigned int j = 0; j < input_event.size(); ++j ) {
Json::Value channel_in = input_event[j];
int ldc = channel_in["ldc_id"].asInt();
std::string detector = channel_in["detector"].asString();
int discriminator = channel_in["discriminator"].asInt();
int equip_type = channel_in["equip_type"].asInt();
int time_stamp = channel_in["time_stamp"].asInt();
int spill = channel_in["phys_event_number"].asInt();
int eventNo = channel_in["part_event_number"].asInt();
int board = channel_in["geo"].asInt()-1;
int bank = channel_in["bank"].asInt();
int channel_ro = channel_in["channel"].asInt();
int adc = channel_in["adc"].asInt();
int tdc = channel_in["tdc"].asInt();
VLSB_C vlsb_c;
vlsb_c.SetEquipType(equip_type);
vlsb_c.SetPhysEventNumber(spill);
vlsb_c.SetTimeStamp(time_stamp);
vlsb_c.SetDetector(detector);
vlsb_c.SetPartEventNumber(eventNo);
vlsb_c.SetChannel(channel_ro);
vlsb_c.SetBankID(bank);
vlsb_c.SetADC(adc);
vlsb_c.SetTDC(tdc);
vlsb_c.SetDiscriminator(discriminator);
vlsb_c.SetLdcId(ldc);
vlsb_c.SetGeo(board);
if ( board < 4 ) {
vlsb_c_tracker0_array.push_back(vlsb_c);
} else {
vlsb_c_tracker1_array.push_back(vlsb_c);
}
if ( !is_good_channel(bank, channel_ro) ) {
// continue;
}
// Get pedestal and gain from calibration.
int new_bank = bank + 4*board;
double adc_pedestal = calibration_[new_bank][channel_ro]["adc_pedestal"].asDouble();
double adc_gain = calibration_[new_bank][channel_ro]["adc_gain"].asDouble();
double tdc_pedestal = calibration_[new_bank][channel_ro]["tdc_pedestal"].asDouble();
double tdc_gain = calibration_[new_bank][channel_ro]["tdc_gain"].asDouble();
// Calculate the number of photoelectrons.
double pe;
if ( adc_pedestal > _min && adc_gain > _min ) {
pe = (adc-adc_pedestal)/adc_gain;
} else {
pe = -10.0;
}
double time = -10.0;
/* No TDC calibration yet.
if ( tdc_pedestal > tdc_pedestal_min && tdc_gain > 0 ) {
time = (tdc-tdc_pedestal)/tdc_gain;
} else {
time = -10.0;
}
*/
// Find tracker, station, plane, channel.
int tracker, station, plane, channel;
int extWG, inWG, WGfib;
bool found = get_StatPlaneChannel(board, bank, channel_ro,
tracker, station, plane,
channel, extWG, inWG, WGfib);
// Exclude missing modules.
if ( found ) { // pe > 1.0 &&
SciFiDigit *digit = new SciFiDigit(spill, eventNo,
tracker, station, plane, channel, pe, time);
event->add_digit(digit);
}
} // ends loop over channels (j)
// Fill event with all vlsb digits.
tracker0daq_event->SetVLSB_CArray(vlsb_c_tracker0_array);
tracker1daq_event->SetVLSB_CArray(vlsb_c_tracker1_array);
}
bool RealDataDigitization::load_calibration(std::string file) {
char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR");
std::string fname = std::string(pMAUS_ROOT_DIR)+"/files/calibration/"+file;
std::ifstream inf(fname.c_str());
if (!inf) {
throw(Exception(Exception::recoverable,
"Could not load Tracker Calibration.",
"RealDataDigitization::load_calibration"));
}
std::string calib((std::istreambuf_iterator(inf)), std::istreambuf_iterator());
Json::Reader reader;
Json::Value calibration_data;
if (!reader.parse(calib, calibration_data))
return false;
size_t n_channels = calibration_data.size();
for ( Json::Value::ArrayIndex i = 0; i < n_channels; ++i ) {
int bank = calibration_data[i]["bank"].asInt();
int channel_n = calibration_data[i]["channel"].asInt();
double adc_pedestal = calibration_data[i]["adc_pedestal"].asDouble();
double adc_gain = calibration_data[i]["adc_gain"].asDouble();
double tdc_pedestal = calibration_data[i]["tdc_pedestal"].asDouble();
double tdc_gain = calibration_data[i]["tdc_gain"].asDouble();
Json::Value channel;
channel["adc_pedestal"] = adc_pedestal;
channel["adc_gain"] = adc_gain;
channel["tdc_pedestal"] = tdc_pedestal;
channel["tdc_gain"] = tdc_gain;
calibration_[bank][channel_n] = channel;
}
return true;
}
bool RealDataDigitization::load_mapping(std::string file) {
char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR");
std::string fname = std::string(pMAUS_ROOT_DIR)+"/src/map/MapCppTrackerDigits/"+file;
std::ifstream inf(fname.c_str());
if (!inf) {
throw(Exception(Exception::recoverable,
"Could not load Tracker Mapping.",
"RealDataDigitization::load_mapping"));
}
std::string line;
for ( int i = 1; i < _total_number_channels; ++i ) {
getline(inf, line);
std::istringstream ist1(line.c_str());
int board, bank, chan_ro, tracker, station, view, fibre, extWG, inWG, WGfib;
ist1 >> board >> bank >> chan_ro >> tracker >> station >>
view >> fibre >> extWG >> inWG >> WGfib;
_board.push_back(board);
_bank.push_back(bank);
_chan_ro.push_back(chan_ro);
_tracker.push_back(tracker);
_station.push_back(station);
_view.push_back(view);
_fibre.push_back(fibre);
_extWG.push_back(extWG);
_inWG.push_back(inWG);
_WGfib.push_back(WGfib);
}
return true;
}
bool RealDataDigitization::get_StatPlaneChannel(int& board, int& bank, int& chan_ro,
int& tracker, int& station, int& plane, int& channel,
int &extWG, int &inWG, int &WGfib) const {
bool found = false;
tracker = station = plane = channel = -1;
for ( size_t i = 0; !found && i < _board.size(); ++i ) {
if ( (board == _board[i]) && (bank == _bank[i]) && (chan_ro == _chan_ro[i]) ) {
station = _station[i];
plane = _view[i];
channel = _fibre[i];
tracker = _tracker[i];
extWG = _extWG[i];
inWG = _inWG[i];
WGfib = _WGfib[i];
found = true;
}
}
return found;
}
bool RealDataDigitization::is_good_channel(const int bank,
const int chan_ro) const {
if ( bank < _number_banks && chan_ro < _number_channels ) {
return _good_chan[bank][chan_ro];
} else {
return false;
}
}
bool RealDataDigitization::load_bad_channels() {
char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR");
std::string fname = std::string(pMAUS_ROOT_DIR)+"/src/map/MapCppTrackerDigits/bad_chan_list.txt";
std::ifstream inf(fname.c_str());
if (!inf) {
throw(Exception(Exception::recoverable,
"Could not load Tracker bad channel list.",
"RealDataDigitization::load_bad_channels"));
}
for ( int bank = 0; bank < _number_banks; ++bank ) {
for ( int chan_ro = 0; chan_ro < _number_channels; ++chan_ro ) {
_good_chan[bank][chan_ro] = true;
}
}
int bad_bank, bad_chan_ro;
while ( !inf.eof() ) {
inf >> bad_bank >> bad_chan_ro;
_good_chan[bad_bank][bad_chan_ro] = false;
}
return true;
}
} // ~namespace MAUS