/* 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 . * */ #include "src/input/InputCppDAQData/InputCppDAQData.hh" #include "src/common_cpp/Utils/CppErrorHandler.hh" #include "src/common_cpp/JsonCppProcessors/SpillProcessor.hh" #include "src/common_cpp/Converter/DataConverters/CppJsonSpillConverter.hh" #include "src/common_cpp/Converter/DataConverters/JsonCppSpillConverter.hh" #include "Utils/Exception.hh" #include "src/common_cpp/API/PyWrapInputBase.hh" namespace MAUS { PyMODINIT_FUNC init_InputCppDAQData(void) { PyWrapInputBase::PyWrapInputBaseModInit( "InputCppDAQData", "", "", "", ""); } InputCppDAQData::InputCppDAQData() : InputBase("InputCppDAQData") { _eventPtr = NULL; _eventsCount = 0; _v1290PartEventProc_cpp = NULL; _v1724PartEventProc_cpp = NULL; _v1731PartEventProc_cpp = NULL; _v830FragmentProc_cpp = NULL; _vLSBFragmentProc_cpp = NULL; _DBBFragmentProc_cpp = NULL; _DBBChainFragmentProc_cpp = NULL; } void InputCppDAQData::_childbirth(const std::string& jsonDataCards) { if ( _dataFileManager.GetNFiles() ) { throw(MAUS::Exception(Exception::recoverable, "STRING", "InputCppDAQData::_childbirth")); } // JsonCpp setup Json::Value configJSON; // this will contain the configuration Json::Reader reader; // Check if the JSON document can be parsed, else return error only bool parsingSuccessful = reader.parse(jsonDataCards, configJSON); if (!parsingSuccessful) { throw(MAUS::Exception(Exception::recoverable, "STRING", "InputCppDAQData::_childbirth")); } // Comfigure the V830 (scaler) data processor. initProcessor(_v830FragmentProc_cpp, configJSON); // Comfigure the V1290 (TDC) data processor. initProcessor(_v1290PartEventProc_cpp, configJSON); // Comfigure the V1724 (TOF and KL fADC) data processor. initProcessor(_v1724PartEventProc_cpp, configJSON); configureZeroSupression(_v1724PartEventProc_cpp, configJSON); // Comfigure the V1731 (CKOV and EMR fADC) data processor. initProcessor(_v1731PartEventProc_cpp, configJSON); configureZeroSupression(_v1731PartEventProc_cpp, configJSON); // Comfigure the VLSB (tracker board) data processor. initProcessor(_vLSBFragmentProc_cpp, configJSON); configureZeroSupressionTK(_vLSBFragmentProc_cpp, configJSON); // Comfigure the DBB (EMR board) data processor. initProcessor(_DBBFragmentProc_cpp, configJSON); // Comfigure the DBB Chain (chain of 6 EMR boards) data processor. initProcessor(_DBBChainFragmentProc_cpp, configJSON); // frankliuao: moved the _map.InitFromCards(configJSON) to InputCppDAQOnlineData // and InputCppDAQOfflineData. There, daq_cabling_source is forced to be "CDB" // Set the map (a static data member) of all the processors. MDarranger::set_DAQ_map(&_map); } bool InputCppDAQData::readNextEvent() { Squeak::mout(Squeak::error) << "ERROR : InputCppDAQData is a base imput class and can not be used to access the DAQ data!" << std::endl << "*** Use InputCppDAQOfflineData or InputCppDAQOnlineData instead. ***" << std::endl << std::endl; return false; } int InputCppDAQData::getCurEvent(MAUS::Data *data) { MAUS::Spill* spill = data->GetSpill(); int nPartEvts(0); try { // Do the loop over the binary DAQ data. nPartEvts = _dataProcessManager.Process(_eventPtr); // The data is now processed and is ready to be filled. unsigned int event_type = _dataProcessManager.GetEventType(); spill->SetDaqEventType(event_type_to_str(event_type)); spill->SetRunNumber(_dataProcessManager.GetRunNumber()); spill->SetSpillNumber(_dataProcessManager.GetSpillNumber()); spill->SetEventId(_dataProcessManager.GetEventId()); spill->SetTimeStamp(_dataProcessManager.GetTimeStamp()); if (event_type == PHYSICS_EVENT) { // Create a new DAQData object. MAUS::DAQData *daq_data = new MAUS::DAQData; daq_data->SetEventSize(_dataProcessManager.GetSuperEventSize()); // Set the DAQData object (a static data member) of all the processors. MDarranger::set_daq_data(daq_data); // Now fill the DAQData object with the data processed by all the processors. if (_DBBFragmentProc_cpp) _DBBFragmentProc_cpp->fill_daq_data(); if (_DBBChainFragmentProc_cpp) _DBBChainFragmentProc_cpp->fill_daq_data(); if (_v1731PartEventProc_cpp) _v1731PartEventProc_cpp->fill_daq_data(); if (_v1724PartEventProc_cpp) _v1724PartEventProc_cpp->fill_daq_data(); if (_v1290PartEventProc_cpp) _v1290PartEventProc_cpp->fill_daq_data(); if (_v830FragmentProc_cpp) _v830FragmentProc_cpp->fill_daq_data(); if (_vLSBFragmentProc_cpp) _vLSBFragmentProc_cpp->fill_daq_data(); // Set the DAQData object of the spill. spill->SetDAQData(daq_data); } } // Deal with exceptions catch (MDexception & lExc) { Squeak::mout(Squeak::error) << lExc.GetDescription() << std::endl << "*** Unpacking exception in void " << "InputCppDAQData::getCurEvent(MAUS::Data *data) : " << std::endl; Squeak::mout(Squeak::error) <<"DAQ Event skipped!" << std::endl << std::endl; std::stringstream ss; ss << _classname << " says:" << lExc.GetDescription() << " Phys. Event " << std::endl << _dataProcessManager.GetPhysEventNumber() << " skipped!"; MAUS::ErrorsMap errors = spill->GetErrors(); errors["bad_data_input"] = ss.str(); spill->SetErrors(errors); nPartEvts = 0; } catch (Exception exc) { Squeak::mout(Squeak::error) << exc.GetLocation() << ": " << exc.GetMessage() << std::endl << "*** MAUS exception in " << "InputCppDAQData::getCurEvent(MAUS::Data *data) : " << std::endl; Squeak::mout(Squeak::error) <<"DAQ Event skipped!" << std::endl << std::endl; std::stringstream ss; ss << exc.GetLocation() << " says:" << exc.GetMessage() << " Phys. Event " << std::endl << _dataProcessManager.GetPhysEventNumber() << " skipped!"; MAUS::ErrorsMap errors = spill->GetErrors(); errors["bad_data_input"] = ss.str(); spill->SetErrors(errors); } catch (std::exception & lExc) { Squeak::mout(Squeak::error) << lExc.what() << std::endl << "*** Standard exception in " << "InputCppDAQData::getCurEvent(MAUS::Data *data) : " << std::endl; Squeak::mout(Squeak::error) <<"DAQ Event skipped!" << std::endl << std::endl; std::stringstream ss; ss << _classname << " says:" << lExc.what() << " Phys. Event " << _dataProcessManager.GetPhysEventNumber() << " skipped!"; MAUS::ErrorsMap errors = spill->GetErrors(); errors["bad_data_input"] = ss.str(); spill->SetErrors(errors); } catch (...) { Squeak::mout(Squeak::error) << "*** InputCppDAQData::getCurEvent(MAUS::Data *data) : " << "Unknown exception occurred." << std::endl; Squeak::mout(Squeak::error) << "DAQ Event skipped!" << std::endl << std::endl; std::stringstream ss; ss << _classname << " says: Unknown exception occurred. Phys. Event " << _dataProcessManager.GetPhysEventNumber() << " skipped!"; MAUS::ErrorsMap errors = spill->GetErrors(); errors["bad_data_input"] = ss.str(); spill->SetErrors(errors); } this->resetAllProcessors(); return nPartEvts; } std::string InputCppDAQData::getCurEvent() { MAUS::Data *data_cpp = new MAUS::Data; MAUS::Spill *spill_cpp = new MAUS::Spill; data_cpp->SetSpill(spill_cpp); this->getCurEvent(data_cpp); Json::Value* spill_json_out = MAUS::CppJsonSpillConverter().convert(data_cpp); // std::cerr << *spill_json_out << std::endl; _eventsCount++; Json::FastWriter xJSONWr; std::string output = xJSONWr.write(*spill_json_out); delete spill_json_out; delete data_cpp; return output; } void InputCppDAQData::_death() { // Free the memory. if (_v1290PartEventProc_cpp) delete _v1290PartEventProc_cpp; if (_v1724PartEventProc_cpp) delete _v1724PartEventProc_cpp; if (_v1731PartEventProc_cpp) delete _v1731PartEventProc_cpp; if (_v830FragmentProc_cpp) delete _v830FragmentProc_cpp; if (_vLSBFragmentProc_cpp) delete _vLSBFragmentProc_cpp; if (_DBBFragmentProc_cpp) delete _DBBFragmentProc_cpp; if (_DBBChainFragmentProc_cpp) delete _DBBChainFragmentProc_cpp; } void InputCppDAQData::resetAllProcessors() { // Reset all the processors. if (_v1290PartEventProc_cpp) _v1290PartEventProc_cpp->reset(); if (_v1724PartEventProc_cpp) _v1724PartEventProc_cpp->reset(); if (_v1731PartEventProc_cpp) _v1731PartEventProc_cpp->reset(); if (_v830FragmentProc_cpp) _v830FragmentProc_cpp->reset(); if (_vLSBFragmentProc_cpp) _vLSBFragmentProc_cpp->reset(); if (_DBBFragmentProc_cpp) _DBBFragmentProc_cpp->reset(); if (_DBBChainFragmentProc_cpp) _DBBChainFragmentProc_cpp->reset(); } template bool InputCppDAQData::initProcessor(procType* &processor, Json::Value configJSON) { processor = new procType(); string xName, xDataCard; xName = processor->get_equipment_name(); xDataCard = "Enable_" + xName + "_Unpacking"; // Enable or disable this equipment. assert(configJSON.isMember(xDataCard)); bool enableThis = configJSON[xDataCard].asBool(); if (enableThis) { // Get a pointer to the equipment fragment object from the static equipment map. unsigned int xFragType = MDequipMap::GetType(xName); MDfragment* xFragPtr = MDequipMap::GetFragmentPtr(xFragType); // Check is the data from this equipment is made of particle events. try { if (xFragPtr->IsMadeOfParticles()) { // Set a processor for particle events. _dataProcessManager.SetPartEventProc(xName, processor); } else { // Set a processor for the entire equipment fragment _dataProcessManager.SetFragmentProc(xName, processor); } } // Deal with exceptions catch (MDexception & lExc) { Squeak::mout(Squeak::error) << lExc.GetDescription() << std::endl << "*** Unpacking exception in InputCppDAQData::initProcessor() : " << endl; } return true; } else { this->disableEquipment(xName); return false; } } void InputCppDAQData::configureZeroSupression(ZeroSupressionFilter* processor, Json::Value configJSON) { string xName, xDataCard; xName = processor->get_equipment_name(); xDataCard = "Do_" + xName + "_Zero_Suppression"; // Enable or disable zero supression. assert(configJSON.isMember(xDataCard)); bool zs = configJSON[xDataCard].asBool(); processor->set_zero_supression(zs); if (zs) { xDataCard = xName + "_Zero_Suppression_Threshold"; assert(configJSON.isMember(xDataCard)); int zs_threshold = configJSON[xDataCard].asInt(); processor->set_zs_threshold(zs_threshold); } } void InputCppDAQData::configureZeroSupressionTK(ZeroSupressionFilterTK* processor, Json::Value configJSON) { string xName, xDataCard, calib_file; xName = processor->get_equipment_name(); xDataCard = "Do_" + xName + "_Zero_Suppression"; // Enable or disable zero supression. assert(configJSON.isMember(xDataCard)); bool zs = configJSON[xDataCard].asBool(); processor->set_zero_supression(zs); if (zs) { xDataCard = xName + "_Zero_Suppression_Threshold"; assert(configJSON.isMember(xDataCard)); int zs_threshold = configJSON[xDataCard].asInt(); processor->set_zs_threshold(zs_threshold); xDataCard = "SciFiCalibrationFileName"; assert(configJSON.isMember(xDataCard)); calib_file = configJSON[xDataCard].asString(); char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR"); std::string fname = std::string(pMAUS_ROOT_DIR)+"/files/calibration/"+calib_file; std::ifstream inf(fname.c_str()); if (!inf) { throw(Exception(Exception::recoverable, "Could not load Tracker calibration", "InputCppDAQData::configureZeroSupressionTK")); } else { std::cerr << "Tracker calibration file found into DAQ\n"; } std::string calib((std::istreambuf_iterator(inf)), std::istreambuf_iterator()); Json::Reader reader; Json::Value calibration_data; TrackerCalibMap *calibration = processor->get_calibration_ptr(); if (!reader.parse(calib, calibration_data)) { throw(Exception(Exception::recoverable, "Could not load Tracker calibration", "InputCppDAQData::configureZeroSupressionTK")); } else { std::cerr << "Tracker calibration parsing into DAQ\n"; } 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(); (*calibration)[bank][channel_n].first = adc_pedestal; (*calibration)[bank][channel_n].second = adc_gain; } } } std::string InputCppDAQData::event_type_to_str(int pType) { std::string event_type; switch (pType) { case START_OF_BURST : event_type = "start_of_burst"; break; case END_OF_BURST: event_type = "end_of_burst"; break; case PHYSICS_EVENT : event_type = "physics_event"; break; case CALIBRATION_EVENT : event_type = "calibration_event"; break; case START_OF_RUN : event_type = "start_of_run"; break; case END_OF_RUN: event_type = "end_of_run"; break; default : std::stringstream xConv; xConv << pType << "unknown"; event_type = xConv.str(); break; } return event_type; } }