CDF II
CDF KITS
source navigation ]
diff markup ]
identifier search ]
freetext search ]
file search ]
 
Architecture: i386 ]
Version: 4.10.4 ] [ 4.10.5 ] [ 4.8.4 ] [ 4.8.4l3s ] [ 4.8.5 ] [ 4.9.0 ] [ 4.9.1 ] [ 4.9.1.hpt3 ] [ 4.9.1hpt3 ] [ 4.9.1top1 ] [ 5.0.0 ] [ 5.1.0 ] [ 5.1.0beamonly ] [ 5.1.1 ] [ 5.2.0 ] [ 5.3.0 ] [ 5.3.1 ] [ 5.3.1dsp ] [ 5.3.3 ] [ 5.3.3_nt ] [ 5.3.4 ] [ 6.1.1 ] [ 6.1.1b ] [ 6.1.2 ] [ 6.1.3 ] [ 6.1.4 ] [ 6.1.4int3 ] [ 6.1.4mc ] [ 6.1.4mc_a ] [ 6.1.6 ] [ development ]

001 #include <unistd.h>
002 #include "AbsEnv/AbsEnv.hh"
003 #include "TrackingObjects/Trybos/TRYRun2SiStripSet.hh"
004 #include "TrackingObjects/SiData/GrayCode.hh"
005 #include "TrackingObjects/SiData/ChipStatus.hh"
006 #include "TrackingObjects/SiData/SixdErrorMonitorHtmlGen.hh"
007 //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
008 
009 void TRYRun2SiStripSet::readSIXDBank_nndata( const SIXD_StorableBank & sixd,
010                                              std::vector<int4> & hdiKeys )
011 {         
012 
013   if (_monitorMode&&1==0) {
014     std::ostringstream oss;
015     oss << "TRYRun2SiStripSet_nndata.cc:" << std::endl << std::dec;
016     std::cout << oss.str();
017   }
018   SIXD_StorableBank::VrbHeaderDecode vrbCode ;
019   SIXD_StorableBank::HdiDecode       hdiCode ;
020           
021   // Set data rep if necessary
022   //
023   if ( _selectDataRepByBankVersion )
024   {
025     SiRecoDataRep::instance()->
026                    dataRep().setDataRepByBankVersion( sixd.bank_version() );
027   }
028       
029   // try to init chip info if new run
030   if (lastRunNumber!=AbsEnv::instance()->runNumber()&&_useNNChipThreshold) {
031     delete _chipStatus;
032     // choose database for online/offline
033     std::string db;
034     char name[128];
035     gethostname(name,128);
036     name[127] = '\0';
037     if (strncmp(name, "b0dap", 5) == 0)
038       db = "onotl_prd_read";
039     else
040       db = "ofotl_prd_read";
041     _chipStatus = new ChipStatus(db.c_str(),AbsEnv::instance()->runNumber());
042     lastRunNumber=AbsEnv::instance()->runNumber();
043   }
044   int eventNum = AbsEnv::instance()->trigNumber();
045   if (dumpHtml && _htmlGen)
046       _htmlGen->SetRunNum(AbsEnv::instance()->runNumber());
047 
048   // Reserve space for all possible SiDigiCode's
049   //
050   SiStripSet::collection_type & stripSet = contents();
051   stripSet.reserve( SiliconRawDataFormat::n_hdi_total_sixd * 2 );
052   
053   // Get bank header information
054   //
055   SIXD_StorableBank::VRB_Iter vrb0( sixd ) ;
056   vrbCode.setHeaderWord(vrb0.header_word());
057   int tsCounter = vrbCode.tsCounter();
058   int timeSinceL1A = vrbCode.timeSinceL1A();  
059   
060   //----------------------------------------------------------
061   //  Loop over data in SIXD bank
062   //----------------------------------------------------------
063  
064   SiDigiCode digiCode;
065   digiCode.setLadder( 0 );
066   SiHdiInfo* hdiInfo = 0;
067   
068   // In order to determine if the HDI block is empty, we need
069   // access to the pointers to the current and the next HDI blocks.
070   // A word count <= to the HDI header length => the block is empty.
071   //
072   SIXD_StorableBank::Simple_Iter sixd_begin = sixd.start_of_data();
073   SIXD_StorableBank::Simple_Iter sixd_end   = sixd.end_of_data();
074 
075   SIXD_StorableBank::Simple_HDI_Pointer_Iter 
076                      nextHdiIndex = sixd.begin_hdi_index();
077   SIXD_StorableBank::Simple_HDI_Pointer_Iter 
078                      hdiIndexEnd  = sixd.end_hdi_index();
079   
080   // check for empty bank
081   if ( nextHdiIndex == hdiIndexEnd )
082   {
083     // No data or a format inconsistency.
084     return;
085   }
086   
087   SIXD_StorableBank::
088   Simple_HDI_Iter hdi = sixd_begin + sixd.hdi_block_offset( nextHdiIndex );
089   // pointer error
090   if ( hdi >= sixd_end )
091   {
092     ERRLOG( ELerror, "SIXD_StorableBank read aborted" )
093             << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
094             << "First HDI pointer out-of-bounds."
095             << "HDI pointer = " << hdi
096             << ", end-of-data pointer = " << sixd_end
097             << endmsg;
098     return;
099   }
100   
101   SIXD_StorableBank::Simple_HDI_Iter nextHdi;
102   SIXD_StorableBank::Simple_HDI_Pointer_Iter hdiIndex;
103 
104 //   for ( hdiIndex = sixd.begin_hdi_index(); hdiIndex < hdiIndexEnd;
105 //      hdiIndex += SIXD_StorableBank_format::n_words_per_hdi_pointer )
106 //     {
107 
108   for (int i = 0; i < hdiKeys.size(); ++i)
109     {
110       int4 key = hdiKeys[i];
111       hdiIndex = sixd.begin_hdi_index() + key * SIXD_StorableBank_format::n_words_per_hdi_pointer;
112 
113       hdi = sixd_begin + sixd.hdi_block_offset( hdiIndex );
114       nextHdiIndex = hdiIndex + SIXD_StorableBank_format::n_words_per_hdi_pointer;
115       nextHdi = sixd_begin + sixd.hdi_block_offset( nextHdiIndex );
116 
117     if ( nextHdi > sixd_end )
118     {
119       ERRLOG( ELerror, "SIXD_StorableBank read aborted" )
120               << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
121               << "'next' HDI pointer out-of-bounds."
122               << "nextHDI = " << nextHdi
123               << ", end-of-data pointer = " << sixd_end
124               << endmsg;
125       return;
126     }
127     
128     // Check for data in this HDI block
129     //
130     if ( (nextHdi - hdi) > SiliconRawDataFormat::hdi_header_length ) { 
131       int4 header = int4(
132                          ( *(hdi + SiliconRawDataFormat::hdi_header_offset)
133                            & SiliconRawDataFormat::header_upper_mask )
134                          << SiliconRawDataFormat::header_upper_shft  )
135         +
136         int4(
137              ( *(hdi + SiliconRawDataFormat::hdi_header_offset + 1)
138                & SiliconRawDataFormat::header_lower_mask )
139              << SiliconRawDataFormat::header_lower_shft  );
140 
141       if (!(hdiCode.setHdiHeader( header ))) {
142         ERRLOG( ELerror, "SIXD_StorableBank read aborted" )
143           << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
144           << "HDI header invalid."
145           << "header = " << header
146           << endmsg;
147         return;
148       }
149       
150       digiCode.setBarrel( hdiCode.barrel() );
151       digiCode.setHalfLadder( hdiCode.halfLadder() );
152       
153       digiCode.setPhiWedge( hdiCode.phiAddr() );
154       digiCode.setLayer( hdiCode.layer() );
155 
156       if (digiCode.getPhiWedge()>=12) {
157         ERRLOG( ELerror, "SIXD_StorableBank read aborted" )
158           << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
159           << "HDI header invalid."
160           << "header = " << header
161           << "svxii phi wedge = " << digiCode.getPhiWedge()
162           << endmsg;
163         return;
164       }
165 
166       int chipHdi = hdiCode.f_hdi();
167       if(_svxDaqInfoSet) {
168         hdiCode.translateRegionToReadout();
169         int vrbId = hdiCode.vrb();
170         SiVrbInfo* vrbInfo = _svxDaqInfoSet->find(vrbId);
171         if(vrbInfo) {
172           vrbInfo->setTSCounter(tsCounter);
173           vrbInfo->setTimeSinceL1A(timeSinceL1A);
174           vrbInfo->setErrorWd0(0);
175           vrbInfo->setErrorWd1(0);
176           int pcId  = hdiCode.f_pc();
177           SiPortCardInfo* pcInfo = vrbInfo->find(pcId);
178           if(pcInfo) {
179             hdiInfo = pcInfo->find(chipHdi);
180             if(hdiInfo) {
181               hdiInfo->setBunchXing(hdiCode.bunchCrossing());
182               hdiInfo->setBEstate(hdiCode.beState());
183             }
184           }
185         }
186       }           
187       
188       // use this 'lastDigiCode' to find when we've entered a new digicode
189       SiDigiCode lastDigiCode( digiCode );
190       // first one of hdi needs to be forced.
191       int firstDigiOfHdi=1;
192 
193       // set up strip vector
194       vector_type * stripVector;
195       int currentVectorStrip = -1;
196       unsigned int hdiErrorWord = 0;
197       
198       // check for 00f3 and c2c2 problems
199       // these are found based on the length of the HDI
200       int dataOverrun=0;
201       if ( nextHdi-hdi == 0xffe)
202         {
203           if (_monitorMode&&1==0) {
204             std::cout << "TRYRun2SiStripSet_nndata.cc: " 
205                       << std::hex << header 
206                       << ": 00f3" 
207                       << std::endl << std::dec;
208           }
209           dataOverrun=1;
210           // LM 08-Oct-2002 used this bit for 00F3
211           //          hdiErrorWord |= SiVrbInfoSet::DATA_OVERRUN;
212         }
213       if ( nextHdi-hdi == 0x4)
214         {
215           hdiErrorWord |= SiVrbInfoSet::C2C2;
216         }
217       if (dumpHtml && _htmlGen) {
218           if (hdiErrorWord)
219               _htmlGen->Put00f3C2c2(eventNum, header, hdiErrorWord);
220       }
221       
222       // data iterator
223       SIXD_StorableBank::Simple_Data_Iter data = sixd.begin_hdi_data( hdi );
224       SIXD_StorableBank::Simple_Data_Iter dataEnd = nextHdi;
225       int4 prev_word=-1;
226       int4 prev_chan=-1;
227       int4 curr_word=int4( (*data)&0xffff );
228       int4 curr_chan=curr_word>>8;
229       // first things first: the first word had better be the first chip ID
230       // If wrong, look to see if its a bit error.
231       // Bit error: one bit different. Correct and continue.
232       // Otherwise: bail
233       int4 next_chip= SiliconRawDataFormat::svxii_last_chip[chipHdi]+0x80;
234       int4 prev_chip=next_chip;
235       if (curr_chan != next_chip) {
236         int4 diff = curr_chan^next_chip;
237         int bit;
238         for (bit=0;!(diff&0x1);diff>>=1,bit++);
239         int bithigh = curr_chan&(1<<bit);
240         if (!(diff>>1)) {
241           if (_monitorMode&&1==0) {
242             std::cout << "TRYRun2SiStripSet_nndata.cc: " 
243                       << std::hex << header 
244                       << ": first chip ID bit error bit " << bit << ((bithigh) ? " high: " : " low: ")
245                       << "seen, expected " << curr_chan << " " << next_chip 
246                       << std::endl << std::dec;
247           }
248           // bit error; correct and go on
249           curr_chan=next_chip;
250           curr_word=(curr_word&0xff)+(next_chip<<8);
251           if (bit==0) 
252             hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
253           else if (bit==1) 
254             hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
255           else
256             hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
257         } else {              
258           // something else; bail
259           if (_monitorMode&&1==0) {
260             std::cout << "TRYRun2SiStripSet_nndata.cc: " 
261                       << std::hex << header 
262                       << ": DRO immediate" 
263                       << ": hdiLength " << nextHdi-hdi
264                       << ": seen, expected " << curr_chan << " " << next_chip << " dump: ";
265             int4 next_word;
266             if (!dataOverrun) {
267               while (data < dataEnd) {
268                 next_word=*(data++); std::cout << " " << next_word;
269               }
270             }
271             std::cout << std::endl << std::dec;
272           }
273           hdiErrorWord |= SiVrbInfoSet::DRO_IMMEDIATE;
274           if(hdiInfo) {
275             hdiInfo->setLastChip(prev_chip & 0x0f);
276             hdiInfo->setErrorWord(hdiErrorWord);
277           }
278           _bankReadoutError |= hdiErrorWord;
279           if (dumpHtml && _htmlGen) {
280               data = sixd.begin_hdi_data( hdi );
281               curr_word=int4( (*data)&0xffff );
282               _htmlGen->PutChipWord( eventNum, header, curr_word, hdiErrorWord,
283                                      curr_word );
284               while (data < dataEnd) {
285                   int4 next_word=int4( (*(++data))&0xffff);
286                   curr_word = next_word;
287                   if (!dataOverrun)
288                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
289                                                         hdiErrorWord );
290               }
291           }
292           continue;
293         }
294       }
295       if (dumpHtml && _htmlGen)
296           _htmlGen->PutChipWord( eventNum, header, curr_word, hdiErrorWord,
297                                  int4( (*data)&0xffff ) );
298       
299 
300       // now loop over the data
301       // strategy is to look ahead and behind for error context
302       // Define onARoll variable.  Decrementing the channel by two for the bit high error should not be done
303       //   when you already have more than 2 channel in a row.
304       int onARoll = 0;
305       while (data < dataEnd) {
306         unsigned int chanErrorWord = 0;
307         int4 org_word = curr_word;
308         int4 next_word=int4( (*(++data))&0xffff);
309         int4 next_chan=next_word>>8;
310         int fillChip=0;
311         int fillChan=0;
312         // look for chip ID
313         if (curr_chan>0x7f) {
314           onARoll = 0;
315           // the right chip ID?
316           //if (digiCode.getBarrel()==0&&digiCode.getLayer()==4&&digiCode.getPhiWedge()==4&&digiCode.getHalfLadder()==0) {
317           //  std::cout << "current chip " << curr_chan << " expected chip " << next_chip << std::endl;
318           //}
319 
320 
321           if (curr_chan==next_chip) {
322             fillChip=1;
323             // Last expected Z side chip can't go below 160 in backwards counting
324             //      if ((digiCode.getLayer()==3||digiCode.getLayer()==4)&&curr_chan==159) {
325             if (curr_chan==159) {
326               fillChip=0;
327               //ERRLOG( ELwarning, "SIXD_StorableBank read aborted" )
328               //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
329               //        << "Too many chips on layer " << digiCode.getLayer()
330               //        << endmsg;
331               return;
332             }
333           } 
334           // something wrong... handle errors
335           // strategy: handle bit errors, ff and d0, in that order
336           // Bit: If its one bit off report that bit, correct and
337           //      try to continue
338           // ff: defined as prev and next in order, current a fake chip ID
339           //     (this is before bit error because it is very unlikely for 
340           //      next channel > prev channel in 7f problems)
341           //     For now, correct the channel for parsing purposes. Don't fill.
342           //     7f always replaces channel preceding next, as opposed to 
343           //      channel following previous. 
344           // d0: only occurs in channel byte when dropping readout. Bail.
345           else {
346             //DIAGNOSE bit error
347             int4 diff = curr_chan^next_chip;
348             int bit;
349             for (bit=0;!(diff&0x1);diff>>=1,bit++);
350             int bithigh = curr_chan&(1<<bit);
351             if (!(diff>>1)) {
352               if (_monitorMode&&1==0) {
353                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
354                           << std::hex << header 
355                           << ": " << prev_word << " " << curr_word << " " << next_word 
356                           << ": chip bit error in chip ID " << next_chip 
357                           << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
358                           << "seen, expected " << curr_chan << " " << next_chip
359                           << std::endl << std::dec; 
360               }
361               curr_chan=next_chip;
362               curr_word=(curr_word&0xff)+(next_chip<<8);
363               //if (digiCode.getBarrel()==0&&digiCode.getLayer()==4&&digiCode.getPhiWedge()==4&&digiCode.getHalfLadder()==0) {
364               //  std::cout << "Corr current chip " << curr_chan << " expected chip " << next_chip << std::endl;
365               //}
366               
367               fillChip=1;
368           // Okay I can correct this in the ugliest way possible
369           // Layer 3 and layer 4should never have a chip id 159
370               //              if ((digiCode.getLayer()==3||digiCode.getLayer()==4)&&curr_chan==159) {
371               if (curr_chan==159) {
372                 fillChip=0;
373                 //ERRLOG( ELwarning, "SIXD_StorableBank read aborted" )
374                 //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
375                 //        << "Correcting to too many chips on layer " << digiCode.getLayer()
376                 //        << endmsg;
377                 //std::cout << "Corr current chip 159!" <<  std::endl;
378               }
379               if (bit==0) {
380                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
381                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
382               }
383               else if (bit==1) {
384                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
385                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
386               }
387               else {
388                 hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
389                 chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
390               }
391             }
392             //DIAGNOSE ff
393             else if ((next_chan>prev_chan+1)&&
394                      ((next_chan<0x80)||(next_chan==next_chip))) {
395               // correct the current channel but don't fill the data
396               // (easier than figuring out which channel you were expecting)
397               // LHM -- 23-july-02 try filling channel anyway...
398               // look to see only high bits
399               if (!(~curr_chan)&(next_chan-1)) {                
400                 curr_word=(curr_word&0xff)+(curr_chan<<8);
401                 fillChan=1;
402               }
403               curr_chan=next_chan-1;
404               if (_monitorMode&&1==0) {
405                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
406                           << std::hex << header 
407                           << ": " << prev_word << " " << curr_word << " " << next_word 
408                           << ": ff at chip " << prev_chip 
409                           << ": chan set to " << curr_chan 
410                           << std::endl << std::dec;
411               }
412               hdiErrorWord |= SiVrbInfoSet::FF_7F;
413               chanErrorWord |= SiVrbInfoSet::FF_7F;
414             }
415             //DIAGNOSE d0
416             else if (curr_chan==0xd0) {
417               if (_monitorMode&&1==0) {
418                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
419                           << std::hex << header 
420                           << ": " << prev_word << " " << curr_word << " " << next_word 
421                           << ": D0 at chip " << prev_chip << std::endl << std::dec;
422               }
423               hdiErrorWord |= SiVrbInfoSet::D0_ERROR;
424               chanErrorWord |= SiVrbInfoSet::D0_ERROR;
425               if (dumpHtml && _htmlGen) {
426                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
427                                          org_word );
428                   while (data < dataEnd) {
429                       curr_word = next_word;
430                       next_word=int4( (*(++data))&0xffff);
431                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
432                                                         chanErrorWord );
433                   }
434               }
435               break;
436             }
437             // something else awry
438             else {
439               if (_monitorMode&&1==0) {
440                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
441                           << std::hex << header 
442                           << ": " << prev_word << " " << curr_word << " " << next_word 
443                           << ": fake chip Id in chip " << prev_chip << " dump: ";
444                 // make sure it truncates
445                 int truncate=0;
446                 while (data < dataEnd) {
447                   if ((next_word=*(data++))&0xc200) truncate=1; std::cout << " " << next_word;
448                 }
449                 std::cout << std::endl << std::dec;
450                 if (!truncate) std::cout << " NO TRUNCATE!" << std::endl << std::dec;
451               }
452               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
453               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
454               if (dumpHtml && _htmlGen) {
455                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
456                                          org_word );
457                   while (data < dataEnd) {
458                       curr_word = next_word;
459                       next_word=int4( (*(++data))&0xffff);
460                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
461                                                         chanErrorWord );
462                   }
463               }
464               break;
465             }
466           }
467           if (dumpHtml && _htmlGen)
468               _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord, org_word );
469         } // end of chip checking
470         
471         //if its not a chip its a channel
472         // look for data
473         else {
474           // see if good
475           //if (digiCode.getBarrel()==1&&digiCode.getLayer()==1&&digiCode.getPhiWedge()==2&&digiCode.getHalfLadder()==1) {
476           //  std::cout << "prev_chan " << prev_chan << " curr_chan " << curr_chan << " next_chan " << next_chan << std::endl;
477           //}
478           if (prev_chan==curr_chan-1) {
479             onARoll++;
480           }
481           else {
482             onARoll = 0;
483           }
484           //if (digiCode.getBarrel()==1&&digiCode.getLayer()==1&&digiCode.getPhiWedge()==2&&digiCode.getHalfLadder()==1) {
485           //  std::cout << "On a roll " << onARoll << std::endl;
486           //}
487           if (((prev_chan<curr_chan)&&(curr_chan<next_chan))||   //in middle
488               ((prev_chan==prev_chip)&&(curr_chan<next_chan))) { //first of chip
489             //all good (middle or end of chip)
490             fillChan=1;
491 
492 
493           }
494           // check for a bit 1 high error special case here:
495           // bit 1 stuck:        Handle  23236767ababefef (bit 1 high)
496           //                             ^^^
497           else if ((prev_chan==next_chan)&&(curr_chan==prev_chan+1)) {
498             if (curr_chan&2) {
499               // bit 1 high error; correct and go on
500               if (_monitorMode&&1==0) {
501                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
502                           << std::hex << header 
503                           << ": " << prev_word << " " << curr_word << " " << next_word 
504                           << ": channel bit error in chip " << prev_chip 
505                           << ": bit 1 high, skipping next word: "
506                           << "seen, expected " << curr_chan << " " << curr_chan-2
507                           << std::endl << std::dec; 
508               }
509 
510 
511               if (onARoll < 2) {
512                 curr_chan-=2;
513                 curr_word=(curr_word&0xff)+(curr_chan<<8);
514                 fillChan=1;
515                 // in addition, we unfortunately have to skip the next word 
516                 // since the previous channel was already filled with the 
517                 // incorrect strip number
518                 next_word=int4( (*(++data))&0xffff);
519                 next_chan=next_word>>8;
520                 hdiErrorWord |= SiVrbInfoSet::BIT_1_HIGH;             
521                 hdiErrorWord |= SiVrbInfoSet::SUSPECT_DATA;           
522                 chanErrorWord |= SiVrbInfoSet::BIT_1_HIGH;            
523                 chanErrorWord |= SiVrbInfoSet::SUSPECT_DATA;          
524               }
525               else {
526                 fillChan = 0;
527                 //ERRLOG( ELwarning, "SIXD_StorableBank no bit 1 high corr" )
528                 //  << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
529                 //  << "Were on a roll: no bit 1 high correction"
530                 //  << "HDI pointer = " << hdi
531                 //  << endmsg;
532               }
533 
534 
535             } else {
536               fillChan=1;
537               if (_monitorMode&&1==0) {
538                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
539                           << std::hex << header 
540                           << ": " << prev_word << " " << curr_word << " " << next_word 
541                           << ": channel bit error in chip " << prev_chip 
542                           << ": bit 1 low in previous channel?" 
543                           << std::endl << std::dec; 
544               }
545             }
546           }
547           // if next channel is lower than previous, then something is wrong, 
548           // but accept the current channel as kosher
549           else if ((prev_chan<curr_chan)&&(next_chan<=(prev_chan+1))) {
550             if (_monitorMode&&1==0) {
551               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
552                         << std::hex << header 
553                         << ": " << prev_word << " " << curr_word << " " << next_word 
554                         << ": OO coming up?" 
555                         << std::endl << std::dec;
556             }
557             fillChan=1;
558           }
559           // something is wrong; handle errors
560           // strategy:           handle duplicate channels (and 00f3), bit errors, 7f
561           //                     and bit 1 stuck (0 handled by above)
562           // duplicate channels: previous channel and data equal to current
563           //                     this only occurs for 00f3 and true duplication
564           //                     ignore and continue if not 00f3 
565           //                     (flagged above by HDI length)
566           // bit errors:         see if the sequence is wrong by one bit
567           // 7f:                 If next channel greater and only bits wrong are high
568           // bit 1 stuck:        Handle 010145458989cdcd (bit 1 low)
569           //                             ^^^
570           //                     That is, the combination of prev=next, current is one less.
571           //                     Other parts of the pattern are already handled 
572           //                     for better or worse.
573           // other:              bail
574           // DIAGNOSE duplicate channel
575           else if (prev_word==curr_word) {
576             if (!dataOverrun) {
577               if (_monitorMode&&1==0) {
578                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
579                           << std::hex << header 
580                           << ": " << prev_word << " " << curr_word << " " << next_word 
581                           << ": duplicate channel at chip " << prev_chip 
582                           << std::endl << std::dec;
583               }
584               // check for 00f3 and bail if it is
585               if ((prev_word==0xf3)&&(curr_word==0xf3)&&(next_word==0xf3)) {
586                 hdiErrorWord |= SiVrbInfoSet::DRO_00F3;       
587                 chanErrorWord |= SiVrbInfoSet::DRO_00F3;                      
588                 break;
589               }
590               if (!((hdiErrorWord&SiVrbInfoSet::BIT_0_LOW)||(hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
591                 hdiErrorWord |= SiVrbInfoSet::DUP_CHAN;       
592               if (!((chanErrorWord&SiVrbInfoSet::BIT_0_LOW)||(chanErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
593                 chanErrorWord |= SiVrbInfoSet::DUP_CHAN;              
594             }
595             else {
596               if (_monitorMode&&1==0) {
597                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
598                           << std::hex << header 
599                           << ": " << prev_word << " " << curr_word << " " << next_word 
600                           << ": 00f3 at chip " << prev_chip 
601                           << std::endl << std::dec;
602               }
603             }
604           }
605           // DIAGNOSE bit error
606           // look for the seed, decide what to compare to
607           // for a single bit difference
608           // One detail: how to get the thresholds? For now use five...
609           else if ((next_chan>prev_chan)||(prev_chan==prev_chip)) {
610             // get the chip threshold
611             int thisChipThreshold=7;
612             int threshfound=0;
613             if (_chipStatus) {
614               int chip = SiliconRawDataFormat::svxii_last_chip[hdiCode.f_hdi()] - hdiCode.nChip() + 1;
615               std::map<SiChipKey,Chipstream>::const_iterator ic = 
616                 _chipStatus->getChipInfo()->find(SiChipKey(digiCode,chip));
617               if (ic != _chipStatus->getChipInfo()->end()) {
618                 thisChipThreshold = ic->second.threshold();
619                 threshfound=1;
620               }
621             }
622             if (!threshfound) {
623               // not found could mean something wrong, 
624               // for now nothing...
625             }
626             int rightSeed=0;
627             int leftSeed=0;
628             int rightData=next_word&0xff;
629             int leftData=prev_word&0xff;
630             int chanExpectedLeft=0;
631             int chanExpectedRight=0x7f;
632             int newData;
633             // get rid of pesky special codes
634             rightData = (rightData>0xf0) ? 0 : rightData;
635             leftData  = (leftData>0xf0)  ? 0 : leftData;
636             // for the purposes of finding a seed
637             // modify the data according to potential stuck bits
638             // convert to gray, modify, take the higher number
639             // as potential seed
640             // GrayCode class has an implicit cast method converting to int
641             // (So the assignment here converts)
642             if (hdiErrorWord&SiVrbInfoSet::BIT_1_HIGH) {
643               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
644                 rightData=newData;
645               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
646                 leftData=newData;
647             }
648             else if (hdiErrorWord&SiVrbInfoSet::BIT_1_LOW) {
649               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
650                 rightData=newData;
651               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
652                 leftData=newData;
653             }
654             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH) {
655               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
656                 rightData=newData;
657               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
658                 leftData=newData;
659             }
660             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_LOW) {
661               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
662                 rightData=newData;
663               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
664                 leftData=newData;
665             }
666             // Could be a stuck bit has a fake "seed" on the left, 
667             // e.g.
668             // normal      0 1 2 3 4 5 6 7 
669             // bit 1 low   0 1 1 0 7 6 6 7
670             // ... 5107 5101 5407 ...
671             // channel 53 (second '51') was seeded by channel 54, not 51.
672 
673             // seeds: left then right
674             if ((prev_chan>0x7f)||(leftData>=thisChipThreshold)) {
675               leftSeed=1;
676               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
677             }
678             if ((next_chan>0x7f)||(rightData>=thisChipThreshold)) {
679               rightSeed=1;
680               chanExpectedRight=(next_chan>0x7f) ? 0x7f : next_chan-1;
681             }
682             // now get the bit error information
683             if (!(leftSeed||rightSeed)) {
684               if (_monitorMode&&1==0) {
685                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
686                           << std::hex << header 
687                           << ": " << prev_word << " " << curr_word << " " << next_word 
688                           << ": No Seed Found!!! (l,r data) " << leftData << " " << rightData
689                           << " in chip " << prev_chip 
690                           << std::endl << std::dec; 
691               }
692               leftSeed=1;
693               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
694             }
695             int bit, found=0;
696             int chanExpected;
697             if (leftSeed) {
698               chanExpected=chanExpectedLeft;
699               int4 diff = curr_chan^chanExpected;
700               if (!diff) {
701                 bit=-1;
702                 found=1;
703               }
704               else { 
705                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
706               }
707               if (!(diff>>1)) {
708                 // found single bit error on left
709                 found=1;
710               }
711             }
712             if ((!found)&&(rightSeed)) {
713               chanExpected=chanExpectedRight;
714               int4 diff = curr_chan^chanExpected;
715               if (!diff) {
716                 bit=-1;
717                 found=1;
718               }
719               else { 
720                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
721               }
722               if (!(diff>>1)) {
723                 // found single bit error on right
724                 found=1;
725               }
726             }
727             if (found) {
728               // bit error; correct and go on
729               if (bit>=0) {
730                 int bithigh = curr_chan&(1<<bit);
731                 if (_monitorMode&&1==0) {
732                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
733                             << std::hex << header 
734                             << ": " << prev_word << " " << curr_word << " " << next_word 
735                             << ": channel bit error in chip " << prev_chip 
736                             << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
737                             << ": seeds (R,L) " << rightSeed << " " << leftSeed
738                             << " seen, expected " << curr_chan << " " << chanExpected
739                             << std::endl << std::dec; 
740                 }
741                 if (bit==0) {
742                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
743                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
744                 }
745                 else if (bit==1) {
746                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
747                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
748                 }
749                 else {
750                   hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
751                   chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
752                 }
753               }
754               else {
755                 if (_monitorMode&&1==0) {
756                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
757                             << std::hex << header 
758                             << ": " << prev_word << " " << curr_word << " " << next_word 
759                             << ": no diff found! continuing for now "
760                             << std::endl << std::dec;
761                 }
762               }
763               curr_chan=chanExpected;
764               curr_word=(curr_word&0xff)+(chanExpected<<8);
765               fillChan=1;
766             }
767             // DIAGNOSE 7f
768             // previous and next ok, only high bits in current
769             else if ((next_chan>prev_chan+1)&&(!((~curr_chan)&chanExpected))) {
770               // correct the current channel
771               fillChan=1;
772               if (_monitorMode&&1==0) {
773                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
774                           << std::hex << header 
775                           << ": " << prev_word << " " << curr_word << " " << next_word 
776                           << ": 7f in chip " << prev_chip 
777                           << ": seen, expected " << curr_chan << " " << chanExpected
778                           << std::endl << std::dec;
779                 }
780               curr_chan=chanExpected;
781               curr_word=(curr_word&0xff)+(chanExpected<<8);
782               hdiErrorWord |= SiVrbInfoSet::FF_7F;            
783               chanErrorWord |= SiVrbInfoSet::FF_7F;           
784             } 
785             // well, if we're still in order then try continuing
786             else if ((prev_chan<curr_chan)||(prev_chan==prev_chip)) {
787               // still fill this channel, it seems
788               fillChan=1;
789               if (_monitorMode&&1==0) {
790                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
791                             << std::hex << header 
792                           << ": " << prev_word << " " << curr_word << " " << next_word 
793                           << ": unknown OO in " << prev_chip 
794                           << std::endl << std::dec;
795               }
796             }
797             // give up and dump the damned thing
798             else {
799               if (_monitorMode&&1==0) {
800                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
801                           << std::hex << header 
802                           << ": " << prev_word << " " << curr_word << " " << next_word 
803                           << ": Context OK, Strip OO at chip " << prev_chip << " dump: ";
804                 if (!dataOverrun) {
805                   while (data < dataEnd) {
806                     next_word=*(data++); std::cout << " " << next_word;
807                   }
808                 }
809                 cout << std::endl << std::dec;
810               }
811               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
812               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
813               if (dumpHtml && _htmlGen) {
814                   _htmlGen->PutChanWord( eventNum, header, curr_word, chanErrorWord,
815                                          org_word );
816                   while (data < dataEnd) {
817                       curr_word = next_word;
818                       next_word=int4( (*(++data))&0xffff);
819                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
820                                                         chanErrorWord );
821                   }
822               }
823               break;
824             }
825           } // end of (next_chan>prev_chan+1)||(prev_chan==prev_chip)
826           // Now check for bit 1 special case:  1 0 1
827           else if ((prev_chan==next_chan)&&(curr_chan==next_chan-1)) {
828             if (!(curr_chan&2)) {
829               // bit 1 low error; correct and go on
830               if (_monitorMode&&1==0) {
831                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
832                           << std::hex << header 
833                           << ": " << prev_word << " " << curr_word << " " << next_word 
834                           << ": channel bit error in chip " << prev_chip 
835                           << ": bit 1 low: "
836                           << "seen, expected " << curr_chan << " " << curr_chan+2
837                           << std::endl << std::dec; 
838               }
839               curr_chan+=2;
840               curr_word=(curr_word&0xff)+(curr_chan<<8);
841               fillChan=1;
842               hdiErrorWord |= SiVrbInfoSet::BIT_1_LOW;        
843               chanErrorWord |= SiVrbInfoSet::BIT_1_LOW;       
844             } else {
845               fillChan=1;
846               if (_monitorMode&&1==0) {
847                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
848                           << std::hex << header 
849                           << ": " << prev_word << " " << curr_word << " " << next_word 
850                           << ": channel bit error in chip " << prev_chip 
851                           << ": bit 1 high in previous channel?" 
852                           << std::endl << std::dec; 
853               }
854             }
855           }
856           else {
857             if (_monitorMode&&1==0) {
858               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
859                         << std::hex << header 
860                         << ": " << prev_word << " " << curr_word << " " << next_word 
861                         << ": Strip OO at chip " << prev_chip << " dump: ";
862               if (!dataOverrun) {
863                 while (data < dataEnd) {
864                   next_word=*(data++); std::cout << " " << next_word;
865                 }
866               }
867               std::cout << std::endl << std::dec;
868             }
869             // Another possibility: 00f3
870             // (doesn't happen in the 'context OK' unknown channel case...)
871             // check that this, the next and the following are all 00F3
872             // bail either way
873             int4 nextnext_word=(++data<dataEnd) ? int4( (*(data))&0xffff) : 0;
874             if ((curr_word==0xf3)&&(next_word==0xf3)&&(nextnext_word==0xf3)) {
875               hdiErrorWord |= SiVrbInfoSet::DRO_00F3;         
876               chanErrorWord |= SiVrbInfoSet::DRO_00F3;                
877             }
878             else {
879               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
880               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
881             }
882             if (dumpHtml && _htmlGen) {
883                 _htmlGen->PutChanWord( eventNum, header, curr_word, chanErrorWord,
884                                        org_word );
885                 while (data < dataEnd) {
886                     curr_word = next_word;
887                     next_word=int4( (*(++data))&0xffff);
888                     _htmlGen->ContinueDataAfterBreak( header, curr_word,
889                                                       chanErrorWord );
890                 }
891             }
892             break;
893           }
894           if (dumpHtml && _htmlGen)
895               _htmlGen->PutChanWord( eventNum, header, curr_word, chanErrorWord, org_word );
896         }  // end of channel checking
897         // fill chip info if ok
898         if (fillChip) {
899           hdiCode.setDataWord( curr_word );
900           prev_chip=next_chip;
901           if ((next_chip&0xf) == 
902               SiliconRawDataFormat::svxii_chips_per_side[1][chipHdi]) {
903             next_chip+=0x20;
904           }
905           next_chip--;
906           int chip = SiliconRawDataFormat::svxii_last_chip[hdiCode.f_hdi()] - hdiCode.nChip() + 1;
907           SiChipInfo* chipInfo = 0;
908           if (_svxDaqInfoSet && hdiInfo) {
909             chipInfo = hdiInfo->find(chip);
910             if(chipInfo) {
911               chipInfo->setStatus(hdiCode.status());
912               chipInfo->setSide(hdiCode.nSide());
913             }
914           }  
915           // Reserve space for the strips in this detector when new digicode encountered
916           // seems to me there's a smarter way to figure out the space needed 
917           // (there are up to four digicodes per HDI!) but perhaps reserving is harmless?
918           digiCode.setPnSide( hdiCode.nSide() );
919           if (( digiCode != lastDigiCode )||(firstDigiOfHdi)) {
920             lastDigiCode = digiCode;
921             firstDigiOfHdi=0;
922             stripVector = &( stripSet[digiCode] );
923             stripVector->reserve( ( nextHdi - hdi ) * 2 );
924             currentVectorStrip = -1;
925           }
926         } // end of fill chip ID
927         
928         // fill this channel if its ok
929         if (fillChan) {
930           hdiCode.setDataWord( curr_word );
931           int thisStrip = hdiCode.strip();
932           if (thisStrip <= currentVectorStrip)
933             {
934 
935               //ERRLOG( ELwarning, "SIXD_StorableBank out of order strip" )
936               //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
937               //        << "Trying to fill out of order strips"
938               //        << "HDI pointer = " << hdi
939               //        << endmsg;
940 
941               // don't store strip if it's strip number is less than the previous strip
942               // Let processing continue
943               //return;
944             }
945           else
946             {
947               currentVectorStrip = thisStrip;
948               stripVector->push_back( SiStrip() );
949               SiStrip & strip = stripVector->back();
950               strip.setGoodStrip();
951               strip.setStripNumber( thisStrip );
952               strip.setScaledAdc( _dataMap.rawToScaled( hdiCode.adc() ) );
953               //strip.setFirstReadFromChip( true );
954               strip.resetNmcIds();
955             }
956         } // end of fill Channel
957 
958         // Finally look for termination character coming up: end of the line
959         if ((next_chan&0xf0)==0xc0) {
960           if (next_chan==0xc2) {
961             if (_monitorMode&&1==0) {
962               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
963                         << std::hex << header 
964                         << ": " << prev_word << " " << curr_word << " " << next_word 
965                         << ": DRO at chip " << prev_chip 
966                         << std::endl << std::dec;           
967             }
968             hdiErrorWord |= SiVrbInfoSet::DRO_TERM;    
969             chanErrorWord |= SiVrbInfoSet::DRO_TERM;    
970           }
971           else if (next_chan!=0xc1) {
972             if (_monitorMode&&1==0) {
973               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
974                         << std::hex << header 
975                         << ": " << prev_word << " " << curr_word << " " << next_word 
976                         << ": illegal termination character at chip " 
977                         << prev_chip << std::endl << std::dec;      
978             }
979             hdiErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
980             chanErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
981           }
982           if (dumpHtml && _htmlGen) {
983               while (data < dataEnd) {
984                   curr_word = next_word;
985                   next_word=int4( (*(++data))&0xffff);
986                   _htmlGen->PutTermWord( eventNum, header, curr_word, chanErrorWord,
987                                          org_word );
988               }
989           }
990           break;
991         }
992         prev_word=curr_word;
993         prev_chan=curr_chan;
994         curr_word=next_word;
995         curr_chan=next_chan;
996       }  // loop over Data
997       if(hdiInfo) {
998         hdiInfo->setLastChip(prev_chip & 0x0f);
999         hdiInfo->setErrorWord(hdiErrorWord);
1000       }
1001       _bankReadoutError |= hdiErrorWord;
1002     }  // loop over HDI blocks
1003   }   // loop over VRB blocks
1004 }
1005 
1006 
1007 
1008 //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1009 // Read ISLD bank using nndata bank access interface
1010 //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1011 
1012 void TRYRun2SiStripSet::readISLDBank_nndata( const ISLD_StorableBank & isld,
1013                                              std::vector<int4> & hdiKeys )
1014 {
1015 
1016   ISLD_StorableBank::VrbHeaderDecode vrbCode ;
1017   ISLD_StorableBank::HdiDecode       hdiCode ;  
1018   HWSiNumerology numer; 
1019 
1020   // Set data rep if necessary
1021   //
1022   if ( _selectDataRepByBankVersion )
1023   {
1024     SiRecoDataRep::instance()->
1025                    dataRep().setDataRepByBankVersion( isld.bank_version() );
1026   }
1027       
1028   // try to init chip info if new run
1029   if (lastRunNumber!=AbsEnv::instance()->runNumber()&&_useNNChipThreshold) {
1030     delete _chipStatus;
1031     // choose database for online/offline
1032     std::string db;
1033     char name[128];
1034     gethostname(name,128);
1035     name[127] = '\0';
1036     if (strncmp(name, "b0dap", 5) == 0)
1037       db = "onotl_prd_read";
1038     else
1039       db = "ofotl_prd_read";
1040     _chipStatus = new ChipStatus(db.c_str(),AbsEnv::instance()->runNumber());
1041     lastRunNumber=AbsEnv::instance()->runNumber();
1042     std::cout << "Getting a new chipstatus";
1043   }
1044   int eventNum = AbsEnv::instance()->trigNumber();
1045   if (dumpHtml && _htmlGen)
1046       _htmlGen->SetRunNum(AbsEnv::instance()->runNumber());
1047 
1048   // Reserve space for all possible SiDigiCode's
1049   //
1050   SiStripSet::collection_type & stripSet = contents();
1051   stripSet.reserve( SiliconRawDataFormat::n_hdi_total_isld * 4 );
1052   
1053   // Get bank header information
1054   //
1055   ISLD_StorableBank::VRB_Iter vrb0( isld ) ;
1056   vrbCode.setHeaderWord(vrb0.header_word());
1057   int tsCounter = vrbCode.tsCounter();
1058   int timeSinceL1A = vrbCode.timeSinceL1A();    
1059   //----------------------------------------------------------
1060   //  Loop over data in ISLD bank
1061   //----------------------------------------------------------
1062     
1063   SiDigiCode digiCode;
1064   digiCode.setLadder( 0 );
1065   SiHdiInfo* hdiInfo = 0;
1066   
1067   // In order to determine if the HDI block is empty, we need
1068   // access to the pointers to the current and the next HDI blocks.
1069   // A word count <= to the HDI header length => the block is empty.
1070   //
1071   ISLD_StorableBank::Simple_Iter isld_begin = isld.start_of_data();
1072   ISLD_StorableBank::Simple_Iter isld_end   = isld.end_of_data();
1073 
1074   ISLD_StorableBank::Simple_HDI_Pointer_Iter 
1075                      nextHdiIndex = isld.begin_hdi_index();
1076   ISLD_StorableBank::Simple_HDI_Pointer_Iter 
1077                      hdiIndexEnd  = isld.end_hdi_index();
1078   
1079   // check for empty bank
1080   if ( nextHdiIndex == hdiIndexEnd )
1081   {
1082     // No data or a format inconsistency.
1083     return;
1084   }
1085   
1086   ISLD_StorableBank::
1087   Simple_HDI_Iter hdi = isld_begin + isld.hdi_block_offset( nextHdiIndex );
1088   if ( hdi >= isld_end )
1089   {
1090     errlog( ELwarning, "ISLD_StorableBank read aborted" )
1091             << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1092             << "First HDI pointer out-of-bounds."
1093             << "HDI pointer = " << hdi
1094             << ", end-of-data pointer = " << isld_end
1095             << endmsg;
1096     return;
1097   }
1098 
1099   ISLD_StorableBank::Simple_HDI_Iter nextHdi;
1100   ISLD_StorableBank::Simple_HDI_Pointer_Iter hdiIndex;
1101 
1102 //   for ( hdiIndex = isld.begin_hdi_index(); hdiIndex < hdiIndexEnd;
1103 //      hdiIndex += ISLD_StorableBank_format::n_words_per_hdi_pointer )
1104 //     {
1105 
1106   for (int i = 0; i < hdiKeys.size(); ++i)
1107     {
1108       int4 key = hdiKeys[i];
1109       hdiIndex = isld.begin_hdi_index() + key * ISLD_StorableBank_format::n_words_per_hdi_pointer;
1110 
1111       hdi = isld_begin + isld.hdi_block_offset( hdiIndex );
1112       nextHdiIndex = hdiIndex + ISLD_StorableBank_format::n_words_per_hdi_pointer;
1113       nextHdi = isld_begin + isld.hdi_block_offset( nextHdiIndex );
1114 
1115 
1116     if ( nextHdi > isld_end )
1117     {
1118       ERRLOG( ELerror, "ISLD_StorableBank read aborted" )
1119               << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1120               << "'next' HDI pointer out-of-bounds."
1121               << "nextHDI = " << nextHdi
1122               << ", end-of-data pointer = " << isld_end
1123               << endmsg;
1124       return;
1125     }
1126     
1127     // Check for data in this HDI block
1128     //
1129     if ( (nextHdi - hdi) > SiliconRawDataFormat::hdi_header_length )
1130     { 
1131       int4 header = int4(
1132                          ( *(hdi + SiliconRawDataFormat::hdi_header_offset)
1133                            & SiliconRawDataFormat::header_upper_mask )
1134                          << SiliconRawDataFormat::header_upper_shft  )
1135         +
1136         int4(
1137              ( *(hdi + SiliconRawDataFormat::hdi_header_offset + 1)
1138                & SiliconRawDataFormat::header_lower_mask )
1139              << SiliconRawDataFormat::header_lower_shft  );
1140 
1141       if (!(hdiCode.setHdiHeader( header ))) {
1142         ERRLOG( ELerror, "ISLD_StorableBank read aborted" )
1143           << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1144           << "HDI header invalid."
1145           << "header = " << header
1146           << endmsg;
1147         return;
1148       }
1149       
1150       if (!hdiCode.isSOC()) {            // check we don't look at the SOC
1151         digiCode.setBarrel( hdiCode.barrel() );
1152         int layer = hdiCode.layer();
1153         if (layer>0&&layer<6) {
1154           //ERRLOG( ELwarning, "ISLD_StorableBank read aborted" )
1155           //  << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1156           //  << "HDI header invalid. Layer = " << layer << " "
1157           //  << "header = " << header
1158           //  << endmsg;
1159           return;
1160         }
1161 
1162 
1163         digiCode.setLayer( layer );
1164         int lastChip = SiliconRawDataFormat::isl_last_chip ;
1165         if ( layer < numer.getMinLayer(AbsSiNumerology::SVXII) ) 
1166           lastChip = ( hdiCode.f_hdi() < 3) ? 
1167             SiliconRawDataFormat::l00_wide_last_chip :
1168           SiliconRawDataFormat::l00_thin_last_chip ;
1169         int chipHdi = hdiCode.f_hdi();
1170         if(_islDaqInfoSet) {
1171           int pcId = hdiCode.f_pc();      
1172           int vrbId;
1173           if(hdiCode.isISL()) {
1174             if( hdiCode.barrel() == 0 )
1175               vrbId = ( hdiCode.halfLadder() 
1176                         * SiliconRawDataFormat::isl_n_pc_per_end_forw + pcId ) 
1177                 / SiliconRawDataFormat::isl_n_pc_per_vrb ;
1178             else if ( hdiCode.barrel() == 1 )
1179               vrbId = SiliconRawDataFormat::isl_n_vrb_forw 
1180                 + hdiCode.halfLadder() 
1181                 * SiliconRawDataFormat::isl_n_vrb_per_end_cent
1182                 + ( pcId / SiliconRawDataFormat::isl_n_pc_per_vrb ) ;
1183             else
1184               vrbId = SiliconRawDataFormat::isl_n_vrb_forw 
1185                 + SiliconRawDataFormat::isl_n_vrb_cent +
1186                 + ((hdiCode.halfLadder() 
1187                     * SiliconRawDataFormat::isl_n_pc_per_end_forw + pcId) 
1188                    / SiliconRawDataFormat::isl_n_pc_per_vrb);
1189           }
1190           else if ( hdiCode.isL00() ) {
1191             if ( hdiCode.barrel() == 0)
1192               vrbId = pcId / SiliconRawDataFormat::l00_n_pc_per_vrb; 
1193             else
1194               vrbId = SiliconRawDataFormat::n_vrb_barrel0_l00_isld 
1195                 + pcId / SiliconRawDataFormat::l00_n_pc_per_vrb;
1196             vrbId += SiliconRawDataFormat::isl_n_vrb;  
1197           }
1198           SiVrbInfo* vrbInfo = _islDaqInfoSet->find(vrbId);
1199           if(vrbInfo) {
1200             vrbInfo->setTSCounter(tsCounter);
1201             vrbInfo->setTimeSinceL1A(timeSinceL1A);
1202             vrbInfo->setErrorWd0(0);
1203             vrbInfo->setErrorWd1(0);
1204             SiPortCardInfo* pcInfo = vrbInfo->find(pcId);
1205             if(pcInfo) {
1206               hdiInfo = pcInfo->find(hdiCode.f_hdi());
1207               if(hdiInfo) {
1208                 hdiInfo->setBunchXing(hdiCode.bunchCrossing());;
1209                 hdiInfo->setBEstate(hdiCode.beState()); 
1210               }  // done with HDIs
1211             }    // done with PCs
1212           }      // done with VRBs
1213         }        // done with VRBinfoset
1214 
1215         // use this 'lastDigiCode' to find when we've entered a new digicode
1216         SiDigiCode lastDigiCode( digiCode );
1217         // first one of hdi needs to be forced.
1218         int firstDigiOfHdi=1;
1219 
1220         // set up strip vector
1221         unsigned int hdiErrorWord = 0;
1222         vector_type * stripVector;
1223         int currentVectorStrip = -1;
1224         
1225         // check for 00f3 and c2c2 problems
1226         // these are found based on the length of the HDI
1227         int dataOverrun=0;
1228         if ( nextHdi-hdi == 0xffe)
1229           {
1230             if (_monitorMode&&1==0) {
1231               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1232                         << std::hex << header 
1233                         << ": 00f3" 
1234                         << std::endl << std::dec;
1235             }
1236             dataOverrun=1;
1237           // LM 08-Oct-2002 used this bit for 00F3
1238           //          hdiErrorWord |= SiVrbInfoSet::DATA_OVERRUN;
1239           }
1240         if ( nextHdi-hdi == 0x4)
1241           {
1242             hdiErrorWord |= SiVrbInfoSet::C2C2;
1243           }
1244         if (dumpHtml && _htmlGen) {
1245             if (hdiErrorWord)
1246                 _htmlGen->Put00f3C2c2(eventNum, header, hdiErrorWord);
1247         }
1248         
1249         ISLD_StorableBank::Simple_Data_Iter data = isld.begin_hdi_data( hdi );
1250         ISLD_StorableBank::Simple_Data_Iter dataEnd = nextHdi;
1251         int4 prev_word=-1;
1252         int4 prev_chan=-1;
1253         int4 curr_word=int4( (*data)&0xffff );
1254         int4 curr_chan=curr_word>>8;
1255         
1256         // first things first: the first word had better be the first chip ID
1257         // If wrong, look to see if its a bit error.
1258         // Bit error: one bit different. Correct and continue.
1259         // Otherwise: bail
1260         int4 next_chip= lastChip+0x80;
1261         int4 prev_chip=next_chip;
1262         if (curr_chan != next_chip) {
1263           int4 diff = curr_chan^next_chip;
1264           int bit;
1265           for (bit=0;!(diff&0x1);diff>>=1,bit++);
1266           int bithigh = curr_chan&(1<<bit);
1267           if (!(diff>>1)) {
1268             if (_monitorMode&&1==0) {
1269               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1270                         << std::hex << header 
1271                         << ": first chip ID bit error bit " << bit << ((bithigh) ? " high: " : " low: ")
1272                         << "seen, expected " << curr_chan << " " << next_chip 
1273                         << std::endl << std::dec;
1274             }
1275             // bit error; correct and go on
1276             curr_chan=next_chip;
1277             curr_word=(curr_word&0xff)+(next_chip<<8);
1278             if (bit==0) 
1279               hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1280             else if (bit==1) 
1281               hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1282             else
1283               hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1284           } else {            
1285             // something else; bail
1286             if (_monitorMode&&1==0) {
1287               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1288                         << std::hex << header 
1289                         << ": DRO immediate" 
1290                         << ": seen, expected " << curr_chan << " " << next_chip << " dump: ";
1291               int4 next_word;
1292               if (!dataOverrun) {
1293                 while (data < dataEnd) {
1294                   next_word=(*(data++)&0xffff); std::cout << " " << next_word;
1295                 }
1296               }
1297               std::cout << std::endl << std::dec;
1298             }
1299             hdiErrorWord |= SiVrbInfoSet::DRO_IMMEDIATE;
1300             if(hdiInfo) {
1301               hdiInfo->setLastChip(prev_chip & 0x0f);
1302               hdiInfo->setErrorWord(hdiErrorWord);
1303             }
1304             _bankReadoutError |= hdiErrorWord;
1305             if (dumpHtml && _htmlGen) {
1306                 data = isld.begin_hdi_data( hdi );
1307                 curr_word=int4( (*data)&0xffff );
1308                 _htmlGen->PutChipWord( eventNum, header, curr_word, hdiErrorWord,
1309                                        curr_word );
1310                 while (data < dataEnd) {
1311                     int4 next_word=int4( (*(++data))&0xffff);
1312                     curr_word = next_word;
1313                     if (!dataOverrun)
1314                         _htmlGen->ContinueDataAfterBreak( header, curr_word,
1315                                                           hdiErrorWord );
1316                 }
1317             }
1318             continue;
1319           }
1320         }
1321         
1322       // now loop over the data
1323       // strategy is to look ahead and behind for error context
1324       while (data < dataEnd) {
1325         unsigned int chanErrorWord = 0;
1326         int4 org_word = curr_word;
1327         int4 next_word=int4( (*(++data))&0xffff);
1328         int4 next_chan=next_word>>8;
1329         int fillChip=0;
1330         int fillChan=0;
1331         
1332         // look for chip ID
1333         if (curr_chan>0x7f) {
1334           // the right chip ID?
1335           // the right chip ID/digicode?
1336           //if (digiCode.getPhiWedge()>11&&digiCode.getLayer()==5) {
1337           //  std::cout << "Phi wed " << digiCode.getPhiWedge() << " current chip " << curr_chan << " expected chip " << next_chip << std::endl;
1338           //}
1339 
1340           if (curr_chan==next_chip) {
1341             fillChip=1;
1342             if (curr_chan==159) {
1343               fillChip=0;
1344               //ERRLOG( ELwarning, "ISLD_StorableBank read aborted" )
1345               //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
1346               //        << "Too many chips on layer " << digiCode.getLayer()
1347               //        << endmsg;
1348               return;
1349             }
1350           } 
1351           // something wrong... handle errors
1352           // strategy: handle bit errors, ff and d0, in that order
1353           // Bit: If its one bit off report that bit, correct and
1354           //      try to continue
1355           // ff: defined as prev and next in order, current a fake chip ID
1356           //     (this is before bit error because it is very unlikely for 
1357           //      next channel > prev channel in 7f problems)
1358           //     For now, correct the channel for parsing purposes. Don't fill.
1359           //     7f always replaces channel preceding next, as opposed to 
1360           //      channel following previous. 
1361           // d0: only occurs in channel byte when dropping readout. Bail.
1362           else {
1363             //DIAGNOSE bit error
1364             int4 diff = curr_chan^next_chip;
1365             int bit;
1366             for (bit=0;!(diff&0x1);diff>>=1,bit++);
1367             int bithigh = curr_chan&(1<<bit);
1368             if (!(diff>>1)) {
1369               if (_monitorMode&&1==0) {
1370                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1371                           << std::hex << header 
1372                           << ": " << prev_word << " " << curr_word << " " << next_word 
1373                           << ": chip bit error in chip ID " << next_chip 
1374                           << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
1375                           << "seen, expected " << curr_chan << " " << next_chip
1376                           << std::endl << std::dec; 
1377               }
1378               curr_chan=next_chip;
1379               curr_word=(curr_word&0xff)+(next_chip<<8);
1380               fillChip=1;
1381               // Okay I can correct this in the ugliest way possible
1382               // No should never have a chip id 159
1383               if (curr_chan==159) {
1384                 fillChip=0;
1385                 //ERRLOG( ELwarning, "SIXD_StorableBank read aborted" )
1386                 //        << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1387                 //        << "Correcting to too many chips on layer " << digiCode.getLayer()
1388                 //        << endmsg;
1389                 //std::cout << "Corr current chip 159!" <<  std::endl;
1390               }
1391 
1392               if (bit==0) {
1393                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1394                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1395               }
1396               else if (bit==1) {
1397                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1398                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1399               }
1400               else {
1401                 hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1402                 chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1403               }
1404             }
1405             //DIAGNOSE ff
1406             else if ((next_chan>prev_chan+1)&&
1407                      ((next_chan<0x80)||(next_chan==next_chip))) {
1408               // correct the current channel but don't fill the data
1409               // (easier than figuring out which channel you were expecting)
1410               // LHM -- 23-july-02 try filling channel anyway...
1411               // look to see only high bits
1412               if (!(~curr_chan)&(next_chan-1)) {                
1413                 curr_word=(curr_word&0xff)+(curr_chan<<8);
1414                 fillChan=1;
1415               }
1416               curr_chan=next_chan-1;
1417               if (_monitorMode&&1==0) {
1418                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1419                           << std::hex << header 
1420                           << ": " << prev_word << " " << curr_word << " " << next_word 
1421                           << ": ff at chip " << prev_chip 
1422                           << ": chan set to " << curr_chan 
1423                           << std::endl << std::dec;
1424               }
1425               hdiErrorWord |= SiVrbInfoSet::FF_7F;
1426               chanErrorWord |= SiVrbInfoSet::FF_7F;
1427             }
1428             //DIAGNOSE d0
1429             else if (curr_chan==0xd0) {
1430               if (_monitorMode&&1==0) {
1431                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1432                           << std::hex << header 
1433                           << ": " << prev_word << " " << curr_word << " " << next_word 
1434                           << ": D0 at chip " << prev_chip << std::endl << std::dec;
1435               }
1436               hdiErrorWord |= SiVrbInfoSet::D0_ERROR;
1437               chanErrorWord |= SiVrbInfoSet::D0_ERROR;
1438               if (dumpHtml && _htmlGen) {
1439                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
1440                                          org_word );
1441                   while (data < dataEnd) {
1442                       curr_word = next_word;
1443                       next_word=int4( (*(++data))&0xffff);
1444                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1445                                                         chanErrorWord );
1446                   }
1447               }
1448               break;
1449             }
1450             // something else awry
1451             else {
1452               if (_monitorMode&&1==0) {
1453                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1454                           << std::hex << header 
1455                           << ": " << prev_word << " " << curr_word << " " << next_word 
1456                           << ": fake chip Id in chip " << prev_chip << " dump: ";
1457                 // make sure it truncates
1458                 int truncate=0;
1459                 while (data < dataEnd) {
1460                   if ((next_word=*(data++))&0xc200) truncate=1; std::cout << " " << (next_word&0xffff);
1461                 }
1462                 std::cout << std::endl << std::dec;
1463                 if (!truncate) std::cout << " NO TRUNCATE!" << std::endl << std::dec;
1464               }
1465               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
1466               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
1467               if (dumpHtml && _htmlGen) {
1468                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
1469                                          org_word );
1470                   while (data < dataEnd) {
1471                       curr_word = next_word;
1472                       next_word=int4( (*(++data))&0xffff);
1473                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1474                                                         chanErrorWord );
1475                   }
1476               }
1477               break;
1478             }
1479           }
1480           if (dumpHtml && _htmlGen)
1481               _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord, org_word );
1482         } // end of chip checking
1483         
1484         //if its not a chip its a channel
1485         // look for data
1486         else {
1487           // see if good
1488           if (((prev_chan<curr_chan)&&(curr_chan<next_chan))||   //in middle
1489               ((prev_chan==prev_chip)&&(curr_chan<next_chan))) { //first of chip
1490             //all good (middle or end of chip)
1491             fillChan=1;
1492           }
1493           // check for a bit 1 high error special case here:
1494           // bit 1 stuck:        Handle  23236767ababefef (bit 1 high)
1495           //                             ^^^
1496           else if ((prev_chan==next_chan)&&(curr_chan==prev_chan+1)) {
1497             if (curr_chan&2) {
1498               // bit 1 high error; correct and go on
1499               if (_monitorMode&&1==0) {
1500                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1501                           << std::hex << header 
1502                           << ": " << prev_word << " " << curr_word << " " << next_word 
1503                           << ": channel bit error in chip " << prev_chip 
1504                           << ": bit 1 high, skipping next word: "
1505                           << "seen, expected " << curr_chan << " " << curr_chan-2
1506                           << std::endl << std::dec; 
1507               }
1508               curr_chan-=2;
1509               curr_word=(curr_word&0xff)+(curr_chan<<8);
1510               fillChan=1;
1511               // in addition, we unfortunately have to skip the next word 
1512               // since the previous channel was already filled with the 
1513               // incorrect strip number
1514               next_word=int4( (*(++data))&0xffff);
1515               next_chan=next_word>>8;
1516               hdiErrorWord |= SiVrbInfoSet::BIT_1_HIGH;       
1517               hdiErrorWord |= SiVrbInfoSet::SUSPECT_DATA;             
1518               chanErrorWord |= SiVrbInfoSet::BIT_1_HIGH;              
1519               chanErrorWord |= SiVrbInfoSet::SUSPECT_DATA;            
1520             } else {
1521               fillChan=1;
1522               if (_monitorMode&&1==0) {
1523                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1524                           << std::hex << header 
1525                           << ": " << prev_word << " " << curr_word << " " << next_word 
1526                           << ": channel bit error in chip " << prev_chip 
1527                           << ": bit 1 low in previous channel?" 
1528                           << std::endl << std::dec; 
1529               }
1530             }
1531           }
1532           // if next channel is lower than previous, then something is wrong, 
1533           // but accept the current channel as kosher
1534           else if ((prev_chan<curr_chan)&&(next_chan<=(prev_chan+1))) {
1535             if (_monitorMode&&1==0) {
1536               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1537                         << std::hex << header 
1538                         << ": " << prev_word << " " << curr_word << " " << next_word 
1539                         << ": OO coming up?" 
1540                         << std::endl << std::dec;
1541             }
1542             fillChan=1;
1543           }
1544           // something is wrong; handle errors
1545           // strategy:           handle duplicate channels (and 00f3), bit errors, 7f
1546           //                     and bit 1 stuck (0 handled by above)
1547           // duplicate channels: previous channel and data equal to current
1548           //                     this only occurs for 00f3 and true duplication
1549           //                     ignore and continue if not 00f3 
1550           //                     (flagged above by HDI length)
1551           // bit errors:         see if the sequence is wrong by one bit
1552           // 7f:                 If next channel greater and only bits wrong are high
1553           // bit 1 stuck:        Handle 010145458989cdcd (bit 1 low)
1554           //                             ^^^
1555           //                     That is, the combination of prev=next, current is one less.
1556           //                     Other parts of the pattern are already handled 
1557           //                     for better or worse.
1558           // other:              bail
1559           // DIAGNOSE duplicate channel
1560           else if (prev_word==curr_word) {
1561             if (!dataOverrun) {
1562               if (_monitorMode&&1==0) {
1563                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1564                           << std::hex << header 
1565                           << ": " << prev_word << " " << curr_word << " " << next_word 
1566                           << ": duplicate channel at chip " << prev_chip 
1567                           << std::endl << std::dec;
1568               }
1569               // check for 00f3 and bail if it is
1570               if ((prev_word==0xf3)&&(curr_word==0xf3)&&(next_word==0xf3)) {
1571                 hdiErrorWord |= SiVrbInfoSet::DRO_00F3;       
1572                 chanErrorWord |= SiVrbInfoSet::DRO_00F3;                      
1573                 break;
1574               }
1575               if (!((hdiErrorWord&SiVrbInfoSet::BIT_0_LOW)||(hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
1576                 hdiErrorWord |= SiVrbInfoSet::DUP_CHAN;       
1577               if (!((chanErrorWord&SiVrbInfoSet::BIT_0_LOW)||(chanErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
1578                 chanErrorWord |= SiVrbInfoSet::DUP_CHAN;              
1579             }
1580             else {
1581               if (_monitorMode&&1==0) {
1582                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1583                           << std::hex << header 
1584                           << ": " << prev_word << " " << curr_word << " " << next_word 
1585                           << ": 00f3 at chip " << prev_chip 
1586                           << std::endl << std::dec;
1587               }
1588             }
1589           }
1590           // DIAGNOSE bit error
1591           // look for the seed, decide what to compare to
1592           // for a single bit difference
1593           // One detail: how to get the thresholds? For now use five...
1594           else if ((next_chan>prev_chan)||(prev_chan==prev_chip)) {
1595             // get the chip threshold
1596             int thisChipThreshold=8;
1597             if (_chipStatus) {
1598               int chip = SiliconRawDataFormat::svxii_last_chip[hdiCode.f_hdi()] - hdiCode.nChip() + 1;
1599               std::map<SiChipKey,Chipstream>::const_iterator ic = 
1600                 _chipStatus->getChipInfo()->find(SiChipKey(digiCode,chip));
1601               if (ic != _chipStatus->getChipInfo()->end()) {
1602                 thisChipThreshold = ic->second.threshold();
1603               }
1604             }
1605             int rightSeed=0;
1606             int leftSeed=0;
1607             int rightData=next_word&0xff;
1608             int leftData=prev_word&0xff;
1609             int chanExpectedLeft=0;
1610             int chanExpectedRight=0x7f;
1611             int newData;
1612             // get rid of pesky special codes
1613             rightData = (rightData>0xf0) ? 0 : rightData;
1614             leftData  = (leftData>0xf0)  ? 0 : leftData;
1615             // for the purposes of finding a seed
1616             // modify the data according to potential stuck bits
1617             // convert to gray, modify, take the higher number
1618             // as potential seed
1619             // GrayCode class has an implicit cast method converting to int
1620             // (So the assignment here converts)
1621             if (hdiErrorWord&SiVrbInfoSet::BIT_1_HIGH) {
1622               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
1623                 rightData=newData;
1624               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
1625                 leftData=newData;
1626             }
1627             else if (hdiErrorWord&SiVrbInfoSet::BIT_1_LOW) {
1628               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
1629                 rightData=newData;
1630               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
1631                 leftData=newData;
1632             }
1633             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH) {
1634               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
1635                 rightData=newData;
1636               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
1637                 leftData=newData;
1638             }
1639             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_LOW) {
1640               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
1641                 rightData=newData;
1642               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
1643                 leftData=newData;
1644             }
1645             // Could be a stuck bit has a fake "seed" on the left, 
1646             // e.g.
1647             // normal      0 1 2 3 4 5 6 7 
1648             // bit 1 low   0 1 1 0 7 6 6 7
1649             // ... 5107 5101 5407 ...
1650             // channel 53 (second '51') was seeded by channel 54, not 51.
1651 
1652             // seeds: left then right
1653             if ((prev_chan>0x7f)||(leftData>=thisChipThreshold)) {
1654               leftSeed=1;
1655               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
1656             }
1657             if ((next_chan>0x7f)||(rightData>=thisChipThreshold)) {
1658               rightSeed=1;
1659               chanExpectedRight=(next_chan>0x7f) ? 0x7f : next_chan-1;
1660             }
1661             // now get the bit error information
1662             if (!(leftSeed||rightSeed)) {
1663               if (_monitorMode&&1==0) {
1664                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1665                           << std::hex << header 
1666                           << ": " << prev_word << " " << curr_word << " " << next_word 
1667                           << ": No Seed Found!!! (l,r data) " << leftData << " " << rightData
1668                           << " in chip " << prev_chip 
1669                           << std::endl << std::dec; 
1670               }
1671               leftSeed=1;
1672               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
1673             }
1674             int bit, found=0;
1675             int chanExpected;
1676             if (leftSeed) {
1677               chanExpected=chanExpectedLeft;
1678               int4 diff = curr_chan^chanExpected;
1679               if (!diff) {
1680                 bit=-1;
1681                 found=1;
1682               }
1683               else { 
1684                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
1685               }
1686               if (!(diff>>1)) {
1687                 // found single bit error on left
1688                 found=1;
1689               }
1690             }
1691             if ((!found)&&(rightSeed)) {
1692               chanExpected=chanExpectedRight;
1693               int4 diff = curr_chan^chanExpected;
1694               if (!diff) {
1695                 bit=-1;
1696                 found=1;
1697               }
1698               else { 
1699                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
1700               }
1701               if (!(diff>>1)) {
1702                 // found single bit error on right
1703                 found=1;
1704               }
1705             }
1706             if (found) {
1707               // bit error; correct and go on
1708               if (bit>=0) {
1709                 int bithigh = curr_chan&(1<<bit);
1710                 if (_monitorMode&&1==0) {
1711                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1712                             << std::hex << header 
1713                             << ": " << prev_word << " " << curr_word << " " << next_word 
1714                             << ": channel bit error in chip " << prev_chip 
1715                             << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
1716                             << ": seeds (R,L) " << rightSeed << " " << leftSeed
1717                             << " seen, expected " << curr_chan << " " << chanExpected
1718                             << std::endl << std::dec; 
1719                 }
1720                 if (bit==0) {
1721                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1722                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1723                 }
1724                 else if (bit==1) {
1725                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1726                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1727                 }
1728                 else {
1729                   hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1730                   chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1731                 }
1732               }
1733               else {
1734                 if (_monitorMode&&1==0) {
1735                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1736                             << std::hex << header 
1737                             << ": " << prev_word << " " << curr_word << " " << next_word 
1738                             << ": no diff found! continuing for now "
1739                             << std::endl << std::dec;
1740                 }
1741               }
1742               curr_chan=chanExpected;
1743               curr_word=(curr_word&0xff)+(chanExpected<<8);
1744               fillChan=1;
1745             }
1746             // DIAGNOSE 7f
1747             // previous and next ok, only high bits in current
1748             else if ((next_chan>prev_chan+1)&&(!((~curr_chan)&chanExpected))) {
1749               // correct the current channel
1750               fillChan=1;
1751               if (_monitorMode&&1==0) {
1752                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1753                           << std::hex << header 
1754                           << ": " << prev_word << " " << curr_word << " " << next_word 
1755                           << ": 7f in chip " << prev_chip 
1756                           << ": seen, expected " << curr_chan << " " << chanExpected
1757                           << std::endl << std::dec;
1758                 }
1759               curr_chan=chanExpected;
1760               curr_word=(curr_word&0xff)+(chanExpected<<8);
1761               hdiErrorWord |= SiVrbInfoSet::FF_7F;            
1762               chanErrorWord |= SiVrbInfoSet::FF_7F;           
1763             } 
1764             // well, if we're still in order then try continuing
1765             else if ((prev_chan<curr_chan)||(prev_chan==prev_chip)) {
1766               // fill this channel anyway
1767               fillChan=1;
1768               if (_monitorMode&&1==0) {
1769                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1770                             << std::hex << header 
1771                           << ": " << prev_word << " " << curr_word << " " << next_word 
1772                           << ": unknown OO in " << prev_chip 
1773                           << std::endl << std::dec;
1774               }
1775             }
1776             // give up and dump the damned thing
1777             else {
1778               if (_monitorMode&&1==0) {
1779                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1780                           << std::hex << header 
1781                           << ": " << prev_word << " " << curr_word << " " << next_word 
1782                           << ": Context OK, Strip OO at chip " << prev_chip << " dump: ";
1783                 if (!dataOverrun) {
1784                   while (data < dataEnd) {
1785                     next_word=*(data++); std::cout << " " << (next_word&0xffff);
1786                   }
1787                 }
1788                 cout << std::endl << std::dec;
1789               }
1790               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
1791               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
1792               if (dumpHtml && _htmlGen) {
1793                   _htmlGen->PutChanWord( eventNum, header, curr_word, chanErrorWord,
1794                                          org_word );
1795                   while (data < dataEnd) {
1796                       curr_word = next_word;
1797                       next_word=int4( (*(++data))&0xffff);
1798                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1799                                                         chanErrorWord );
1800                   }
1801               }
1802               break;
1803             }
1804           } // end of (next_chan>prev_chan+1)||(prev_chan==prev_chip)
1805           // Now check for bit 1 special case:  1 0 1
1806           else if ((prev_chan==next_chan)&&(curr_chan==next_chan-1)) {
1807             if (!(curr_chan&2)) {
1808               // bit 1 low error; correct and go on
1809               if (_monitorMode&&1==0) {
1810                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1811                           << std::hex << header 
1812                           << ": " << prev_word << " " << curr_word << " " << next_word 
1813                           << ": channel bit error in chip " << prev_chip 
1814                           << ": bit 1 low: "
1815                           << "seen, expected " << curr_chan << " " << curr_chan+2
1816                           << std::endl << std::dec; 
1817               }
1818               curr_chan+=2;
1819               curr_word=(curr_word&0xff)+(curr_chan<<8);
1820               fillChan=1;
1821               hdiErrorWord |= SiVrbInfoSet::BIT_1_LOW;        
1822               chanErrorWord |= SiVrbInfoSet::BIT_1_LOW;       
1823             } else {
1824               fillChan=1;
1825               if (_monitorMode&&1==0) {
1826                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1827                           << std::hex << header 
1828                           << ": " << prev_word << " " << curr_word << " " << next_word 
1829                           << ": channel bit error in chip " << prev_chip 
1830                           << ": bit 1 high in previous channel?" 
1831                           << std::endl << std::dec; 
1832               }
1833             }
1834           }
1835           else {
1836             if (_monitorMode&&1==0) {
1837               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1838                         << std::hex << header 
1839                         << ": " << prev_word << " " << curr_word << " " << next_word 
1840                         << ": Strip OO at chip " << prev_chip << " dump: ";
1841               if (!dataOverrun) {
1842                 while (data < dataEnd) {
1843                   next_word=*(data++); std::cout << " " << (next_word&0xffff);
1844                 }
1845               }
1846               std::cout << std::endl << std::dec;
1847             }
1848             // Another possibility: 00f3
1849             // (doesn't happen in the 'context OK' unknown channel case...)
1850             // check that this, the next and the following are all 00F3
1851             // bail either way
1852             int4 nextnext_word=(++data<dataEnd) ? int4( (*(data))&0xffff) : 0;
1853             if ((curr_word==0xf3)&&(next_word==0xf3)&&(nextnext_word==0xf3)) {
1854               hdiErrorWord |= SiVrbInfoSet::DRO_00F3;         
1855               chanErrorWord |= SiVrbInfoSet::DRO_00F3;                
1856             }
1857             else {
1858               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
1859               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
1860             }
1861             if (dumpHtml && _htmlGen) {
1862                 _htmlGen->PutChanWord(eventNum, header, curr_word, chanErrorWord, org_word);
1863                 while (data < dataEnd) {
1864                     curr_word = next_word;
1865                     next_word=int4( (*(++data))&0xffff);
1866                     _htmlGen->ContinueDataAfterBreak( header, curr_word, chanErrorWord );
1867                 }
1868             }
1869             break;
1870           }
1871           if (dumpHtml && _htmlGen)
1872               _htmlGen->PutChanWord(eventNum, header, curr_word, chanErrorWord, org_word);
1873         }  // end of channel checking
1874         // fill chip info if ok
1875         if (fillChip) {
1876           hdiCode.setDataWord( curr_word );
1877           prev_chip=next_chip;
1878           // calculate the next expected chip ID
1879           if (hdiCode.isISL()) {
1880             if ((next_chip&0xf) == 0xc) next_chip+=0x10; // change to second ladder
1881             if ((next_chip&0xf) == 8)   next_chip+=0x20; // change side
1882             if ((next_chip&0xf) == 0x4) next_chip-=0x10; // change to first ladder
1883           }
1884           next_chip--;
1885           int chip = lastChip - hdiCode.nChip() + 1;
1886           SiChipInfo* chipInfo = 0;
1887           if (_svxDaqInfoSet && hdiInfo) {
1888             chipInfo = hdiInfo->find(chip);
1889             if(chipInfo) {
1890               chipInfo->setStatus(hdiCode.status());
1891               chipInfo->setSide(hdiCode.nSide());
1892             }
1893           }  
1894           // Reserve space for the strips in this detector when new digicode encountered
1895           // seems to me there's a smarter way to figure out the space needed 
1896           // (there are up to four digicodes per HDI!) but perhaps reserving is harmless?
1897           digiCode.setPnSide( hdiCode.nSide() );
1898           digiCode.setHalfLadder( hdiCode.halfLadder() );
1899           digiCode.setPhiWedge( hdiCode.phiAddr() );
1900           if (( digiCode != lastDigiCode )||(firstDigiOfHdi)) {
1901             lastDigiCode = digiCode;
1902             firstDigiOfHdi=0;
1903             stripVector = &( stripSet[digiCode] );
1904             stripVector->reserve( ( nextHdi - hdi ) * 2 );
1905             currentVectorStrip = -1;
1906           }
1907         } // end of fill chip ID
1908         
1909         // fill this channel if its ok
1910         if (fillChan) {
1911           hdiCode.setDataWord( curr_word );
1912           int thisStrip = hdiCode.strip();
1913           if (thisStrip <= currentVectorStrip)
1914             {
1915 
1916               //ERRLOG( ELwarning, "ISLD_StorableBank out of order strip" )
1917               //        << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1918               //        << "Trying to fill out of order strips"
1919               //        << "HDI pointer = " << hdi
1920               //        << endmsg;
1921 
1922               // don't store strip if it's strip number is less than the previous strip
1923               // Let processing continue
1924               //return;
1925             }
1926           else
1927             {
1928               currentVectorStrip = thisStrip;
1929               stripVector->push_back( SiStrip() );
1930               SiStrip & strip = stripVector->back();
1931               strip.setGoodStrip();
1932               strip.setStripNumber( thisStrip );
1933               strip.setScaledAdc( _dataMap.rawToScaled( hdiCode.adc() ) );
1934               //strip.setFirstReadFromChip( true );
1935               strip.resetNmcIds();
1936             }
1937         } // end of fill Channel
1938 
1939         // Finally look for termination character coming up: end of the line
1940         if ((next_chan&0xf0)==0xc0) {
1941           if (next_chan==0xc2) {
1942             if (_monitorMode&&1==0) {
1943               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1944                         << std::hex << header 
1945                         << ": " << prev_word << " " << curr_word << " " << next_word 
1946                         << ": DRO at chip " << prev_chip 
1947                         << std::endl << std::dec;           
1948             }
1949             hdiErrorWord |= SiVrbInfoSet::DRO_TERM;    
1950             chanErrorWord |= SiVrbInfoSet::DRO_TERM;    
1951           }
1952           else if (next_chan!=0xc1) {
1953             if (_monitorMode&&1==0) {
1954               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1955                         << std::hex << header 
1956                         << ": " << prev_word << " " << curr_word << " " << next_word 
1957                         << ": illegal termination character at chip " 
1958                         << prev_chip << std::endl << std::dec;      
1959             }
1960             hdiErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
1961             chanErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
1962           }
1963           if (dumpHtml && _htmlGen) {
1964               while (data < dataEnd) {
1965                   curr_word = next_word;
1966                   next_word=int4( (*(++data))&0xffff);
1967                   _htmlGen->PutTermWord( eventNum, header, curr_word, chanErrorWord,
1968                                          org_word );
1969               }
1970           }
1971           break;
1972         }
1973         prev_word=curr_word;
1974         prev_chan=curr_chan;
1975         curr_word=next_word;
1976         curr_chan=next_chan;
1977       }  // loop over Data
1978 
1979       if(hdiInfo) {
1980         hdiInfo->setLastChip(prev_chip & 0x0f);
1981         hdiInfo->setErrorWord(hdiErrorWord);
1982       }
1983       _bankReadoutError |= hdiErrorWord;
1984       }     // done with checking this HDI is not from the  SOC 
1985     }  // loop over HDI blocks
1986   }   // loop over VRB blocks
1987 }

source navigation ] diff markup ] identifier search ] freetext search ] file search ]

This page was automatically generated by the LXR engine.
The LXR team
Valid HTML 4.01!

Send problems or questions to cdfcode@fnal.gov