00001 #include "nx/Processor.h"
00002
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <math.h>
00006
00007 #include <algorithm>
00008
00009 #include "base/commons.h"
00010 #include "base/ProcMgr.h"
00011
00012 #include "nx/SubEvent.h"
00013
00014 double nx::Processor::fNXDisorderTm = 17000.;
00015 bool nx::Processor::fLastEpochCorr = false;
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 int nx::NxRec::corr_nexthit(roc::Message& msg, uint64_t fulltm, bool docorr, bool firstscan)
00161 {
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 uint64_t& lastfulltm = firstscan ? lastfulltm1 : lastfulltm2;
00174
00175 int res = 0;
00176
00177 if (msg.getNxLastEpoch()) {
00178
00179
00180 if (msg.getNxTs()<15800) res = -1; else
00181
00182 if (((msg.getNxLtsMsb()+7) & 0x7) != ((msg.getNxTs()>>11)&0x7)) res = -5; else
00183
00184 if (fulltm + 800 < lastfulltm) res = -1; else
00185
00186 res = 1;
00187
00188 } else {
00189
00190
00191 if (fulltm + 800 < lastfulltm) {
00192 if (msg.getNxTs() < 30) res = -2;
00193 else res = -3;
00194 }
00195 }
00196
00197 lastfulltm = fulltm;
00198 if ((res==-1) || (res==-5)) {
00199 lastfulltm += 16*1024;
00200 if (docorr) msg.setNxLastEpoch(0);
00201 }
00202
00203 return res;
00204 }
00205
00206
00207
00208 nx::Processor::Processor(unsigned rocid, unsigned nxmask) :
00209 base::SysCoreProc("ROC", rocid),
00210 fIter(),
00211 fIter2()
00212 {
00213 mgr()->RegisterProc(this, roc::proc_RocEvent, rocid);
00214
00215
00216
00217 fMsgsKind = MakeH1("MsgKind", "kind of messages", 8, 0, 8, "xbin:NOP,HIT,EPOCH,SYNC,AUX,-,-,SYS;kind");
00218 fSysTypes = MakeH1("SysTypes", "Distribution of system messages", 16, 0, 16, "systype");
00219
00220 CreateBasicHistograms();
00221
00222
00223
00224 for (unsigned nx=0; (nx<8) && (nxmask!=0); nx++) {
00225 NX.push_back(NxRec());
00226 NX[nx].used = (nxmask & 1) == 1;
00227 nxmask = nxmask >> 1;
00228 if (!NX[nx].used) continue;
00229
00230 SetSubPrefix("NX", nx);
00231
00232 NX[nx].fChannels = MakeH1("Channels", "NX channels", 128, 0, 128, "ch");
00233
00234 NX[nx].fADCs = MakeH2("ADC", "ADC distribution", 128, 0., 128., 1024, 0., 4096., "ch;adc");
00235 NX[nx].fHITt = MakeH1("HITt", "Hit time distribution", 10000, 0., 1000., "s");
00236
00237
00238 }
00239
00240 SetSubPrefix("");
00241
00242
00243
00244
00245 SetSyncSource(0);
00246
00247 SetNoTriggerSignal();
00248
00249 fNumHits = 0;
00250 fNumBadHits = 0;
00251 fNumCorrHits = 0;
00252 }
00253
00254 nx::Processor::~Processor()
00255 {
00256 printf("%s NumHits %9d NumCorr %8d (%5.1f%s) NumBad %8d (%5.3f%s)\n",
00257 GetProcName().c_str(), fNumHits,
00258 fNumCorrHits, fNumHits > 0 ? 100.* fNumCorrHits / fNumHits : 0., "%",
00259 fNumBadHits, fNumHits > 0 ? 100.* fNumBadHits / fNumHits : 0.,"%");
00260
00261
00262 }
00263
00264 void nx::Processor::AssignBufferTo(roc::Iterator& iter, const base::Buffer& buf)
00265 {
00266 if (buf.null()) return;
00267
00268 iter.setFormat(buf().format);
00269 iter.setRocNumber(buf().boardid);
00270
00271 unsigned msglen = roc::Message::RawSize(buf().format);
00272
00273
00274 iter.assign(buf().buf, buf().datalen - msglen);
00275 }
00276
00277
00278
00279 bool nx::Processor::FirstBufferScan(const base::Buffer& buf)
00280 {
00281 if (buf.null()) return false;
00282
00283 AssignBufferTo(fIter, buf);
00284
00285 roc::Message& msg = fIter.msg();
00286
00287 unsigned cnt(0), msgcnt(0);
00288
00289 bool first = true;
00290
00291
00292
00293
00294
00295
00296
00297 while (fIter.next()) {
00298
00299 cnt++;
00300
00301
00302 if (fIter.islast() && msg.isEpochMsg()) continue;
00303
00304 unsigned rocid = msg.getRocNumber();
00305
00306 if (rocid != GetBoardId()) {
00307 printf("Message from wrong ROCID %u, expected %u\n", rocid, GetBoardId());
00308 continue;
00309 }
00310
00311 msgcnt++;
00312
00313 FillH1(fMsgsKind, msg.getMessageType());
00314
00315 uint64_t fulltm = fIter.getMsgFullTime();
00316
00317
00318 double msgtm = (fulltm % 1000000000000LLU)*1e-9;
00319
00320 FillH1(fALLt, msgtm);
00321
00322 int isok = 0;
00323
00324 switch (msg.getMessageType()) {
00325
00326 case roc::MSG_NOP:
00327 break;
00328
00329 case roc::MSG_HIT: {
00330 unsigned nxid = msg.getNxNumber();
00331 unsigned nxch = msg.getNxChNum();
00332 unsigned nxadc = msg.getNxAdcValue();
00333
00334 if (!nx_in_use(nxid)) break;
00335
00336 fNumHits++;
00337
00338 if (IsLastEpochCorr()) {
00339 isok = NX[nxid].corr_nexthit(msg, fulltm, true, true);
00340 if ((isok==-1) || (isok==-5)) fNumCorrHits++; else
00341 if (isok<0) fNumBadHits++;
00342 }
00343
00344 FillH1(NX[nxid].fChannels, nxch);
00345 FillH2(NX[nxid].fADCs, nxch, nxadc);
00346 FillH1(NX[nxid].fHITt, msgtm);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 break;
00372 }
00373
00374 case roc::MSG_GET4: {
00375
00376 printf("FAILURE - no any GET4 in nx processor!!!\n");
00377 exit(5);
00378 break;
00379 }
00380
00381 case roc::MSG_EPOCH: {
00382
00383
00384
00385
00386 break;
00387 }
00388
00389 case roc::MSG_EPOCH2: {
00390 printf("FAILURE - no any GET4 EPOCHs in nx processor!!!\n");
00391 exit(5);
00392 break;
00393 }
00394
00395 case roc::MSG_SYNC: {
00396 unsigned sync_ch = msg.getSyncChNum();
00397
00398
00399 FillH1(fSYNCt[sync_ch], msgtm);
00400
00401
00402 if (sync_ch == fSyncSource) {
00403
00404 base::SyncMarker marker;
00405 marker.uniqueid = msg.getSyncData();
00406 marker.localid = msg.getSyncChNum();
00407 marker.local_stamp = fulltm;
00408 marker.localtm = fIter.getMsgFullTimeD();
00409
00410
00411
00412
00413
00414
00415
00416 AddSyncMarker(marker);
00417 }
00418
00419 if (fTriggerSignal == (10 + sync_ch)) {
00420
00421 base::LocalTriggerMarker marker;
00422 marker.localid = 10 + sync_ch;
00423 marker.localtm = fulltm;
00424
00425 AddTriggerMarker(marker);
00426 }
00427
00428 break;
00429 }
00430
00431 case roc::MSG_AUX: {
00432 unsigned auxid = msg.getAuxChNum();
00433
00434 FillH1(fAUXt[auxid], msgtm);
00435
00436 if (fTriggerSignal == auxid) {
00437
00438 base::LocalTriggerMarker marker;
00439 marker.localid = auxid;
00440 marker.localtm = fulltm;
00441
00442 AddTriggerMarker(marker);
00443 }
00444
00445 break;
00446 }
00447
00448 case roc::MSG_SYS: {
00449 FillH1(fSysTypes, msg.getSysMesType());
00450 break;
00451 }
00452 }
00453
00454
00455
00456 if (first && !msg.isEpochMsg()) {
00457 first = false;
00458 buf().local_tm = fIter.getMsgFullTimeD();
00459 }
00460
00461
00462 if (fNumPrintMessages > 0) {
00463
00464 bool doprint = true;
00465
00466 if ((fPrintLeft>0) && (fPrintLeft < fPrintRight)) {
00467 double safety = fAnyPrinted ? 0.0001 : 0.;
00468 doprint = (msgtm >= fPrintLeft-safety) && (msgtm <= fPrintRight+safety);
00469 if (!doprint && fAnyPrinted) {
00470 fNumPrintMessages = 0;
00471
00472 printf("Stop printing while message time is %9.6f\n", msgtm);
00473
00474 }
00475 }
00476
00477 if (doprint) {
00478
00479 fNumPrintMessages--;
00480 fAnyPrinted = true;
00481 if (isok==0) printf(" "); else
00482 if (isok==1) printf(" ok "); else
00483 if (isok==-1) printf("err "); else
00484 if (isok==-2) printf("nxt "); else
00485 if (isok==-3) printf("oth "); else
00486 if (isok==-4) printf("dff "); else
00487 if (isok==-5) printf("msb ");
00488 fIter.printMessage(roc::msg_print_Human);
00489 }
00490
00491 }
00492
00493 }
00494
00495 FillMsgPerBrdHist(msgcnt);
00496
00497 return true;
00498 }
00499
00500 unsigned nx::Processor::GetTriggerMultipl(unsigned indx)
00501 {
00502 nx::SubEvent* ev = (nx::SubEvent*) fGlobalTrig[indx].subev;
00503
00504 return ev ? ev->fExtMessages.size() : 0;
00505 }
00506
00507
00508 bool nx::Processor::SecondBufferScan(const base::Buffer& buf)
00509 {
00510 if (buf.null()) return false;
00511
00512
00513
00514
00515
00516 AssignBufferTo(fIter2, buf);
00517
00518 roc::Message& msg = fIter2.msg();
00519
00520 unsigned cnt = 0;
00521
00522 unsigned help_index = 0;
00523
00524 while (fIter2.next()) {
00525
00526 cnt++;
00527
00528
00529 if (fIter2.islast() && msg.isEpochMsg()) continue;
00530
00531 unsigned rocid = msg.getRocNumber();
00532
00533 if (rocid != GetBoardId()) continue;
00534
00535
00536
00537 switch (msg.getMessageType()) {
00538
00539 case roc::MSG_NOP:
00540 break;
00541
00542 case roc::MSG_SYNC:
00543 case roc::MSG_AUX:
00544 case roc::MSG_HIT: {
00545
00546
00547 uint64_t stamp = fIter2.getMsgFullTime();
00548
00549 bool isnxmsg = msg.isHitMsg() && nx_in_use(msg.getNxNumber());
00550
00551 if (isnxmsg && IsLastEpochCorr())
00552 NX[msg.getNxNumber()].corr_nexthit(msg, stamp, true, false);
00553
00554 base::GlobalTime_t globaltm = LocalToGlobalTime(stamp, &help_index);
00555
00556 unsigned indx = TestHitTime(globaltm, isnxmsg);
00557
00558 if ((indx < fGlobalTrig.size()) && !fGlobalTrig[indx].isflush) {
00559 nx::SubEvent* ev = (nx::SubEvent*) fGlobalTrig[indx].subev;
00560
00561 if (ev==0) {
00562 ev = new nx::SubEvent;
00563 fGlobalTrig[indx].subev = ev;
00564
00565 }
00566
00567 ev->fExtMessages.push_back(nx::MessageExtended(msg, globaltm));
00568 }
00569 break;
00570 }
00571
00572 case roc::MSG_GET4: {
00573
00574 printf("FAILURE - no any GET4 in nx processor!!!\n");
00575 exit(5);
00576 break;
00577 }
00578
00579 case roc::MSG_EPOCH: {
00580 break;
00581 }
00582
00583 case roc::MSG_EPOCH2: {
00584 printf("FAILURE - no any GET4 EPOCHs in nx processor!!!\n");
00585 exit(5);
00586 break;
00587 }
00588
00589 case roc::MSG_SYS: {
00590 break;
00591 }
00592 }
00593
00594 }
00595
00596 return true;
00597 }
00598
00599 void nx::Processor::SortDataInSubEvent(base::SubEvent* subev)
00600 {
00601 nx::SubEvent* nxsub = (nx::SubEvent*) subev;
00602
00603 std::sort(nxsub->fExtMessages.begin(), nxsub->fExtMessages.end());
00604 }
00605