/* * Nomad Instrument Control Software * * Copyright 2011 Institut Laue-Langevin * * Licensed under the EUPL, Version 1.1 only (the "License"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://www.osor.eu/eupl * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. */ #include "Event.h" #include #include #include #include using namespace std; namespace lstdpp128 { time_type Event::time() const { return (((int64_t)rollover << 32) | timestamp); } void Event::setTime(time_type value) { timestamp = (value & 0xFFFFFFFF); rollover = ((value >> 32) & 0xFFFF); } std::ostream& operator<< (std::ostream& os, Event const & e) { return os << setw(20) << e.time() << setw(12) << e.energy << setw(8) << (int)e.crate << ", " << (int)e.board << setw(8) << e.channel << setw(8) << e.data; } std::string printBinary(int32_t * buffer) { ostringstream os; os << hex << setw(8) << setfill('0') << (uint32_t)(*(buffer)) << " " << setw(8) << setfill('0') << (uint32_t)(*(buffer + 1)) << " " << setw(8) << setfill('0') << (uint32_t)(*(buffer + 2)) << " " << setw(8) << setfill('0') << (uint32_t)(*(buffer + 3)) << setw(0) << setfill(' ') << dec; return os.str(); } int32_t EventBlock::maxId = 0; EventBlock * EventBlock::split() { time_type midTime = (minTime() + maxTime()) / 2; return split(midTime); } EventBlock * EventBlock::split(time_type midTime) { EventBlock * upperBlock = new EventBlock(); Event event; event.setTime(midTime); multiset::const_iterator e = events.upper_bound(event); upperBlock->events = multiset(e, events.end()); events = multiset(events.begin(), e); return upperBlock; } std::ostream& operator<< (std::ostream& os, EventBlock const & b) { if (b.events.empty()) { return os << b.id << " : empty"; } return os << b.id << " : " << b.minTime() << " - " << b.maxTime() << " (" << b.events.size() << ")"; } bool readEvent(Event & event, int32_t * buffer) { uint8_t crate = (uint8_t)((*buffer >> 28) & 0xF); uint8_t board = (uint8_t)((*buffer >> 22) & 0x3F); if (crate >= listModeContext.crateBoard.nbCrates) { // No output because the log file can be very large return false; } if (board >= listModeContext.crateBoard.crates[event.crate].nbBoards) { // No output because the log file can be very large return false; } event.crate = crate; event.board = board; event.channel = (uint8_t)((*buffer >> 16) & 0x3F); event.rollover = (uint16_t)(*buffer & 0xFFFF); BoardType boardType = event.boardType(); if (boardType == CFD_BOARD_TYPE) { event.timestamp = (uint32_t)(*(buffer + 1) & 0xFFFFFFFF); event.energy = (uint16_t)(*(buffer + 2) & 0xFFF); // Extra data if zero crossing int32_t temp = (*(buffer + 3) & 0xFFFFFFFF); memcpy(reinterpret_cast(&event.data), reinterpret_cast(&temp), 4); } else if (boardType == V1751_BOARD_TYPE) { event.timestamp = (uint32_t)(*(buffer + 1) & 0xFFFFFFFF); event.energy = (uint16_t)((*(buffer + 2) >> 16) & 0x7FFF); // Extra data event.data = (uint16_t)((*(buffer + 2)) & 0x7FFF); } else if ((boardType == V1724_BOARD_TYPE) || (boardType == V1730_BOARD_TYPE)) { event.timestamp = (uint32_t)(*(buffer + 1) & 0x3FFFFFFF); event.energy = (uint16_t)(*(buffer + 2) & 0x7FFF); } // Use printBinary(buffer) to debug if necessary. // Set the absolute time. Here the event is still in relative time. time_type absoluteTime = event.time() * event.timeResolution(); // We can set the absolute time that changes the rollover and timestamp. event.setTime(absoluteTime); if (absoluteTime != event.time()) { cerr << "Problem while converting relative time to absolute time" << endl; } return true; } void writeEvent(Event const & event, int32_t * buffer) { Event relativeTimeEvent(event); // We reset the event time to the relative time because we do not want to change the header of the lsto. time_type relativeTime = event.time() / event.timeResolution(); // We can set the absolute time that changes the rollover and timestamp. relativeTimeEvent.setTime(relativeTime); *buffer = 0; *buffer |= ((relativeTimeEvent.crate & 0xF) << 28); *buffer |= ((relativeTimeEvent.board & 0x3F) << 22); *buffer |= ((relativeTimeEvent.channel & 0x3F) << 16); *buffer |= (relativeTimeEvent.rollover & 0xFFFF); BoardType boardType = relativeTimeEvent.boardType(); if (boardType == CFD_BOARD_TYPE) { *(buffer + 1) = relativeTimeEvent.timestamp; *(buffer + 2) = (relativeTimeEvent.energy & 0xFFF); memcpy(buffer + 3, reinterpret_cast(&relativeTimeEvent.data), 4); } else if (boardType == V1751_BOARD_TYPE) { // There is one bit that is not used: first bit of data (the buffer written may be different from the buffer read). *(buffer + 1) = relativeTimeEvent.timestamp; *(buffer + 2) = ((relativeTimeEvent.energy << 16)) | (event.data & 0x7FFF); *(buffer + 3) = 0; } else if ((boardType == V1724_BOARD_TYPE) || (boardType == V1730_BOARD_TYPE)) { *(buffer + 1) = (relativeTimeEvent.timestamp & 0x3FFFFFFF); *(buffer + 2) = (relativeTimeEvent.energy & 0x7FFF); *(buffer + 3) = 0; } // Use printBinary(buffer) to debug if necessary. } }