ICP  1
detector_card.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 
3 #include "detector_card.h"
4 #include "isisvme.h"
5 #include "icputils.h"
6 #include "dae_events.h"
7 
8 static bool memory_check = false;
9 
10 // there are ntc user time channels and hence ntc+1
11 // user supplied boundaries. ntc+1 values are written to
12 // the TCGLUT memory, but the size of a spectrum, is (ntc+1)
13 // rather than (ntc) as there is a special "channel 0" where counts
14 // that occur before the first time channel go
15 
16 template <class DetCardPolicy>
18 {
19  if (m_options & DetectorCard::EventMode)
20  {
21  return (m_reg.event_reg.eventMode(status) != 0) ? true : false;
22  }
23  else
24  {
25  return false;
26  }
27 }
28 
29 template <class DetCardPolicy>
30 void DetectorCard<DetCardPolicy>::printStatus(std::ostream& os, DAEstatus& status)
31 {
32  isisU32_t value;
33  DAE2Card::printStatus(os, status);
34  os << "This is a " << DetCardPolicy::card_type << " DETECTOR card with " << m_memsize / (1024*1024)
35  << " MB memory" << std::endl;
36  os << "Mode is " << (m_mode & ModeNeutronData ? "neutron" : "sample environment") << std::endl;
37  os << "Highest DAE2 spectrum used = " << m_highspec << std::endl;
38  getNTimeChannels(&value, status);
39  os << value << " time channels" << std::endl;
40  if (m_hardware_periods)
41  {
42  os << "HARDWARE periods: number of DAQ periods = " << m_nperiods << std::endl;
43  getCurrentHardwarePeriod(&value, status);
44  os << "Current DAQ period number = " << value << std::endl;
45  readRegister16As32(DCPERSIZE0, DCPERSIZE1, &value, status);
46  os << "Current DAQ period size (words) = " << value << std::endl;
47  }
48  else
49  {
50  os << "SOFTWARE periods: number of periods = " << m_nperiods << std::endl;
51  }
52  getTotalCounts(&value, status);
53  os << "Total counts register = " << value << std::endl;
54  if (m_options & DetectorCard::VetoLogging)
55  {
56  printVetoStatus(os, false, status);
57  }
58  else
59  {
60  os << "Veto logging not supported" << std::endl;
61  }
62  if (m_options & DetectorCard::DelayedFrameSync)
63  {
64  getFrameSyncDelay(&value, status);
65  os << "Delayed Frame synch = " << value << std::endl;
66  }
67  md5checksum_t checksum;
68  md5sumString(m_poslut, DCPOSLUTSIZE * sizeof(isisU32_t), checksum, status);
69  os << "POSLUT checksum = " << checksumAsString(checksum) << std::endl;
70  if (m_options & DetectorCard::EventMode)
71  {
72  printRegister("Next Frame Marker Register", DCNXFRMR, os);
73  printRegister("Next Memory Write Register", DCNXMEMWR, os);
74  printRegister("Number of Memory Wraps Register", DCNMEMWR, os);
75  printRegister("Last Read Register", DCADDLRR, os);
76  printRegister("Event Mode Register", DCEVNTMD, os, true);
77  }
78 // printSpecmap(os);
79 }
80 
81 template <class DetCardPolicy>
82 int DetectorCard<DetCardPolicy>::printVetoStatus(std::ostream& os, bool triggered_only, DAEstatus& status)
83 {
84  isisU16_t temp16, value16;
85  getDIMVetos(&temp16, status);
86  readDIMVetoOccurredFlag(&value16, status);
87  for(int i=0; i<16; i++)
88  {
89  bool enabled = ((temp16 & (1 << i)) != 0);
90  bool triggered = ((value16 & (1 << i)) != 0);
91  if (!triggered_only || (enabled && triggered))
92  {
93  os << "Detector card " << m_position << " Veto for Dim" << i <<
94  " is " << (enabled ? "ENABLED" : "DISABLED") <<
95  (triggered ? " OCCURRED" : " CLEAR") << std::endl;
96  }
97  }
98  printVetoStatus(FrameOverflowVeto, os, triggered_only, status);
99  printVetoStatus(MemoryFullVeto, os, triggered_only, status);
100  printVetoStatus(FIFOLateVeto, os, triggered_only, status);
101  return 0;
102 }
103 
104 template <class DetCardPolicy>
105 int DetectorCard<DetCardPolicy>::printVetoStatus(DetectorCardVeto veto, std::ostream& os, bool triggered_only, DAEstatus& status)
106 {
107  bool enabled = isVetoEnabled(veto, status);
108  bool triggered = hasVetoOccurred(veto, status);
109  if (!triggered_only || (enabled && triggered))
110  {
111  os << "Detector card " << m_position << " " << getVetoName(veto) << (enabled ? " ENABLED, " : " DISABLED ") << (triggered ? "OCCURRED" : "CLEAR") << std::endl;
112  }
113  return 0;
114 }
115 
116 template <class DetCardPolicy>
118 {
119  int i;
120  os << "DAE2 -> DAE1 spec map" << std::endl;
121  for(i=0; i<= m_highspec; i++)
122  {
123  if (m_dae2specmap[i] != NOSPECTRUM)
124  {
125  os << i << " -> " << m_dae2specmap[i] << std::endl;
126  }
127  }
128  os << "DAE1 -> DAE2 spec map" << std::endl;
129  for(i=0; i<DAESPECMAX; i++)
130  {
131  if (m_dae1specmap[i] != NOSPECTRUM)
132  {
133  os << i << " -> " << m_dae1specmap[i] << std::endl;
134  }
135  }
136 }
137 
138 template <class DetCardPolicy>
140 {
141  isisU32_t val;
142  int i;
143  readPOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
144  os << "*** DUMP OF POSLUT ***\n";
145  for(i=0; i<DCPOSLUTSIZE; i++)
146  {
147  val = m_poslut[i];
148  os << val << ((i+1) % 20 == 0 ? '\n' : ' ');
149  }
150  os << "*** DUMP DONE ***\n";
151 }
152 
153 
154 template <class DetCardPolicy>
155 void DetectorCard<DetCardPolicy>::printTimeChannels(std::ostream& os, int start, int end)
156 {
157  isisU32_t ntc, value;
158  DAEstatus status;
159  int i;
160  if (m_options & DetectorCard::DelayedFrameSync)
161  {
162  getFrameSyncDelay(&value, status);
163  os << "Delayed frame sync = " << value << std::endl;
164  }
165  getNTimeChannels(&ntc, status);
166  os << ntc << " time channels - first few boundaries in clock pulses\n";
167  if (end == -1)
168  {
169  end = ntc+1;
170  }
171  isisU32_t* tcb = new isisU32_t[ntc+1];
172  getTimeChannels(tcb, ntc, status);
173  for(i=start; i<end; i++)
174  {
175 //for real time need to divide by m_clock_frequency
176  os << tcb[i] << ( ((i+1) % 10) ? " " : "\n");
177  }
178  os << "\n";
179  delete []tcb;
180 }
181 
182 template <class DetCardPolicy>
184 {
185  *value = 0;
186  return readDescriptorTimeBinLimitRegister(value, status);
187 }
188 
189 template <class DetCardPolicy>
191 {
192  *ntc = 0;
193  return readTCGTimeBinLimitRegister(ntc, status);
194 }
195 
196 template <class DetCardPolicy>
198 {
199  writeDescriptorTimeBinLimitRegister(ntc+1, status);
200  return writeTCGTimeBinLimitRegister(ntc, status);
201 }
202 
203 template <class DetCardPolicy>
204 int DetectorCard<DetCardPolicy>::readDAE1Spectrum(int dae1_spec, isisU32_t* buffer, int nbuffer, DAEstatus& status)
205 {
206  isisU32_t nchan;
207  int spec = findDAE1Spectrum(dae1_spec, status);
208  if (spec != NOSPECTRUM)
209  {
210  if (isEventMode(status))
211  {
212  memset(buffer, 0, nbuffer * sizeof(isisU32_t)); // no data to read
213 // status.addInfoVa(FAC_DETCARD, "Card %d using event mode - readDAE1Spectrum not done", position());
214  return 0;
215  }
216  getSpectrumSize(&nchan, status);
217  if (nchan > nbuffer)
218  {
219  status.addInfoVa(FAC_DETCARD, "Card %d reading DAE1 spectrum %d truncated (%d > %d)", position(), dae1_spec, nchan, nbuffer);
220  }
221  return readHistogramMemory(4*spec*nchan, buffer, nbuffer /* nchan */, status);
222  }
223  else
224  {
225  memset(buffer, 0, sizeof(isisU32_t) * nbuffer);
226  return -1;
227  }
228 }
229 
231 template <class DetCardPolicy>
232 int DetectorCard<DetCardPolicy>::readDAE1Spectra(isisU32_t* buffer, int nbuffer, const int spec_to_crpt_offset[], int spec_start, int nspec, int period, int persize, DAEstatus& status)
233 {
234  std::ostringstream message;
235  isisU32_t nchan;
236  int dae1_spec, i, j, n;
237  if (isEventMode(status))
238  {
239 // memset(buffer, 0, nbuffer * sizeof(isisU32_t)); // we get passed the CRPT with histogrammed events so do not want to do this!
240 // status.addInfoVa(FAC_DETCARD, "Card %d using event mode - readDAE1Spectra not done", position());
241  return 0;
242  }
243  if (spec_start + nspec >= DAESPECMAX)
244  {
245  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Too many spectra * periods in readDAE1Spectra");
246  return 0;
247  }
248  std::vector<int> dae2_spec;
249  dae2_spec.reserve(nspec);
250  for(i = 0; i < nspec; ++i)
251  {
252  dae1_spec = i + spec_start;
253  if (m_dae1specmap[dae1_spec] != NOSPECTRUM)
254  {
255  dae2_spec.push_back(m_dae1specmap[dae1_spec]);
256  }
257  else
258  {
259  dae2_spec.push_back(NOSPECTRUM); // need to make sure we had contiguous dae2 spec -> contiguous dae1 spec
260  }
261  }
262  std::vector<int> consec_points, consec_sizes;
263  findConsecutive(dae2_spec, NOSPECTRUM, consec_points, consec_sizes);
264  getSpectrumSize(&nchan, status);
265  for(i=0; i<consec_points.size(); ++i)
266  {
267  j = consec_points[i];
268  n = consec_sizes[i];
269  int d2spec = dae2_spec[j];
270  dae1_spec = m_dae2specmap[d2spec];
271  int effective_period = dae1_spec / m_dae1persize; // this is to allow for higher spectrum numbers beiging used to indicate periods
272  int offset = spec_to_crpt_offset[dae1_spec % m_dae1persize] + (period + effective_period) * persize;
273  if ( (offset + n * nchan) > nbuffer )
274  {
275  message << "DetectorCard: too small buffer " << nbuffer << " for reading DAE1 spectrum " << dae1_spec << " period " << period << " from card " << position() << "\n";
276  }
277  else if (readHistogramMemory(4*nchan*(d2spec + period*m_dae2persize), buffer + offset, n*nchan, status) != ISISVME::Success)
278  {
279  message << "DetectorCard: error reading DAE1 spectrum " << dae1_spec << " from card " << position() << "\n";
280  }
281  }
282  if (message.str().size() > 0)
283  {
284  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message.str());
285  }
286  return 0;
287 }
288 
292 template <class DetCardPolicy>
293 int DetectorCard<DetCardPolicy>::readAllDAE1Spectra(isisU32_t* buffer, int nbuffer, const int spec_to_crpt_offset[], int persize, DAEstatus& status)
294 {
295  std::ostringstream message;
296 // int nper_daq = nbuffer / persize;
297  isisU32_t nchan;
298  int dae1_spec, i, j, n;
299  if (isEventMode(status))
300  {
301 // status.addInfoVa(FAC_DETCARD, "Card %d using event mode - readAllDAE1Spectra not done", position());
302  return 0;
303  }
304  std::vector<int> consec_points, consec_sizes;
305  findConsecutive(m_dae2specmap, NOSPECTRUM, consec_points, consec_sizes);
306  getSpectrumSize(&nchan, status);
307  for(i=0; i<consec_points.size(); ++i)
308  {
309  j = consec_points[i];
310  n = consec_sizes[i];
311  dae1_spec = m_dae2specmap[j];
312  if (dae1_spec == 0) // skip spectrum 0 for now - see comments above
313  {
314  if (n == 1)
315  {
316  continue;
317  }
318  else
319  {
320  ++j;
321  --n;
322  ++dae1_spec;
323  }
324  }
325  int period = j / m_dae2persize;
326  int offset = spec_to_crpt_offset[dae1_spec % m_dae1persize] + period * persize;
327 // if (period >= nper_daq)
328 // {
329 // status.addWarningVa(FAC_DETCARD, "DetectorCard: reading period %d on card %d when nper_daq=%d - this can be ignored if you are using hardware periods with DEWLL periods\n", period + 1, position(), nper_daq);
330 // }
331 // else if ( (offset + n * nchan) > nbuffer )
332  if ( (offset + n * nchan) > nbuffer )
333  {
334  message << "DetectorCard: too small buffer " << nbuffer << " for reading " << n << " DAE1 spectra starting at " << dae1_spec << " period " << period << " on card " << position() << "\n";
335  }
336  else if (readHistogramMemory(4*j*nchan, buffer + offset, n*nchan, status) != ISISVME::Success)
337  {
338  message << "DetectorCard: error reading " << n << " DAE1 spectra starting at " << dae1_spec << " on card " << position() << "\n";
339  }
340  }
341 #if 0
342  bool done;
343  for(i=0; i<=m_highspec; i++)
344  {
345  dae1_spec = m_dae2specmap[i];
346  if (dae1_spec != NOSPECTRUM)
347  {
348  if ( (dae1_spec+1)*nchan > nbuffer )
349  {
350  done = true;
351  }
352  else
353  {
354  done = false;
355  }
356  while(!done)
357  {
358  if (readHistogramMemory(4*i*nchan, buffer + dae1_spec*nchan, nchan, status) != ISISVME::Success)
359  {
360  message << "DetectorCard: error reading DAE1 spectrum " << dae1_spec << " from card " << position() << "; retrying\n";
361  }
362  else
363  {
364  done = true;
365  }
366  }
367  }
368  }
369 #endif /* 0 */
370  if (message.str().size() > 0)
371  {
372  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message.str());
373  }
374  return 0;
375 }
376 
378 template <class DetCardPolicy>
379 int DetectorCard<DetCardPolicy>::readSpectrum(int spec, isisU32_t* buffer, int nbuffer, DAEstatus& status)
380 {
381  isisU32_t nchan;
382  if (isEventMode(status))
383  {
384  memset(buffer, 0, nbuffer * sizeof(isisU32_t)); // no data to read
385 // status.addInfoVa(FAC_DETCARD, "Card %d using event mode - readSpectrum not done", position());
386  return 0;
387  }
388  getSpectrumSize(&nchan, status);
389  if (nchan > nbuffer)
390  {
391  status.addInfoVa(FAC_DETCARD, "Card %d reading DAE2 spectrum %d truncated (%d > %d)", position(), spec, nchan, nbuffer);
392  }
393  return readHistogramMemory(4*spec*nchan, buffer, nbuffer /* nchan */, status);
394 }
395 
396 template <class DetCardPolicy>
398 {
399  setNTimeChannels(ntc, status);
400  return writeTCGLUTMemory(0, tcb, ntc+1, status);
401 }
402 
403 template <class DetCardPolicy>
405 {
406  return readTCGLUTMemory(0, tcb, ntc+1, status);
407 }
408 
411 template <class DetCardPolicy>
413 {
414  int i, j, dae1_highest = -1;
415  isisU32_t nchan;
416  if (isEventMode(status))
417  {
418  status.addInfoVa(FAC_DETCARD, "Card %d using event mode - addmap not updated", position());
419  return 0;
420  }
421  getSpectrumSize(&nchan, status);
422  for(i=0; i<=m_highspec; i++)
423  {
424  j = m_dae2specmap[i];
425  if (j >= len)
426  {
427  status.addVa(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "fillAddmap: too many spectra %d >= %d", j, len);
428  continue;
429  }
430  if (j != NOSPECTRUM)
431  {
432  // don't update spectrum zero unless we do spectrum 1 too
433  // used during testing of multiple time regimes - may want to do it permanently after more thought?
434  //
435  // if (j == 0 && m_dae1specmap[1] == NOSPECTRUM)
436  // {
437  // continue;
438  // }
439  if (j > dae1_highest)
440  {
441  dae1_highest = j;
442  }
443  addmap[j].spec = i;
444  addmap[j].card = m_position;
445  addmap[j].dc = this;
446  addmap[j].dae1add = 4*j*nchan;
447  addmap[j].dae2add = 4*i*nchan;
448  addmap[j].len = nchan;
449  }
450  }
451  return dae1_highest + 1; // number of elements used
452 }
453 
454 template <class DetCardPolicy>
456 {
457  std::ostringstream message;
458  int modn_min=1000000, modn_max=-1, mpos_min=1000000, mpos_max=-1;
459  int i, j, s, np;
460  readPOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
461  m_highspec = 0;
462  np = 0;
463  m_dae1persize = 0;
464  m_dae2persize = 0;
465  m_nperiods = 1;
466  for(i=0; i<DAESPECMAX; i++)
467  {
468  m_dae1specmap[i] = NOSPECTRUM;
469  m_dae2specmap[i] = NOSPECTRUM;
470  }
471  m_dae1specmap[0] = 0; // map spectrum 0
472  m_dae2specmap[0] = 0; // map spectrum 0
473  for(i=0; i<DCDIMMAX; i++)
474  {
475  for(j=0; j<DCPOSMAX; j++)
476  {
477  s = m_poslut[DCPOSMAX*i + j];
478  if (s > m_highspec)
479  {
480  m_highspec = s;
481  }
482  if (s != 0)
483  {
484  np++;
485  if (i > modn_max)
486  {
487  modn_max = i;
488  }
489  if (j > mpos_max)
490  {
491  mpos_max = j;
492  }
493  if (i < modn_min)
494  {
495  modn_min = i;
496  }
497  if (j < mpos_min)
498  {
499  mpos_min = j;
500  }
501 // std::cerr << "Data from (dim,position) = (" << i << ","
502 // << j << ") going to spectrum " << s << std::endl;
503  }
504  }
505  }
506 // we may have junk in the POSLUT, so check value found
507  if (m_highspec >= DAESPECMAX)
508  {
509  m_highspec = DAESPECMAX;
510  }
511 // m_dae2persize = m_highspec + 1;
512  message << "Highest DAE2 spectrum: " << m_highspec << "\n";
513  message << "Number of position: " << np << "\n";
514  message << "MPOS: " << mpos_min << " to " << mpos_max << "\n";
515  message << "MODN: " << modn_min << " to " << modn_max << "\n";
516  status.addInfo(FAC_DETCARD, message.str());
517  return 0;
518 }
519 
520 template <class DetCardPolicy>
521 int DetectorCard<DetCardPolicy>::programPOSLUT(int cards[], int dims[], int pos_start[],
522  int npos[], int spec[], int spec_step[],
523  int nblocks, int nperiods, int dae1persize, DAEstatus& status)
524 {
525  std::ostringstream message;
526  int i, j, s, np;
527  m_highspec = 0;
528  np = 0;
529  m_dae1persize = dae1persize;
530  m_nperiods = nperiods;
531  memset(m_poslut, 0, DCPOSLUTSIZE * sizeof(isisU32_t));
532  for(i=0; i<DAESPECMAX; i++)
533  {
534  m_dae1specmap[i] = NOSPECTRUM;
535  m_dae2specmap[i] = NOSPECTRUM;
536  }
537  m_dae1specmap[0] = 0; // map spectrum 0
538  m_dae2specmap[0] = 0; // map spectrum 0
539  for(i=0; i<nblocks; i++)
540  {
541  if (cards[i] != m_position)
542  {
543  continue;
544  }
545  s = spec[i];
546  for(j=0; j<npos[i]; j++)
547  {
548  m_poslut[DCPOSMAX * dims[i] + pos_start[i] + j] = s;
549  m_dae1specmap[s] = s;
550  m_dae2specmap[s] = s;
551  if (s > m_highspec)
552  {
553  m_highspec = s;
554  }
555  s += spec_step[i];
556  np++;
557  }
558  }
559  m_dae2persize = m_highspec + 1;
560  message << "Card: " << m_position << " DAE2 Highest: " << m_highspec << "NPOS: " << np << std::endl;
561  if (m_highspec > DAESPECMAX)
562  {
564  "Detector Card %d has too many spectra: %d",
565  m_position, m_highspec);
566  }
567  status.addInfo(FAC_DETCARD, message.str());
568  return writePOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
569 }
570 
571 template <class DetCardPolicy>
573  int mpos[], int spec[], int ndet,
574  int nperiods, int dae1persize, DAEstatus& status)
575 {
576  std::ostringstream message_i, message_e, message_w;
577  int i, j, s, dae1min, dae1max, npos, ngap;
578  bool card_used;
579  int modn_min=1000000, modn_max=-1, mpos_min=1000000, mpos_max=-1;
580  npos = 0;
581  memset(m_poslut, 0, DCPOSLUTSIZE * sizeof(isisU32_t));
582  m_dae1persize = dae1persize;
583  m_nperiods = nperiods;
584  if (ndet > DAESPECMAX)
585  {
586  status.addVa(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Too may spectra - DAESPECMAX needs increasing to more than %d", ndet);
587  return ISISVME::Error;
588  }
589  if (m_mode & ModeSEData)
590  {
591  return programDAE1POSLUTDataDae(status);
592  }
593  for(i=0; i<DAESPECMAX; i++)
594  {
595  m_dae1specmap[i] = NOSPECTRUM;
596  m_dae2specmap[i] = NOSPECTRUM;
597  }
598  m_dae1specmap[0] = 0; // map spectrum 0 - will remove later if card not used
599  m_dae2specmap[0] = 0; // map spectrum 0 - will remove later if card not used
600 // find all DAE1 spectra on this card and
601 // assign dummy DAE2 spectrum number of 1
602  dae1max = -1;
603  dae1min=1000000;
604  card_used = false;
605  for(i=0; i<ndet; i++)
606  {
607  if (crat[i] == m_position)
608  {
609  card_used = true;
610  if (spec[i] != 0) // do not remap spectrum 0
611  {
612  m_dae1specmap[spec[i]] = SPECTRUM_PLACEHOLDER;
613  }
614  if (spec[i] > dae1max)
615  {
616  dae1max = spec[i];
617  }
618  if (spec[i] < dae1min)
619  {
620  dae1min = spec[i];
621  }
622  }
623  }
624 // now assign them sequential DAE2 spectrum numbers
625  ngap = 0;
626  m_highspec = 0;
627  for(i=dae1min; i<=dae1max; i++)
628  {
629  if (m_dae1specmap[i] == SPECTRUM_PLACEHOLDER)
630  {
631  m_dae1specmap[i] = ++m_highspec;
632  m_dae2specmap[m_highspec] = i;
633  }
634  else
635  {
636  ngap++;
637  }
638  }
639  if (m_highspec > DCMAXSPECPOSLUT)
640  {
641  status.addVa(FAC_DETCARD, SEV_WARNING, ERRTYPE_INVCARD, "Too many spectra for poslut %d > %d", m_highspec, DCMAXSPECPOSLUT);
642  return ISISVME::Error;
643  }
644  m_dae2persize = m_highspec + 1;
645  if (ngap > 0)
646  {
647  message_i << "There is a gap of total size " << ngap << " in the DAE1 spectra on the card" << std::endl;
648  }
649 // now assign spectra for periods
650  if (m_dae2persize * m_nperiods >= DAESPECMAX)
651  {
653  "Detector Card %d has too many spectra * periods: %d > %d",
654  m_position, m_dae2persize * m_nperiods, DAESPECMAX);
655  return ISISVME::Error;
656  }
657  if (m_nperiods * m_dae1persize + m_highspec >= DAESPECMAX)
658  {
660  "Detector Card %d has too many spectra * periods: %d > %d",
661  m_position, m_dae1persize * m_nperiods + m_highspec, DAESPECMAX);
662  return ISISVME::Error;
663  }
664  for(i=0; i<m_dae2persize; i++)
665  {
666  s = m_dae2specmap[i];
667  if (s != NOSPECTRUM) // not sure if this really occurs for neutrons, but needed in MuonDetetcorCard so do here for symmetry
668  {
669  for(j=1; j<m_nperiods; j++)
670  {
671  m_dae2specmap[i + j * m_dae2persize] = s + j * m_dae1persize;
672  m_dae1specmap[s + j * m_dae1persize] = i + j * m_dae2persize;
673  }
674  }
675  }
676  m_highspec = m_nperiods * m_dae2persize - 1;
677  // now calculate the POSLUT
678  for(i=0; i<ndet; i++)
679  {
680  if (crat[i] == m_position)
681  {
682  npos++;
683  if (mpos[i] < mpos_min)
684  {
685  mpos_min = mpos[i];
686  }
687  if (modn[i] < modn_min)
688  {
689  modn_min = modn[i];
690  }
691  if (mpos[i] > mpos_max)
692  {
693  mpos_max = mpos[i];
694  }
695  if (modn[i] > modn_max)
696  {
697  modn_max = modn[i];
698  }
699  j = m_dae1specmap[spec[i]];
700  if (j >= 0)
701  {
702  m_poslut[DCPOSMAX * modn[i] + mpos[i]] = j;
703  }
704  else
705  {
706  message_e << "DetectorCard: Error in mapping for dae1 spectrum " << spec[i] << " -> dae2 spectrum " << j << std::endl;
707  }
708  }
709  }
710  if (card_used)
711  {
712  message_i << "Card: " << m_position << " DAE2 Highest: " << m_highspec
713  << " DAE1 low: " << dae1min << " DAE1 high: " << dae1max
714  << " NPOS: " << npos << std::endl;
715  message_i << "MPOS: " << mpos_min << " to " << mpos_max << std::endl;
716  message_i << "MODN: " << modn_min << " to " << modn_max << std::endl;
717  }
718  else
719  {
720  message_w << "*** Detector Card " << m_position << " not used" << std::endl;
721  m_dae1specmap[0] = NOSPECTRUM; // unmap spectrum 0 - this is so we don't pick it up by accident on a scan of Addmaps on cards
722  m_dae2specmap[0] = NOSPECTRUM; // unmap spectrum 0
723  }
724  if (message_i.str().size() > 0)
725  {
726  status.addInfo(FAC_DETCARD, message_i.str());
727  }
728  if (message_w.str().size() > 0)
729  {
730  status.add(FAC_DETCARD, SEV_WARNING, ERRTYPE_INVCARD, message_w.str());
731  }
732  if (message_e.str().length() > 0)
733  {
734  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message_e.str());
735  }
736  // check enough memory on card
737  isisU32_t nchan, mem_needed;
738  getSpectrumSize(&nchan, status);
739  mem_needed = 4 * m_nperiods * m_dae2persize * nchan; // bytes
740  if (isEventMode(status))
741  {
742  status.addInfoVa(FAC_DETCARD, "Card %d using event mode - equivalent card histogram memory needed would be %d MBytes",
743  position(), mem_needed / (1024 * 1024));
744  }
745  else if (mem_needed > m_memsize)
746  {
748  "Detector Card %d has too little memory: %d < %d bytes",
749  m_position, m_memsize, mem_needed);
750  }
751  else
752  {
753  status.addInfoVa(FAC_DETCARD, "Card %d using %d of %d bytes of available histogram memory",
754  position(), mem_needed, m_memsize);
755  }
756  return writePOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
757 }
758 
759 
760 // read len 4 byte words
761 template <class DetCardPolicy>
762 int DetectorCard<DetCardPolicy>::readHistogramMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
763 {
764  ICPCritical cs(&m_critical);
766  int /*i,*/ stat;
767 // std::cerr << "Reading dc histogram memory start,len = " << start << "," << len << " to address " << buffer << " from card " << m_position << std::endl;
768  if ( (m_memsize == 0) || ((start + 4 * len) <= m_memsize) )
769  {
770  stat = readMemory(start + DCMEMSTART, buffer, len, props, status);
771 // for(i=0; i<len; i++)
772 // {
773 // reverseEndian(&buffer[i]);
774 // }
775  return stat;
776  }
777  else
778  {
779  std::ostringstream message;
780  message << "readHistogramMemory: not enough memory on card for address range 0x" << std::hex << start << " to 0x" << start + 4*len << std::dec << std::endl;
781  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message.str());
782  return ISISVME::Error;
783  }
784 }
785 
786 template <class DetCardPolicy>
788 {
790  int stat = ISISVME::Error;
791  int i, len, max_i;
792 // int chunk_len = 1024 * 1024;
793  std::ostringstream message;
794  isisU32_t sum = 0;
795  isisU32_t* buffer = 0;
796  len = m_memsize / 4;
797  if (len > 0)
798  {
799  buffer = new isisU32_t[len];
800 // stat = readMemoryChunked(DCMEMSTART, buffer, len, chunk_len, true, true, status);
801  stat = readMemory(DCMEMSTART, buffer, len, props, status);
802  }
803  max_i = -1;
804  if (stat == ISISVME::Error)
805  {
806  message << "sumHistogramMemory: ERROR" << std::endl;
807  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message.str());
808  }
809  else
810  {
811  for(i=0; i<len; i++)
812  {
813  sum += buffer[i];
814  if (buffer[i] > 0)
815  {
816  max_i = i;
817  }
818  }
819  }
820  if (buffer != 0)
821  {
822  delete []buffer;
823  }
824  status.addInfoVa(FAC_DAE, "Detector card at position %d has memory sum %u, last non zero location after %d words\n", m_position, sum, max_i);
825  return sum;
826 }
827 
828 template <class DetCardPolicy>
829 int DetectorCard<DetCardPolicy>::writeHistogramMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
830 {
832  if ( (m_memsize == 0) || ((start + 4 * len) <= m_memsize) )
833  {
834  return writeMemory(start + DCMEMSTART, buffer, len, 0, props, status);
835  }
836  else
837  {
838  std::ostringstream message;
839  message << "writeHistogramMemory: not enough memory on card" << std::endl;
840  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, message.str());
841  return ISISVME::Error;
842  }
843 }
844 
845 template <class DetCardPolicy>
846 int DetectorCard<DetCardPolicy>::readPOSLUTMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
847 {
848  int i;
849  setTCGAccessRegister(DCTPOSLUT, status);
851  readMemory(start + DCPOSLUT, buffer, len, props, status);
852  for(i=0; i<len; i++)
853  {
854  buffer[i] &= DetCardPolicy::DCPOSLUTMASK;
855  }
856  return 0;
857 }
858 
859 template <class DetCardPolicy>
860 int DetectorCard<DetCardPolicy>::writePOSLUTMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
861 {
862  setTCGAccessRegister(DCTPOSLUT, status);
864  return writeMemory(start + DCPOSLUT, buffer, len, (memory_check ? DCPOSLUTMASK : 0x0), props, status);
865 }
866 
867 template <class DetCardPolicy>
868 int DetectorCard<DetCardPolicy>::clearPOSLUTMemory(DAEstatus& status, unsigned long start, int len)
869 {
870  setTCGAccessRegister(DCTPOSLUT, status);
872  return zeroMemory<isisU32_t>(start + DCPOSLUT, len, (memory_check ? DCPOSLUTMASK : 0x0), props, status);
873 }
874 
875 template <class DetCardPolicy>
876 int DetectorCard<DetCardPolicy>::readTCGLUTMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
877 {
878 // setTCGAccessRegister(DCTTCGLUT);
879 // TCGLUT memory is 24 bit registers, but should read as 32 bit OK
881  return readMemory(start + DCTCGLUT, buffer, len, props, status);
882 }
883 
884 template <class DetCardPolicy>
885 int DetectorCard<DetCardPolicy>::writeTCGLUTMemory(unsigned long start, isisU32_t* buffer, int len, DAEstatus& status)
886 {
887 // setTCGAccessRegister(DCTTCGLUT);
889  return writeMemory(start + DCTCGLUT, buffer, len, (memory_check ? 0xffffffff : 0x0), props, status);
890 }
891 
892 template <class DetCardPolicy>
894 {
895  return writeRegister(DCTAC, mask, status);
896 }
897 
898 template <class DetCardPolicy>
900 {
901  return setAndClearRegisterBits(DCTAC, mask, true, status);
902 }
903 
904 template <class DetCardPolicy>
906 {
907  return readRegister(DCTAC, value, status);
908 }
909 
910 // use isClearHistogramMemoryComplete() to check later
911 template <class DetCardPolicy>
913 {
914  m_last_address_read = m_memsize - 4; // dae set this to 0 on a clear, so we cannot read it from dae here
915  m_wrap_counter = 0;
916  if (isRegisterUsed(DCTAC))
917  {
918  return setTCGAccessRegister(DCTHISCLE, status);
919  }
920  else
921  {
922  return writeRegister(DCRUNMEMCLEAR, 0x1, status);
923  }
924 }
925 
926 // the TCG clears the bit once the clar is completed
927 template <class DetCardPolicy>
929 {
930  isisU32_t value;
931  if (isRegisterUsed(DCTAC))
932  {
933  readTCGAccessRegister(&value, status);
934  value &= DCTHISCLE;
935  }
936  else
937  {
938  readRegister(DCRUNMEMCLEAR, &value, status);
939  }
940  if (value)
941  {
942  return false; // bit still set, clear still in progress
943  }
944  else
945  {
946  if (m_options & DetectorCard::EventMode)
947  {
948  readRegister(DCADDLRR, &value, status);
950  // the DAE sets this to zero at begin, but should be "end of memory", so hack to allow for this
951  if (value != m_last_address_read)
952  {
953  LOGSTR_WARNING("zero last address workaround");
954  status.addWarning(FAC_DAE, "zero last address workaround");
955  writeRegister(DCADDLRR, m_last_address_read, status);
956  }
957  }
958  return true; // bit reset, clear now finished
959  }
960 }
961 
962 // contains ntc+1
963 template <class DetCardPolicy>
965 {
966  if (m_options & DetectorCard::DelayedFrameSync)
967  {
968  readRegister(DCDESCRX, value, status);
969  }
970  else
971  {
972  setTCGAccessRegister(DCTDESCR, status);
973  readRegister(DCDESCR, value, status);
974  }
975  *value &= 0xffff;
976  return 1;
977 }
978 
979 // contains ntc+1
980 template <class DetCardPolicy>
982 {
983  if (m_options & DetectorCard::DelayedFrameSync)
984  {
985  return writeRegister(DCDESCRX, value, status);
986  }
987  else
988  {
989  setTCGAccessRegister(DCTDESCR, status);
990  return writeRegister(DCDESCR, value, status);
991  }
992 }
993 
994 // contains ntc
995 template <class DetCardPolicy>
997 {
998  readRegister(DCTCGTBL, value, status);
999  *value &= 0xffff;
1000  return 1;
1001 }
1002 
1003 // contains ntc
1004 template <class DetCardPolicy>
1006 {
1007  return writeRegister(DCTCGTBL, value, status);
1008 }
1009 
1010 template <class DetCardPolicy>
1011 DetectorCard<DetCardPolicy>::DetectorCard(int position, ISISVME* vme, int* specmap_array, int specmap_len, DAEstatus& status) : DAE2Card(position, vme, status), m_highspec(0), m_memsize(0),
1012  m_nperiods(1), m_dae1persize(0), m_dae2persize(0), m_options(0), m_reg(this), m_last_address_read(0),m_wrap_counter(0),
1013  m_dae1specmap(DAESPECMAX),m_dae2specmap(DAESPECMAX),m_mode(ModeNeutronData)
1014 {
1015  int i;
1016  setLoggerName("DetectorCard");
1017  std::ostringstream message;
1018  isisU32_t value;
1019  DAEstatus temp_status;
1020  InitializeCriticalSection(&m_critical);
1021 
1022  // check for card features
1023  if (readRegister(DCPERCNT0, &value, temp_status, false, false) == 1)
1024  {
1025  message << "This Card Supports HARDWARE periods" << "\n";
1027  }
1028  temp_status.clear(SEV_ERROR, SEV_GE);
1029  if (readRegister(DCVETOFLAG /* DCVETOENABLE */, &value, temp_status, false, false) == 1)
1030  {
1031  message << "This Card Supports VETO logging" << "\n";
1033  }
1034  temp_status.clear(SEV_ERROR, SEV_GE);
1035  if (readRegister(DCFSDEL0, &value, temp_status, false, false) == 1)
1036  {
1037  message << "This Card supports delayed frame sync" << "\n";
1039  }
1040  temp_status.clear(SEV_ERROR, SEV_GE);
1041  if (readRegister(DCNXFRMR, &value, temp_status, false, false) == 1)
1042  {
1043  message << "This Card supports Event Mode data collection" << "\n";
1045  }
1046  temp_status.clear(SEV_ERROR, SEV_GE);
1047  if (readRegister(DCTOTCNTS, &value, temp_status, false, false) == 1)
1048  {
1049  message << "This Card has a total counts register" << "\n";
1051  }
1052  temp_status.clear(SEV_ERROR, SEV_GE);
1053 
1054  m_poslut = new isisU32_t[DCPOSLUTSIZE];
1055  m_dae1specmap.resize(DAESPECMAX, NOSPECTRUM);
1056  m_dae2specmap.resize(DAESPECMAX, NOSPECTRUM);
1057  m_dae1specmap[0] = 0;
1058  m_dae2specmap[0] = 0;
1059  readPOSLUT(status);
1060 // printTimeChannels(cout, 0, 100);
1061 
1062  if (specmap_array != NULL)
1063  {
1064  loadDAE2SpecmapFromArray(specmap_array, specmap_len, status);
1065  }
1066  else
1067  {
1068  // just map 1 to 1 with DAE1 spectra; we have no better info
1069  for(i=1; i<=m_highspec; i++)
1070  {
1071  m_dae2specmap[i] = i;
1072  }
1073  }
1074  recreateDAE1Specmap(status);
1075 
1076 // determine memory size
1077  int j;
1078  bool done = false;
1079  isisU32_t pattern = 0x01010101, zero = 0x0;
1080  isisU32_t save_start, temp1, temp2;
1081  readHistogramMemory(0, &save_start, 1, status);
1082  writeHistogramMemory(0, &zero, 1, status);
1083 // for(j=1; j<70 && !done; j++)
1084  for(j=64; j<65 && !done; j++) // cards are either 64 or 128
1085  {
1086  readHistogramMemory(j*1024*1024, &temp1, 1, status);
1087  writeHistogramMemory(j*1024*1024, &pattern, 1, status);
1088  readHistogramMemory(0, &temp2, 1, status);
1089  writeHistogramMemory(j*1024*1024, &temp1, 1, status);
1090 // message << "Wrote " << pattern << " read " << temp2 << " for MB = " << j << std::endl;
1091  if (temp2 == pattern)
1092  {
1093  m_memsize = j * 1024 * 1024;
1094  message << "The card has " << j << "Mb of memory" << std::endl;
1095  status.addInfo(FAC_DETCARD, message.str());
1096  done = true;
1097  }
1098  pattern++;
1099  }
1100  writeHistogramMemory(0, &save_start, 1, status);
1101  // fix for 128 Mb cards - they do not wrap as the address would be a valid one for the
1102  // next card in the crate. We should only have either 64 or 128 so have to assume 128
1103  // if unable to determine memory
1104  if (!done)
1105  {
1106  m_memsize = 128 * 1024 * 1024;
1107  done = true;
1108  status.addInfo(FAC_DETCARD, "Unable to determine card memory size; assuming 128Mb");
1109  }
1110  if (!done)
1111  {
1112  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Cannot determine card memory");
1113  }
1115  {
1116  readRegister(DCADDLRR, &m_last_address_read, status);
1117  readRegister(DCNMEMWR, &m_wrap_counter, status);
1118  }
1119  printStatus(message, status);
1120  status.addInfo(FAC_ENVCARD, message.str());
1121 }
1122 
1123 // format is m_position m_highspec m_dae2specmap[0->m_highspec]
1124 template <class DetCardPolicy>
1126 {
1127  bool found = false;
1128  int i, highspec = 0, offset = 0;
1129  while(!found && (offset < len))
1130  {
1131  highspec = array[offset+1];
1132  if (array[offset] == m_position)
1133  {
1134  found = true;
1135  }
1136  else
1137  {
1138  offset += (highspec + 3);
1139  }
1140  }
1141  if (!found)
1142  {
1143  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Error loading detector card");
1144  return 0;
1145  }
1146  if (highspec != m_highspec)
1147  {
1148  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Detector card spectrum problem");
1149  return 0;
1150  }
1151  for(i=0; i<=m_highspec; i++)
1152  {
1153  m_dae2specmap[i] = array[i+offset+2];
1154  }
1155 // m_dae2persize = m_highspec + 1;
1156  return 0;
1157 }
1158 
1159 // format is m_position m_highspec m_dae2specmap[0->m_highspec]
1160 template <class DetCardPolicy>
1161 int DetectorCard<DetCardPolicy>::saveDAE2SpecmapToArray(int* array, int offset, int len, DAEstatus& status)
1162 {
1163  int i, new_offset = offset + m_highspec + 3;
1164  if (new_offset <= len)
1165  {
1166  array[offset] = m_position;
1167  array[offset+1] = m_highspec;
1168  for(i=0; i<=m_highspec; i++)
1169  {
1170  array[i+offset+2] = m_dae2specmap[i];
1171  }
1172  return new_offset;
1173  }
1174  else
1175  {
1176  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Not enough room for specmap");
1177  return 0;
1178  }
1179 }
1180 
1181 // recreate m_dae1specmap from m_dae2specmap
1182 template <class DetCardPolicy>
1184 {
1185  std::ostringstream message;
1186  int i, j, dae1_high = 0, dae1_low = 999999;
1187  bool gap = false;
1188  for(i=0; i<DAESPECMAX; i++)
1189  {
1190  m_dae1specmap[i] = NOSPECTRUM;
1191  }
1192  m_dae1specmap[0] = 0; // dae1 0 -> dae2 0
1193  for(i=1; i<=m_highspec; i++)
1194  {
1195  j = m_dae2specmap[i];
1196  if (j != NOSPECTRUM)
1197  {
1198  if (j > dae1_high)
1199  {
1200  dae1_high = j;
1201  }
1202  if (j < dae1_low)
1203  {
1204  dae1_low = j;
1205  }
1206  m_dae1specmap[j] = i;
1207  }
1208  else
1209  {
1210  gap = true;
1211  }
1212  }
1213  if (gap)
1214  {
1215  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "ERROR: Gap detected in DAE2 specmap");
1216  }
1217  message << "Recreated DAE1 specmap with DAE1 spec range " << dae1_low << " to " << dae1_high << std::endl;
1218  if ( (dae1_high - dae1_low + 1) != m_highspec )
1219  {
1220  message << "DAE1 and DAE2 spectra not contiguous" << std::endl;
1221  }
1222  status.addInfo(FAC_DETCARD, message.str());
1223  return 0;
1224 }
1225 
1226 template <class DetCardPolicy>
1228 {
1229  if (nperiod <= 0)
1230  {
1231  status.addWarning(FAC_DETCARD, "Cannot change number of periods; nperiod <= 0");
1232  return ISISVME::Error;
1233  }
1234  if (m_dae2persize <= 0 || m_dae1persize <= 0)
1235  {
1236  status.addWarning(FAC_DETCARD, "Cannot change number of periods; do not know DAE2 period size");
1237  return ISISVME::Error;
1238  }
1239  if (m_dae2persize * nperiod >= DAESPECMAX)
1240  {
1242  "Detector Card %d has too many spectra * periods: %d > %d",
1243  m_position, m_dae2persize * nperiod, DAESPECMAX);
1244  return ISISVME::Error;
1245  }
1246  if (nperiod * m_dae1persize + m_dae2persize >= DAESPECMAX)
1247  {
1249  "Detector Card %d has too many spectra * periods: %d > %d",
1250  m_position, m_dae1persize * nperiod + m_dae2persize, DAESPECMAX);
1251  return ISISVME::Error;
1252  }
1253  // check enough memory on card
1254  isisU32_t nchan, mem_needed;
1255  getSpectrumSize(&nchan, status);
1256  if (nchan > 0)
1257  {
1258  mem_needed = 4 * nperiod * m_dae2persize * nchan; // bytes
1259  if ( !isEventMode(status) && (mem_needed > m_memsize) )
1260  {
1261  status.addWarningVa(FAC_DETCARD,
1262  "Detector Card %d has too little memory for %d periods: %d < %d bytes",
1263  m_position, nperiod, m_memsize, mem_needed);
1264  return ISISVME::Error;
1265  }
1266  }
1267  m_nperiods = nperiod;
1268  int i, j, s;
1269  for(i=m_dae2persize; i<m_dae2specmap.size(); ++i)
1270  {
1271  m_dae2specmap[i] = NOSPECTRUM;
1272  }
1273  for(i=m_dae1persize; i<m_dae1specmap.size(); ++i)
1274  {
1275  m_dae1specmap[i] = NOSPECTRUM;
1276  }
1277  for(i=0; i<m_dae2persize; ++i)
1278  {
1279  s = m_dae2specmap[i];
1280  if (s != NOSPECTRUM) // we need this test for muons as may be unassigned DAE2 spectra due to no POSLUT
1281  {
1282  for(j=1; j<m_nperiods; ++j)
1283  {
1284  m_dae2specmap[i + j * m_dae2persize] = s + j * m_dae1persize;
1285  m_dae1specmap[s + j * m_dae1persize] = i + j * m_dae2persize;
1286  }
1287  }
1288  }
1289  m_highspec = m_nperiods * m_dae2persize - 1;
1290  return ISISVME::Success;
1291 }
1292 
1293 // period 0 is the first period with detectors going into
1294 // DAE2 spectra 0, 1, 2, 3 ... N (=m_highspec) etc
1295 // period 1 will have it going into N+1, N+2, ..., 2*(N+1)-1
1296 // period 2 will be 2*(N+1) ... 3*(N+1)-1
1297 //
1298 template <class DetCardPolicy>
1300 {
1301  int i, j, s, period_incr;
1302  if (period >= m_nperiods)
1303  {
1304  status.addVa(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Cannot change period to %d >= %d", period, m_nperiods);
1305  return ISISVME::Error;
1306  }
1307  if (m_dae2persize == 0)
1308  {
1309  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "Cannot change period; do not know DAE2 period size");
1310  return ISISVME::Error;
1311  }
1312  if (m_options & DetectorCard::HardwarePeriods)
1313  {
1314  return setPeriodCounter(period, status);
1315  }
1316  else
1317  {
1318  period_incr = period * m_dae2persize;
1319  for(i=0; i<DCDIMMAX; i++)
1320  {
1321  for(j=0; j<DCPOSMAX; j++)
1322  {
1323  s = m_poslut[DCPOSMAX*i + j] % m_dae2persize; // make spectrum relative to first period
1324  m_poslut[DCPOSMAX*i + j] = s + period_incr;
1325  if (s + period_incr > DCMAXSPECPOSLUT)
1326  {
1327  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "spectrum * period number too big for POSLUT");
1328  return ISISVME::Error;
1329  }
1330  }
1331  }
1332  return writePOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
1333  }
1334 }
1335 
1337 template <class DetCardPolicy>
1339 {
1340  isisU32_t value;
1341  if (m_options & DetectorCard::VetoLogging)
1342  {
1343  readRegister(DCVETOENABLE, &value, status);
1344  *dim_mask = (isisU16_t)(value >> 16);
1345  }
1346  else
1347  {
1348  *dim_mask = 0;
1349  }
1350  return 0;
1351 }
1352 
1353 // set bit 0 for dim 0 etc
1354 template <class DetCardPolicy>
1356 {
1357  if (m_options & DetectorCard::VetoLogging)
1358  {
1359  return setRegisterBits(DCVETOENABLE, (isisU32_t)dim_mask << 16, true, status);
1360  }
1361  else
1362  {
1363  return 0;
1364  }
1365 }
1366 
1367 template <class DetCardPolicy>
1369 {
1370  if (m_options & DetectorCard::VetoLogging)
1371  {
1372  return clearRegisterBits(DCVETOENABLE, 0xffff0000, status);
1373  }
1374  else
1375  {
1376  return 0;
1377  }
1378 }
1379 
1380 template <class DetCardPolicy>
1382 {
1383  if (m_options & DetectorCard::VetoLogging)
1384  {
1385  return writeRegister(DCVETOFLAG, 0, status);
1386  }
1387  else
1388  {
1389  return 0;
1390  }
1391 }
1392 
1393 // set bit 0 for dim 0 etc
1394 template <class DetCardPolicy>
1396 {
1397  isisU32_t v;
1398  if (m_options & DetectorCard::VetoLogging)
1399  {
1400  readRegister(DCVETOFLAG, &v, status);
1401  *dim_mask = (isisU16_t)(v >> 16);
1402  }
1403  else
1404  {
1405  *dim_mask = 0;
1406  }
1407  return 0;
1408 }
1409 
1411 template <class DetCardPolicy>
1413 {
1414  switch(veto)
1415  {
1416  case FrameOverflowVeto:
1417  return (1 << 15);
1418  case MemoryFullVeto:
1419  return (1 << 14);
1420  case FIFOLateVeto:
1421  return (1 << 13);
1422  default:
1423  return 0;
1424  }
1425 }
1426 
1427 template <class DetCardPolicy>
1429 {
1430  switch(veto)
1431  {
1432  case FrameOverflowVeto:
1433  return "FrameOverflowVeto";
1434  case MemoryFullVeto:
1435  return "MemoryFullVeto";
1436  case FIFOLateVeto:
1437  return "FIFOLateVeto";
1438  default:
1439  return "UNKNOWN";
1440  }
1441 }
1442 
1443 template <class DetCardPolicy>
1445 {
1446  return setRegisterBits(DCVETOENABLE, getVetoMask(veto), true, status);
1447 }
1448 
1449 template <class DetCardPolicy>
1451 {
1452  return clearRegisterBits(DCVETOENABLE, getVetoMask(veto), status);
1453 }
1454 
1455 template <class DetCardPolicy>
1457 {
1458  return registerBitsSet(DCVETOENABLE, getVetoMask(veto), status);
1459 }
1460 
1461 template <class DetCardPolicy>
1463 {
1464  return registerBitsSet(DCVETOFLAG, getVetoMask(veto), status);
1465 }
1466 
1467 template <class DetCardPolicy>
1469 {
1470  delete []m_poslut;
1471  DeleteCriticalSection(&m_critical);
1472 }
1473 
1474 template <class DetCardPolicy>
1476  {
1477  if (m_options & DetectorCard::HardwarePeriods)
1478  {
1479  return writeRegister32As16(DCPERCNT0, DCPERCNT1, period, status);
1480  }
1481  else
1482  {
1483  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "HardwarePeriods not available");
1484  return 1;
1485  }
1486  }
1487 
1488 template <class DetCardPolicy>
1489 int DetectorCard<DetCardPolicy>::setPeriodSize(int per_size, DAEstatus& status) // in 32 bit words
1490  {
1491  if (m_options & DetectorCard::HardwarePeriods)
1492  {
1493  return writeRegister32As16(DCPERSIZE0, DCPERSIZE1, per_size, status);
1494  }
1495  else
1496  {
1497  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "HardwarePeriods not available");
1498  return 1;
1499  }
1500  }
1501 
1502  template <class DetCardPolicy>
1504  {
1505  if (m_options & DetectorCard::HardwarePeriods)
1506  {
1507  readRegister16As32(DCPERCNT0, DCPERCNT1, value, status);
1508  if (*value < 0 || *value >= m_nperiods)
1509  {
1510  status.addWarningVa(FAC_DETCARD, "Detcard: DAQ Period %d invalid (>%d)", *value+1, m_nperiods);
1511  }
1512  return ISISVME::Success;
1513  }
1514  else
1515  {
1516  *value = 0;
1517  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "HardwarePeriods not available");
1518  return ISISVME::Error;
1519  }
1520  }
1521 
1522 template <class DetCardPolicy>
1523  int DetectorCard<DetCardPolicy>::setPeriodType(bool hardware_periods, bool single_daq_period, DAEstatus& status)
1524  {
1525  isisU32_t value;
1526  if (m_options & DetectorCard::HardwarePeriods)
1527  {
1528  m_hardware_periods = hardware_periods;
1529  getSpectrumSize(&value, status);
1530  // this is a workaround for noise on the backplane that can cause a period jump
1531  if (single_daq_period)
1532  {
1533  setPeriodSize(0, status);
1534  }
1535  else
1536  {
1537  setPeriodSize(m_dae2persize * value, status);
1538  }
1539  setPeriodCounter(0, status);
1540  }
1541  else
1542  {
1543  m_hardware_periods = false;
1544  if (hardware_periods)
1545  {
1546  status.add(FAC_DETCARD, SEV_ERROR, ERRTYPE_INVCARD, "HardwarePeriods not available");
1547  }
1548  }
1549  return 0;
1550  }
1551 
1552 template <class DetCardPolicy>
1554  {
1555  if (m_options & DetectorCard::TotalCounts)
1556  {
1557  return readRegister(DCTOTCNTS, counts, status);
1558  }
1559  else
1560  {
1561  *counts = 0;
1562  return ISISVME::Success;
1563  }
1564  }
1565 
1566 template <class DetCardPolicy>
1568  {
1569  if (m_options & DetectorCard::TotalCounts)
1570  {
1571  return setAndClearTCGAccessRegister(DCTTOTCNTSCLE, status);
1572  }
1573  else
1574  {
1575  return ISISVME::Success;
1576  }
1577  }
1578 
1579  template <class DetCardPolicy>
1581  {
1582  if (m_options & DetectorCard::DelayedFrameSync)
1583  {
1584  return readRegister16As32(DCFSDEL0, DCFSDEL1, value, status);
1585  }
1586  else
1587  {
1588  *value = 0;
1589  return ISISVME::Success;
1590  }
1591  }
1592 
1593 template <class DetCardPolicy>
1595  {
1596  if (m_options & DetectorCard::DelayedFrameSync)
1597  {
1598  return writeRegister32As16(DCFSDEL0, DCFSDEL1, value , status);
1599  }
1600  else if (value == 0)
1601  {
1602  return ISISVME::Success;
1603  }
1604  else
1605  {
1607  "Attempt to set a non-zero frame sync delay on a card without such support");
1608  return ISISVME::Error;
1609  }
1610  }
1611 
1612 
1613 // if (pattern == 0) fill with test pattern where upper bits are card address
1614 // and lower bits are memory location offset
1615 // otherwise fill all of memory with pattern
1616 
1617 #define MAKE_TEST_PATTERN(addr) ( ((addr) << 4) + m_position ) // write card ID as botton 4 bits
1618 
1619 template <class DetCardPolicy>
1621 {
1622  int n;
1623  bool done = false;
1624  unsigned long i, j, start;
1625  const int bufsize = 100000;
1626  isisU32_t* buffer = new isisU32_t[bufsize];
1627  start = 0;
1628  while(!done)
1629  {
1630  if (start + 4*bufsize < m_memsize)
1631  {
1632  n = bufsize;
1633  }
1634  else
1635  {
1636  n = (m_memsize - start) / 4;
1637  done = true;
1638  }
1639  for(i=0; i<n; i++)
1640  {
1641  j = i + start / 4;
1642  if (0 == pattern)
1643  {
1644  buffer[i] = MAKE_TEST_PATTERN(j);
1645  }
1646  else if (1 == pattern)
1647  {
1648  buffer[i] = rand();
1649  }
1650  else
1651  {
1652  buffer[i] = pattern;
1653  }
1654  }
1655  writeHistogramMemory(start, buffer, n, status);
1656  start += 4*n;
1657  }
1658  delete[] buffer;
1659  return ISISVME::Success;
1660 }
1661 
1662 template <class DetCardPolicy>
1664 {
1665  int n;
1666  bool done = false;
1667  unsigned long i, start, j;
1668  int nerror = 0;
1669  const int bufsize = 100000, max_error = 20;
1670  isisU32_t* buffer = new isisU32_t[bufsize];
1671  start = 0;
1672  unsigned long tpattern;
1673  ICPTimer icptimer("checkTestPattern(DC)", status);
1674  while(!done)
1675  {
1676  if (start + 4*bufsize < m_memsize)
1677  {
1678  n = bufsize;
1679  }
1680  else
1681  {
1682  n = (m_memsize - start) / 4;
1683  done = true;
1684  }
1685  readHistogramMemory(start, buffer, n, status);
1686  for(i=0; i<n; i++)
1687  {
1688  j = i + start / 4;
1689  if (0 == pattern)
1690  {
1691  tpattern = MAKE_TEST_PATTERN(j);
1692  }
1693  else
1694  {
1695  tpattern = pattern;
1696  }
1697  if (buffer[i] != tpattern)
1698  {
1699  if (nerror < max_error)
1700  {
1701  status.addVa(FAC_DAE, SEV_ERROR, ERRTYPE_OUTOFMEM, "Error at offset %d on card %d", j, m_position);
1702  }
1703  ++nerror;
1704  }
1705  }
1706  start += 4*n;
1707  }
1708  if (nerror > 0)
1709  {
1711  "There were %d error(s) on card %d (only first %d printed)", nerror, m_position, max_error);
1712  }
1713  else
1714  {
1715  status.addInfoVa(FAC_DAE, "There were no errors on card %d (%d MB checked)", m_position, m_memsize / (1024 * 1024));
1716  }
1717  delete[] buffer;
1718  return status.result();
1719 }
1720 
1721 template <class DetCardPolicy>
1723 {
1724  if (m_options & DetectorCard::VetoLogging)
1725  {
1726  printVetoStatus(os, true, status);
1727  }
1728  return ISISVME::Success;
1729 }
1730 
1732 template <class DetCardPolicy>
1734  {
1735  LOGSTR_DEBUG("Setting event collection mode to " << enable);
1736  if (enable)
1737  {
1738  if (m_options & DetectorCard::EventMode)
1739  {
1740  m_reg.event_reg.eventMode(true, status);
1741  m_reg.event_reg.enable32bitEvents(status);
1742  m_reg.event_reg.allVetoesInHeader(false, status);
1743  m_reg.event_reg.storeVetodData(false, status);
1744  m_reg.event_reg.setHeaderType(EventModeRegister<DetCardPolicy>::NormalEventHeader, status);
1745  return ISISVME::Success;
1746  }
1747  else
1748  {
1749  return ISISVME::Error;
1750  }
1751  }
1752  else
1753  {
1754  if (m_options & DetectorCard::EventMode)
1755  {
1756  m_reg.event_reg.eventMode(false, status);
1757  }
1758  return ISISVME::Success;
1759  }
1760  }
1761 
1762 
1764 template <class DetCardPolicy>
1766 {
1767  if ( !isEventMode(status) )
1768  {
1769  return;
1770  }
1771  isisU32_t last_mem_write;
1772  LOGSTR_DEBUG("Updating dae address to " << m_last_address_read);
1773  readRegister(DCNXMEMWR, &last_mem_write, status);
1774  writeRegister(DCADDLRR, m_last_address_read, status);
1775  unsigned bytes_diff = (m_memsize + m_last_address_read - last_mem_write) % m_memsize;
1776  if (bytes_diff < 4096)
1777  {
1778  LOGSTR_WARNING("memory nearly full only " << bytes_diff << " free");
1779  }
1780 }
1781 
1787 template <class DetCardPolicy>
1788 uint32_t DetectorCard<DetCardPolicy>::getNewEvents(isisU32_t* buffer, uint32_t maxlen, uint64_t& num_unread,
1789  bool& run_ended, DAEstatus& status)
1790 {
1791  if ( !isEventMode(status) )
1792  {
1793  num_unread = 0;
1794  run_ended = true;
1795  return 0;
1796  }
1797  isisU32_t value32;
1798  isisU16_t value16;
1799  std::string error_message;
1800  uint32_t len;
1801  num_unread = 0;
1802  run_ended = false;
1803  readRegister(DCADDLRR, &value32, status);
1804  if (value32 != m_last_address_read)
1805  {
1806  LOGSTR_WARNING("DAE and ICP disagree on last value read - dae " << value32 << " icp " << m_last_address_read);
1807  m_last_address_read = value32;
1808  //throw std::runtime_error("DAE and ICP disagree on last value read");
1809  }
1810  poco_assert(m_last_address_read % 4 == 0);
1811  int start_address = (m_last_address_read + 4) % m_memsize;
1812  uint32_t new_words = static_cast<uint32_t>(nNewEventWords(status)); // we cannot evenr have uint64 words on this card
1813  LOGSTR_DEBUG("new words in dae " << new_words << " starting from address " << start_address);
1814  if (new_words == 0)
1815  {
1816  // we may have ended the run - see if there is an end run header present
1817  readRegister(DCNXMEMWR, &value32, status);
1818  if ( (m_memsize + value32 - start_address) % m_memsize >= sizeof(DAEEventHeader) )
1819  {
1820  DAEEventHeader temp_head;
1821  readHistogramMemoryWrapped(start_address, reinterpret_cast<isisU32_t*>(&temp_head), DAE_EVENT_HEADER_WORDS, status);
1822  int iret = DAEEventList::checkEventHeader(&temp_head, error_message);
1823  if (iret == 0)
1824  {
1825  run_ended = DAEEventList::isEndRunHeader(&temp_head, status);
1826  }
1827  else if (iret != 0x20) // 0x20 means dummy pre-frame header is present
1828  {
1829  LOGSTR_WARNING("No new events, but invalid header present " << error_message)
1830  }
1831  }
1832  if (run_ended)
1833  {
1834  LOGSTR_INFORMATION("End header present");
1835  }
1836  return 0; // no new data
1837  }
1838  if (new_words > maxlen)
1839  {
1840  num_unread = new_words - maxlen;
1841  len = maxlen;
1842  }
1843  else
1844  {
1845  len = new_words;
1846  }
1847  if (readHistogramMemoryWrapped(start_address, buffer, len, status))
1848  {
1849  ++m_wrap_counter;
1850  readRegister(DCNMEMWR, &value16, status);
1851  LOGSTR_NOTICE("Detector card memory wrapped, count = " << value16);
1852  if (value16 != m_wrap_counter)
1853  {
1854  LOGSTR_WARNING("mismatch in event memory wrap count: dae = " << value16 << ", icp = " << m_wrap_counter);
1855 // throw std::runtime_error("mismatch in event memory wrap count");
1856  }
1857  }
1858  m_last_address_read = (m_last_address_read + 4 * len) % m_memsize;
1859  return len;
1860 }
1861 
1863 template <class DetCardPolicy>
1864 bool DetectorCard<DetCardPolicy>::readHistogramMemoryWrapped(unsigned long start, isisU32_t* buffer, uint32_t len, DAEstatus& status)
1865 {
1866  poco_assert( start % 4 == 0 );
1867  poco_assert( start < m_memsize );
1868  poco_assert( 4 * len <= m_memsize );
1869  uint32_t end_limit = (start + 4 * len) % m_memsize;
1870  if (end_limit > start)
1871  {
1872  readHistogramMemory(start, buffer, len, status);
1873  return false;
1874  }
1875  else // memory wrapped
1876  {
1877  unsigned len1 = (m_memsize - start) / 4;
1878  unsigned len2 = end_limit / 4;
1879  poco_assert(len == len1 + len2);
1880  readHistogramMemory(start, buffer, len1, status);
1881  readHistogramMemory(0, buffer + len1, len2, status);
1882  return true;
1883  }
1884 }
1885 
1886 
1888 template <class DetCardPolicy>
1890 {
1891  if ( !isEventMode(status) )
1892  {
1893  return 0;
1894  }
1895  isisU32_t next_dae_frame_address;
1896  readRegister(DCNXFRMR, &next_dae_frame_address, status);
1897  poco_assert(next_dae_frame_address % 4 == 0);
1898  uint32_t num_bytes = (m_memsize + next_dae_frame_address - m_last_address_read - 4) % m_memsize;
1899  poco_assert(num_bytes % 4 == 0);
1900 // int fake_max = 1024;
1901 // if (num_bytes > fake_max)
1902 // {
1903 // num_bytes = fake_max;
1904 // }
1905  return num_bytes / 4;
1906 }
1907 
1908 
1923 template <class DetCardPolicy>
1925 {
1926  LOGSTR_INFORMATION("Resetting card state");
1928  uint32_t check_mask = 0x0;
1929 // mantalk 0 %1 40000 C0000000
1930  writeRegister(DCTAC, 0xC0000000, status);
1931 // mantalk 0 %1 80000 0 20000
1932  zeroMemory<isisU32_t>(DCTCGLUT, DCTCGLUTSIZE, check_mask, props, status); // 0x20000 = 131072
1933 // mantalk 0 %1 0 0 E
1934  zeroMemory<isisU32_t>(0, 0xE, check_mask, ISISVME::TransferIORegisterSpace, status);
1935 // mantalk 0 %1 40010 0
1936  writeRegister(DCEVNTMD, 0x0, status);
1937 // mantalk 0 %1 40080 0 2
1938  writeRegister(DCDESCRX, 0x0, status);
1939  writeRegister(DCTCGTBL, 0x0, status);
1940  return ISISVME::Success;
1941 }
1942 
1943 template <class DetCardPolicy>
1944 void DetectorCard<DetCardPolicy>::setCardMode(DetectorCardMode mode)
1945 {
1946  if (m_mode == mode)
1947  {
1948  return;
1949  }
1950  if (mode != ModeSEData)
1951  {
1952  LOGSTR_ERROR("Cannot change mode from SE");
1953  return;
1954  }
1955  m_mode = mode;
1956 }
1957 
1958 template <class DetCardPolicy>
1960 {
1961  int i;
1962  for(i=0; i<DAESPECMAX; i++)
1963  {
1964  m_dae1specmap[i] = NOSPECTRUM;
1965  m_dae2specmap[i] = NOSPECTRUM;
1966  }
1967 // m_dae1specmap[0] = 0; // do not map spectrum 0 as card is unused
1968 // m_dae2specmap[0] = 0; // do not map spectrum 0 as card is unused
1969  m_highspec = 0;
1970  m_dae2persize = m_highspec + 1;
1971  m_highspec = m_nperiods * m_dae2persize - 1;
1972  status.addInfoVa(FAC_DETCARD, "Programming Card %d for sample environment data", position());
1973  // poslut needs to be consqcquitive integeers
1974  for(i=0; i < DCPOSLUTSIZE; ++i)
1975  {
1976  m_poslut[i] = i;
1977  }
1978  return writePOSLUTMemory(0, m_poslut, DCPOSLUTSIZE, status);
1979 }
1980 
1981 const int DetectorCardIntf::NOSPECTRUM = -1;
1983 
1984 template class DetectorCard<DAE2DetCardPolicy>;
1985 template class DetectorCard<DAE3DetCardPolicy>;
int clearPOSLUTMemory(DAEstatus &status, unsigned long start=0, int len=65536)
uint32_t TransferProps
combination of TransferProp values
Definition: isisvme.h:16
#define FAC_DAE
#define ERRTYPE_OUTOFMEM
int readSpectrum(int spec, isisU32_t *buffer, int nbuffer, DAEstatus &status)
read DAE2 spectrum
int setTCGAccessRegister(isisU32_t mask, DAEstatus &status)
void printSpecmap(std::ostream &os)
std::string checksumAsString(md5checksum_t checksum)
Definition: icputils.cpp:354
unsigned long m_memsize
histogram memory in bytes
virtual int programDAE1POSLUT(int crat[], int modn[], int mpos[], int spec[], int ndet, int nperiods, int dae1persize, DAEstatus &status)
int setFrameSyncDelay(isisU32_t value, DAEstatus &status)
int clearVetoOccurredFlag(DAEstatus &status)
virtual int getNTimeChannels(isisU32_t *ntc, DAEstatus &status)
int addVa(int facility, int severity, int errtype, const char *format,...)
Definition: DAEstatus.cpp:54
#define SEV_WARNING
int readAllDAE1Spectra(isisU32_t *buffer, int nbuffer, const int spec_to_crpt_offset[], int persize, DAEstatus &status)
int saveDAE2SpecmapToArray(int *array, int offset, int len, DAEstatus &status)
int readTCGAccessRegister(isisU32_t *value, DAEstatus &status)
int getCurrentHardwarePeriod(isisU32_t *period, DAEstatus &status)
int getFrameSyncDelay(isisU32_t *value, DAEstatus &status)
void updateDAEEventLastRead(DAEstatus &status)
called when all events returned by getNewEvents() have been safely processed
int clearTotalCountsRegister(DAEstatus &status)
uint32_t getNewEvents(isisU32_t *buffer, uint32_t maxlen, uint64_t &num_unread, bool &run_ended, DAEstatus &status)
virtual int setPeriodType(bool hardware_periods, bool single_daq_period, DAEstatus &status)
unsigned long dae1add
Definition: detector_card.h:13
int readTCGLUTMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
int getTotalCounts(isisU32_t *counts, DAEstatus &status)
fixed header marker for DAEEventHeader
Definition: dae_events.h:44
unsigned long isisU32_t
Definition: isisvme_types.h:8
CRITICAL_SECTION m_critical
int readTCGTimeBinLimitRegister(isisU32_t *value, DAEstatus &status)
std::vector< int > m_dae1specmap
dae2spec = m_dae1specmap[dae1spec]
int add(DAEstatus &dstatus, bool clear)
Definition: DAEstatus.cpp:131
int setPeriodSize(int per_size, DAEstatus &status)
void printPOSLUT(std::ostream &os, DAEstatus &status)
int enableDIMVetos(isisU16_t dim_mask, DAEstatus &status)
virtual void printStatus(std::ostream &os, DAEstatus &status)
#define LOGSTR_DEBUG(__arg)
Definition: IsisBase.h:71
int fillAddmap(Addmap *addmap, int len, DAEstatus &status)
virtual int getTimeChannels(isisU32_t *tcb, int ntc, DAEstatus &status)
int spec
Definition: detector_card.h:14
int readDIMVetoOccurredFlag(isisU16_t *dim_mask, DAEstatus &status)
#define LOGSTR_NOTICE(__arg)
Definition: IsisBase.h:85
int m_highspec
highest DAE2 spectrum used
virtual void printStatus(std::ostream &os, DAEstatus &dstatus)
Definition: dae2_card.cpp:453
isisU16_t m_wrap_counter
number of times memory wrapped in event mode
int checkTestPattern(unsigned long pattern, DAEstatus &status)
uint32_t getVetoMask(DetectorCardVeto veto)
for use with DAE2DetCardPolicy::DCVETOENABLE and DAE2DetCardPolicy::DCVETOFLAG - see DAEEventHeaderIn...
#define LOGSTR_WARNING(__arg)
Definition: IsisBase.h:92
int writeHistogramMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
virtual int readPOSLUT(DAEstatus &status)
bool isRegisterUsed(const T &address)
registers are either &quot;unsigned&quot; or &quot;unused_t&quot;
Definition: dae_policy.h:8
static bool memory_check
virtual int setTimeChannels(isisU32_t *tcb, int ntc, DAEstatus &status)
int clearHistogramMemoryStart(DAEstatus &status)
int writeTCGLUTMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
bool hasVetoOccurred(DetectorCardVeto veto, DAEstatus &status)
const char * getVetoName(DetectorCardVeto veto)
int enableVeto(DetectorCardVeto veto, DAEstatus &status)
int printVetoStatus(std::ostream &os, bool triggered_only, DAEstatus &status)
#define SEV_ERROR
virtual int programDAE1POSLUTDataDae(DAEstatus &status)
int clear(int severity, int direction, bool reset_overall_severity=true)
Definition: DAEstatus.cpp:201
bool isClearHistogramMemoryComplete(DAEstatus &status)
void printTimeChannels(std::ostream &os, int start=0, int end=-1)
virtual ~DetectorCard()
bit assignmments for DAE2DetCardPolicy::DCEVNTMD
Definition: detector_card.h:21
isisU32_t sumHistogramMemory(DAEstatus &status)
#define LOGSTR_INFORMATION(__arg)
Definition: IsisBase.h:78
DetectorCard(int position, ISISVME *vme, int *specmap_array, int specmap_len, DAEstatus &status)
int readRegister(unsigned long address, isisU32_t *value, DAEstatus &status, bool little_endian=false, bool retry=true)
int getDIMVetos(isisU16_t *dim_mask, DAEstatus &status)
dim mask for vetos that are enabled
#define LOGSTR_ERROR(__arg)
Definition: IsisBase.h:99
unsigned short isisU16_t
Definition: isisvme_types.h:7
int recreateDAE1Specmap(DAEstatus &status)
DetectorCardIntf * dc
Definition: detector_card.h:11
unsigned char md5checksum_t[16]
Definition: icputils.h:303
bool isVetoEnabled(DetectorCardVeto veto, DAEstatus &status)
int addWarning(int facility, const std::string &text)
Definition: DAEstatus.cpp:101
int disableDIMVetos(DAEstatus &status)
int addWarningVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:106
int readHistogramMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
isisU32_t m_last_address_read
last memory addess read in event mode
uint64_t nNewEventWords(DAEstatus &status)
determine how many words there are to read that correspond to complete frames of events ...
int md5sumString(const void *buffer, int len, unsigned char *md5sum, DAEstatus &status)
Definition: icputils.cpp:277
bool readHistogramMemoryWrapped(unsigned long start, isisU32_t *buffer, uint32_t len, DAEstatus &status)
return true is memory wrapped during read
static const int NOSPECTRUM
static const unsigned DAE_EVENT_HEADER_WORDS
Definition: dae_events.h:102
int writeDescriptorTimeBinLimitRegister(isisU32_t value, DAEstatus &status)
unsigned long dae2add
Definition: detector_card.h:12
int readPOSLUTMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
int writePOSLUTMemory(unsigned long start, isisU32_t *buffer, int len, DAEstatus &status)
static bool isEndRunHeader(const DAEEventHeader *head, DAEstatus &status)
check whether an event frame header is a special enf of frame header
Definition: dae_events.cpp:179
int fillWithTestPattern(unsigned long pattern, DAEstatus &status)
virtual int resetCardState(DAEstatus &status)
#define ERRTYPE_INVCARD
virtual int changePeriod(int period, DAEstatus &status)
#define FAC_ENVCARD
int writeTCGTimeBinLimitRegister(isisU32_t value, DAEstatus &status)
int getSpectrumSize(isisU32_t *value, DAEstatus &status)
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
static const int SPECTRUM_PLACEHOLDER
int setEventCollectionMode(bool enable, DAEstatus &status)
set up for event or histogram mode
int loadDAE2SpecmapFromArray(int *array, int len, DAEstatus &status)
int disableVeto(DetectorCardVeto veto, DAEstatus &status)
int addInfo(int facility, const std::string &text)
Definition: DAEstatus.cpp:86
virtual int programPOSLUT(int cards[], int dims[], int pos_start[], int npos[], int spec[], int spec_step[], int nblocks, int nperiods, int dae1persize, DAEstatus &status)
int setPeriodCounter(int period, DAEstatus &status)
int readDAE1Spectrum(int dae1_spec, isisU32_t *buffer, int nbuffer, DAEstatus &status)
#define SEV_GE
isisU32_t * m_poslut
temp workspace for POSLUT programming
int whichVeto(std::ostream &os, DAEstatus &status)
int card
dae2 spectrum;
Definition: detector_card.h:15
#define FAC_DETCARD
int result()
Definition: DAEstatus.h:144
#define MAKE_TEST_PATTERN(addr)
int readDAE1Spectra(isisU32_t *buffer, int nbuffer, const int spec_to_crpt_offset[], int spec_start, int nspec, int period, int persize, DAEstatus &status)
reads into buffer the spectra on this card that are in the range considered
std::vector< int > m_dae2specmap
dae1spec = m_dae2specmap[dae2spec]
virtual int setNTimeChannels(isisU32_t ntc, DAEstatus &status)
int addInfoVa(int facility, const char *format,...)
Definition: DAEstatus.cpp:91
void setCardMode(DetectorCardMode mode)
CardOptions m_options
void findConsecutive(const std::vector< T > &vec, T invalid_val, std::vector< int > &indexes, std::vector< int > &sizes)
return an array of indices containing the start points of consecutive sequences of numbers ...
Definition: icputils.cpp:664
int setAndClearTCGAccessRegister(isisU32_t mask, DAEstatus &status)
bool isEventMode(DAEstatus &status)
virtual int changeNumberOfPeriods(int nperiod, DAEstatus &status)
int readDescriptorTimeBinLimitRegister(isisU32_t *value, DAEstatus &status)
static void checkEventHeader(const DAEEventHeader *head)
Definition: dae_events.cpp:22