StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SVTV1P0_ZS_SR.cxx
1 /***************************************************************************
2  *
3  * $Id: SVTV1P0_ZS_SR.cxx,v 1.9 2014/06/25 15:33:16 jeromel Exp $
4  *
5  * Author: J. Schambach
6  *
7  ***************************************************************************
8  *
9  * Description: SVT Zero Suppressed Reader
10  *
11  ***************************************************************************
12  *
13  * $Log: SVTV1P0_ZS_SR.cxx,v $
14  * Revision 1.9 2014/06/25 15:33:16 jeromel
15  * Code not used but erradicated use of flush
16  *
17  * Revision 1.8 2007/12/24 06:04:28 fine
18  * introduce OLDEVP namespace to allow ole and new EVP library concurrently
19  *
20  * Revision 1.7 2007/08/07 19:44:10 perev
21  * Gene scalers added
22  *
23  * Revision 1.6 2007/01/04 21:27:51 jml
24  * zero suppressed reader no longer uses adcx, only seqd. Fixes bug from early 2005
25  *
26  * Revision 1.5 2003/09/02 17:55:33 perev
27  * gcc 3.2 updates + WarnOff
28  *
29  * Revision 1.4 2003/02/20 21:39:45 ward
30  * Remove voluminous warning message.
31  *
32  * Revision 1.3 2001/05/14 16:07:36 jschamba
33  * corrected mezzanine and transition board evaluation in constructors
34  *
35  * Revision 1.2 2001/04/18 19:47:25 ward
36  * StDaqLib/SVT stuff from Jo Schambach.
37  *
38  * Revision 1.1 2000/06/06 18:08:31 jml
39  * Initial version of SVT Readers (author: marcello munholz, helen caines)
40  *
41  *
42  **************************************************************************/
43 #include <Stiostream.h>
44 
45 #include "StDaqLib/GENERIC/EventReader.hh"
46 #include "SVTV1P0.hh"
47 //
48 using namespace OLDEVP;
49 SVTV1P0_ZS_SR::SVTV1P0_ZS_SR(int w, SVTV1P0_Reader *det)
50 {
51  int w1;
52  int numberOfLadders[3] = {8,12,16};
53  int numberOfWafers[3] = {4,6,7};
54  /*
55  * The relationship between waferIndex (w [0..215]) and the triplet
56  * (barrel[1..3], ladder[1..8,12,16], wafer[1..4,6,7]) is as follows:
57  * w = 0 is wafer = 1, ladder = 1, barrel = 1
58  * w = 1 is wafer = 2, ladder = 1, barrel = 1
59  * ...
60  * w = 4 is wafer = 1, ladder = 2, barrel = 1
61  * ...
62  * w = 32 is wafer = 1, ladder = 1, barrel = 2
63  * ...
64  * w = 215 is wafer = 7, ladder = 16, barrel = 3
65  */
66 
67  if (w < (numberOfWafers[0] * numberOfLadders[0])) {
68  barrel = 1;
69  ladder = w/numberOfWafers[0] + 1;
70  wafer = w%numberOfWafers[0] + 1;
71  }
72  else if( (w1 = w - numberOfWafers[0]*numberOfLadders[0]) <
73  (numberOfWafers[1] * numberOfLadders[1])) {
74  barrel = 2;
75  ladder = w1/numberOfWafers[1] + 1;
76  wafer = w1%numberOfWafers[1] + 1;
77  }
78  else {
79  w1 = w - numberOfWafers[0]*numberOfLadders[0]
80  - numberOfWafers[1]*numberOfLadders[1];
81  barrel = 3;
82  ladder = w1/numberOfWafers[2] + 1;
83  wafer = w1%numberOfWafers[2] + 1;
84  }
85 
86  detector = det;
87 
88  // Now determine the hypersector, receiver board and mezzanine for this wafer
89  switch (barrel) {
90  case 1:
91  {
92  const int mezzIndex[] = {1,2,2,1};
93  if (wafer > 2) hyperSector = 1;
94  else hyperSector = 3;
95  rcb = (ladder-1)/2 + ladder;
96  mezz = mezzIndex[wafer-1];
97  transitionBoard = 2;
98  break;
99  }
100  case 2:
101  {
102  const int mezzIndex[3][6] = { {1,1,3,3,1,1},
103  {1,2,3,3,2,1},
104  {2,2,3,3,2,2} };
105  if (wafer > 3) hyperSector = 1;
106  else hyperSector = 3;
107  rcb = (ladder+2)/3;
108  rcb *= 3;
109  mezz = mezzIndex[(ladder-1)%3][wafer-1];
110  transitionBoard = (ladder-1)%3 + 1;
111  break;
112  }
113  case 3:
114  {
115  const int mezzIndex[] = {2,2,3,3,3,1,1};
116  if (wafer > (4-(ladder%2))) hyperSector = 1;
117  else hyperSector = 3;
118  rcb = (ladder-1)/4 + (ladder+1)/2;
119  if (ladder%2) { //odd ladders
120  mezz = mezzIndex[wafer-1];
121  if (hyperSector == 1) transitionBoard = 1;
122  else transitionBoard = 3;
123  }
124  else { //even ladders
125  mezz = mezzIndex[7-wafer];
126  if (hyperSector == 1) transitionBoard = 3;
127  else transitionBoard = 1;
128  }
129  break;
130  }
131  }
132 
133  if (rcb > 6) {
134  hyperSector++;
135  rcb -= 6;
136  }
137 
138  /*
139  printf("barrel %d, ladder %d, wafer %d hs %d rcb %d, mezz %d tb %d\n",
140  barrel, ladder, wafer, hyperSector, rcb, mezz, transitionBoard);
141  */
142 
143  // NULLS in banks array
144  adcd_p = (classname(Bank_SVTADCD) *)NULL;
145  adcx_p = (classname(Bank_SVTADCX) *)NULL;
146  seqd_p = (classname(Bank_SVTSEQD) *)NULL;
147 
148  for (int ii=0; ii<SVT_HYBRIDS; ii++) HybridSpacePts[ii] = 0;
149 }
150 
151 SVTV1P0_ZS_SR::SVTV1P0_ZS_SR(int b, int l, int w, SVTV1P0_Reader *det)
152 {
153  barrel = b;
154  ladder = l;
155  wafer = w;
156  detector = det;
157 
158  // Now determine the hypersector, receiver board and mezzanine for this wafer
159  switch (barrel) {
160  case 1:
161  {
162  const int mezzIndex[] = {1,2,2,1};
163  if (wafer > 2) hyperSector = 1;
164  else hyperSector = 3;
165  rcb = (ladder-1)/2 + ladder;
166  mezz = mezzIndex[wafer-1];
167  transitionBoard = 2;
168  break;
169  }
170  case 2:
171  {
172  const int mezzIndex[3][6] = { {1,1,3,3,1,1},
173  {1,2,3,3,2,1},
174  {2,2,3,3,2,2} };
175  if (wafer > 3) hyperSector = 1;
176  else hyperSector = 3;
177  rcb = (ladder+2)/3;
178  rcb *= 3;
179  mezz = mezzIndex[(ladder-1)%3][wafer-1];
180  transitionBoard = (ladder-1)%3 + 1;
181  break;
182  }
183  case 3:
184  {
185  const int mezzIndex[] = {2,2,3,3,3,1,1};
186  if (wafer > (4-(ladder%2))) hyperSector = 1;
187  else hyperSector = 3;
188  rcb = (ladder-1)/4 + (ladder+1)/2;
189  if (ladder%2) { //odd ladders
190  mezz = mezzIndex[wafer-1];
191  if (hyperSector == 1) transitionBoard = 1;
192  else transitionBoard = 3;
193  }
194  else { //even ladders
195  mezz = mezzIndex[7-wafer];
196  if (hyperSector == 1) transitionBoard = 3;
197  else transitionBoard = 1;
198  }
199  break;
200  }
201  }
202 
203  if (rcb > 6) {
204  hyperSector++;
205  rcb -= 6;
206  }
207 
208  // NULLS in banks array
209  adcd_p = (classname(Bank_SVTADCD) *)NULL;
210  adcx_p = (classname(Bank_SVTADCX) *)NULL;
211  seqd_p = (classname(Bank_SVTSEQD) *)NULL;
212 
213  for (int ii=0; ii<SVT_HYBRIDS; ii++) HybridSpacePts[ii] = 0;
214 }
215 
216 int SVTV1P0_ZS_SR::initialize()
217 {
218 // printf("zs init\n");
219 
220  for (int hyb=0; hyb<SVT_HYBRIDS; hyb++) {
221  for (int anode=0; anode<SVT_ANODES; anode++) {
222  Anode_array[hyb][anode].nseq = 0;
223  Anode_array[hyb][anode].seq = (Sequence *)0;
224  }
225  }
226 
227  // printf("Looking for ADCD, ADCX, and SEQD banks...\n");
228  adcd_p = detector->getBankSVTADCD(hyperSector, rcb, mezz);
229  if ((void *)adcd_p != NULL) {
230  if (detector->ercpy->verbose) printf("found ADCD RB%d MZ%d\n",rcb,mezz);
231  }
232 
233  seqd_p = detector->getBankSVTSEQD(hyperSector, rcb, mezz);
234 
235  if ((void *)seqd_p != NULL) {
236  if (detector->ercpy->verbose) printf("found SEQD RB%d MZ%d\n",rcb,mezz);
237  }
238 
239  if((adcd_p == NULL) || (seqd_p == NULL)) { // perfectly valid, just no data...
240  return TRUE;
241  }
242 
243 // printf("got banks (adcd_p = 0x%x seqd = 0x%x)\n",adcd_p,seqd_p);
244 
245  // number of entries in SVTSEQD bank
246  int banklen = seqd_p->header.BankLength - (sizeof(Bank_Header)/4);
247  int numseq = (4*banklen)/sizeof(short);
248 
249  // now loop through the hybrids of this wafer
250  for (int hybrid=1; hybrid<=SVT_HYBRIDS; hybrid++) {
251  INT32 hybridID =
252  hybrid |
253  (wafer << 2) |
254  (transitionBoard << 5);
255  int i;
256 
257  int adcd_offset = 0;
258  int seqd_offset = 0;
259  int found = 0;
260  for(i=0;i<numseq;i++) {
261  unsigned short x = seqd_p->sequence[i];
262 
263  if(x & 0x8000) { // This is an index entry...
264 // printf("[%d] index %d/%d\n",
265 // i,(x & 0x7fff)/256,(x&0x7fff)%256);
266 
267  if((x & 0x7fff) / 256 == hybridID) {
268  found = 1;
269  seqd_offset = i;
270  break;
271  }
272  }
273  else { // This is a sequence entry...
274 // printf("[%d] seq %d %d %d\n",
275 // i,
276 // (x & 0x7fc0)>>6,
277 // x & 0x20,
278 // x & 0x1f);
279 
280  adcd_offset += x & 0x1f; // in adc counts...
281  }
282  }
283 
284 
285 
286  // printf("hybridID = %d found = %d adcd_off = %d, seqd_off = %d\n",
287 // hybridID, found, adcd_offset, seqd_offset);
288 
289 
290  if(!found) continue;
291 
292 
293  /********************************************/
294  // go through the SEQD twice:
295  // First: malloc the Sequence arrays needed
296  // Second: fill in the Sequence structs
297  /********************************************/
298  i = seqd_offset;
299  int anode = -1, oldtb=0;
300  while (i < numseq) {
301  if (seqd_p->sequence[i] & 0x8000) { // index descriptor
302  anode = (seqd_p->sequence[i])& 0xff;
303  INT32 seq_hybridID = (seqd_p->sequence[i]>>8)& 0x7f;
304 
305  if (seq_hybridID != hybridID) break; //start of the next hybrid
306  if (anode == 255) break;
307  oldtb=0;
308  }
309  else { // sequence descriptor
310  unsigned short work = seqd_p->sequence[i];
311  int tb = (work>>6) & 0xff;
312 // int len = work & 0x1f;
313  int last = work & 0x20;
314 
315  if(oldtb > tb) {
316  printf("Time bins are messed up old=%d, new=%d\n",oldtb,tb);
317  }
318 
319  oldtb = tb;
320 
321  Anode_array[hybrid-1][anode-1].nseq++;
322  if(last) {
323  char *t = (char *)malloc(Anode_array[hybrid-1][anode-1].nseq *
324  sizeof(Sequence));
325 
326  Anode_array[hybrid-1][anode-1].seq = (Sequence *)t;
327 
328  if(!t) {
329  printf("Failed to malloc() sequence structures\n");
330  return FALSE;
331  }
332 
333  anode++;
334  oldtb = 0;
335  }
336  }
337  i++;
338  }
339 
340 // printf("pass1 done\n");
341 
342  /************************************************************/
343  /* Now process SVTSEQD again to fill in the sequence arrays */
344  /************************************************************/
345 
346  u_char *adc_locn = (u_char *)&(adcd_p->ADC[adcd_offset]);
347  i = seqd_offset;
348  int anode_seq = 0;
349  while (i < numseq) {
350  if (seqd_p->sequence[i] & 0x8000) { // index element
351  anode = (seqd_p->sequence[i])& 0xff;
352  INT32 seq_hybridID = (seqd_p->sequence[i]>>8)& 0x7f;
353 
354  if (anode == 255) break; // anode 255 is the last word as a filler
355  if (seq_hybridID != hybridID) break; //start of the next hybrid
356 
357  anode_seq = 0;
358  } // ...if (seqd_p->sequence[i] < 0
359  else { // sequence descriptor element
360  unsigned short work = seqd_p->sequence[i];
361  int tb = (work>>6) & 0xff;
362  int len = work & 0x1f;
363  int last = work & 0x20;
364 
365  Anode_array[hybrid-1][anode-1].seq[anode_seq].startTimeBin = tb;
366  Anode_array[hybrid-1][anode-1].seq[anode_seq].Length = len;
367  Anode_array[hybrid-1][anode-1].seq[anode_seq].FirstAdc = adc_locn;
368  adc_locn +=len;
369  anode_seq++;
370 
371 
372  if(last) { //last sequence ?
373  anode++; // default to next pad in this padrow
374  anode_seq = 0;
375  }
376  }
377  i++;
378  }
379 
380 // printf("pass 2 done\n");
381  }
382 
383  return TRUE;
384 }
385 
386 SVTV1P0_ZS_SR::~SVTV1P0_ZS_SR()
387 {
388  // free memory allocated for Sequence arrays
389  for (int hyb=0; hyb<SVT_HYBRIDS; hyb++) {
390  for (int anode=0; anode<SVT_ANODES; anode++) {
391  void *memaddr = Anode_array[hyb][anode].seq;
392  if (memaddr) free (memaddr);
393  }
394  if (HybridSpacePts[hyb])
395  free(HybridSpacePts[hyb]);
396  }
397 }
398 
399 int SVTV1P0_ZS_SR::getPadList(int Hybrid, u_char **anodeList)
400 {
401  if ((Hybrid < 1) || (Hybrid > 2)) return -1;
402 
403  // fill in hybrid anode list
404  int anode, nanode=0;
405  for (anode=1; anode<241; anode++) {
406  if (Anode_array[Hybrid-1][anode-1].nseq)
407  anodelist[Hybrid-1][nanode++] = anode;
408  }
409 
410  *anodeList = &anodelist[Hybrid-1][0];
411 
412  return nanode;
413 }
414 
415 int SVTV1P0_ZS_SR::getSequences(int Hybrid, int Anode, int *nSeq,
416  Sequence **SeqData)
417 {
418  *nSeq = Anode_array[Hybrid-1][Anode-1].nseq; // number of sequences this anode
419  *SeqData = Anode_array[Hybrid-1][Anode-1].seq; // pass back pointer to Sequence array
420  return 0;
421 }
422 
423 int SVTV1P0_ZS_SR::getFeeSequences(int Fee, int Pin, int *nSeq,
424  Sequence **SeqData)
425 {
426  return 0;
427 }
428 
429 
430 // Read the clusters (space points) found in the mezzanine cluster-finder
431 int SVTV1P0_ZS_SR::getSpacePts(int Hybrid, int *nSpacePts, SpacePt **SpacePts)
432 {
433  classname(Bank_SVTMZCLD) *cld;
434 // int numSpPts = 0;
435  INT32 hybridID =
436  Hybrid |
437  (wafer << 2) |
438  (transitionBoard << 5);
439 
440  *nSpacePts = 0;
441  *SpacePts = HybridSpacePts[Hybrid-1];
442 
443  // make sure the array is empty to begin with
444  if (HybridSpacePts[Hybrid-1])
445  free(HybridSpacePts[Hybrid-1]);
446 
447  cld = detector->getBankSVTMZCLD(hyperSector, rcb, mezz);
448 
449  if (cld == (classname(Bank_SVTMZCLD) *)NULL) {
450  // SVTMZCLD bank doesn't exist
451  if (detector->ercpy->verbose) {
452  printf("SVTMZCLD for HS %d, Receiver %d, Mezz %d does not exist\n",
453  hyperSector, rcb, mezz);
454  }
455  }
456  else { // SVTMZCLD bank exists
457  int numHybrids = cld->NumHybrids;
458  if (numHybrids > 0) { // are there any entries?
459  int *ptr = (int *)&cld->stuff;
460  int i = 0;
461  while (i < numHybrids) {
462  INT32 cld_hybridID = *ptr++;
463  int nsp = *ptr++; // number of space points this hybrid
464  if (cld_hybridID == hybridID) { // found the right hybrid
465  if (detector->ercpy->verbose)
466  cout << "Barrel " << barrel <<"ladder " << ladder <<"wafer "
467  << wafer << " hybrid " << Hybrid << ": found "
468  << nsp << " space pts" << endl;
469 
470  HybridSpacePts[Hybrid-1] = (SpacePt *)malloc(nsp *sizeof(struct SpacePt));
471  if (HybridSpacePts[Hybrid] == NULL) {
472  cout << "failed to malloc() Space Point structures " << endl;
473  return FALSE;
474  }
475  // now fill in the spacepoints
476  for (int isp=0; isp<nsp; isp++, ptr+=2) {
477  HybridSpacePts[Hybrid-1][isp] = *(SpacePt *)ptr;
478  }
479  *nSpacePts = nsp;
480  break;
481  }
482  ptr += 2*nsp; // move pointer over spacepoints for this hybrid
483  i++;
484  } // ...while (int i < numHybrids
485  } // ...if (cld->NumHybrids > 0
486  } // ...else { SVTMZCLD bank exists
487 
488  return TRUE;
489 }
490 
491 
492 int SVTV1P0_ZS_SR::MemUsed()
493 {
494  return 0;
495 }
496