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, "b0", 2) == 0)
038       db = "onotl_prd_read";
039     else
040       db = _defaultDbName;
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 (_dropSIXDz && hdiCode.nSide()!=0)  // Drop SVX z side if needed 
909     {
910       break;
911     }
912           if (_svxDaqInfoSet && hdiInfo) {
913             chipInfo = hdiInfo->find(chip);
914             if(chipInfo) {
915               chipInfo->setStatus(hdiCode.status());
916               chipInfo->setSide(hdiCode.nSide());
917             }
918           }  
919           // Reserve space for the strips in this detector when new digicode encountered
920           // seems to me there's a smarter way to figure out the space needed 
921           // (there are up to four digicodes per HDI!) but perhaps reserving is harmless?
922           digiCode.setPnSide( hdiCode.nSide() );
923           if (( digiCode != lastDigiCode )||(firstDigiOfHdi)) {
924             lastDigiCode = digiCode;
925             firstDigiOfHdi=0;
926             stripVector = &( stripSet[digiCode] );
927             stripVector->reserve( ( nextHdi - hdi ) * 2 );
928             currentVectorStrip = -1;
929           }
930         } // end of fill chip ID
931         
932         // fill this channel if its ok
933         if (fillChan) {
934           hdiCode.setDataWord( curr_word );
935           int thisStrip = hdiCode.strip();
936           if (thisStrip <= currentVectorStrip)
937             {
938 
939               //ERRLOG( ELwarning, "SIXD_StorableBank out of order strip" )
940               //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
941               //        << "Trying to fill out of order strips"
942               //        << "HDI pointer = " << hdi
943               //        << endmsg;
944 
945               // don't store strip if it's strip number is less than the previous strip
946               // Let processing continue
947               //return;
948             }
949           else
950             {
951               currentVectorStrip = thisStrip;
952               stripVector->push_back( SiStrip() );
953               SiStrip & strip = stripVector->back();
954               strip.setGoodStrip();
955               strip.setStripNumber( thisStrip );
956               strip.setScaledAdc( _dataMap.rawToScaled( hdiCode.adc() ) );
957               //strip.setFirstReadFromChip( true );
958               strip.resetNmcIds();
959             }
960         } // end of fill Channel
961 
962         // Finally look for termination character coming up: end of the line
963         if ((next_chan&0xf0)==0xc0) {
964           if (next_chan==0xc2) {
965             if (_monitorMode&&1==0) {
966               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
967                         << std::hex << header 
968                         << ": " << prev_word << " " << curr_word << " " << next_word 
969                         << ": DRO at chip " << prev_chip 
970                         << std::endl << std::dec;           
971             }
972             hdiErrorWord |= SiVrbInfoSet::DRO_TERM;    
973             chanErrorWord |= SiVrbInfoSet::DRO_TERM;    
974           }
975           else if (next_chan!=0xc1) {
976             if (_monitorMode&&1==0) {
977               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
978                         << std::hex << header 
979                         << ": " << prev_word << " " << curr_word << " " << next_word 
980                         << ": illegal termination character at chip " 
981                         << prev_chip << std::endl << std::dec;      
982             }
983             hdiErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
984             chanErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
985           }
986           if (dumpHtml && _htmlGen) {
987               while (data < dataEnd) {
988                   curr_word = next_word;
989                   next_word=int4( (*(++data))&0xffff);
990                   _htmlGen->PutTermWord( eventNum, header, curr_word, chanErrorWord,
991                                          org_word );
992               }
993           }
994           break;
995         }
996         prev_word=curr_word;
997         prev_chan=curr_chan;
998         curr_word=next_word;
999         curr_chan=next_chan;
1000       }  // loop over Data
1001       if(hdiInfo) {
1002         hdiInfo->setLastChip(prev_chip & 0x0f);
1003         hdiInfo->setErrorWord(hdiErrorWord);
1004       }
1005       _bankReadoutError |= hdiErrorWord;
1006     }  // loop over HDI blocks
1007   }   // loop over VRB blocks
1008 }
1009 
1010 
1011 
1012 //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1013 // Read ISLD bank using nndata bank access interface
1014 //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1015 
1016 void TRYRun2SiStripSet::readISLDBank_nndata( const ISLD_StorableBank & isld,
1017                                              std::vector<int4> & hdiKeys )
1018 {
1019 
1020   ISLD_StorableBank::VrbHeaderDecode vrbCode ;
1021   ISLD_StorableBank::HdiDecode       hdiCode ;  
1022   HWSiNumerology numer; 
1023 
1024   // Set data rep if necessary
1025   //
1026   if ( _selectDataRepByBankVersion )
1027   {
1028     SiRecoDataRep::instance()->
1029                    dataRep().setDataRepByBankVersion( isld.bank_version() );
1030   }
1031       
1032   // try to init chip info if new run
1033   if (lastRunNumber!=AbsEnv::instance()->runNumber()&&_useNNChipThreshold) {
1034     delete _chipStatus;
1035     // choose database for online/offline
1036     std::string db;
1037     char name[128];
1038     gethostname(name,128);
1039     name[127] = '\0';
1040     if (strncmp(name, "b0", 2) == 0)
1041       db = "onotl_prd_read";
1042     else
1043       db = "ofotl_prd_read";
1044     _chipStatus = new ChipStatus(db.c_str(),AbsEnv::instance()->runNumber());
1045     lastRunNumber=AbsEnv::instance()->runNumber();
1046     std::cout << "Getting a new chipstatus";
1047   }
1048   int eventNum = AbsEnv::instance()->trigNumber();
1049   if (dumpHtml && _htmlGen)
1050       _htmlGen->SetRunNum(AbsEnv::instance()->runNumber());
1051 
1052   // Reserve space for all possible SiDigiCode's
1053   //
1054   SiStripSet::collection_type & stripSet = contents();
1055   stripSet.reserve( SiliconRawDataFormat::n_hdi_total_isld * 4 );
1056   
1057   // Get bank header information
1058   //
1059   ISLD_StorableBank::VRB_Iter vrb0( isld ) ;
1060   vrbCode.setHeaderWord(vrb0.header_word());
1061   int tsCounter = vrbCode.tsCounter();
1062   int timeSinceL1A = vrbCode.timeSinceL1A();    
1063   //----------------------------------------------------------
1064   //  Loop over data in ISLD bank
1065   //----------------------------------------------------------
1066     
1067   SiDigiCode digiCode;
1068   digiCode.setLadder( 0 );
1069   SiHdiInfo* hdiInfo = 0;
1070   
1071   // In order to determine if the HDI block is empty, we need
1072   // access to the pointers to the current and the next HDI blocks.
1073   // A word count <= to the HDI header length => the block is empty.
1074   //
1075   ISLD_StorableBank::Simple_Iter isld_begin = isld.start_of_data();
1076   ISLD_StorableBank::Simple_Iter isld_end   = isld.end_of_data();
1077 
1078   ISLD_StorableBank::Simple_HDI_Pointer_Iter 
1079                      nextHdiIndex = isld.begin_hdi_index();
1080   ISLD_StorableBank::Simple_HDI_Pointer_Iter 
1081                      hdiIndexEnd  = isld.end_hdi_index();
1082   
1083   // check for empty bank
1084   if ( nextHdiIndex == hdiIndexEnd )
1085   {
1086     // No data or a format inconsistency.
1087     return;
1088   }
1089   
1090   ISLD_StorableBank::
1091   Simple_HDI_Iter hdi = isld_begin + isld.hdi_block_offset( nextHdiIndex );
1092   if ( hdi >= isld_end )
1093   {
1094     errlog( ELwarning, "ISLD_StorableBank read aborted" )
1095             << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1096             << "First HDI pointer out-of-bounds."
1097             << "HDI pointer = " << hdi
1098             << ", end-of-data pointer = " << isld_end
1099             << endmsg;
1100     return;
1101   }
1102 
1103   ISLD_StorableBank::Simple_HDI_Iter nextHdi;
1104   ISLD_StorableBank::Simple_HDI_Pointer_Iter hdiIndex;
1105 
1106 //   for ( hdiIndex = isld.begin_hdi_index(); hdiIndex < hdiIndexEnd;
1107 //      hdiIndex += ISLD_StorableBank_format::n_words_per_hdi_pointer )
1108 //     {
1109 
1110   for (int i = 0; i < hdiKeys.size(); ++i)
1111     {
1112       int4 key = hdiKeys[i];
1113       hdiIndex = isld.begin_hdi_index() + key * ISLD_StorableBank_format::n_words_per_hdi_pointer;
1114 
1115       hdi = isld_begin + isld.hdi_block_offset( hdiIndex );
1116       nextHdiIndex = hdiIndex + ISLD_StorableBank_format::n_words_per_hdi_pointer;
1117       nextHdi = isld_begin + isld.hdi_block_offset( nextHdiIndex );
1118 
1119 
1120     if ( nextHdi > isld_end )
1121     {
1122       ERRLOG( ELerror, "ISLD_StorableBank read aborted" )
1123               << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1124               << "'next' HDI pointer out-of-bounds."
1125               << "nextHDI = " << nextHdi
1126               << ", end-of-data pointer = " << isld_end
1127               << endmsg;
1128       return;
1129     }
1130     
1131     // Check for data in this HDI block
1132     //
1133     if ( (nextHdi - hdi) > SiliconRawDataFormat::hdi_header_length )
1134     { 
1135       int4 header = int4(
1136                          ( *(hdi + SiliconRawDataFormat::hdi_header_offset)
1137                            & SiliconRawDataFormat::header_upper_mask )
1138                          << SiliconRawDataFormat::header_upper_shft  )
1139         +
1140         int4(
1141              ( *(hdi + SiliconRawDataFormat::hdi_header_offset + 1)
1142                & SiliconRawDataFormat::header_lower_mask )
1143              << SiliconRawDataFormat::header_lower_shft  );
1144 
1145       if (!(hdiCode.setHdiHeader( header ))) {
1146         ERRLOG( ELerror, "ISLD_StorableBank read aborted" )
1147           << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1148           << "HDI header invalid."
1149           << "header = " << header
1150           << endmsg;
1151         return;
1152       }
1153       
1154       if (!hdiCode.isSOC()) {            // check we don't look at the SOC
1155         digiCode.setBarrel( hdiCode.barrel() );
1156         int layer = hdiCode.layer();
1157         if (layer>0&&layer<6) {
1158           //ERRLOG( ELwarning, "ISLD_StorableBank read aborted" )
1159           //  << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1160           //  << "HDI header invalid. Layer = " << layer << " "
1161           //  << "header = " << header
1162           //  << endmsg;
1163           return;
1164         }
1165 
1166 
1167         digiCode.setLayer( layer );
1168         int lastChip = SiliconRawDataFormat::isl_last_chip ;
1169         if ( layer < numer.getMinLayer(AbsSiNumerology::SVXII) ) 
1170           lastChip = ( hdiCode.f_hdi() < 3) ? 
1171             SiliconRawDataFormat::l00_wide_last_chip :
1172           SiliconRawDataFormat::l00_thin_last_chip ;
1173         int chipHdi = hdiCode.f_hdi();
1174         if(_islDaqInfoSet) {
1175           int pcId = hdiCode.f_pc();      
1176           int vrbId;
1177           if(hdiCode.isISL()) {
1178             if( hdiCode.barrel() == 0 )
1179               vrbId = ( hdiCode.halfLadder() 
1180                         * SiliconRawDataFormat::isl_n_pc_per_end_forw + pcId ) 
1181                 / SiliconRawDataFormat::isl_n_pc_per_vrb ;
1182             else if ( hdiCode.barrel() == 1 )
1183               vrbId = SiliconRawDataFormat::isl_n_vrb_forw 
1184                 + hdiCode.halfLadder() 
1185                 * SiliconRawDataFormat::isl_n_vrb_per_end_cent
1186                 + ( pcId / SiliconRawDataFormat::isl_n_pc_per_vrb ) ;
1187             else
1188               vrbId = SiliconRawDataFormat::isl_n_vrb_forw 
1189                 + SiliconRawDataFormat::isl_n_vrb_cent +
1190                 + ((hdiCode.halfLadder() 
1191                     * SiliconRawDataFormat::isl_n_pc_per_end_forw + pcId) 
1192                    / SiliconRawDataFormat::isl_n_pc_per_vrb);
1193           }
1194           else if ( hdiCode.isL00() ) {
1195             if ( hdiCode.barrel() == 0)
1196               vrbId = pcId / SiliconRawDataFormat::l00_n_pc_per_vrb; 
1197             else
1198               vrbId = SiliconRawDataFormat::n_vrb_barrel0_l00_isld 
1199                 + pcId / SiliconRawDataFormat::l00_n_pc_per_vrb;
1200             vrbId += SiliconRawDataFormat::isl_n_vrb;  
1201           }
1202           SiVrbInfo* vrbInfo = _islDaqInfoSet->find(vrbId);
1203           if(vrbInfo) {
1204             vrbInfo->setTSCounter(tsCounter);
1205             vrbInfo->setTimeSinceL1A(timeSinceL1A);
1206             vrbInfo->setErrorWd0(0);
1207             vrbInfo->setErrorWd1(0);
1208             SiPortCardInfo* pcInfo = vrbInfo->find(pcId);
1209             if(pcInfo) {
1210               hdiInfo = pcInfo->find(hdiCode.f_hdi());
1211               if(hdiInfo) {
1212                 hdiInfo->setBunchXing(hdiCode.bunchCrossing());;
1213                 hdiInfo->setBEstate(hdiCode.beState()); 
1214               }  // done with HDIs
1215             }    // done with PCs
1216           }      // done with VRBs
1217         }        // done with VRBinfoset
1218 
1219         // use this 'lastDigiCode' to find when we've entered a new digicode
1220         SiDigiCode lastDigiCode( digiCode );
1221         // first one of hdi needs to be forced.
1222         int firstDigiOfHdi=1;
1223 
1224         // set up strip vector
1225         unsigned int hdiErrorWord = 0;
1226         vector_type * stripVector;
1227         int currentVectorStrip = -1;
1228         
1229         // check for 00f3 and c2c2 problems
1230         // these are found based on the length of the HDI
1231         int dataOverrun=0;
1232         if ( nextHdi-hdi == 0xffe)
1233           {
1234             if (_monitorMode&&1==0) {
1235               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1236                         << std::hex << header 
1237                         << ": 00f3" 
1238                         << std::endl << std::dec;
1239             }
1240             dataOverrun=1;
1241           // LM 08-Oct-2002 used this bit for 00F3
1242           //          hdiErrorWord |= SiVrbInfoSet::DATA_OVERRUN;
1243           }
1244         if ( nextHdi-hdi == 0x4)
1245           {
1246             hdiErrorWord |= SiVrbInfoSet::C2C2;
1247           }
1248         if (dumpHtml && _htmlGen) {
1249             if (hdiErrorWord)
1250                 _htmlGen->Put00f3C2c2(eventNum, header, hdiErrorWord);
1251         }
1252         
1253         ISLD_StorableBank::Simple_Data_Iter data = isld.begin_hdi_data( hdi );
1254         ISLD_StorableBank::Simple_Data_Iter dataEnd = nextHdi;
1255         int4 prev_word=-1;
1256         int4 prev_chan=-1;
1257         int4 curr_word=int4( (*data)&0xffff );
1258         int4 curr_chan=curr_word>>8;
1259         
1260         // first things first: the first word had better be the first chip ID
1261         // If wrong, look to see if its a bit error.
1262         // Bit error: one bit different. Correct and continue.
1263         // Otherwise: bail
1264         int4 next_chip= lastChip+0x80;
1265         int4 prev_chip=next_chip;
1266         if (curr_chan != next_chip) {
1267           int4 diff = curr_chan^next_chip;
1268           int bit;
1269           for (bit=0;!(diff&0x1);diff>>=1,bit++);
1270           int bithigh = curr_chan&(1<<bit);
1271           if (!(diff>>1)) {
1272             if (_monitorMode&&1==0) {
1273               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1274                         << std::hex << header 
1275                         << ": first chip ID bit error bit " << bit << ((bithigh) ? " high: " : " low: ")
1276                         << "seen, expected " << curr_chan << " " << next_chip 
1277                         << std::endl << std::dec;
1278             }
1279             // bit error; correct and go on
1280             curr_chan=next_chip;
1281             curr_word=(curr_word&0xff)+(next_chip<<8);
1282             if (bit==0) 
1283               hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1284             else if (bit==1) 
1285               hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1286             else
1287               hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1288           } else {            
1289             // something else; bail
1290             if (_monitorMode&&1==0) {
1291               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1292                         << std::hex << header 
1293                         << ": DRO immediate" 
1294                         << ": seen, expected " << curr_chan << " " << next_chip << " dump: ";
1295               int4 next_word;
1296               if (!dataOverrun) {
1297                 while (data < dataEnd) {
1298                   next_word=(*(data++)&0xffff); std::cout << " " << next_word;
1299                 }
1300               }
1301               std::cout << std::endl << std::dec;
1302             }
1303             hdiErrorWord |= SiVrbInfoSet::DRO_IMMEDIATE;
1304             if(hdiInfo) {
1305               hdiInfo->setLastChip(prev_chip & 0x0f);
1306               hdiInfo->setErrorWord(hdiErrorWord);
1307             }
1308             _bankReadoutError |= hdiErrorWord;
1309             if (dumpHtml && _htmlGen) {
1310                 data = isld.begin_hdi_data( hdi );
1311                 curr_word=int4( (*data)&0xffff );
1312                 _htmlGen->PutChipWord( eventNum, header, curr_word, hdiErrorWord,
1313                                        curr_word );
1314                 while (data < dataEnd) {
1315                     int4 next_word=int4( (*(++data))&0xffff);
1316                     curr_word = next_word;
1317                     if (!dataOverrun)
1318                         _htmlGen->ContinueDataAfterBreak( header, curr_word,
1319                                                           hdiErrorWord );
1320                 }
1321             }
1322             continue;
1323           }
1324         }
1325         
1326       // now loop over the data
1327       // strategy is to look ahead and behind for error context
1328       while (data < dataEnd) {
1329         unsigned int chanErrorWord = 0;
1330         int4 org_word = curr_word;
1331         int4 next_word=int4( (*(++data))&0xffff);
1332         int4 next_chan=next_word>>8;
1333         int fillChip=0;
1334         int fillChan=0;
1335         
1336         // look for chip ID
1337         if (curr_chan>0x7f) {
1338           // the right chip ID?
1339           // the right chip ID/digicode?
1340           //if (digiCode.getPhiWedge()>11&&digiCode.getLayer()==5) {
1341           //  std::cout << "Phi wed " << digiCode.getPhiWedge() << " current chip " << curr_chan << " expected chip " << next_chip << std::endl;
1342           //}
1343 
1344           if (curr_chan==next_chip) {
1345             fillChip=1;
1346             if (curr_chan==159) {
1347               fillChip=0;
1348               //ERRLOG( ELwarning, "ISLD_StorableBank read aborted" )
1349               //        << "@SUB=TRYRun2SiStripSet::readSIXDBank_nndata"
1350               //        << "Too many chips on layer " << digiCode.getLayer()
1351               //        << endmsg;
1352               return;
1353             }
1354           } 
1355           // something wrong... handle errors
1356           // strategy: handle bit errors, ff and d0, in that order
1357           // Bit: If its one bit off report that bit, correct and
1358           //      try to continue
1359           // ff: defined as prev and next in order, current a fake chip ID
1360           //     (this is before bit error because it is very unlikely for 
1361           //      next channel > prev channel in 7f problems)
1362           //     For now, correct the channel for parsing purposes. Don't fill.
1363           //     7f always replaces channel preceding next, as opposed to 
1364           //      channel following previous. 
1365           // d0: only occurs in channel byte when dropping readout. Bail.
1366           else {
1367             //DIAGNOSE bit error
1368             int4 diff = curr_chan^next_chip;
1369             int bit;
1370             for (bit=0;!(diff&0x1);diff>>=1,bit++);
1371             int bithigh = curr_chan&(1<<bit);
1372             if (!(diff>>1)) {
1373               if (_monitorMode&&1==0) {
1374                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1375                           << std::hex << header 
1376                           << ": " << prev_word << " " << curr_word << " " << next_word 
1377                           << ": chip bit error in chip ID " << next_chip 
1378                           << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
1379                           << "seen, expected " << curr_chan << " " << next_chip
1380                           << std::endl << std::dec; 
1381               }
1382               curr_chan=next_chip;
1383               curr_word=(curr_word&0xff)+(next_chip<<8);
1384               fillChip=1;
1385               // Okay I can correct this in the ugliest way possible
1386               // No should never have a chip id 159
1387               if (curr_chan==159) {
1388                 fillChip=0;
1389                 //ERRLOG( ELwarning, "SIXD_StorableBank read aborted" )
1390                 //        << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1391                 //        << "Correcting to too many chips on layer " << digiCode.getLayer()
1392                 //        << endmsg;
1393                 //std::cout << "Corr current chip 159!" <<  std::endl;
1394               }
1395 
1396               if (bit==0) {
1397                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1398                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1399               }
1400               else if (bit==1) {
1401                 hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1402                 chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1403               }
1404               else {
1405                 hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1406                 chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1407               }
1408             }
1409             //DIAGNOSE ff
1410             else if ((next_chan>prev_chan+1)&&
1411                      ((next_chan<0x80)||(next_chan==next_chip))) {
1412               // correct the current channel but don't fill the data
1413               // (easier than figuring out which channel you were expecting)
1414               // LHM -- 23-july-02 try filling channel anyway...
1415               // look to see only high bits
1416               if (!(~curr_chan)&(next_chan-1)) {                
1417                 curr_word=(curr_word&0xff)+(curr_chan<<8);
1418                 fillChan=1;
1419               }
1420               curr_chan=next_chan-1;
1421               if (_monitorMode&&1==0) {
1422                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1423                           << std::hex << header 
1424                           << ": " << prev_word << " " << curr_word << " " << next_word 
1425                           << ": ff at chip " << prev_chip 
1426                           << ": chan set to " << curr_chan 
1427                           << std::endl << std::dec;
1428               }
1429               hdiErrorWord |= SiVrbInfoSet::FF_7F;
1430               chanErrorWord |= SiVrbInfoSet::FF_7F;
1431             }
1432             //DIAGNOSE d0
1433             else if (curr_chan==0xd0) {
1434               if (_monitorMode&&1==0) {
1435                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1436                           << std::hex << header 
1437                           << ": " << prev_word << " " << curr_word << " " << next_word 
1438                           << ": D0 at chip " << prev_chip << std::endl << std::dec;
1439               }
1440               hdiErrorWord |= SiVrbInfoSet::D0_ERROR;
1441               chanErrorWord |= SiVrbInfoSet::D0_ERROR;
1442               if (dumpHtml && _htmlGen) {
1443                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
1444                                          org_word );
1445                   while (data < dataEnd) {
1446                       curr_word = next_word;
1447                       next_word=int4( (*(++data))&0xffff);
1448                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1449                                                         chanErrorWord );
1450                   }
1451               }
1452               break;
1453             }
1454             // something else awry
1455             else {
1456               if (_monitorMode&&1==0) {
1457                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1458                           << std::hex << header 
1459                           << ": " << prev_word << " " << curr_word << " " << next_word 
1460                           << ": fake chip Id in chip " << prev_chip << " dump: ";
1461                 // make sure it truncates
1462                 int truncate=0;
1463                 while (data < dataEnd) {
1464                   if ((next_word=*(data++))&0xc200) truncate=1; std::cout << " " << (next_word&0xffff);
1465                 }
1466                 std::cout << std::endl << std::dec;
1467                 if (!truncate) std::cout << " NO TRUNCATE!" << std::endl << std::dec;
1468               }
1469               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
1470               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHIP;
1471               if (dumpHtml && _htmlGen) {
1472                   _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord,
1473                                          org_word );
1474                   while (data < dataEnd) {
1475                       curr_word = next_word;
1476                       next_word=int4( (*(++data))&0xffff);
1477                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1478                                                         chanErrorWord );
1479                   }
1480               }
1481               break;
1482             }
1483           }
1484           if (dumpHtml && _htmlGen)
1485               _htmlGen->PutChipWord( eventNum, header, curr_word, chanErrorWord, org_word );
1486         } // end of chip checking
1487         
1488         //if its not a chip its a channel
1489         // look for data
1490         else {
1491           // see if good
1492           if (((prev_chan<curr_chan)&&(curr_chan<next_chan))||   //in middle
1493               ((prev_chan==prev_chip)&&(curr_chan<next_chan))) { //first of chip
1494             //all good (middle or end of chip)
1495             fillChan=1;
1496           }
1497           // check for a bit 1 high error special case here:
1498           // bit 1 stuck:        Handle  23236767ababefef (bit 1 high)
1499           //                             ^^^
1500           else if ((prev_chan==next_chan)&&(curr_chan==prev_chan+1)) {
1501             if (curr_chan&2) {
1502               // bit 1 high error; correct and go on
1503               if (_monitorMode&&1==0) {
1504                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1505                           << std::hex << header 
1506                           << ": " << prev_word << " " << curr_word << " " << next_word 
1507                           << ": channel bit error in chip " << prev_chip 
1508                           << ": bit 1 high, skipping next word: "
1509                           << "seen, expected " << curr_chan << " " << curr_chan-2
1510                           << std::endl << std::dec; 
1511               }
1512               curr_chan-=2;
1513               curr_word=(curr_word&0xff)+(curr_chan<<8);
1514               fillChan=1;
1515               // in addition, we unfortunately have to skip the next word 
1516               // since the previous channel was already filled with the 
1517               // incorrect strip number
1518               next_word=int4( (*(++data))&0xffff);
1519               next_chan=next_word>>8;
1520               hdiErrorWord |= SiVrbInfoSet::BIT_1_HIGH;       
1521               hdiErrorWord |= SiVrbInfoSet::SUSPECT_DATA;             
1522               chanErrorWord |= SiVrbInfoSet::BIT_1_HIGH;              
1523               chanErrorWord |= SiVrbInfoSet::SUSPECT_DATA;            
1524             } else {
1525               fillChan=1;
1526               if (_monitorMode&&1==0) {
1527                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1528                           << std::hex << header 
1529                           << ": " << prev_word << " " << curr_word << " " << next_word 
1530                           << ": channel bit error in chip " << prev_chip 
1531                           << ": bit 1 low in previous channel?" 
1532                           << std::endl << std::dec; 
1533               }
1534             }
1535           }
1536           // if next channel is lower than previous, then something is wrong, 
1537           // but accept the current channel as kosher
1538           else if ((prev_chan<curr_chan)&&(next_chan<=(prev_chan+1))) {
1539             if (_monitorMode&&1==0) {
1540               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1541                         << std::hex << header 
1542                         << ": " << prev_word << " " << curr_word << " " << next_word 
1543                         << ": OO coming up?" 
1544                         << std::endl << std::dec;
1545             }
1546             fillChan=1;
1547           }
1548           // something is wrong; handle errors
1549           // strategy:           handle duplicate channels (and 00f3), bit errors, 7f
1550           //                     and bit 1 stuck (0 handled by above)
1551           // duplicate channels: previous channel and data equal to current
1552           //                     this only occurs for 00f3 and true duplication
1553           //                     ignore and continue if not 00f3 
1554           //                     (flagged above by HDI length)
1555           // bit errors:         see if the sequence is wrong by one bit
1556           // 7f:                 If next channel greater and only bits wrong are high
1557           // bit 1 stuck:        Handle 010145458989cdcd (bit 1 low)
1558           //                             ^^^
1559           //                     That is, the combination of prev=next, current is one less.
1560           //                     Other parts of the pattern are already handled 
1561           //                     for better or worse.
1562           // other:              bail
1563           // DIAGNOSE duplicate channel
1564           else if (prev_word==curr_word) {
1565             if (!dataOverrun) {
1566               if (_monitorMode&&1==0) {
1567                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1568                           << std::hex << header 
1569                           << ": " << prev_word << " " << curr_word << " " << next_word 
1570                           << ": duplicate channel at chip " << prev_chip 
1571                           << std::endl << std::dec;
1572               }
1573               // check for 00f3 and bail if it is
1574               if ((prev_word==0xf3)&&(curr_word==0xf3)&&(next_word==0xf3)) {
1575                 hdiErrorWord |= SiVrbInfoSet::DRO_00F3;       
1576                 chanErrorWord |= SiVrbInfoSet::DRO_00F3;                      
1577                 break;
1578               }
1579               if (!((hdiErrorWord&SiVrbInfoSet::BIT_0_LOW)||(hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
1580                 hdiErrorWord |= SiVrbInfoSet::DUP_CHAN;       
1581               if (!((chanErrorWord&SiVrbInfoSet::BIT_0_LOW)||(chanErrorWord&SiVrbInfoSet::BIT_0_HIGH))) 
1582                 chanErrorWord |= SiVrbInfoSet::DUP_CHAN;              
1583             }
1584             else {
1585               if (_monitorMode&&1==0) {
1586                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1587                           << std::hex << header 
1588                           << ": " << prev_word << " " << curr_word << " " << next_word 
1589                           << ": 00f3 at chip " << prev_chip 
1590                           << std::endl << std::dec;
1591               }
1592             }
1593           }
1594           // DIAGNOSE bit error
1595           // look for the seed, decide what to compare to
1596           // for a single bit difference
1597           // One detail: how to get the thresholds? For now use five...
1598           else if ((next_chan>prev_chan)||(prev_chan==prev_chip)) {
1599             // get the chip threshold
1600             int thisChipThreshold=8;
1601             if (_chipStatus) {
1602               int chip = SiliconRawDataFormat::svxii_last_chip[hdiCode.f_hdi()] - hdiCode.nChip() + 1;
1603               std::map<SiChipKey,Chipstream>::const_iterator ic = 
1604                 _chipStatus->getChipInfo()->find(SiChipKey(digiCode,chip));
1605               if (ic != _chipStatus->getChipInfo()->end()) {
1606                 thisChipThreshold = ic->second.threshold();
1607               }
1608             }
1609             int rightSeed=0;
1610             int leftSeed=0;
1611             int rightData=next_word&0xff;
1612             int leftData=prev_word&0xff;
1613             int chanExpectedLeft=0;
1614             int chanExpectedRight=0x7f;
1615             int newData;
1616             // get rid of pesky special codes
1617             rightData = (rightData>0xf0) ? 0 : rightData;
1618             leftData  = (leftData>0xf0)  ? 0 : leftData;
1619             // for the purposes of finding a seed
1620             // modify the data according to potential stuck bits
1621             // convert to gray, modify, take the higher number
1622             // as potential seed
1623             // GrayCode class has an implicit cast method converting to int
1624             // (So the assignment here converts)
1625             if (hdiErrorWord&SiVrbInfoSet::BIT_1_HIGH) {
1626               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
1627                 rightData=newData;
1628               if ((newData=GrayCode((0x2)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
1629                 leftData=newData;
1630             }
1631             else if (hdiErrorWord&SiVrbInfoSet::BIT_1_LOW) {
1632               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
1633                 rightData=newData;
1634               if ((newData=GrayCode((~0x2)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
1635                 leftData=newData;
1636             }
1637             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_HIGH) {
1638               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(rightData).grayCode())))>rightData)
1639                 rightData=newData;
1640               if ((newData=GrayCode((0x1)|(GrayCode::decToGray(leftData).grayCode())))>leftData)
1641                 leftData=newData;
1642             }
1643             else if (hdiErrorWord&SiVrbInfoSet::BIT_0_LOW) {
1644               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(rightData).grayCode())))>rightData)
1645                 rightData=newData;
1646               if ((newData=GrayCode((~0x1)&(GrayCode::decToGray(leftData).grayCode())))>leftData)
1647                 leftData=newData;
1648             }
1649             // Could be a stuck bit has a fake "seed" on the left, 
1650             // e.g.
1651             // normal      0 1 2 3 4 5 6 7 
1652             // bit 1 low   0 1 1 0 7 6 6 7
1653             // ... 5107 5101 5407 ...
1654             // channel 53 (second '51') was seeded by channel 54, not 51.
1655 
1656             // seeds: left then right
1657             if ((prev_chan>0x7f)||(leftData>=thisChipThreshold)) {
1658               leftSeed=1;
1659               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
1660             }
1661             if ((next_chan>0x7f)||(rightData>=thisChipThreshold)) {
1662               rightSeed=1;
1663               chanExpectedRight=(next_chan>0x7f) ? 0x7f : next_chan-1;
1664             }
1665             // now get the bit error information
1666             if (!(leftSeed||rightSeed)) {
1667               if (_monitorMode&&1==0) {
1668                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1669                           << std::hex << header 
1670                           << ": " << prev_word << " " << curr_word << " " << next_word 
1671                           << ": No Seed Found!!! (l,r data) " << leftData << " " << rightData
1672                           << " in chip " << prev_chip 
1673                           << std::endl << std::dec; 
1674               }
1675               leftSeed=1;
1676               chanExpectedLeft=(prev_chan>0x7f) ? 0 : prev_chan+1;
1677             }
1678             int bit, found=0;
1679             int chanExpected;
1680             if (leftSeed) {
1681               chanExpected=chanExpectedLeft;
1682               int4 diff = curr_chan^chanExpected;
1683               if (!diff) {
1684                 bit=-1;
1685                 found=1;
1686               }
1687               else { 
1688                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
1689               }
1690               if (!(diff>>1)) {
1691                 // found single bit error on left
1692                 found=1;
1693               }
1694             }
1695             if ((!found)&&(rightSeed)) {
1696               chanExpected=chanExpectedRight;
1697               int4 diff = curr_chan^chanExpected;
1698               if (!diff) {
1699                 bit=-1;
1700                 found=1;
1701               }
1702               else { 
1703                 for (bit=0;!(diff&0x1);diff>>=1,bit++);
1704               }
1705               if (!(diff>>1)) {
1706                 // found single bit error on right
1707                 found=1;
1708               }
1709             }
1710             if (found) {
1711               // bit error; correct and go on
1712               if (bit>=0) {
1713                 int bithigh = curr_chan&(1<<bit);
1714                 if (_monitorMode&&1==0) {
1715                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1716                             << std::hex << header 
1717                             << ": " << prev_word << " " << curr_word << " " << next_word 
1718                             << ": channel bit error in chip " << prev_chip 
1719                             << ": bit " << bit << ((bithigh) ? " high: " : " low: ") 
1720                             << ": seeds (R,L) " << rightSeed << " " << leftSeed
1721                             << " seen, expected " << curr_chan << " " << chanExpected
1722                             << std::endl << std::dec; 
1723                 }
1724                 if (bit==0) {
1725                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1726                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_0_HIGH : SiVrbInfoSet::BIT_0_LOW;
1727                 }
1728                 else if (bit==1) {
1729                   hdiErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1730                   chanErrorWord |= (bithigh) ? SiVrbInfoSet::BIT_1_HIGH : SiVrbInfoSet::BIT_1_LOW;
1731                 }
1732                 else {
1733                   hdiErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1734                   chanErrorWord |= SiVrbInfoSet::BIT_ERROR;  
1735                 }
1736               }
1737               else {
1738                 if (_monitorMode&&1==0) {
1739                   std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1740                             << std::hex << header 
1741                             << ": " << prev_word << " " << curr_word << " " << next_word 
1742                             << ": no diff found! continuing for now "
1743                             << std::endl << std::dec;
1744                 }
1745               }
1746               curr_chan=chanExpected;
1747               curr_word=(curr_word&0xff)+(chanExpected<<8);
1748               fillChan=1;
1749             }
1750             // DIAGNOSE 7f
1751             // previous and next ok, only high bits in current
1752             else if ((next_chan>prev_chan+1)&&(!((~curr_chan)&chanExpected))) {
1753               // correct the current channel
1754               fillChan=1;
1755               if (_monitorMode&&1==0) {
1756                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1757                           << std::hex << header 
1758                           << ": " << prev_word << " " << curr_word << " " << next_word 
1759                           << ": 7f in chip " << prev_chip 
1760                           << ": seen, expected " << curr_chan << " " << chanExpected
1761                           << std::endl << std::dec;
1762                 }
1763               curr_chan=chanExpected;
1764               curr_word=(curr_word&0xff)+(chanExpected<<8);
1765               hdiErrorWord |= SiVrbInfoSet::FF_7F;            
1766               chanErrorWord |= SiVrbInfoSet::FF_7F;           
1767             } 
1768             // well, if we're still in order then try continuing
1769             else if ((prev_chan<curr_chan)||(prev_chan==prev_chip)) {
1770               // fill this channel anyway
1771               fillChan=1;
1772               if (_monitorMode&&1==0) {
1773                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1774                             << std::hex << header 
1775                           << ": " << prev_word << " " << curr_word << " " << next_word 
1776                           << ": unknown OO in " << prev_chip 
1777                           << std::endl << std::dec;
1778               }
1779             }
1780             // give up and dump the damned thing
1781             else {
1782               if (_monitorMode&&1==0) {
1783                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1784                           << std::hex << header 
1785                           << ": " << prev_word << " " << curr_word << " " << next_word 
1786                           << ": Context OK, Strip OO at chip " << prev_chip << " dump: ";
1787                 if (!dataOverrun) {
1788                   while (data < dataEnd) {
1789                     next_word=*(data++); std::cout << " " << (next_word&0xffff);
1790                   }
1791                 }
1792                 cout << std::endl << std::dec;
1793               }
1794               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
1795               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
1796               if (dumpHtml && _htmlGen) {
1797                   _htmlGen->PutChanWord( eventNum, header, curr_word, chanErrorWord,
1798                                          org_word );
1799                   while (data < dataEnd) {
1800                       curr_word = next_word;
1801                       next_word=int4( (*(++data))&0xffff);
1802                       _htmlGen->ContinueDataAfterBreak( header, curr_word,
1803                                                         chanErrorWord );
1804                   }
1805               }
1806               break;
1807             }
1808           } // end of (next_chan>prev_chan+1)||(prev_chan==prev_chip)
1809           // Now check for bit 1 special case:  1 0 1
1810           else if ((prev_chan==next_chan)&&(curr_chan==next_chan-1)) {
1811             if (!(curr_chan&2)) {
1812               // bit 1 low error; correct and go on
1813               if (_monitorMode&&1==0) {
1814                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1815                           << std::hex << header 
1816                           << ": " << prev_word << " " << curr_word << " " << next_word 
1817                           << ": channel bit error in chip " << prev_chip 
1818                           << ": bit 1 low: "
1819                           << "seen, expected " << curr_chan << " " << curr_chan+2
1820                           << std::endl << std::dec; 
1821               }
1822               curr_chan+=2;
1823               curr_word=(curr_word&0xff)+(curr_chan<<8);
1824               fillChan=1;
1825               hdiErrorWord |= SiVrbInfoSet::BIT_1_LOW;        
1826               chanErrorWord |= SiVrbInfoSet::BIT_1_LOW;       
1827             } else {
1828               fillChan=1;
1829               if (_monitorMode&&1==0) {
1830                 std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1831                           << std::hex << header 
1832                           << ": " << prev_word << " " << curr_word << " " << next_word 
1833                           << ": channel bit error in chip " << prev_chip 
1834                           << ": bit 1 high in previous channel?" 
1835                           << std::endl << std::dec; 
1836               }
1837             }
1838           }
1839           else {
1840             if (_monitorMode&&1==0) {
1841               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1842                         << std::hex << header 
1843                         << ": " << prev_word << " " << curr_word << " " << next_word 
1844                         << ": Strip OO at chip " << prev_chip << " dump: ";
1845               if (!dataOverrun) {
1846                 while (data < dataEnd) {
1847                   next_word=*(data++); std::cout << " " << (next_word&0xffff);
1848                 }
1849               }
1850               std::cout << std::endl << std::dec;
1851             }
1852             // Another possibility: 00f3
1853             // (doesn't happen in the 'context OK' unknown channel case...)
1854             // check that this, the next and the following are all 00F3
1855             // bail either way
1856             int4 nextnext_word=(++data<dataEnd) ? int4( (*(data))&0xffff) : 0;
1857             if ((curr_word==0xf3)&&(next_word==0xf3)&&(nextnext_word==0xf3)) {
1858               hdiErrorWord |= SiVrbInfoSet::DRO_00F3;         
1859               chanErrorWord |= SiVrbInfoSet::DRO_00F3;                
1860             }
1861             else {
1862               hdiErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;             
1863               chanErrorWord |= SiVrbInfoSet::UNKNOWN_CHAN;            
1864             }
1865             if (dumpHtml && _htmlGen) {
1866                 _htmlGen->PutChanWord(eventNum, header, curr_word, chanErrorWord, org_word);
1867                 while (data < dataEnd) {
1868                     curr_word = next_word;
1869                     next_word=int4( (*(++data))&0xffff);
1870                     _htmlGen->ContinueDataAfterBreak( header, curr_word, chanErrorWord );
1871                 }
1872             }
1873             break;
1874           }
1875           if (dumpHtml && _htmlGen)
1876               _htmlGen->PutChanWord(eventNum, header, curr_word, chanErrorWord, org_word);
1877         }  // end of channel checking
1878         // fill chip info if ok
1879         if (fillChip) {
1880           hdiCode.setDataWord( curr_word );
1881           prev_chip=next_chip;
1882           // calculate the next expected chip ID
1883           if (hdiCode.isISL()) {
1884             if ((next_chip&0xf) == 0xc) next_chip+=0x10; // change to second ladder
1885             if ((next_chip&0xf) == 8)   next_chip+=0x20; // change side
1886             if ((next_chip&0xf) == 0x4) next_chip-=0x10; // change to first ladder
1887           }
1888           next_chip--;
1889           int chip = lastChip - hdiCode.nChip() + 1;
1890           SiChipInfo* chipInfo = 0;
1891           if (_svxDaqInfoSet && hdiInfo) {
1892             chipInfo = hdiInfo->find(chip);
1893             if(chipInfo) {
1894               chipInfo->setStatus(hdiCode.status());
1895               chipInfo->setSide(hdiCode.nSide());
1896             }
1897           }  
1898     // This is good place to check for z side and probably also for layer. Layer could 
1899     // be checked earlier, but few lines before some important code is (calculation of next chip)
1900     if (_dropForwardIsl && hdiCode.barrel()!=1)  // Drop forward and backward barrel 
1901     {
1902       break;
1903     }
1904     if (_dropISLDz && hdiCode.nSide()!=0)  // Drop SVX z side if needed 
1905     {
1906       break;
1907     }
1908     if (_dropISLL7 && hdiCode.layer()==7)  // Drop SVX z side if needed 
1909     {
1910       break;
1911     }
1912     if (_dropL00 && hdiCode.layer()==0)  // Drop SVX z side if needed 
1913     {
1914       break;
1915     }
1916 
1917           // Reserve space for the strips in this detector when new digicode encountered
1918           // seems to me there's a smarter way to figure out the space needed 
1919           // (there are up to four digicodes per HDI!) but perhaps reserving is harmless?
1920           digiCode.setPnSide( hdiCode.nSide() );
1921           digiCode.setHalfLadder( hdiCode.halfLadder() );
1922           digiCode.setPhiWedge( hdiCode.phiAddr() );
1923           if (( digiCode != lastDigiCode )||(firstDigiOfHdi)) {
1924             lastDigiCode = digiCode;
1925             firstDigiOfHdi=0;
1926             stripVector = &( stripSet[digiCode] );
1927             stripVector->reserve( ( nextHdi - hdi ) * 2 );
1928             currentVectorStrip = -1;
1929           }
1930         } // end of fill chip ID
1931         
1932         // fill this channel if its ok
1933         if (fillChan) {
1934           hdiCode.setDataWord( curr_word );
1935           int thisStrip = hdiCode.strip();
1936           if (thisStrip <= currentVectorStrip)
1937             {
1938 
1939               //ERRLOG( ELwarning, "ISLD_StorableBank out of order strip" )
1940               //        << "@SUB=TRYRun2SiStripSet::readISLDBank_nndata"
1941               //        << "Trying to fill out of order strips"
1942               //        << "HDI pointer = " << hdi
1943               //        << endmsg;
1944 
1945               // don't store strip if it's strip number is less than the previous strip
1946               // Let processing continue
1947               //return;
1948             }
1949           else
1950             {
1951               currentVectorStrip = thisStrip;
1952               stripVector->push_back( SiStrip() );
1953               SiStrip & strip = stripVector->back();
1954               strip.setGoodStrip();
1955               strip.setStripNumber( thisStrip );
1956               strip.setScaledAdc( _dataMap.rawToScaled( hdiCode.adc() ) );
1957               //strip.setFirstReadFromChip( true );
1958               strip.resetNmcIds();
1959             }
1960         } // end of fill Channel
1961 
1962         // Finally look for termination character coming up: end of the line
1963         if ((next_chan&0xf0)==0xc0) {
1964           if (next_chan==0xc2) {
1965             if (_monitorMode&&1==0) {
1966               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1967                         << std::hex << header 
1968                         << ": " << prev_word << " " << curr_word << " " << next_word 
1969                         << ": DRO at chip " << prev_chip 
1970                         << std::endl << std::dec;           
1971             }
1972             hdiErrorWord |= SiVrbInfoSet::DRO_TERM;    
1973             chanErrorWord |= SiVrbInfoSet::DRO_TERM;    
1974           }
1975           else if (next_chan!=0xc1) {
1976             if (_monitorMode&&1==0) {
1977               std::cout << "TRYRun2SiStripSet_nndata.cc: " 
1978                         << std::hex << header 
1979                         << ": " << prev_word << " " << curr_word << " " << next_word 
1980                         << ": illegal termination character at chip " 
1981                         << prev_chip << std::endl << std::dec;      
1982             }
1983             hdiErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
1984             chanErrorWord |= SiVrbInfoSet::ILLEGAL_TERM;    
1985           }
1986           if (dumpHtml && _htmlGen) {
1987               while (data < dataEnd) {
1988                   curr_word = next_word;
1989                   next_word=int4( (*(++data))&0xffff);
1990                   _htmlGen->PutTermWord( eventNum, header, curr_word, chanErrorWord,
1991                                          org_word );
1992               }
1993           }
1994           break;
1995         }
1996         prev_word=curr_word;
1997         prev_chan=curr_chan;
1998         curr_word=next_word;
1999         curr_chan=next_chan;
2000       }  // loop over Data
2001 
2002       if(hdiInfo) {
2003         hdiInfo->setLastChip(prev_chip & 0x0f);
2004         hdiInfo->setErrorWord(hdiErrorWord);
2005       }
2006       _bankReadoutError |= hdiErrorWord;
2007       }     // done with checking this HDI is not from the  SOC 
2008     }  // loop over HDI blocks
2009   }   // loop over VRB blocks
2010 }

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