Event.cpp 6 KB
Newer Older
legoc's avatar
legoc committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * 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 <iomanip>
#include <cmath>
#include <string.h>
#include <sstream>

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);
}

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
std::string eventColumnsToString(BoardType type) {

	ostringstream os;

	os 	<< setw(10) << (int)type
			<< setw(10) << "time"
			<< setw(8) << "roll."
			<< setw(12) << "timestamp"
			<< setw(8) << "crate"
			<< setw(8) << "board"
			<< setw(8) << "channel"
			<< setw(11) << "board type";

	return os.str();
}

legoc's avatar
legoc committed
56
std::ostream& operator<< (std::ostream& os, Event const & e) {
57
58
59
60
61
62
63
64
65

	return os << dec
			<< setw(20) << e.time()
			<< setw(8) << e.rollover
			<< setw(12) << e.timestamp
			<< setw(8) << (int)e.crate
			<< setw(8) << (int)e.board
			<< setw(8) << e.channel
			<< setw(11) << (int)e.boardType();
legoc's avatar
legoc committed
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
}

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<Event, CompareEvents>::const_iterator e = events.upper_bound(event);

	upperBlock->events = multiset<Event, CompareEvents>(e, events.end());
	events = multiset<Event, CompareEvents>(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) {

114
	// Read crate, board, channel.
legoc's avatar
legoc committed
115
116
117
118
	uint8_t crate = (uint8_t)((*buffer >> 28) & 0xF);
	uint8_t board = (uint8_t)((*buffer >> 22) & 0x3F);

	if (crate >= listModeContext.crateBoard.nbCrates) {
119
		// No output because the log file can be very large.
legoc's avatar
legoc committed
120
121
122
123
		return false;
	}

	if (board >= listModeContext.crateBoard.crates[event.crate].nbBoards) {
124
		// No output because the log file can be very large.
legoc's avatar
legoc committed
125
126
127
128
129
130
131
132
133
134
		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();

135
	// The number of bits for timestamp.
136
137
	int numberOfBitsOfTimestamp = 32;

138
139
	// In case of 1724 PHA, the number of bits for timestamp is 30.
	if (boardType == C1724_PHA_RT) {
140
141
		numberOfBitsOfTimestamp = 30;
		event.timestamp = (uint32_t)(*(buffer + 1) & 0x3FFFFFFF);
142
143
	}
	else {
144
		event.timestamp = (uint32_t)(*(buffer + 1) & 0xFFFFFFFF);
legoc's avatar
legoc committed
145
146
	}

147
148
149
	// Copy data.
	memcpy(reinterpret_cast<void *>(event.data), reinterpret_cast<const void *>(buffer + 2), 8);

legoc's avatar
legoc committed
150
151
	// Use printBinary(buffer) to debug if necessary.

152
153
154
	// Calculate the absolute time.
	time_type absoluteTime = (((int64_t)event.rollover << numberOfBitsOfTimestamp) | event.timestamp);

155
156
	// Testing if we must apply the time resolution or not in case of a board that has relative time.
	if (BoardRelativeTime[boardType]) {
157
		// Set the absolute time. Here the event is still in relative time.
158
		absoluteTime = absoluteTime * event.timeResolution();
159
160
161
162
163
164
165

		// 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;
		}
legoc's avatar
legoc committed
166
	}
167
168
169
170
	else {
		// We can set the absolute time that changes the rollover and timestamp.
		event.setTime(absoluteTime);
	}
171

legoc's avatar
legoc committed
172
173
174
175
176
177
178
	return true;
}

void writeEvent(Event const & event, int32_t * buffer) {

	Event relativeTimeEvent(event);

179
180
	// Testing if we must apply the time resolution or not in case of a board that has relative time.
	if (BoardRelativeTime[event.boardType()]) {
legoc's avatar
legoc committed
181

182
183
184
		// 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();

185
		// We can set the relative time that changes the rollover and timestamp.
186
187
		relativeTimeEvent.setTime(relativeTime);
	}
legoc's avatar
legoc committed
188
189
190
191
192
193
194
195

	*buffer = 0;
	*buffer |= ((relativeTimeEvent.crate & 0xF) << 28);
	*buffer |= ((relativeTimeEvent.board & 0x3F) << 22);
	*buffer |= ((relativeTimeEvent.channel & 0x3F) << 16);

	BoardType boardType = relativeTimeEvent.boardType();

196
	if (boardType == C1724_PHA_RT) {
197
198
199
200
201
202
203
204

		// The card timestamp is on 30bits with 2 bits of zero.
		// The rollover is calculated by taking the 2 bits of the actual timestamp (>> 30 for 32 bits = 2 bits).
		int32_t rollover = ((relativeTimeEvent.rollover << 2) | (relativeTimeEvent.timestamp >> 30));
		*buffer |= (rollover & 0xFFFF);

		// Taking the 30 bits and setting 0 to the 2 first bits.
		*(buffer + 1) = (relativeTimeEvent.timestamp & 0x3FFFFFFF);
205
206
	}
	else {
207
208
		*buffer |= (relativeTimeEvent.rollover & 0xFFFF);

209
		*(buffer + 1) = relativeTimeEvent.timestamp;
legoc's avatar
legoc committed
210
211
	}

212
213
214
	// Copy data.
	memcpy(buffer + 2, reinterpret_cast<const void *>(&relativeTimeEvent.data), 8);

legoc's avatar
legoc committed
215
216
217
218
	// Use printBinary(buffer) to debug if necessary.
}

}