diff --git a/DataQuality/DataQualityUtils/python/detmaskmod.py b/DataQuality/DataQualityUtils/python/detmaskmod.py
index f15d5c092a76acbf10e74b5520d23e4ccf1d4dff..0cbfe3ab8064c0e3302faf527122c424920bedd2 100644
--- a/DataQuality/DataQualityUtils/python/detmaskmod.py
+++ b/DataQuality/DataQualityUtils/python/detmaskmod.py
@@ -4,6 +4,7 @@ import eformat
 import operator
 
 detmaskmap = {
+    'FORWARD_AFP': 'AFP',
     'FORWARD_ALPHA': 'ALFA',
     'FORWARD_BCM': 'IDBCM',                                     
     'FORWARD_LUCID': 'LCD',                                       
@@ -44,8 +45,9 @@ detmaskmap = {
     }
 
 detmaskmap_defects = {
+    #'FORWARD_AFP': 'AFP_DISABLED', # not yet functional
     'FORWARD_ALPHA': 'ALFA_DISABLED',
-    'FORWARD_LUCID': 'LCD_DISABLED',
+    #'FORWARD_LUCID': 'LCD_DISABLED', # LUCID now operates outside ATLAS partition
     'FORWARD_ZDC': 'ZDC_DISABLED',
     'LAR_EM_BARREL_A_SIDE': 'LAR_EMBA_DISABLED',
     'LAR_EM_BARREL_C_SIDE': 'LAR_EMBC_DISABLED',
diff --git a/DataQuality/DataQualityUtils/python/hancoolmod.py b/DataQuality/DataQualityUtils/python/hancoolmod.py
index 3702a524cd7709407d1895ceca741751a504c6a3..a4f93c27eabae3e743d7d6ee0e6bf5c4a1b77c1b 100644
--- a/DataQuality/DataQualityUtils/python/hancoolmod.py
+++ b/DataQuality/DataQualityUtils/python/hancoolmod.py
@@ -332,23 +332,73 @@ def ctp_defects(d, i, runNumber):
             import detmaskmod # ugly: could happen for more than one defect - should be cheap though
             nlbs = detmaskmod.getNumLumiBlocks(runNumber)
             rv.append(defect_iov(defect, message, False, when.GetNbinsX(), nlbs+1))
-    print "The following defects were extracted: " # TODO: remove this line?
-    print rv # TODO: remove this line?
+    #print "The following defects were extracted: " # TODO: remove this line?
+    #print rv # TODO: remove this line?
     return rv
 
+def sct_lowstat_defect(d, i, runNumber):
+    histogram = d.Get('InnerDetector/SCT/Summary/tracksPerRegion')
+    if not histogram:
+        return None
+    if histogram.GetEntries() < 200:
+        return [defect_val('SCT_GLOBAL_LOWSTAT', 'Low statistics', False)]
+    else:
+        return []
+
 def sct_conf_defects(d, i, runNumber):
-    mapping = { 1: 'SCT_MOD_OUT_GT40',
-                4: 'SCT_MOD_ERR_GT40',
-                6: 'SCT_MOD_NOISE_GT40',
-                }
+    def sct_conf_defects_core(d, i, runNumber, histname, mapping):
+        rv = []
+        histogram = d.Get(histname)
+        if not histogram: 
+            return None
+        for bin in mapping:
+            if histogram.GetBinContent(bin) > 40:
+                rv.append(defect_val(mapping[bin], '%.1d modules affected' % histogram.GetBinContent(bin), False))
+        return rv
+
+    rv1 = sct_conf_defects_core(d, i, runNumber, 'InnerDetector/SCT/Summary/SCTConfOutM',
+                                { 1: 'SCT_MOD_OUT_GT40' })
+    rv2 = sct_conf_defects_core(d, i, runNumber, 'InnerDetector/SCT/Summary/SCTConfNew',
+                                { 3: 'SCT_MOD_ERR_GT40',
+                                  5: 'SCT_MOD_NOISE_GT40' })
+    if rv1 is None and rv2 is None:
+        return None
+    else:
+        return (rv1 if rv1 is not None else [])+(rv2 if rv2 is not None else [])
+
+def sct_perlb_defects(d, i, runNumber):
+    pairs = [('InnerDetector/SCT/Summary/SCT_LinksWithLinkLevelErrorsVsLbs', 
+              'SCT_PERIOD_ERR_GT40', lambda _: _ > 80),
+             ('InnerDetector/SCT/Summary/SCT_LinksWithRODLevelErrorsVsLbs', 
+              'SCT_ROD_OUT', lambda _: _ >= 1)]
 
     rv = []
-    histogram = d.Get('InnerDetector/SCT/SCTAll/ModuleStatus/SCTConf')
-    if not histogram: return None
-    for bin in mapping:
-        if histogram.GetBinContent(bin) > 40:
-            rv.append(defect_val(mapping[bin], '%.1d modules affected' % histogram.GetBinContent(bin), False))
-    return rv    
+    bad_lbs = {}
+    overflow_bad_lbs = {}
+    message = 'Automatically set'
+    foundany = False
+
+    for hname, dname, policy in pairs:
+        when = d.Get(hname)
+        if not when:
+            continue
+        foundany = True
+
+    # extract bad bins
+        bad_lbs[dname] = [bin for bin in xrange(1, when.GetNbinsX()+1) if policy(when.GetBinContent(bin))]
+        overflow_bad_lbs[dname] = policy(when.GetBinContent(when.GetNbinsX()+1))
+        
+        for lb in bad_lbs[dname]:
+            rv.append(defect_iov(dname, message, False, lb, lb+1))
+        if overflow_bad_lbs[dname]:
+            message += '; defect occurred past end of monitoring histogram, marking end of run as bad'
+            import detmaskmod # ugly: could happen for more than one defect - should be cheap though
+            nlbs = detmaskmod.getNumLumiBlocks(runNumber)
+            rv.append(defect_iov(dname, message, False, when.GetNbinsX(), nlbs+1))
+    if foundany:
+        return rv
+    else:
+        return None
 
 def iovs_merge(l):
     l.sort(key=lambda x: x.since)
@@ -371,54 +421,23 @@ def iovs_merge(l):
         rl.append(previous._replace(until=until))
     return rl
 
-def sct_readout_defects(d, i, runNumber):
-    def sct_readout_defects_core(d, prefix, l, comment):
-        import re
-        for k in d.GetListOfKeys():
-            keyname = k.GetName()
-            m = re.search(prefix + '\((\d+)', keyname)
-            if m:
-                l.append(int(m.group(1))+1)
-
-    def lb_comment(lb, l):
-        # l is a tuple name, list
-        rvl = []
-        for name, l2 in l:
-            if lb in l2:
-                rvl.append(name)
-        return ' '.join(rvl)
-
-    robfragment = d.Get('InnerDetector/SCT/SCTAll/ModuleStatus/SCTROBFragmentConf_/Results')
-    robwarnings = []; roberrors = []
-    if not robfragment: return None
-    for prefix, l in (('WarningBin', robwarnings),
-                      ('ErrorBin', roberrors)):
-        sct_readout_defects_core(robfragment, prefix, l, 'ROBFragment')
-
-    maskedlink = d.Get('InnerDetector/SCT/SCTAll/ModuleStatus/SCTMaskedLinkConf_/Results')
-    linkwarnings = []; linkerrors = []
-    if not maskedlink: return None
-    for prefix, l in (('WarningBin', linkwarnings),
-                      ('ErrorBin', linkerrors)):
-        sct_readout_defects_core(maskedlink, prefix, l, 'MaskedLink')
-    allwarnings = set(robwarnings + roberrors + linkwarnings + linkerrors)
-    namelisttuple = (('ROBFragment', robwarnings),
-                     ('MaskedLink', linkwarnings),
-                     ('ROBFragment', roberrors),
-                     ('MaskedLink', linkerrors))
-    allwarnings_defects = [defect_iov('SCT_ROD_OUT_1', lb_comment(lb, namelisttuple), False, lb, lb+1) for lb in allwarnings]
-    allwarnings_defects = iovs_merge(allwarnings_defects)
-
-    allerrors = set(roberrors + linkerrors)
-    namelisttuple = (('ROBFragment', roberrors),
-                     ('MaskedLink', linkerrors))
-    allerrors_defects = [defect_iov('SCT_GLOBAL_UNKNOWN', lb_comment(lb, namelisttuple), False, lb, lb+1) for lb in allerrors]
-    allerrors_defects = iovs_merge(allerrors_defects)
-    
-    #if allwarnings_defects: print allwarnings_defects
-    #if allerrors_defects: print allerrors_defects
-    
-    return allwarnings_defects + allerrors_defects
+def sct_eff_defect(d, i, runNumber):
+    h1 = d.Get('InnerDetector/SCT/Summary/SctTotalEffBCID_/Results/Status')
+    h2 = d.Get('InnerDetector/SCT/Summary/SctTotalEff_/Results/Status')
+    if not h1 or not h2: return None
+    badstatuses = set(['Yellow', 'Red'])
+    statuscheck = []
+    for h in h1, h2:
+        status = set(x.GetName() for x in h.GetListOfKeys())
+        if len(badstatuses & status) > 0:
+            assert len(status) == 1, 'Status must be length one or the file is corrupt'
+            statuscheck.append(True)
+        else:
+            statuscheck.append(False)
+    if all(statuscheck):
+        return [defect_val('SCT_EFF_LT99', 'Automatically set for whole run', False)]
+    else:
+        return []
 
 def dqmf_node_defect(node, defect, badstatuses=['Red']):
     badstatuses = set(badstatuses)
@@ -436,19 +455,19 @@ def dqmf_node_defect(node, defect, badstatuses=['Red']):
 def hancool_defects(runNumber, filePath="./", dbConnection="", db_tag='HEAD', isESn=True):
     import pix_defect
     analyzers = []
-    if False:
-        analyzers += [ctp_defects]
     if isESn:
-        analyzers += [dqmf_node_defect('InnerDetector/SCT/SCTAll/Hits/SctTotalEff', 'SCT_EFF_LT99', ['Yellow', 'Red']),
-                      dqmf_node_defect('InnerDetector/SCT/SCTAll/Hits/SctTotalEff', 'SCT_GLOBAL_UNKNOWN', ['Red']),
-                      dqmf_node_defect('InnerDetector/SCT/SCTAll/ModuleStatus/SCTConf', 'SCT_GLOBAL_UNKNOWN', ['Red']),
+        # CTP
+        analyzers += [ctp_defects]
+        # SCT
+        analyzers += [sct_eff_defect,
+                      sct_lowstat_defect,
                       sct_conf_defects,
-                      sct_readout_defects,
+                      sct_perlb_defects,
                       ]
 
     if ( len(filePath) == 0 or filePath[-1] != '/'):
         filePath+="/"
-    if (len(dbConnection)<1): dbConnection = "/afs/cern.ch/user/a/atlasdqm/dqmdisk1/cherrypy-devel/defectstest.db/CONDBR2"
+    if (len(dbConnection)<1): dbConnection = "/afs/cern.ch/user/a/atlasdqm/dqmdisk1/cherrypy-devel/defectstest.db/COMP200"
 
     import ROOT
     # Conflict logic: shorter intervals override longer ones
@@ -485,7 +504,8 @@ def hancool_defects(runNumber, filePath="./", dbConnection="", db_tag='HEAD', is
         globname = fnames[0][0]
         filename = os.path.basename(globname)    
         since, until = getLimits(filename)
-        defects += pix_defect.execute(runNumber, globname, until-1)
+        # disabled until fixed
+        #defects += pix_defect.execute(runNumber, globname, until-1)
 
     from DQDefects import DefectsDB
     ddb = DefectsDB(dbConnection, read_only=False)
@@ -493,7 +513,6 @@ def hancool_defects(runNumber, filePath="./", dbConnection="", db_tag='HEAD', is
         detmask_defects(runNumber, ddb)
     with ddb.storage_buffer:
         for defect in iovs_merge(defects):
-            #print defect
             ddb.insert(defect.defect, since=(runNumber << 32 | defect.since),
                        until=(runNumber << 32 | defect.until),
                        comment=defect.comment,