Skip to content

Commit 4ba9ada

Browse files
committed
Clock reset counter implemented. Some additional reporting to DB
1 parent e593c67 commit 4ba9ada

9 files changed

Lines changed: 213 additions & 21 deletions

File tree

DAQController.cc

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ int DAQController::InitializeElectronics(std::string opts){
4747
fStatus = 1;
4848
for(auto d : fOptions->GetBoards("V1724")){
4949

50-
V1724 *digi = new V1724();
50+
V1724 *digi = new V1724(fLog);
5151
if(digi->Init(d.link, d.crate, d.board, d.vme_address)==0){
5252
fDigitizers.push_back(digi);
5353
std::stringstream mess;
@@ -160,7 +160,21 @@ void DAQController::ReadData(){
160160
d.buff=NULL;
161161
d.size=0;
162162
d.bid = fDigitizers[x]->bid();
163-
d.size = fDigitizers[x]->ReadMBLT(d.buff);
163+
d.size = fDigitizers[x]->ReadMBLT(d.buff);
164+
165+
// Here's the fancy part. We gotta grab the header of the first
166+
// event in the buffer and get the clock reset counter from the
167+
// board. This gets shipped off with the buffer.
168+
u_int32_t idx=0;
169+
while(idx < d.size/sizeof(u_int32_t)){
170+
if(d.buff[idx]>>20==0xA00){
171+
d.header_time = d.buff[idx+3]&0x7FFFFFFF;
172+
d.clock_counter = fDigitizers[x]->GetClockCounter(d.header_time);
173+
break;
174+
}
175+
idx++;
176+
}
177+
164178
lastRead += d.size;
165179

166180
if(d.size<0){
@@ -225,6 +239,22 @@ void* DAQController::ProcessingThreadWrapper(void* data){
225239
return data;
226240
}
227241

242+
bool DAQController::CheckErrors(){
243+
244+
// This checks for errors from the threads by checking the
245+
// error flag in each object. It's appropriate to poll this
246+
// on the order of ~second(s) and initialize a STOP in case
247+
// the function returns "true"
248+
249+
for(unsigned int i=0; i<fProcessingThreads.size(); i++){
250+
if(fProcessingThreads[i].inserter->CheckError()){
251+
fLog->Entry("Error found in processing thread.", MongoLog::Error);
252+
fStatus=4;
253+
return true;
254+
}
255+
}
256+
return false;
257+
}
228258

229259
void DAQController::OpenProcessingThreads(){
230260

DAQController.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ public:
5151
static void* ProcessingThreadWrapper(void* data);
5252

5353
u_int64_t GetDataSize(){ u_int64_t ds = fDatasize; fDatasize=0; return ds;};
54-
54+
bool CheckErrors();
55+
56+
5557
private:
5658
void AppendData(vector<data_packet> d);
5759

MongoInserter.cc

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ MongoInserter::MongoInserter(){
77
fActive = true;
88
fBulkInsertSize=100;
99
fLog = NULL;
10+
fErrorBit = false;
1011
}
1112

1213
MongoInserter::~MongoInserter(){
@@ -17,6 +18,7 @@ int MongoInserter::Initialize(Options *options, MongoLog *log, DAQController *d
1718
fBulkInsertSize = fOptions->GetInt("bulk_insert_size", 100);
1819
fDataSource = dataSource;
1920
fLog = log;
21+
fErrorBit = false;
2022
return 0;
2123
}
2224

@@ -33,10 +35,21 @@ std::string MongoInserter::FormatString(const std::string format,
3335

3436
void MongoInserter::ParseDocuments(
3537
std::vector<bsoncxx::document::value> &doc_array,
36-
u_int32_t *buff, u_int32_t size, u_int32_t bid){
38+
data_packet dp){
3739
// Take a buffer and break it up into one document per channel
3840
// Put these documents into doc array
3941

42+
// Unpack the things from the data packet
43+
u_int32_t bid = dp.bid;
44+
vector<u_int32_t> clock_counters;
45+
for(int i=0; i<8; i++)
46+
clock_counters.push_back(dp.clock_counter);
47+
vector<u_int32_t> last_times_seen = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
48+
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
49+
u_int32_t size = dp.size;
50+
u_int32_t *buff = dp.buff;
51+
52+
4053
u_int32_t idx = 0;
4154
while(idx < size/sizeof(u_int32_t) &&
4255
buff[idx] != 0xFFFFFFFF){
@@ -62,6 +75,31 @@ void MongoInserter::ParseDocuments(
6275
idx++;
6376
u_int32_t channel_time = buff[idx]&0x7FFFFFFF;
6477
idx++;
78+
79+
// OK. Here's the logic for the clock reset, and I realize this is the
80+
// second place in the code where such weird logic is needed but that's it
81+
// First, on the first instance of a channel we gotta check if
82+
// the channel clock rolled over BEFORE this clock and adjust the counter
83+
if(channel_time > 15e8 && dp.header_time<5e8 &&
84+
last_times_seen[channel] == 0xFFFFFFFF){
85+
clock_counters[channel]--;
86+
}
87+
// Now check the opposite
88+
else if(channel_time <5e8 && dp.header_time > 15e8 &&
89+
last_times_seen[channel] == 0xFFFFFFFF){
90+
clock_counters[channel]++;
91+
}
92+
93+
// Now check if this time < last time (indicates rollover)
94+
if(channel_time < last_times_seen[channel] &&
95+
last_times_seen[channel]!=0xFFFFFFFF)
96+
clock_counters[channel]++;
97+
98+
last_times_seen[channel] = channel_time;
99+
100+
int iBitShift = 31;
101+
int64_t Time64 = ((unsigned long)clock_counters[channel] <<
102+
iBitShift) + channel_time;
65103

66104
u_int32_t *channel_payload = new u_int32_t[channel_size-2];
67105

@@ -75,6 +113,7 @@ void MongoInserter::ParseDocuments(
75113
"channel_time" << static_cast<int32_t>(channel_time) <<
76114
"size" << static_cast<int32_t>((channel_size-2)*
77115
sizeof(u_int32_t)) <<
116+
"time" << Time64 <<
78117
"data" << bsoncxx::types::b_binary {
79118
bsoncxx::binary_sub_type::k_binary,
80119
static_cast<u_int32_t>((channel_size-2)*
@@ -149,12 +188,20 @@ int MongoInserter::ReadAndInsertData(){
149188
<< bsoncxx::builder::stream::finalize);
150189
*/
151190
// Bulk Inserts
152-
ParseDocuments(documents, (*readVector)[i].buff, (*readVector)[i].size,
153-
(*readVector)[i].bid);
191+
ParseDocuments(documents, (*readVector)[i]);
154192

155193
if(documents.size()>fBulkInsertSize){
156-
coll.insert_many(documents);
157-
documents.clear();
194+
try{
195+
coll.insert_many(documents);
196+
documents.clear();
197+
}
198+
catch(const std::exception &e){
199+
fLog->Entry("Failure to insert raw data into database. Quitting. Error follows.",
200+
MongoLog::Error);
201+
fLog->Entry(e.what(), MongoLog::Error);
202+
fErrorBit = true;
203+
documents.clear();
204+
}
158205
}
159206

160207
//coll.insert_one(bsoncxx::builder::stream::document{} <<

MongoInserter.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class DAQController;
1919
struct data_packet{
2020
u_int32_t *buff;
2121
u_int32_t size;
22+
u_int32_t clock_counter;
23+
u_int32_t header_time;
2224
int bid;
2325
};
2426

@@ -36,10 +38,10 @@ public:
3638
void Close();
3739

3840
int ReadAndInsertData();
39-
41+
bool CheckError(){ return fErrorBit; };
4042
private:
4143
static void ParseDocuments(std::vector<bsoncxx::document::value> &doc_array,
42-
u_int32_t *buff, u_int32_t size, u_int32_t bid);
44+
data_packet dp);
4345

4446
//std::string FormatString(const std::string& format, ...);
4547
std::string FormatString(const std::string format,
@@ -49,6 +51,7 @@ private:
4951
MongoLog *fLog;
5052
DAQController *fDataSource;
5153
bool fActive;
54+
bool fErrorBit;
5255
};
5356

5457
#endif

V1724.cc

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "V1724.hh"
22

3-
V1724::V1724(){
3+
V1724::V1724(MongoLog *log){
44
fBoardHandle=fLink=fCrate=fBID=-1;
55
fBaseAddress=0;
6+
fLog = log;
67
}
78
V1724::~V1724(){
89
End();
@@ -20,15 +21,89 @@ int V1724::Init(int link, int crate, int bid, unsigned int address=0){
2021
fBID = bid;
2122
fBaseAddress=address;
2223
cout<<"Successfully initialized board at "<<fBoardHandle<<endl;
24+
clock_counter = 0;
25+
last_time = 0;
26+
seen_over_15 = false;
27+
seen_under_5 = true; // starts run as true
2328
return 0;
2429
}
2530

31+
int V1724::GetClockCounter(u_int32_t timestamp){
32+
// The V1724 has a 31-bit on board clock counter that counts 10ns samples.
33+
// So it will reset every 21 seconds. We need to count the resets or we
34+
// can't run longer than that. But it's not as simple as incementing a
35+
// counter every time a timestamp is less than the previous one because
36+
// we're multi-threaded and channels are quasi-independent. So we need
37+
// this fancy logic here.
38+
39+
//Seen under 5, true first time you see something under 5. False first time you
40+
// see something under 15 but >5
41+
// Seen over 15, true first time you se something >15 if under 5=false. False first
42+
// time you see something under 5
43+
44+
// First, is this number greater than the previous?
45+
if(timestamp > last_time){
46+
47+
// Case 1. This is over 15s but seen_under_5 is true. Give 1 back
48+
if(timestamp >= 15e8 && seen_under_5)
49+
return clock_counter-1;
50+
51+
// Case 2. This is over 5s and seen_under_5 is true.
52+
else if(timestamp >= 5e8 && timestamp < 15e8 && seen_under_5){
53+
seen_under_5 = false;
54+
last_time = timestamp;
55+
return clock_counter;
56+
}
57+
58+
// Case 3. This is over 15s and seen_under_5 is false
59+
else if(timestamp >= 15e8 && !seen_under_5){
60+
seen_over_15 = true;
61+
last_time = timestamp;
62+
return clock_counter;
63+
}
64+
65+
// Case 5. Anything else where the clock is progressing correctly
66+
else{
67+
last_time = timestamp;
68+
return clock_counter;
69+
}
70+
}
71+
72+
// Second, is this number less than the previous?
73+
else if(timestamp < last_time){
74+
75+
// Case 1. Genuine clock reset. under 5s is false and over 15s is true
76+
if(timestamp < 5e8 && !seen_under_5 && seen_over_15){
77+
seen_under_5 = true;
78+
seen_over_15 = false;
79+
last_time = timestamp;
80+
clock_counter++;
81+
return clock_counter;
82+
}
83+
84+
// Case 2: Any other jitter within the 21 seconds, just return
85+
else{
86+
return clock_counter;
87+
}
88+
}
89+
else{
90+
std::stringstream err;
91+
err<<"Something odd in your clock counters. t_new: "<<timestamp<<
92+
" last time: "<<last_time<<" over 15: "<<seen_over_15<<
93+
" under 5: "<<seen_under_5;
94+
fLog->Entry(err.str(), MongoLog::Warning);
95+
return clock_counter;
96+
}
97+
}
98+
2699
int V1724::WriteRegister(unsigned int reg, unsigned int value){
27100
std::cout<<"Writing reg:val: "<<hex<<reg<<":"<<value<<dec<<std::endl;
28101
if(CAENVME_WriteCycle(fBoardHandle,fBaseAddress+reg,
29102
&value,cvA32_U_DATA,cvD32) != cvSuccess){
30-
cout<<"Failed to write register 0x"<<hex<<reg<<dec<<" to board "<<fBID<<
103+
std::stringstream err;
104+
err<<"Failed to write register 0x"<<hex<<reg<<dec<<" to board "<<fBID<<
31105
" with value "<<hex<<value<<dec<<" board handle "<<fBoardHandle<<endl;
106+
fLog->Entry(err.str(), MongoLog::Warning);
32107
return -1;
33108
}
34109
return 0;
@@ -38,7 +113,9 @@ unsigned int V1724::ReadRegister(unsigned int reg){
38113
unsigned int temp;
39114
if(CAENVME_ReadCycle(fBoardHandle, fBaseAddress+reg, &temp,
40115
cvA32_U_DATA, cvD32) != cvSuccess){
41-
cout<<"Failed to read register 0x"<<hex<<reg<<dec<<" on board "<<fBID<<endl;
116+
std::stringstream err;
117+
err<<"Failed to read register 0x"<<hex<<reg<<dec<<" on board "<<fBID<<endl;
118+
fLog->Entry(err.str(), MongoLog::Warning);
42119
return -1;
43120
}
44121
return temp;
@@ -57,7 +134,9 @@ u_int32_t V1724::ReadMBLT(unsigned int *&buffer){
57134
((unsigned char*)tempBuffer)+blt_bytes,
58135
BLT_SIZE, cvA32_U_BLT, cvD32, &nb);
59136
if( (ret != cvSuccess) && (ret != cvBusError) ){
60-
cout<<"Read error in board "<<fBID<<" after "<<count<<" reads."<<endl;
137+
stringstream err;
138+
err<<"Read error in board "<<fBID<<" after "<<count<<" reads.";
139+
fLog->Entry(err.str(), MongoLog::Error);
61140
delete[] tempBuffer;
62141
return 0;
63142
}
@@ -66,8 +145,11 @@ u_int32_t V1724::ReadMBLT(unsigned int *&buffer){
66145
blt_bytes+=nb;
67146

68147
if(blt_bytes>BLT_SIZE){
69-
cout<<"You managed to transfer more data than fits on board."<<endl;
70-
cout<<"Transferred: "<<blt_bytes<<" bytes, Buffer: "<<BLT_SIZE<<" bytes."<<endl;
148+
stringstream err;
149+
err<<"You managed to transfer more data than fits on board."<<
150+
"Transferred: "<<blt_bytes<<" bytes, Buffer: "<<BLT_SIZE<<" bytes.";
151+
fLog->Entry(err.str(), MongoLog::Error);
152+
71153
delete[] tempBuffer;
72154
return 0;
73155
}

V1724.hh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
#include <vector>
1010

1111
#include <iostream>
12+
#include "MongoLog.hh"
1213

1314
using namespace std;
1415

1516
class V1724{
1617

1718
public:
18-
V1724();
19+
V1724(MongoLog *log);
1920
~V1724();
2021

2122
int Init(int link, int crate, int bid, unsigned int address);
@@ -26,6 +27,7 @@ class V1724{
2627
int ntries,
2728
vector <unsigned int> start_values,
2829
vector <unsigned int> &end_values);
30+
int GetClockCounter(u_int32_t timestamp);
2931
int End();
3032

3133
int bid(){
@@ -37,6 +39,13 @@ class V1724{
3739
int fLink, fCrate, fBID;
3840
unsigned int fBaseAddress;
3941

42+
// Stuff for clock reset tracking
43+
u_int32_t clock_counter;
44+
u_int32_t last_time;
45+
bool seen_under_5;
46+
bool seen_over_15;
47+
48+
MongoLog *fLog;
4049
};
4150

4251

helpers/initialize_databases.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pymongo
22
import os
33

4-
client = pymongo.MongoClient("mongodb://daq:%s@127.0.0.1:27017/admin"%os.environ["MONGO_PASSWORD"])
4+
client = pymongo.MongoClient("mongodb://admin:%s@127.0.0.1:27017/admin"%os.environ["MONGO_PASSWORD"])
55
db = client['dax']
66

77
# Create capped collection 'status' of about 50MB

0 commit comments

Comments
 (0)