• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

newmonitor/nx/Processor.cxx (r3879/r3878)

Go to the documentation of this file.
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 void nx::NxRec::corr_reset()
00019 {
00020    lasthittm = 0;
00021    reversecnt = 0;
00022 
00023    for (unsigned n=0;n<128;n++) lasthit[n] = 0;
00024    lastch = 0;
00025    lastepoch = 0;
00026 
00027    lastfulltm = 0;
00028 }
00029 
00030 
00031 void nx::NxRec::corr_nextepoch(unsigned epoch)
00032 {
00033    reversecnt = 0;
00034 
00035    bool nextepoch = (epoch == lastepoch+1);
00036 
00037    for (unsigned n=0;n<128;n++)
00038       if ((lasthit[n]>=16384) && nextepoch)
00039          lasthit[n]-=16384;
00040       else
00041          lasthit[n]=0;
00042 
00043    lastepoch = epoch;
00044 }
00045 
00046 int nx::NxRec::corr_nexthit_old(roc::Message& msg, bool docorr)
00047 {
00048    // return 0 - no last epoch, 1 - last epoch is ok, -1 - last epoch err, -2 - next epoch error
00049 
00050    if (msg.getNxLastEpoch()) {
00051       if ((reversecnt>0) && (reversecnt>lasthittm)) return 1;
00052 
00053       if (reversecnt==0) {
00054          if (msg.getNxTs()>16340) return 1;
00055          if ((lasthittm>16000) && (msg.getNxTs()>16000)) return 1;
00056       }
00057 
00058       if (docorr) msg.setNxLastEpoch(0);
00059       return -1;
00060    } else {
00061 
00062       if ((msg.getNxTs() < lasthittm) && (reversecnt>0)) {
00063          if ((lasthittm>2*reversecnt) && (msg.getNxTs() < lasthittm - 2*reversecnt)) return -2;
00064       }
00065 
00066       reversecnt+=32;
00067 
00068       lasthittm = msg.getNxTs();
00069       // msg.getNxChNum();
00070    }
00071 
00072    return 0;
00073 }
00074 
00075 
00076 int nx::NxRec::corr_nexthit_next(roc::Message& msg, bool docorr)
00077 {
00078    // check time stamp three times
00079    // first as it is, is ok - done,
00080    // second - if lastepoch is set and we try without it or lastepoch is not set but we suppose next epoch
00081 
00082    // return 0 - no last epoch,
00083    //        1 - last epoch is ok,
00084    //       -1 - last epoch err,
00085    //       -2 - next epoch error
00086    //       -3 - any other error
00087 
00088    bool normalhit = false;
00089    bool correctedhit = false;
00090 
00091    unsigned hitts(0);
00092 
00093    for (int numtry = 0; numtry<2; numtry++) {
00094 
00095       hitts = msg.getNxTs();
00096 
00097       if (numtry==0) {
00098          if (!msg.getNxLastEpoch()) hitts += 16384;
00099       } else {
00100          if (msg.getNxLastEpoch()) hitts += 16384;
00101                               else hitts += 16384*2;
00102       }
00103 
00104       unsigned id = (msg.getNxChNum() - 1) % 128;
00105       unsigned maxdiff = 0;
00106       unsigned loop_time = 0;
00107       while (id != msg.getNxChNum()) {
00108          if (lasthit[id]!=0) loop_time+=32;
00109          if (hitts < lasthit[id]) {
00110             unsigned diff = lasthit[id] - hitts;
00111             if (diff > maxdiff) maxdiff = diff;
00112          }
00113          id = (id - 1) % 128;
00114       }
00115 
00116       if ((numtry==0) && (maxdiff <= loop_time)) {
00117          // if last-epoch set, but full loop time less than distance to epoch, than error
00118          if (msg.getNxLastEpoch() && (loop_time + 32 < (16384 - hitts))) continue;
00119 
00120          normalhit = true;
00121          break;
00122       }
00123 
00124       if ((maxdiff <= loop_time) && (numtry==1)) {
00125          correctedhit = true;
00126          break;
00127       }
00128    }
00129 
00130    int newres = 0;
00131 
00132    if (normalhit || correctedhit) {
00133 
00134       lastch = (lastch + 1) % 128;
00135 
00136       while (lastch != msg.getNxChNum()) {
00137          lasthit[lastch] = 0;
00138          lastch = (lastch + 1) % 128;
00139       }
00140 
00141       lasthit[lastch] = hitts;
00142    } else {
00143       if (msg.getNxLastEpoch()) newres = -1; else newres = -3;
00144    }
00145 
00146    if (normalhit && msg.getNxLastEpoch()) newres = 1;
00147    if (correctedhit && msg.getNxLastEpoch()) newres = -1;
00148    if (correctedhit && !msg.getNxLastEpoch()) newres = -2;
00149 
00150    int oldres = corr_nexthit_old(msg, docorr);
00151 
00152    return oldres;
00153 
00154 //   if (oldres != newres) newres = -4;
00155 //   return newres;
00156 }
00157 
00158 */
00159 
00160 int nx::NxRec::corr_nexthit(roc::Message& msg, uint64_t fulltm, bool docorr, bool firstscan)
00161 {
00162    // try to make as simple as possible
00163    // if last-epoch specified, one should check FIFO fill status
00164 
00165    // return 1 - last epoch is ok,
00166    //        0 - no last epoch,
00167    //       -1 - last epoch err,
00168    //       -2 - next epoch error
00169    //       -3 - any other error
00170    //       -5 - last epoch err, MSB err
00171 
00172 
00173    uint64_t& lastfulltm = firstscan ? lastfulltm1 : lastfulltm2;
00174 
00175    int res = 0;
00176 
00177    if (msg.getNxLastEpoch()) {
00178 
00179       // do not believe that message can have last-epoch marker
00180       if (msg.getNxTs()<15800) res = -1; else
00181       // fifo fill status should be equal to 1 - most probable situation
00182       if (((msg.getNxLtsMsb()+7) & 0x7) != ((msg.getNxTs()>>11)&0x7)) res = -5; else
00183       // if message too far in past relative to previous
00184       if (fulltm + 800 < lastfulltm) res = -1; else
00185       // we decide that lastepoch bit is set correctly
00186       res = 1;
00187 
00188    } else {
00189 
00190       // imperical 800 ns value
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 //   printf("Start histo creation\n");
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 //   printf("Histo creation done\n");
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       // NX[nx].corr_reset();
00238    }
00239 
00240    SetSubPrefix("");
00241 
00242 //   printf("Histo creation done\n");
00243 
00244 
00245    SetSyncSource(0); // use for NX as default SYNC0 for synchronisation
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    //   printf("nx::Processor::~Processor\n");
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    // we exclude last message which is duplication of SYNC
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 //   printf("======== MESSAGES for board %u ==========\n", GetBoardId());
00292 
00293 
00294 //   static int doprint = 0;
00295 //   static double mymarker = 4311410447414.;
00296 
00297    while (fIter.next()) {
00298 
00299       cnt++;
00300 
00301       // ignore epoch message at the end of the buffer
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       // this time used for histograming and print selection
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             bool data_hit(true), ped_hit(false);
00351 
00352             if( data_hit ) {
00353                fNxTm[nxid][nxch] = fulltm;
00354 
00355                fHITt[nxid]->Fill((msgtm % 10000) * 0.1);
00356 
00357                fChs[nxid]->Fill(nxch);
00358                fADCs[nxid]->Fill(nxch, nxadc);
00359                if (fParam->baselineCalibr) {
00360                   nxadc_corr = fPedestals->GetPedestal(rocid, nxid, nxch) - nxadc;
00361                   ROC[rocid].fADCs_wo_baseline[nxid]->Fill(nxch, nxadc_corr);
00362                } else {
00363                   nxadc_corr = 4095 - nxadc;
00364                }
00365             }
00366 
00367             if( ped_hit ) {
00368                 ROC[rocid].fBaseline[nxid]->Fill(nxch, nxadc);
00369             }
00370 */
00371             break;
00372          }
00373 
00374          case roc::MSG_GET4: {
00375             // must be ignored
00376             printf("FAILURE - no any GET4 in nx processor!!!\n");
00377             exit(5);
00378             break;
00379          }
00380 
00381          case roc::MSG_EPOCH: {
00382 //            if (IsLastEpochCorr())
00383 //               for (unsigned nx=0;nx<NX.size();nx++)
00384 //                  NX[nx].corr_nextepoch(msg.getEpochNumber());
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             // unsigned sync_id = msg.getSyncData();
00398 
00399             FillH1(fSYNCt[sync_ch], msgtm);
00400 
00401             // use configured sync source
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(); // nx gave us time in ns
00409 
00410                // printf("ROC%u Find sync %u tm %6.3f\n", rocid, marker.uniqueid, marker.localtm*1e-9);
00411                // if (marker.uniqueid > 11798000) exit(11);
00412 
00413                // marker.globaltm = 0.; // will be filled by the StreamProc
00414                // marker.bufid = 0; // will be filled by the StreamProc
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       } // switch
00453 
00454 
00455       // keep time of first non-epoch message as start point of the buffer
00456       if (first && !msg.isEpochMsg()) {
00457          first = false;
00458          buf().local_tm = fIter.getMsgFullTimeD(); // nx-based is always in ns
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          //fIter.printMessage();
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 //   printf("Start second buffer scan left %u  right %u  size %u\n", lefttrig, righttrig, fGlobalTrig.size());
00513 //   for (unsigned n=0;n<fGlobalTrig.size();n++)
00514 //      printf("TRIG %u %12.9f flush:%u\n", n, fGlobalTrig[n].globaltm*1e-9, fGlobalTrig[n].isflush);
00515 
00516    AssignBufferTo(fIter2, buf);
00517 
00518    roc::Message& msg = fIter2.msg();
00519 
00520    unsigned cnt = 0;
00521 
00522    unsigned help_index = 0; // special index to simplify search of respective syncs
00523 
00524    while (fIter2.next()) {
00525 
00526       cnt++;
00527 
00528       // ignore epoch message at the end of the buffer
00529       if (fIter2.islast() && msg.isEpochMsg()) continue;
00530 
00531       unsigned rocid = msg.getRocNumber();
00532 
00533       if (rocid != GetBoardId()) continue;
00534 
00535 //      printf("Scan message %u type %u\n", cnt, msg.getMessageType());
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             // here is time in ns anyway, use it as it is
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 //                     printf("Create new event %u\n", cnt);
00565                }
00566 
00567                ev->fExtMessages.push_back(nx::MessageExtended(msg, globaltm));
00568             }
00569             break;
00570          }
00571 
00572          case roc::MSG_GET4: {
00573             // must be ignored
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       } // switch
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 

Generated on Thu Dec 13 2012 04:52:22 for ROCsoft by  doxygen 1.7.1